mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(gateway): substantive-plan gate — approach >=150 + real sub_task descriptions (#171)
Plans were vague because the gate accepted the bare minimum: PM approach >=20 chars and title-only sub_tasks. minimax wrote exactly the minimum. - IWillPlanRequest.approach min_length 20 -> 150 (kept in sync with _PM_APPROACH_MIN_LEN; the gate enforces it at the choreographer layer too so direct/MCP callers can't bypass the HTTP boundary). - New _thin_subtask_hint: every PM sub_task must have a title and a description >= _PM_SUBTASK_DESC_MIN_LEN (60) saying what the step does — each sub_task is both a delegate target AND a progress-checklist item, so a title alone is not a plan. - cell_pm/main_pm role prompts: explicit "the gate REJECTS thin plans" framing + concrete sub_task example + the new minimums. - Updated all affected test fixtures across the suite to use substantive approaches/descriptions; added thin-sub_task rejection coverage. Commit 1 of 3 for the plan/progress quality work (#171/#172/#173).
This commit is contained in:
@@ -325,8 +325,22 @@ async def test_i_will_plan_pm_with_already_active_task_rejects() -> None:
|
||||
task_id,
|
||||
plan="x" * 30,
|
||||
rich_plan={
|
||||
"approach": "Decompose planning task into backend and frontend subtasks.",
|
||||
"sub_tasks": [{"title": "Slice A", "description": "backend API work"}],
|
||||
"approach": (
|
||||
"Decompose the planning task into backend and frontend "
|
||||
"developer-claimable subtasks. Backend lands first, QA "
|
||||
"reviews each PR after it opens, documentation follows, then "
|
||||
"complete and submit up. Strict sequencing with no cross-cell "
|
||||
"dependencies beyond the stated ordering."
|
||||
),
|
||||
"sub_tasks": [
|
||||
{
|
||||
"title": "Slice A",
|
||||
"description": (
|
||||
"be-dev-1 implements the backend API change with "
|
||||
"tests and opens the leaf PR for QA review."
|
||||
),
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
body = env.as_dict()
|
||||
@@ -427,8 +441,22 @@ async def test_i_will_plan_pending_claim_fails() -> None:
|
||||
task_id,
|
||||
plan="my plan that is long enough",
|
||||
rich_plan={
|
||||
"approach": "Decompose planning task into backend and frontend subtasks.",
|
||||
"sub_tasks": [{"title": "Slice A", "description": "backend API work"}],
|
||||
"approach": (
|
||||
"Decompose the planning task into backend and frontend "
|
||||
"developer-claimable subtasks. Backend lands first, QA "
|
||||
"reviews each PR after it opens, documentation follows, then "
|
||||
"complete and submit up. Strict sequencing with no cross-cell "
|
||||
"dependencies beyond the stated ordering."
|
||||
),
|
||||
"sub_tasks": [
|
||||
{
|
||||
"title": "Slice A",
|
||||
"description": (
|
||||
"be-dev-1 implements the backend API change with "
|
||||
"tests and opens the leaf PR for QA review."
|
||||
),
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
body = env.as_dict()
|
||||
@@ -1047,8 +1075,22 @@ async def test_i_will_plan_pending_claim_returns_none_emit_rejection() -> None:
|
||||
task_id,
|
||||
plan="my plan that is long enough",
|
||||
rich_plan={
|
||||
"approach": "Decompose planning task into backend and frontend subtasks.",
|
||||
"sub_tasks": [{"title": "Slice A", "description": "backend API work"}],
|
||||
"approach": (
|
||||
"Decompose the planning task into backend and frontend "
|
||||
"developer-claimable subtasks. Backend lands first, QA "
|
||||
"reviews each PR after it opens, documentation follows, then "
|
||||
"complete and submit up. Strict sequencing with no cross-cell "
|
||||
"dependencies beyond the stated ordering."
|
||||
),
|
||||
"sub_tasks": [
|
||||
{
|
||||
"title": "Slice A",
|
||||
"description": (
|
||||
"be-dev-1 implements the backend API change with "
|
||||
"tests and opens the leaf PR for QA review."
|
||||
),
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
body = env.as_dict()
|
||||
|
||||
Reference in New Issue
Block a user