generated from coulomb/repo-seed
feat(tasks): add needs_human intervention flag (CUST-WP-0009)
- Migration b4c5d6e7f8a9: adds needs_human (bool) + intervention_note (text) to tasks - API: needs_human filter on GET /tasks/; 422 if flagged without note - 3 MCP tools: flag_for_human, clear_human_flag, list_human_interventions - Dashboard: interventions.md with amber cards and "Mark done" button - Policy router + workstream DoD policy (workstream-dod.md) - Workstream lifecycle docs page + workplan CUST-WP-0010 - CLAUDE.md: add step 4 (run fix-consistency after workplan writes) - consistency_check.py: promote C-11 unlinked tasks from INFO to WARN Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -321,6 +321,71 @@ def update_task_status(
|
||||
return json.dumps(task, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def flag_for_human(task_id: str, note: str) -> str:
|
||||
"""Flag a task as requiring human intervention.
|
||||
|
||||
Sets needs_human=True and records the required action as intervention_note.
|
||||
Emits a progress event so the flag is visible in session history.
|
||||
|
||||
Args:
|
||||
task_id: UUID of the task to flag
|
||||
note: description of the action required from the human (required)
|
||||
"""
|
||||
task = _patch(f"/tasks/{task_id}", {
|
||||
"needs_human": True,
|
||||
"intervention_note": note,
|
||||
})
|
||||
_post("/progress", {
|
||||
"task_id": task_id,
|
||||
"workstream_id": task.get("workstream_id"),
|
||||
"event_type": "task_flagged_human",
|
||||
"summary": f"Task flagged for human intervention: {task['title']}",
|
||||
"author": "custodian",
|
||||
"detail": {"intervention_note": note},
|
||||
})
|
||||
return json.dumps(task, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def clear_human_flag(task_id: str) -> str:
|
||||
"""Clear the human-intervention flag from a task.
|
||||
|
||||
Sets needs_human=False. The intervention_note is preserved as a
|
||||
historical record. Call this after the human has completed the action.
|
||||
|
||||
Args:
|
||||
task_id: UUID of the task to clear
|
||||
"""
|
||||
task = _patch(f"/tasks/{task_id}", {
|
||||
"needs_human": False,
|
||||
})
|
||||
_post("/progress", {
|
||||
"task_id": task_id,
|
||||
"workstream_id": task.get("workstream_id"),
|
||||
"event_type": "task_flag_cleared",
|
||||
"summary": f"Human-intervention flag cleared: {task['title']}",
|
||||
"author": "custodian",
|
||||
})
|
||||
return json.dumps(task, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def list_human_interventions(workstream_id: str | None = None) -> str:
|
||||
"""List all tasks flagged for human intervention.
|
||||
|
||||
Returns tasks where needs_human=True, optionally filtered to one workstream.
|
||||
Use this at session start to surface Bernd's action items.
|
||||
|
||||
Args:
|
||||
workstream_id: optional UUID to scope results to one workstream
|
||||
"""
|
||||
return json.dumps(
|
||||
_get("/tasks", {"needs_human": "true", "workstream_id": workstream_id}),
|
||||
indent=2,
|
||||
)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def record_decision(
|
||||
title: str,
|
||||
|
||||
Reference in New Issue
Block a user