mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
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.
114 lines
2.4 KiB
Python
114 lines
2.4 KiB
Python
"""Request schemas for /api/v2/flow/* intent verbs."""
|
|
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class GiveMeWorkRequest(BaseModel):
|
|
"""Empty request body — agent_id comes from header."""
|
|
|
|
|
|
class IWillWorkOnRequest(BaseModel):
|
|
task_id: UUID
|
|
plan: str | None = None
|
|
|
|
|
|
class SubmitForQaRequest(BaseModel):
|
|
task_id: UUID
|
|
|
|
|
|
class IAmDoneRequest(BaseModel):
|
|
task_id: UUID
|
|
notes: str = ""
|
|
|
|
|
|
class IAmBlockedRequest(BaseModel):
|
|
task_id: UUID
|
|
reason: str = Field(..., min_length=1)
|
|
|
|
|
|
class UnclaimRequest(BaseModel):
|
|
task_id: UUID
|
|
|
|
|
|
class ResumeRequest(BaseModel):
|
|
task_id: UUID
|
|
|
|
|
|
class IAmIdleRequest(BaseModel):
|
|
"""Empty request body."""
|
|
|
|
|
|
class ClaimReviewRequest(BaseModel):
|
|
task_id: UUID
|
|
|
|
|
|
class PassReviewRequest(BaseModel):
|
|
task_id: UUID
|
|
notes: str = Field(..., min_length=1)
|
|
|
|
|
|
class FailReviewRequest(BaseModel):
|
|
task_id: UUID
|
|
issues: list[str] = Field(..., min_length=1)
|
|
|
|
|
|
class ClaimDocTaskRequest(BaseModel):
|
|
task_id: UUID
|
|
|
|
|
|
class IDocumentedRequest(BaseModel):
|
|
task_id: UUID
|
|
notes: str = Field(..., min_length=1)
|
|
files: list[str] = Field(..., min_length=1)
|
|
|
|
|
|
class TriageRequest(BaseModel):
|
|
"""Empty request body."""
|
|
|
|
|
|
class UnblockRequest(BaseModel):
|
|
task_id: UUID
|
|
restore: bool = True
|
|
|
|
|
|
class CompleteRequest(BaseModel):
|
|
task_id: UUID
|
|
notes: str = Field(..., min_length=1)
|
|
|
|
|
|
class EscalateUpRequest(BaseModel):
|
|
task_id: UUID
|
|
reason: str = Field(..., min_length=1)
|
|
|
|
|
|
class EscalateToCeoRequest(BaseModel):
|
|
task_id: UUID
|
|
reason: str = Field(..., min_length=1)
|
|
|
|
|
|
class IWillPlanRequest(BaseModel):
|
|
task_id: UUID
|
|
plan: str = Field(..., min_length=1)
|
|
|
|
|
|
class DelegateRequest(BaseModel):
|
|
parent_task_id: UUID
|
|
title: str = Field(..., min_length=1)
|
|
description: str = Field(..., min_length=1)
|
|
assigned_to: str = Field(..., min_length=1)
|
|
team: str = Field(..., min_length=1)
|
|
# task_type is REQUIRED. The 2026-05-08 trace showed agents omitting
|
|
# it and the old default of 'code' deadlocking the lifecycle. Force
|
|
# callers to declare intent: code | documentation | research |
|
|
# planning | design | administrative.
|
|
task_type: str = Field(..., min_length=1)
|
|
acceptance_criteria: list[str] | None = None
|
|
estimated_complexity: str = "medium"
|
|
|
|
|
|
class SubmitUpRequest(BaseModel):
|
|
task_id: UUID
|
|
notes: str = Field(..., min_length=1)
|