feat(consistency): add C-13 workstream-auto-complete check
Detects when all DB tasks are done/cancelled but the workstream status is still 'active' — the pattern where a worker completes tasks via MCP but forgets to call update_workstream_status(). Auto-fixable via --fix. Also extends the C-04/C-05 fix path to handle C-13 (same PATCH logic). Motivated by marki-docx WP-0001/WP-0002 visibility gap (2026-03-16). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ Checks:
|
|||||||
C-10 task-status-drift WARN Yes Task status differs between file and DB
|
C-10 task-status-drift WARN Yes Task status differs between file and DB
|
||||||
C-11 task-unlinked WARN Yes Task block has no state_hub_task_id
|
C-11 task-unlinked WARN Yes Task block has no state_hub_task_id
|
||||||
C-12 orphan-db-task WARN No DB task in workstream has no file backing
|
C-12 orphan-db-task WARN No DB task in workstream has no file backing
|
||||||
|
C-13 workstream-auto-complete WARN Yes All DB tasks done but workstream still active
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
python scripts/consistency_check.py --repo SLUG [--fix] [--json] [--api-base URL]
|
python scripts/consistency_check.py --repo SLUG [--fix] [--json] [--api-base URL]
|
||||||
@@ -535,6 +536,32 @@ def check_repo(api_base: str, repo_slug: str) -> ConsistencyReport:
|
|||||||
fixable=False,
|
fixable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# C-13: all DB tasks done but workstream still active — worker forgot to close
|
||||||
|
db_status = ws.get("status", "")
|
||||||
|
if db_status == "active" and isinstance(db_tasks, list) and db_tasks:
|
||||||
|
non_terminal = [
|
||||||
|
t for t in db_tasks
|
||||||
|
if t.get("status") not in ("done", "cancelled")
|
||||||
|
]
|
||||||
|
if not non_terminal:
|
||||||
|
report.add(
|
||||||
|
severity="WARN", check_id="C-13",
|
||||||
|
message=(
|
||||||
|
f"All {len(db_tasks)} DB tasks for '{ws.get('slug')}' are "
|
||||||
|
f"done/cancelled but workstream status is still 'active' — "
|
||||||
|
f"worker likely forgot update_workstream_status()"
|
||||||
|
),
|
||||||
|
file_path=fname,
|
||||||
|
db_id=ws_id,
|
||||||
|
db_value="active",
|
||||||
|
fixable=True,
|
||||||
|
_fix_context={
|
||||||
|
"ws_id": ws_id,
|
||||||
|
"field": "status",
|
||||||
|
"value": "completed",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
# C-07 / C-08: orphan DB workstreams (have repo_id=this_repo but no backing file)
|
# C-07 / C-08: orphan DB workstreams (have repo_id=this_repo but no backing file)
|
||||||
_check_orphan_db(api_base, repo_id, set(file_ws_ids.keys()), report)
|
_check_orphan_db(api_base, repo_id, set(file_ws_ids.keys()), report)
|
||||||
|
|
||||||
@@ -588,7 +615,7 @@ def fix_repo(api_base: str, repo_slug: str) -> ConsistencyReport:
|
|||||||
for issue in fixable:
|
for issue in fixable:
|
||||||
ctx = issue._fix_context
|
ctx = issue._fix_context
|
||||||
try:
|
try:
|
||||||
if issue.check_id in ("C-04", "C-05"):
|
if issue.check_id in ("C-04", "C-05", "C-13"):
|
||||||
ws_id = ctx["ws_id"]
|
ws_id = ctx["ws_id"]
|
||||||
result = _api_patch(api_base, f"/workstreams/{ws_id}",
|
result = _api_patch(api_base, f"/workstreams/{ws_id}",
|
||||||
{ctx["field"]: ctx["value"]})
|
{ctx["field"]: ctx["value"]})
|
||||||
|
|||||||
Reference in New Issue
Block a user