#!/usr/bin/env python3 """Verify the file-tree census & extension census artifact against a fresh git recompute. Exit code 0 = artifact matches a fresh source recompute (all checks passed), nonzero = mismatch. Not a tautology: it re-enumerates the repo from git and compares the produced tables field-for-field against the committed files. """ import csv import os import subprocess import sys from collections import Counter REPO = "/root/troupe-standup" DEST = os.path.join(REPO, "wizard-work", "ledger") FILES = ["repo_tree.tsv", "repo_exts.tsv", "repo_files.tsv"] def run(args): return subprocess.run(args, cwd=REPO, capture_output=True, text=True) def read_tsv(name): with open(os.path.join(DEST, name), newline="", encoding="utf-8") as f: return list(csv.reader(f, delimiter="\t")) def main(): failures = 0 def check(name, cond, detail=""): nonlocal failures print(("%s %s" % ("PASS" if cond else "FAIL", name)) + ((" " + detail) if (detail and not cond) else "")) if not cond: failures += 1 # 1) fresh enumeration from git tree = run(["git", "ls-tree", "-r", "--name-only", "HEAD"]) check("git ls-tree exit 0", tree.returncode == 0, tree.stderr.strip()) paths = [l for l in tree.stdout.splitlines() if l.strip()] check("git ls-tree lists files", len(paths) > 0, "got %d" % len(paths)) dir_counts = Counter() ext_counts = Counter() for p in paths: d = os.path.dirname(p) dir_counts[d if d else "(root)"] += 1 ext = os.path.splitext(p)[1].lstrip(".").lower() or "(none)" ext_counts[ext] += 1 # 2) repo_tree.tsv rows = read_tsv("repo_tree.tsv") check("repo_tree header", rows[0] == ["rank", "directory", "file_count"], str(rows[0])) data = rows[1:] expected_tree = sorted(dir_counts.items(), key=lambda kv: (-kv[1], kv[0])) check("repo_tree rows == directory groups", len(data) == len(expected_tree), "got %d, expected %d" % (len(data), len(expected_tree))) check("repo_tree dir/counts match recompute", [(r[1], int(r[2])) for r in data] == [(d, c) for d, c in expected_tree]) # 3) repo_exts.tsv rows = read_tsv("repo_exts.tsv") check("repo_exts header", rows[0] == ["rank", "extension", "file_count"], str(rows[0])) data = rows[1:] expected_ext = sorted(ext_counts.items(), key=lambda kv: (-kv[1], kv[0])) check("repo_exts rows == extension groups", len(data) == len(expected_ext), "got %d, expected %d" % (len(data), len(expected_ext))) check("repo_exts ext/counts match recompute", [(r[1], int(r[2])) for r in data] == [(d, c) for d, c in expected_ext]) # 4) repo_files.tsv rows = read_tsv("repo_files.tsv") check("repo_files header", rows[0] == ["rank", "path"], str(rows[0])) file_paths = [r[1] for r in rows[1:]] check("repo_files data rows == git ls-tree rows", len(file_paths) == len(paths), "got %d, git ls-tree %d" % (len(file_paths), len(paths))) check("repo_files rows equal git ls-tree set", sorted(file_paths) == sorted(paths)) # 5) group sums reconcile to total check("dir sum == total", sum(dir_counts.values()) == len(paths), "got %d, total %d" % (sum(dir_counts.values()), len(paths))) check("ext sum == total", sum(ext_counts.values()) == len(paths), "got %d, total %d" % (sum(ext_counts.values()), len(paths))) print("result:", "PASS" if failures == 0 else "FAIL") sys.exit(1 if failures else 0) if __name__ == "__main__": main()