feat(consistency): coordination hygiene checks and MCP workplan_id aliases
Add C-25..C-30 fix-consistency checks for blocked-workplan inbox sweeps, stale unread triage, workplan ID prefix/collision lint, and SCOPE freshness. Extend brief generation and get_domain_summary with inbox hygiene warnings. Complete workplan_id aliases on remaining MCP tools and retry transient _api_get failures to reduce false stale-reference errors under load.
This commit is contained in:
parent
cc656a2b16
commit
9693946755
5 changed files with 819 additions and 58 deletions
|
|
@ -195,7 +195,7 @@ class TestMCPWriteTools:
|
|||
"/progress",
|
||||
{
|
||||
"topic_id": None,
|
||||
"workstream_id": "ws-1",
|
||||
"workplan_id": "ws-1",
|
||||
"task_id": None,
|
||||
"event_type": "note",
|
||||
"summary": "MCP progress",
|
||||
|
|
@ -260,7 +260,7 @@ class TestMCPWriteTools:
|
|||
"title": body["title"],
|
||||
"decision_type": body["decision_type"],
|
||||
"topic_id": body["topic_id"],
|
||||
"workstream_id": body["workstream_id"],
|
||||
"workplan_id": body.get("workplan_id"),
|
||||
"status": "open",
|
||||
"escalation_note": None,
|
||||
}
|
||||
|
|
@ -321,3 +321,74 @@ class TestMCPWriteTools:
|
|||
assert body["tool"] == "record_decision"
|
||||
assert body["error"] == "API response missing required field(s): id"
|
||||
assert [path for path, _ in calls] == ["/decisions"]
|
||||
|
||||
async def test_record_decision_accepts_workplan_id_alias(self, monkeypatch):
|
||||
calls: list[tuple[str, dict[str, Any]]] = []
|
||||
|
||||
def fake_post(path: str, body: dict[str, Any]) -> dict[str, Any]:
|
||||
calls.append((path, body))
|
||||
if path == "/decisions":
|
||||
return {
|
||||
"id": "decision-1",
|
||||
"title": body["title"],
|
||||
"decision_type": body["decision_type"],
|
||||
"topic_id": body["topic_id"],
|
||||
"workplan_id": body["workplan_id"],
|
||||
"status": "open",
|
||||
"escalation_note": None,
|
||||
}
|
||||
if path == "/progress":
|
||||
return {"id": "event-1", **body}
|
||||
raise AssertionError(f"unexpected POST {path}")
|
||||
|
||||
monkeypatch.setattr(server, "_post", fake_post)
|
||||
|
||||
body = await _call_tool(
|
||||
"record_decision",
|
||||
{
|
||||
"title": "Alias check",
|
||||
"decision_type": "made",
|
||||
"topic_id": "topic-1",
|
||||
"workplan_id": "wp-1",
|
||||
},
|
||||
)
|
||||
|
||||
assert body["id"] == "decision-1"
|
||||
assert calls[0][1]["workplan_id"] == "wp-1"
|
||||
assert calls[1][1]["workplan_id"] == "wp-1"
|
||||
|
||||
async def test_list_blocked_tasks_accepts_workplan_id_alias(self, monkeypatch):
|
||||
captured: dict[str, Any] = {}
|
||||
|
||||
def fake_get(path: str, params: dict[str, Any] | None = None) -> Any:
|
||||
captured["path"] = path
|
||||
captured["params"] = params
|
||||
return []
|
||||
|
||||
monkeypatch.setattr(server, "_get", fake_get)
|
||||
|
||||
await _call_tool("list_blocked_tasks", {"workplan_id": "wp-1"})
|
||||
|
||||
assert captured["params"]["workplan_id"] == "wp-1"
|
||||
assert captured["params"]["workstream_id"] == "wp-1"
|
||||
|
||||
async def test_record_token_event_accepts_workplan_id_alias(self, monkeypatch):
|
||||
calls: list[tuple[str, dict[str, Any]]] = []
|
||||
|
||||
def fake_post(path: str, body: dict[str, Any]) -> dict[str, Any]:
|
||||
calls.append((path, body))
|
||||
return {"id": "token-1", "tokens_total": 1500}
|
||||
|
||||
def fake_get(path: str, params: dict[str, Any] | None = None) -> Any:
|
||||
return {"tokens_total": 1500, "event_count": 1}
|
||||
|
||||
monkeypatch.setattr(server, "_post", fake_post)
|
||||
monkeypatch.setattr(server, "_get", fake_get)
|
||||
|
||||
body = await _call_tool(
|
||||
"record_token_event",
|
||||
{"tokens_in": 1000, "tokens_out": 500, "workplan_id": "wp-1"},
|
||||
)
|
||||
|
||||
assert body["event_id"] == "token-1"
|
||||
assert calls[0][1]["workplan_id"] == "wp-1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue