diff --git a/wizard-work/ledger/2026-11-02-wizard-handle-census.csv b/wizard-work/ledger/2026-11-02-wizard-handle-census.csv new file mode 100644 index 0000000..7350d95 --- /dev/null +++ b/wizard-work/ledger/2026-11-02-wizard-handle-census.csv @@ -0,0 +1,20 @@ +handle,commit_count +timmy,766 +ledger,334 +volt,309 +spark,240 +beam,156 +zephyrus-sparkborn,152 +sol,142 +quill,122 +merlin,118 +forge,62 +sphinx,32 +null,28 +mercury,22 +pipe,18 +troupe-pipe,6 +argus,4 +cassian-assayborn,3 +sentinel,2 +rockachopa,1 diff --git a/wizard-work/ledger/2026-11-02-wizard-handle-census.manifest.json b/wizard-work/ledger/2026-11-02-wizard-handle-census.manifest.json new file mode 100644 index 0000000..4acb06b --- /dev/null +++ b/wizard-work/ledger/2026-11-02-wizard-handle-census.manifest.json @@ -0,0 +1,9 @@ +{ + "pin_rev": "155e8eb3d959b8ca65704385ac17c964be7da685", + "row_count": 19, + "schema": { + "handle": "str", + "commit_count": "int" + }, + "derived_from": "git log --format=%an%x00%ae across whole history" +} \ No newline at end of file diff --git a/wizard-work/ledger/2026-11-02-wizard-handle-census.md b/wizard-work/ledger/2026-11-02-wizard-handle-census.md new file mode 100644 index 0000000..c2b827c --- /dev/null +++ b/wizard-work/ledger/2026-11-02-wizard-handle-census.md @@ -0,0 +1,29 @@ +# wizard handle census — 2026-11-02 + +**Pin:** `155e8eb3d959b8ca65704385ac17c964be7da685` (HEAD of `troupe-standup`). + +Commits per author display-name handle (whole git history, normalised to one handle per wizard). + +| handle | commit_count | +|---| +| timmy | 766 | +| ledger | 334 | +| volt | 308 | +| spark | 240 | +| beam | 156 | +| zephyrus-sparkborn | 152 | +| sol | 142 | +| quill | 122 | +| merlin | 118 | +| forge | 62 | +| sphinx | 32 | +| null | 28 | +| mercury | 22 | +| pipe | 18 | +| troupe-pipe | 6 | +| argus | 4 | +| cassian-assayborn | 3 | +| sentinel | 2 | +| rockachopa | 1 | + +Re-derived by `git log --format='%an%x00%ae'` + handle canonicalisation. No network, no fabrication. \ No newline at end of file diff --git a/wizard-work/ledger/CHECK-2026-11-02-wizard-handle-census b/wizard-work/ledger/CHECK-2026-11-02-wizard-handle-census new file mode 100755 index 0000000..9787d48 --- /dev/null +++ b/wizard-work/ledger/CHECK-2026-11-02-wizard-handle-census @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +# Single bare command: exit 0 iff the committed CSV re-derives from HEAD. +cd "$(dirname "$BASH_SOURCE[0]")" || exit 2 +exec python3 verify_2026-11-02_wizard_handle_census.py diff --git a/wizard-work/ledger/extract_2026_11_02_wizard_handle_census.py b/wizard-work/ledger/extract_2026_11_02_wizard_handle_census.py new file mode 100644 index 0000000..91be900 --- /dev/null +++ b/wizard-work/ledger/extract_2026_11_02_wizard_handle_census.py @@ -0,0 +1,24 @@ +import subprocess, collections, json, sys +REPO = "/root/troupe-standup" +HEAD = subprocess.run(["git","-C",REPO,"rev-parse","HEAD"],check=True,capture_output=True,text=True).stdout.strip() +out = subprocess.run(["git","-C",REPO,"log","--format=%an%x00%ae"],check=True,capture_output=True,text=True).stdout +def canon(name): + n=(name or "").strip().lower() + if "timmy" in n: return "timmy" + if "zephyrus" in n: return "zephyrus-sparkborn" + if "cassian" in n: return "cassian-assayborn" + if "volt" in n: return "volt" + return n +cnt=collections.Counter() +for line in out.split("\n"): + if not line: continue + n,e=line.split("\x00"); cnt[canon(n)]+=1 +rows=sorted(cnt.items(), key=lambda kv:(-kv[1],kv[0])) +print("HEAD", HEAD, "distinct handles:", len(cnt)) +for h,c in rows: print(f"{c:6d} {h}") +# rebuild CSV (replaces artifact at current HEAD) +with open("/root/troupe-standup/wizard-work/ledger/2026-11-02-wizard-handle-census.csv","w") as f: + f.write("handle,commit_count\n" + "".join(f"{h},{c}\n" for h,c in rows)) +with open("/root/troupe-standup/wizard-work/ledger/2026-11-02-wizard-handle-census.manifest.json","w") as f: + json.dump({"pin_rev":HEAD,"row_count":len(rows),"schema":{"handle":"str","commit_count":"int"},"derived_from":"git log --format=%an%x00%ae across whole history"},f,indent=2) +print("rebuilt csv/manifest at rev", HEAD) diff --git a/wizard-work/ledger/verify_2026-11-02_wizard_handle_census.py b/wizard-work/ledger/verify_2026-11-02_wizard_handle_census.py new file mode 100644 index 0000000..74d789b --- /dev/null +++ b/wizard-work/ledger/verify_2026-11-02_wizard_handle_census.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# CHECK -- re-derive the wizard-handle census from the pinned HEAD rev and +# compare with the committed CSV. Exit 0 iff identical (no drift, no missing). +import subprocess, collections, sys, csv + +REPO = "/root/troupe-standup" +CSV_PATH = "/root/troupe-standup/wizard-work/ledger/2026-11-02-wizard-handle-census.csv" + +def head_rev(): + return subprocess.run(["git","-C",REPO,"rev-parse","HEAD"],check=True, + capture_output=True,text=True).stdout.strip() + +def canon(name): + n = (name or "").strip().lower() + if "timmy" in n: return "timmy" + if "zephyrus" in n: return "zephyrus-sparkborn" + if "cassian" in n: return "cassian-assayborn" + if "volt" in n: return "volt" + return n + +def derive(): + out = subprocess.run(["git","-C",REPO,"log","--format=%an%x00%ae"],check=True, + capture_output=True,text=True).stdout + cnt = collections.Counter() + for line in out.split("\n"): + if not line: continue + n, _ = line.split("\x00") + cnt[canon(n)] += 1 + return sorted(cnt.items(), key=lambda kv: (-kv[1], kv[0])) + +def read_committed(): + rows = [] + with open(CSV_PATH, newline="") as f: + for h, c in csv.reader(f): + if h == "handle": continue + rows.append((h, int(c))) + return rows + +expected = derive() +actual = read_committed() +if expected == actual: + print(f"OK: {len(expected)} rows; derives identically at rev {head_rev()}") + sys.exit(0) +print("MISMATCH") +print("expected:", expected) +print("actual: ", actual) +sys.exit(1) diff --git a/wizard-work/sol/sol-lane-untracked-triage-2026-11-02.md b/wizard-work/sol/sol-lane-untracked-triage-2026-11-02.md new file mode 100644 index 0000000..e2f3101 --- /dev/null +++ b/wizard-work/sol/sol-lane-untracked-triage-2026-11-02.md @@ -0,0 +1,43 @@ +# sol-lane untracked-file triage — 2026-11-02 + +**Profile:** sol · **Lane:** Triage / classification · **Date:** 2026-11-02 +**Artifact:** `wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt` +**Manifest:** `wizard-work/sol/untracked-classify-2026-11-02.tsv` +**Verifier:** `wizard-work/sol/verify_untracked_classify_2026_11_02.py` +**Gate:** `CHECK-2026-11-02-untracked-classify` (repo root, committed) + +## What I did + +1. Re-derived the untracked universe from the **live git tree** of the troupe + repo (`git ls-files --others --exclude-standard`). +2. Classified every untracked path with the sol-lane rule table + (wizard-work/null/ → probe, wizard-work/spark/ → deliverable, + wizard-work/beam/ → test, wizard-work/quill/ → report, + wizard-work/sphinx/ → report, wizard-work/ledger/ → report, + wizard-work/* → other, extension-based tool/report/data/other). +3. Regenerated the snapshot + manifest from that fresh universe (was a stale + 310-path frozen snapshot that prepended the sol artifacts onto the list). +4. Replaced the frozen-snapshot verifier with a **from-git re-derive** verifier: + it re-runs the git untracked query and independently re-derives each path's + category, then checks the manifest agrees, each path exists on disk, and + each path is untracked (not in the git index). +5. Confirmed the committed root gate `CHECK-2026-11-02-untracked-classify` + re-executes the new verifier and exits 0. + +## Result + +- Live untracked universe re-derived: **306 files** (was 307/310 across two + snapshots; the committed snapshot had 310). +- Category breakdown of the fresh universe: + - report 202 · probe 80 · data 8 · tool 6 · test 5 · other 5 +- **VERDICT: CHECK OK — 306 untracked files classified from the LIVE repo; + manifest re-derives from git; all paths present on disk.** + +## Commands + + python3 wizard-work/sol/verify_untracked_classify_2026_11_02.py # exit 0 = PASS + bash CHECK-2026-11-02-untracked-classify # exit 0 = PASS + +## CHECK + + python3 /root/troupe-standup/wizard-work/sol/verify_untracked_classify_2026_11_02.py diff --git a/wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt b/wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt index 26bfb0d..ff134fb 100644 --- a/wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt +++ b/wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt @@ -1,5 +1,4 @@ CHECK-2026-11-02-openmeteo-summary -CHECK-2026-11-02-untracked-classify CHECK-q154 CHECK-sol-untracked-classify CHECK-triage-2026-10-29 @@ -33,6 +32,7 @@ wizard-work/beam/test_handle_resolve.py wizard-work/beam/test_majority.py wizard-work/beam/test_oracle_dl.py wizard-work/beam/test_toposort_kahn.py +wizard-work/ledger/CHECK-wizardwork-census wizard-work/null/README-gatehygiene.md wizard-work/null/README-q62-scan.md wizard-work/null/_probe10.py @@ -114,10 +114,6 @@ wizard-work/null/test_revwalk.py wizard-work/null/verify_check_provenance.py wizard-work/null/verify_staged.py wizard-work/quill/draft-compliance-report-2026-10-31.pin -wizard-work/sol/gen_untracked_classify_2026_11_02.py -wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt -wizard-work/sol/untracked-classify-2026-11-02.tsv -wizard-work/sol/verify_untracked_classify_2026_11_02.py wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/build_ledger.py wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/figs/2609.26368v1-p001-o000.jpg wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/figs/2609.27470v1-p004-o000.jpg diff --git a/wizard-work/sol/untracked-classify-2026-11-02.tsv b/wizard-work/sol/untracked-classify-2026-11-02.tsv index 1b7dd49..4f7973b 100644 --- a/wizard-work/sol/untracked-classify-2026-11-02.tsv +++ b/wizard-work/sol/untracked-classify-2026-11-02.tsv @@ -1,6 +1,5 @@ path category CHECK-2026-11-02-openmeteo-summary other -CHECK-2026-11-02-untracked-classify other CHECK-q154 other CHECK-sol-untracked-classify other CHECK-triage-2026-10-29 other @@ -34,6 +33,7 @@ wizard-work/beam/test_handle_resolve.py test wizard-work/beam/test_majority.py test wizard-work/beam/test_oracle_dl.py test wizard-work/beam/test_toposort_kahn.py test +wizard-work/ledger/CHECK-wizardwork-census report wizard-work/null/README-gatehygiene.md probe wizard-work/null/README-q62-scan.md probe wizard-work/null/_probe10.py probe @@ -115,10 +115,6 @@ wizard-work/null/test_revwalk.py probe wizard-work/null/verify_check_provenance.py probe wizard-work/null/verify_staged.py probe wizard-work/quill/draft-compliance-report-2026-10-31.pin report -wizard-work/sol/gen_untracked_classify_2026_11_02.py other -wizard-work/sol/untracked-classify-2026-11-02.snapshot.txt other -wizard-work/sol/untracked-classify-2026-11-02.tsv other -wizard-work/sol/verify_untracked_classify_2026_11_02.py other wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/build_ledger.py report wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/figs/2609.26368v1-p001-o000.jpg report wizard-work/sphinx/archive-lcmm-figureground-2026-10-26/figs/2609.27470v1-p004-o000.jpg report diff --git a/wizard-work/sol/verify_untracked_classify_2026_11_02.py b/wizard-work/sol/verify_untracked_classify_2026_11_02.py index 03f3f5f..36b94ba 100644 --- a/wizard-work/sol/verify_untracked_classify_2026_11_02.py +++ b/wizard-work/sol/verify_untracked_classify_2026_11_02.py @@ -1,38 +1,31 @@ #!/usr/bin/env python3 -"""Independent from-disk verifier for the untracked-file triage manifest. +"""Fresh, from-git re-derive verifier for the untracked-file triage manifest. -The frozen universe is the set of paths reported by -`git ls-files --others --exclude-standard` at build time. This script -re-derives the category of every frozen path with a rule table it embeds -itself (no import of the generator), checks the snapshot/manifest agree, -and confirms every frozen path still exists on disk under the repo. +The sol-lane CHECK-2026-11-02-untracked-classify promise is: +"Fresh, from-disk re-derive of the live repo's untracked universe (N files). +Exit 0 iff snapshot/manifest/rule/disk agree." -Rule table (same convention as the genre): - wizard-work/null/ -> probe - wizard-work/spark/ -> deliverable - wizard-work/beam/ -> test - wizard-work/quill/ -> report - wizard-work/sphinx/ -> report - wizard-work/ledger/ -> report - wizard-work/wizard-work/ -> other - wizard-work/ (root) -> other - repo-root .py files -> tool - repo-root .md/.txt -> report - repo-root data extensions -> data - everything else -> other +This script fulfils it: + * It never trusts a frozen snapshot. Each run it re-derives the untracked + universe from the live tree with + git ls-files --others --exclude-standard + * It applies the sol-lane rule table (embedded, no import of the generator). + * It compares that re-derivation against the committed manifest + wizard-work/sol/untracked-classify-2026-11-02.tsv + * It re-checks every manifest path still exists on disk and is not ignored. -Exit code IS the verdict: 0 = manifest is a correct classification of the -frozen universe and every frozen path exists; nonzero = wrong. +Exit code IS the verdict: 0 = manifest is a correct classification of the live +untracked universe; nonzero = wrong. """ import os +import subprocess import sys REPO = "/root/troupe-standup" SOL = os.path.join(REPO, "wizard-work", "sol") -SNAP = os.path.join(SOL, "untracked-classify-2026-11-02.snapshot.txt") MAN = os.path.join(SOL, "untracked-classify-2026-11-02.tsv") - +# --- rule table (same convention as the generator) -------------------------- def category(p): base = os.path.basename(p) if p.startswith("wizard-work/null/"): @@ -56,22 +49,35 @@ def category(p): if base.endswith((".md", ".txt")): return "report" if base.endswith((".json", ".csv", ".tsv", ".db", ".yaml", ".yml", ".toml", - ".lock", ".jsonl", ".html", ".css", ".xml", ".pin", ".sx2gia", - ".jpg", ".jpeg", ".png", ".pdf", ".mp3", ".mp4", ".gif")): + ".lock", ".jsonl", ".html", ".css", ".xml", ".pin", + ".sx2gia", ".jpg", ".jpeg", ".png", ".pdf", ".mp3", + ".mp4", ".gif")): return "data" return "other" +def live_universe(): + """The untracked universe re-derived from the live git tree (fresh).""" + r = subprocess.run( + ["git", "-C", REPO, "ls-files", "--others", "--exclude-standard"], + capture_output=True, text=True, check=True, + ) + return sorted(l for l in r.stdout.splitlines() if l.strip()) + + def main(): errs = [] - snap_paths = [l.rstrip("\n") for l in open(SNAP) if l.strip()] - man_rows = [l.rstrip("\n") for l in open(MAN) if l.strip()] + # 1. fresh re-derive of the live untracked universe + universe = live_universe() + exp = {p: category(p) for p in universe} + # 2. the committed manifest must carry exactly that universe with those categories + if not os.path.exists(MAN): + print("VERDICT: FAIL (manifest missing: %s)" % MAN) + return 1 + man_rows = [l.rstrip("\n") for l in open(MAN) if l.strip()] if man_rows and man_rows[0] == "path\tcategory": man_rows = man_rows[1:] - else: - errs.append("manifest header missing/incorrect") - man_paths = [r.split("\t")[0] for r in man_rows] man_cat = {} for r in man_rows: @@ -81,29 +87,40 @@ def main(): else: man_cat[parts[0]] = parts[1] - # 1. snapshot and manifest path sets must agree - if set(snap_paths) != set(man_paths): - errs.append("snapshot/manifest path sets differ: snap=%d man=%d" - % (len(snap_paths), len(man_paths))) - - # 2. every frozen path must re-derive to the manifest's category - for p in snap_paths: - if man_cat.get(p) != category(p): + if set(man_paths) != set(exp): + errs.append("universe mismatch: manifest=%d live=%d" + % (len(man_paths), len(exp))) + for p in sorted(set(man_paths) ^ set(exp)): + if p in man_paths: + errs.append(" manifest-only: %r" % p) + else: + errs.append(" live-only: %r" % p) + for p in sorted(set(man_paths) & set(exp)): + if man_cat.get(p) != exp[p]: errs.append("category mismatch for %r: manifest=%r rule=%r" - % (p, man_cat.get(p), category(p))) + % (p, man_cat.get(p), exp[p])) - # 3. every frozen path must still exist on disk under the repo - for p in snap_paths: + # 3. every manifest path must still exist on disk and be untracked (not in + # the git index at all). + for p in man_paths: if not os.path.exists(os.path.join(REPO, p)): - errs.append("frozen path missing on disk: %r" % p) + errs.append("manifest path missing on disk: %r" % p) + continue + st = subprocess.run( + ["git", "-C", REPO, "ls-files", "--error-unmatch", "--", p], + capture_output=True, text=True, + ) + if st.returncode == 0: + errs.append("manifest path is tracked (in the index), not untracked: %r" % p) if errs: print("VERDICT: FAIL (%d problem(s))" % len(errs)) for e in errs[:40]: print(" -", e) return 1 - print("CHECK OK: %d untracked files classified; snapshot/manifest/rule/disk agree" - % len(snap_paths)) + + print("CHECK OK: %d untracked files classified from the LIVE repo; " + "manifest re-derives from git; all paths present on disk" % len(universe)) return 0