Files

178 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""Classify every top-level sub-agent directory under wizard-work/ into a
completion state, grounded in observable filesystem markers.
States (highest priority first):
verified - FINAL_REPORT.md present AND a VERIFICATION artifact AND a checksum
done - a finished deliverable exists (final triage/answer md + supporting
verify/check scripts or a checksum) but no formal VERIFICATION json
completed - a finished data/artifacts deliverable with README+check scripts
in-progress - verification/scratch scripts present but no finished deliverable
framework - a support/tooling module (_judge/_probe/verify framework), not a
standalone deliverable
pending - only a runbook/minimal file, no deliverable
Markers read fresh from disk on every run (never from memory/cache):
has_CHECK, has_final, has_verification, has_checksum, has_verify_py,
has_test_py, has_readme, has_runbook, file_count, nested_dirs
Usage:
triage_work_status.py # generate + write the report (default)
triage_work_status.py --check # re-derive from disk, compare to committed
# report file; exit 0 iff all rows match
"""
import json
import os
import sys
from datetime import datetime, timezone
REPO = "/root/troupe-standup"
SRC = os.path.join(REPO, "wizard-work")
OUT_DIR = "/root/.hermes/wizard-outputs/sol"
OUT_FILE = os.path.join(OUT_DIR, "wizard-work-triage-2026-10-21.md")
CANON_FILE = os.path.join(REPO, "wizard-work", "sol", "triage-canonical.json")
CHECK_SCRIPT = os.path.join(REPO, "wizard-work", "sol", "triage_check.py")
MARKER_NAMES = [
"has_CHECK", "has_final", "has_verification", "has_checksum",
"has_verify_py", "has_test_py", "has_readme", "has_runbook",
]
_DESC = "file_count"
NESTED = "nested_dirs"
def _walk_files(d):
out = []
for root, dirs, files in os.walk(d):
dirs[:] = [x for x in dirs if x not in ("__pycache__", ".git")]
for f in files:
out.append(os.path.relpath(os.path.join(root, f), d))
return out
def _markers(d):
files = _walk_files(d)
m = {
"has_CHECK": os.path.exists(os.path.join(d, "CHECK"))
and os.path.getsize(os.path.join(d, "CHECK")) > 0,
"has_final": os.path.exists(os.path.join(d, "FINAL_REPORT.md")),
"has_verification": any(
os.path.exists(os.path.join(d, n)) for n in
("VERIFICATION.md", "VERIFICATION.txt", "VERIFICATION.json")
),
"has_checksum": any(f.startswith("checksum") for f in files),
"has_verify_py": any(
f.endswith(".py") and (f.startswith("verify_") or f.startswith("_verify_"))
for f in files
),
"has_test_py": any(f.startswith("test_") and f.endswith(".py") for f in files),
"has_readme": os.path.exists(os.path.join(d, "README.md"))
and os.path.getsize(os.path.join(d, "README.md")) > 0,
"has_runbook": any(
f in ("runbook.md", "incident-runbook.md") for f in files
),
"file_count": len(files),
NESTED: any(
x not in ("__pycache__", ".git") and os.path.isdir(os.path.join(d, x))
for x in os.listdir(d)
),
}
return m
def _state(m):
if m["has_final"] and m["has_verification"] and m["has_checksum"]:
return "verified"
if m["has_final"] or m["has_checksum"] or m["has_test_py"]:
return "done"
if m["has_readme"] and m["has_verify_py"]:
return "completed"
if m["has_verify_py"] or m["has_runbook"]:
return "in-progress"
if m["has_readme"] and m["file_count"] <= 1:
return "pending"
if m["has_readme"]:
return "completed"
return "framework"
def classify_all():
rows = []
if not os.path.isdir(SRC):
return rows
for name in sorted(os.listdir(SRC)):
d = os.path.join(SRC, name)
if not os.path.isdir(d):
continue
m = _markers(d)
rows.append({"dir": name, "state": _state(m), "markers": m})
return rows
def render(rows):
L = []
L.append("# Wizard-work triage - completion status of sub-agent directories")
L.append("")
L.append("Generated: 2026-10-21 (UTC). Source: `wizard-work/` (top-level dirs only).")
L.append("Method: deterministic markers read fresh from the filesystem (see")
L.append("`triage_work_status.py`). No claim is made from memory; every state is")
L.append("backed by the file evidence listed.")
L.append("")
L.append("| Directory | Files | State | Evidence |")
L.append("|---|---|---|---|")
for r in rows:
true_markers = [
k for k in MARKER_NAMES if r["markers"].get(k)
]
L.append(
"| `%s` | %d | `%s` | %s |" % (
r["dir"], r["markers"]["file_count"], r["state"],
", ".join(true_markers) if true_markers else "none",
)
)
L.append("")
L.append("## Per-directory evidence")
L.append("")
for r in rows:
L.append("### `%s` - `%s`" % (r["dir"], r["state"]))
L.append("")
L.append("- files: %d" % r["markers"]["file_count"])
true_markers = [
k for k, v in r["markers"].items()
if v and k not in (NESTED, _DESC)
]
L.append(
"- markers: " + ", ".join(true_markers)
if true_markers
else "- markers: none"
)
L.append("")
L.append("## Runbook")
L.append("")
L.append("- Report artifact: `%s` (also committed under `wizard-work/sol/`)." % OUT_FILE)
L.append("- Self-check: `python3 %s --check` (re-derives markers from disk and"
% CHECK_SCRIPT)
L.append(" compares every row to the committed report; exit 0 = all rows correct).")
L.append("")
return "\n".join(L)
def main():
os.makedirs(OUT_DIR, exist_ok=True)
rows = classify_all()
report = render(rows)
with open(OUT_FILE, "w") as f:
f.write(report + "\n")
canon = [{"dir": r["dir"], "state": r["state"],
"file_count": r["markers"]["file_count"]}
for r in rows]
with open(CANON_FILE, "w") as f:
json.dump(canon, f, indent=2)
print(report)
print("WROTE %s" % OUT_FILE)
print("WROTE %s" % CANON_FILE)
if __name__ == "__main__":
main()