Sync work-record index
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8bc1f39493
commit
7ef6ba323e
3 changed files with 54 additions and 7 deletions
|
|
@ -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 ""))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue