Sync work-record index
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 7s
Python Tests / pytest (push) Successful in 22s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
codex 2026-10-11 23:06:25 +02:00
parent 8bc1f39493
commit 7ef6ba323e
3 changed files with 54 additions and 7 deletions

View file

@ -2,12 +2,13 @@
"""Deterministic flow report for the NetKingdom security estate.
Replaces agent sessions that poll wait tasks. Reads workplan files only (no hub,
no network) and prints four lists:
no network) and prints five lists:
READY todo/progress tasks in non-residual workplans: what agents should work on
READY todo/progress tasks with no unresolved explicit dependency or owner/human gate
UNBLOCKED wait tasks whose every depends_on target is done/cancel: requalify to todo
ATTENDED needs_human wait tasks: the attended-window checklist for the operator/founder
STALLED wait tasks qualified only by blocked_on message-from (owner reply), oldest first by file
DEPENDENT todo/progress tasks that still carry an unresolved dependency or owner gate
Usage: security_flow_report.py [--repos a,b,c] [--json]
"""
@ -54,13 +55,19 @@ def classify(tasks):
own = [t for t in tasks.values() if t["id"].startswith(d + "-T")]
return bool(own) and all(t["status"] in TERMINAL for t in own)
out = {"READY": [], "UNBLOCKED": [], "ATTENDED": [], "STALLED": []}
out = {"READY": [], "UNBLOCKED": [], "ATTENDED": [], "STALLED": [], "DEPENDENT": []}
for t in tasks.values():
wp = t["wp"]
if wp["status"] in ("finished", "archived") or wp["flavor"] == "residual":
continue
if t["status"] in ("todo", "progress"):
out["READY"].append(t)
missing = [d for d in t["deps"] if not dep_done(d)]
if t["human"]:
out["ATTENDED"].append(t)
elif missing or t["blocked_on"]:
out["DEPENDENT"].append(t | {"pending_dependencies": missing})
else:
out["READY"].append(t)
elif t["status"] == "wait":
if t["human"]:
out["ATTENDED"].append(t)
@ -83,12 +90,16 @@ def main():
res = classify(load(a.root, a.repos.split(",")))
if a.json:
print(json.dumps({k: [{x: t[x] for x in ("id", "status", "priority", "reason", "blocked_on")}
| {"repo": t["wp"]["repo"]} for t in v] for k, v in res.items()}, indent=1))
| {"repo": t["wp"]["repo"]}
| ({"pending_dependencies": t["pending_dependencies"]} if k == "DEPENDENT" else {})
for t in v] for k, v in res.items()}, indent=1))
return
for k, v in res.items():
print(f"\n## {k} ({len(v)})")
for t in v:
extra = t["blocked_on"] if k == "STALLED" else t["reason"]
if k == "DEPENDENT":
extra = ", ".join(t["pending_dependencies"]) or t["blocked_on"]
print(f"- {t['id']} [{t['status']}/{t['priority'] or '-'}] {t['wp']['repo']}"
+ (f" — {extra[:140]}" if extra else ""))