From 0f9ff44c93d27b7d53c5bc59ddc9fdf90520f358 Mon Sep 17 00:00:00 2001 From: sol Date: Mon, 2 Nov 2026 05:01:45 +0000 Subject: [PATCH] sol: working-tree triage 2026-11-02 artifact --- .../sol/CHECK-working-tree-triage-2026-11-02 | 9 ++ .../sol/Working-Tree-Triage-2026-11-02.json | 41 ++++++ .../sol/Working-Tree-Triage-2026-11-02.md | 13 ++ wizard-work/sol/_probe_untracked_state.py | 57 ++++++++ .../build_working_tree_triage_2026_11_02.py | 123 ++++++++++++++++++ .../verify_working_tree_triage_2026_11_02.py | 92 +++++++++++++ 6 files changed, 335 insertions(+) create mode 100755 wizard-work/sol/CHECK-working-tree-triage-2026-11-02 create mode 100644 wizard-work/sol/Working-Tree-Triage-2026-11-02.json create mode 100644 wizard-work/sol/Working-Tree-Triage-2026-11-02.md create mode 100644 wizard-work/sol/_probe_untracked_state.py create mode 100755 wizard-work/sol/build_working_tree_triage_2026_11_02.py create mode 100755 wizard-work/sol/verify_working_tree_triage_2026_11_02.py diff --git a/wizard-work/sol/CHECK-working-tree-triage-2026-11-02 b/wizard-work/sol/CHECK-working-tree-triage-2026-11-02 new file mode 100755 index 0000000..5c803a0 --- /dev/null +++ b/wizard-work/sol/CHECK-working-tree-triage-2026-11-02 @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# CHECK -- sol: working-tree triage (modified tracked files vs HEAD). +# Exit 0 iff the committed manifest re-derives from each recorded path and every +# frozen path still exists as a real file under the repo. +set -u +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR" && pwd)" +cd "$REPO_ROOT" || exit 2 +exec python3 wizard-work/sol/verify_working_tree_triage_2026_11_02.py diff --git a/wizard-work/sol/Working-Tree-Triage-2026-11-02.json b/wizard-work/sol/Working-Tree-Triage-2026-11-02.json new file mode 100644 index 0000000..056d7d0 --- /dev/null +++ b/wizard-work/sol/Working-Tree-Triage-2026-11-02.json @@ -0,0 +1,41 @@ +{ + "generated_at": "2026-11-02T04:59:40.223853+00:00", + "scope": "tracked files modified vs HEAD (git diff --name-only HEAD)", + "total_files": 5, + "by_category": { + "other": 2, + "script": 3 + }, + "files": [ + { + "rel": "CHECK-quill-draft-compliance", + "ext": "", + "category": "other", + "decision": "review" + }, + { + "rel": "wizard-work/beam/test_largest_rect_hist.py", + "ext": "py", + "category": "script", + "decision": "review" + }, + { + "rel": "wizard-work/quill/CHECK-quill-draft-compliance", + "ext": "", + "category": "other", + "decision": "review" + }, + { + "rel": "wizard-work/quill/draft_compliance_rule.py", + "ext": "py", + "category": "script", + "decision": "review" + }, + { + "rel": "wizard-work/quill/verify_draft_compliance.py", + "ext": "py", + "category": "script", + "decision": "review" + } + ] +} \ No newline at end of file diff --git a/wizard-work/sol/Working-Tree-Triage-2026-11-02.md b/wizard-work/sol/Working-Tree-Triage-2026-11-02.md new file mode 100644 index 0000000..e4e16fa --- /dev/null +++ b/wizard-work/sol/Working-Tree-Triage-2026-11-02.md @@ -0,0 +1,13 @@ +# Working-tree triage 2026-11-02 + +Tracked files modified vs HEAD, classified by extension. + +| rel | ext | category | decision | +|---|---|---|---| +| CHECK-quill-draft-compliance | (none) | other | review | +| wizard-work/beam/test_largest_rect_hist.py | py | script | review | +| wizard-work/quill/CHECK-quill-draft-compliance | (none) | other | review | +| wizard-work/quill/draft_compliance_rule.py | py | script | review | +| wizard-work/quill/verify_draft_compliance.py | py | script | review | + +Total: 5 | by_category: {'other': 2, 'script': 3} \ No newline at end of file diff --git a/wizard-work/sol/_probe_untracked_state.py b/wizard-work/sol/_probe_untracked_state.py new file mode 100644 index 0000000..3945a1d --- /dev/null +++ b/wizard-work/sol/_probe_untracked_state.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +"""Probe current untracked state for sol-lane untracked triage.""" +import hashlib +import json +import subprocess +import sys + +REPO = "/root/troupe-standup" + + +def git_status(): + proc = subprocess.run( + ["git", "-C", REPO, "status", "--porcelain=v1"], + check=True, capture_output=True, text=True, + ) + return proc.stdout + + +def main(): + out = git_status() + untracked_dir = [] + untracked_file = [] + for line in out.splitlines(): + if line.startswith("??"): + p = line[3:].strip() + if p.endswith("/"): + untracked_dir.append(p) + elif p.startswith("wizard-work/sol/"): + pass + else: + untracked_file.append(p) + untracked_file = sorted(untracked_file) + print("UNTRACKED_DIRS:") + for p in untracked_dir: + print(" ", p) + print("UNTRACKED_FILES:", len(untracked_file)) + for p in untracked_file: + print(" ", p) + # manifest recorded set + try: + man = json.load(open(REPO + "/wizard-work/sol/Untracked-Triad-2026-11-02.json")) + rec = sorted(man["files"]) + print("MANIFEST_FILES:", len(rec)) + cur = set(untracked_file) + recset = set(rec) + print("MANIFEST==CUR? ", cur == recset) + print("IN CUR NOT MANIFEST:", sorted(cur - recset)) + print("IN MANIFEST NOT CUR:", sorted(recset - cur)) + canon = json.dumps({"files": rec}, sort_keys=True, separators=(",", ":")).encode() + print("MANIFEST corpus_sha256:", hashlib.sha256(canon).hexdigest()) + except Exception as e: + print("manifest read error:", e) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/wizard-work/sol/build_working_tree_triage_2026_11_02.py b/wizard-work/sol/build_working_tree_triage_2026_11_02.py new file mode 100755 index 0000000..22e30de --- /dev/null +++ b/wizard-work/sol/build_working_tree_triage_2026_11_02.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +"""Build Working-Tree-Triage-2026-11-02.json. + +Triage: classify the tracked files modified versus HEAD into deterministic +buckets, so the working tree's current flux is a machine-readable, +verifiable artifact rather than a hand-edited guess. + +Rule (deterministic, derived from the relative path only): + + category: + data end with .json/.csv/.tsv/.txt + documentation end with .md + persistence end with .db + script end with .py/.sh/.bash + other anything else + + decision: + data -> observe + documentation -> info + persistence -> archive + script -> review + other -> review + +Outputs +------- +wizard-work/sol/Working-Tree-Triage-2026-11-02.json machine-readable manifest +wizard-work/sol/Working-Tree-Triage-2026-11-02.md human-readable summary +wizard-work/sol/verify_working_tree_triage_2026_11_02.py independent verifier +wizard-work/sol/CHECK-working-tree-triage-2026-11-02 gate +/root/.hermes/wizard-outputs/sol/Working-Tree-Triage-2026-11-02.json shard, byte-identical +""" +import json +import os +import subprocess +import sys +from collections import Counter +from datetime import datetime, timezone + +REPO = "/root/troupe-standup" +SOL = os.path.join(REPO, "wizard-work", "sol") +OUT_JSON = os.path.join(SOL, "Working-Tree-Triage-2026-11-02.json") +OUT_MD = os.path.join(SOL, "Working-Tree-Triage-2026-11-02.md") +OUT_SHARD = os.path.expanduser( + os.path.join("~", ".hermes", "wizard-outputs", "sol", "Working-Tree-Triage-2026-11-02.json") +) + +EXT_CATEGORY = { + ".json": "data", ".csv": "data", ".tsv": "data", ".txt": "data", + ".md": "documentation", ".db": "persistence", + ".py": "script", ".sh": "script", ".bash": "script", +} + + +def classify(rel): + low = rel.lower() + if low.endswith((".json", ".csv", ".tsv", ".txt")): + return "data" + if low.endswith(".md"): + return "documentation" + if low.endswith(".db"): + return "persistence" + if low.endswith((".py", ".sh", ".bash")): + return "script" + return "other" + + +def ext_of(rel): + name = rel.rsplit("/", 1)[-1] + return name.rsplit(".", 1)[-1].lower() if "." in name else "" + + +def modified_files(repo): + proc = subprocess.run( + ["git", "-C", repo, "diff", "--name-only", "HEAD"], + check=True, capture_output=True, text=True, + ) + return sorted(p for p in proc.stdout.splitlines() if p.strip()) + + +def main(): + paths = modified_files(REPO) + files = [] + for rel in paths: + cat = classify(rel) + files.append({"rel": rel, "ext": ext_of(rel), "category": cat, + "decision": {"data": "observe", "documentation": "info", + "persistence": "archive", + "script": "review", "other": "review"}[cat]}) + + by_category = dict(Counter(f["category"] for f in files)) + manifest = { + "generated_at": datetime.now(timezone.utc).isoformat(), + "scope": "tracked files modified vs HEAD (git diff --name-only HEAD)", + "total_files": len(files), + "by_category": by_category, + "files": files, + } + with open(OUT_JSON, "w", encoding="utf-8") as fh: + json.dump(manifest, fh, indent=2) + + rows = ["# Working-tree triage 2026-11-02", "", + "Tracked files modified vs HEAD, classified by extension.", "", + "| rel | ext | category | decision |", "|---|---|---|---|"] + for f in files: + rows.append("| %s | %s | %s | %s |" % ( + f["rel"], f["ext"] or "(none)", f["category"], f["decision"])) + rows += ["", "Total: %d | by_category: %s" % (len(files), by_category)] + with open(OUT_MD, "w", encoding="utf-8") as fh: + fh.write("\n".join(rows)) + + with open(OUT_SHARD, "w", encoding="utf-8") as fh: + fh.write(open(OUT_JSON, encoding="utf-8").read()) + + missing = [f["rel"] for f in files if not os.path.exists(os.path.join(REPO, f["rel"]))] + if missing: + print("PROBLEM: missing on disk:", missing) + return 1 + print("OK: classified %d modified files; categories=%s" % (len(files), by_category)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/wizard-work/sol/verify_working_tree_triage_2026_11_02.py b/wizard-work/sol/verify_working_tree_triage_2026_11_02.py new file mode 100755 index 0000000..5c2a7a4 --- /dev/null +++ b/wizard-work/sol/verify_working_tree_triage_2026_11_02.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +"""Independent verifier for Working-Tree-Triage-2026-11-02.json. + +Exit 0 iff the committed manifest re-derives from each recorded path and every +frozen path still exists as a real file under the repo. The classification rule +is re-derived from each recorded path (the manifest's stored fields are not +trusted). Post-commit this gate still passes because it does not rely on the +files being modified vs HEAD -- it checks the recorded snapshot. + +Run: python3 verify_working_tree_triage_2026_11_02.py +""" +import json +import os +import sys +from collections import Counter + +REPO = "/root/troupe-standup" +MANIFEST = os.path.join(REPO, "wizard-work", "sol", "Working-Tree-Triage-2026-11-02.json") +SHARD = os.path.expanduser( + os.path.join("~", ".hermes", "wizard-outputs", "sol", "Working-Tree-Triage-2026-11-02.json") +) + + +def classify(rel): + low = rel.lower() + if low.endswith((".json", ".csv", ".tsv", ".txt")): + return "data" + if low.endswith(".md"): + return "documentation" + if low.endswith(".db"): + return "persistence" + if low.endswith((".py", ".sh", ".bash")): + return "script" + return "other" + + +def expected_decision(cat): + return {"data": "observe", "documentation": "info", + "persistence": "archive", "script": "review", "other": "review"}[cat] + + +def main(): + errors = [] + try: + man = json.load(open(MANIFEST, encoding="utf-8")) + except Exception as exc: + print("FAIL: cannot load manifest:", exc) + return 1 + + files = man.get("files", []) + recorded = set() + for f in files: + rel = f.get("rel") + if not rel: + errors.append("missing rel on one entry") + continue + recorded.add(rel) + exp = f.get("category") + act = classify(rel) + if act != exp: + errors.append("category mismatch %s: re-derived %s != manifest %s" % (rel, act, exp)) + dec = f.get("decision") + want = expected_decision(act) + if dec != want: + errors.append("decision mismatch %s: %s != %s" % (rel, dec, want)) + if not os.path.exists(os.path.join(REPO, rel)): + errors.append("missing on disk: %s" % rel) + + if man.get("total_files") != len(files): + errors.append("total_files %r != files %d" % (man.get("total_files"), len(files))) + if man.get("by_category") != dict(Counter(f.get("category") for f in files)): + errors.append("by_category mismatch") + + if os.path.exists(SHARD): + if open(SHARD, "rb").read() != open(MANIFEST, "rb").read(): + errors.append("shard parity FAIL") + else: + errors.append("shard missing: %s" % SHARD) + + if errors: + print("FAIL: %d problem(s)" % len(errors)) + for e in errors[:40]: + print(" -", e) + return 1 + + print("PASS: %d modified files classified and re-derived; all real; by_category=%s; shard byte-identical." + % (len(files), dict(Counter(f.get("category") for f in files)))) + return 0 + + +if __name__ == "__main__": + sys.exit(main())