chore(plans): make kind=plan retirement consistent across MCP, REST, UI, skills
Audit of the plugin + MCP surface after milestone-as-plan (T3): every path that could still create a kind=plan task or describe the old plan-task model is now aligned with the hard-retire decision. - create_task (MCP + REST POST /api/tasks): reject kind=plan with a message pointing to start_planning. The 'plan' enum value stays valid so legacy plan-tasks remain readable; update paths never touch kind, so they round-trip. - create_task / get_task docstrings: 'plan' dropped from creatable kinds; get_task's rules-augmentation noted as legacy-only (get_milestone for new plans). - skills/writing-plans: rewritten for milestone-as-plan (body = design, steps = child tasks, get_milestone to read back). - skills/using-scribe: "plans live in milestones via start_planning", not kind=plan. - TaskEditorView Kind selector: offers Work/Issue; "Plan (legacy)" shown only when the loaded task is already kind=plan (display round-trip). - test: create_task rejects kind=plan. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,16 @@ async def test_create_task_passes_status():
|
||||
assert mock.call_args.kwargs["status"] == "todo"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_task_rejects_retired_plan_kind():
|
||||
"""kind=plan is hard-retired — plans are milestones (start_planning)."""
|
||||
mock = AsyncMock()
|
||||
with patch("scribe.mcp.tools.tasks.notes_svc.create_note", mock):
|
||||
with pytest.raises(ValueError, match="kind=plan is retired"):
|
||||
await create_task(title="x", kind="plan")
|
||||
assert not mock.called # never reached the create
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_task_priority_empty_becomes_none():
|
||||
fake = _fake_task()
|
||||
|
||||
Reference in New Issue
Block a user