Files
roboco/tests/unit/api/test_schemas_v2_flow.py
T
Renn F 01ff44b83f fix(gateway): unblock PM planning + drop magic delegate task_type
Two coupled fixes from the 2026-05-08 smoke-test trace:

1. pm_cannot_execute_code is now scoped to i_will_work_on (the
   EXECUTION verb) only. Pre-fix it also fired on i_will_plan, which
   deadlocked any code-typed parent: cell_pm couldn't plan, so couldn't
   transition parent to in_progress, so couldn't delegate. PMs PLAN
   code-typed parents and DELEGATE the work — that's exactly the verb
   we were blocking.

2. delegate.task_type is now REQUIRED at both the HTTP boundary
   (DelegateRequest) and the choreographer dataclass (DelegateInputs).
   The pre-fix default of 'code' silently changed semantics whenever a
   caller forgot the field — main-pm's call in the smoke trace omitted
   it, schema defaulted to 'code', and the cell PM downstream was
   wedged. Also drops the choreographer's task.task_type fallback
   (the DB column is NOT NULL anyway).

Plus middleware coverage tests for the parallel ServiceError →
4xx handler hierarchy added in the prior session, restoring 100%
coverage across the touched files.

Tests: 3101 passing, 100% coverage, ruff clean.
2026-05-08 07:45:18 +02:00

43 lines
1.3 KiB
Python

"""Schema-level tests for v2 flow request bodies."""
from __future__ import annotations
from uuid import uuid4
import pytest
from pydantic import ValidationError
from roboco.api.schemas.v2.flow import DelegateRequest
def test_delegate_request_requires_task_type() -> None:
"""task_type must be supplied explicitly — no magic default.
Background: the 2026-05-08 smoke-test trace showed main-pm calling
delegate without task_type, the schema defaulted to 'code', the
cell PM downstream couldn't plan a code-typed parent (pre-fix), and
the run deadlocked. Make the field required so misuse fails at the
HTTP boundary with a clear 422.
"""
with pytest.raises(ValidationError) as exc:
DelegateRequest(
parent_task_id=uuid4(),
title="t",
description="d",
assigned_to="be-dev-1",
team="backend",
# task_type intentionally omitted
)
assert "task_type" in str(exc.value)
def test_delegate_request_accepts_explicit_task_type() -> None:
req = DelegateRequest(
parent_task_id=uuid4(),
title="t",
description="d",
assigned_to="be-dev-1",
team="backend",
task_type="code",
)
assert req.task_type == "code"