Finish STATE-WP-0069: retire legacy completion event and DELETE /workstreams
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Stop dual-publishing org.statehub.workstream.completed; return 410 Gone for
legacy DELETE /workstreams/{id}. Migrate fix-consistency, MCP adhoc bootstrap,
and dashboard token summary to /workplans/. Add legacy-meter evidence capture
script and pytest snapshot; update docs and close out the workplan.
This commit is contained in:
tegwick 2026-07-08 23:36:58 +02:00
parent b659ff8d13
commit e0c954d098
13 changed files with 404 additions and 149 deletions

View file

@ -904,7 +904,7 @@ def check_repo(api_base: str, repo_slug: str, repo_path_override: str | None = N
)
continue
ws = _api_get(api_base, f"/workstreams/{ws_id}")
ws = _api_get(api_base, f"/workplans/{ws_id}")
if ws is None:
# C-03: stale workstream reference
report.add(
@ -1079,7 +1079,7 @@ def check_repo(api_base: str, repo_slug: str, repo_path_override: str | None = N
for t in db_tasks:
db_task_by_id[t["id"]] = t
existing_deps = _api_get(api_base, f"/workstreams/{ws_id}/dependencies") or []
existing_deps = _api_get(api_base, f"/workplans/{ws_id}/dependencies") or []
existing_dep_keys = set()
if isinstance(existing_deps, list):
for dep in existing_deps:
@ -1376,7 +1376,7 @@ def _check_orphan_db(
) -> None:
"""Flag DB workstreams with repo_id=this_repo that have no backing workplan file."""
active_file_ws_ids = active_file_ws_ids or file_ws_ids
all_ws = _api_get(api_base, "/workstreams", {"repo_id": repo_id})
all_ws = _api_get(api_base, "/workplans", {"repo_id": repo_id})
if not isinstance(all_ws, list):
return
for ws in all_ws:
@ -1434,14 +1434,14 @@ def _check_ghost_duplicates(
# Gather topic_ids from all file-backed workstreams so we can query by topic
topic_ids: set[str] = set()
for ws_id in file_ws_ids:
ws = _api_get(api_base, f"/workstreams/{ws_id}")
ws = _api_get(api_base, f"/workplans/{ws_id}")
if ws and ws.get("topic_id"):
topic_ids.add(ws["topic_id"])
for topic_id in topic_ids:
topic_ws: list[dict] = []
for status in OPEN_WORKSTREAM_STATUSES:
status_rows = _api_get(api_base, "/workstreams", {"topic_id": topic_id, "status": status})
status_rows = _api_get(api_base, "/workplans", {"topic_id": topic_id, "status": status})
if isinstance(status_rows, list):
topic_ws.extend(status_rows)
for ws in topic_ws:
@ -2004,12 +2004,12 @@ def _write_custodian_brief(api_base: str, repo_slug: str, repo_path: str) -> boo
# so that a fully-finished repo doesn't degrade to "(unknown)".
workstreams: list[dict] = []
for status in OPEN_WORKSTREAM_STATUSES:
rows = _api_get(api_base, "/workstreams", {"repo_id": repo_id, "status": status}) or []
rows = _api_get(api_base, "/workplans", {"repo_id": repo_id, "status": status}) or []
if isinstance(rows, list):
workstreams.extend(rows)
_ws_for_domain = workstreams if workstreams else []
if not _ws_for_domain:
all_ws = _api_get(api_base, "/workstreams", {"repo_id": repo_id}) or []
all_ws = _api_get(api_base, "/workplans", {"repo_id": repo_id}) or []
_ws_for_domain = all_ws if isinstance(all_ws, list) else []
if _ws_for_domain:
topic = _api_get(api_base, f"/topics/{_ws_for_domain[0].get('topic_id', '')}")
@ -2301,7 +2301,7 @@ def fix_repo(
try:
if issue.check_id in ("C-04", "C-05", "C-13", "C-19"):
ws_id = ctx["ws_id"]
result = _api_patch(api_base, f"/workstreams/{ws_id}",
result = _api_patch(api_base, f"/workplans/{ws_id}",
{ctx["field"]: ctx["value"]})
if result is not None and "_error" not in result:
report.fixes_applied.append(
@ -2317,7 +2317,7 @@ def fix_repo(
elif issue.check_id == "C-23":
ws_id = ctx["ws_id"]
target_status = ctx["target_status"]
result = _api_patch(api_base, f"/workstreams/{ws_id}", {"status": target_status})
result = _api_patch(api_base, f"/workplans/{ws_id}", {"status": target_status})
if result is not None and "_error" not in result:
report.fixes_applied.append(
f"C-23 fixed: workstream {ws_id[:8]}… status → {target_status!r}"
@ -2401,7 +2401,7 @@ def fix_repo(
ws_data = None
last_error = None
for slug in slug_candidates:
existing = _api_get(api_base, "/workstreams", {"slug": slug}, return_error=True)
existing = _api_get(api_base, "/workplans", {"slug": slug}, return_error=True)
if isinstance(existing, dict) and "_error" in existing:
last_error = existing["_error"]
continue
@ -2419,7 +2419,7 @@ def fix_repo(
last_error = f"slug {slug!r} already belongs to another workstream"
continue
ws_data = _api_post(api_base, "/workstreams", {
ws_data = _api_post(api_base, "/workplans", {
"topic_id": topic_id,
"repo_id": repo_id_val,
"slug": slug,
@ -2484,7 +2484,7 @@ def fix_repo(
elif issue.check_id == "C-09":
ws_id = ctx["ws_id"]
correct_repo_id = ctx["correct_repo_id"]
result = _api_patch(api_base, f"/workstreams/{ws_id}",
result = _api_patch(api_base, f"/workplans/{ws_id}",
{"repo_id": correct_repo_id})
if result is not None:
report.fixes_applied.append(
@ -2499,7 +2499,7 @@ def fix_repo(
"to_task_id": ctx.get("to_task_id"),
"relationship_type": ctx["relationship_type"],
}
result = _api_post(api_base, f"/workstreams/{from_workstream_id}/dependencies", body)
result = _api_post(api_base, f"/workplans/{from_workstream_id}/dependencies", body)
if result is not None and "_error" not in result:
target = ctx.get("to_workstream_id") or ctx.get("to_task_id")
report.fixes_applied.append(