#!/usr/bin/env python3 """CHECK-file-tree-census — verify the ledger file-tree census against git. Exit code 0 = the artifact matches the git source of truth at the revision it documents (verdict PASS). Non-zero = mismatch (verdict FAIL). The artifact is a snapshot of `wizard-work/ledger/` at the revision it records in its own `summary.head_sha`, taken BEFORE the five artifact files themselves were added to the tree. So it must be re-derived from THAT pinned revision, not from the moving HEAD (re-deriving from HEAD would count the artifact files themselves and wrongly fail). Run: python3 CHECK-file-tree-census (from wizard-work/ledger/) """ import json import subprocess import sys REPO = "/root/troupe-standup" OUT = "/root/troupe-standup/wizard-work/ledger" DAY = "2026-10-30" JSON_PATH = "%s/%s-file-tree-census.json" % (OUT, DAY) CSV_PATH = "%s/%s-file-tree-census.csv" % (OUT, DAY) def git(args): return subprocess.check_output(["git"] + args, cwd=REPO, text=True) def main(): with open(JSON_PATH) as f: j = json.load(f) s = j["summary"] json_files = s["total_files"] json_bytes = s["total_bytes"] rev = s["head_sha"] # revision the artifact describes # Independently re-derive the same figures from the pinned revision. git_files = 0 git_bytes = 0 for line in git(["ls-tree", "-r", "--format=%(objecttype) %(objectname) %(path) %(objectsize)", rev]).strip().splitlines(): otype, _obj, path, size_s = line.split(" ", 3) if otype == "blob" and path.startswith("wizard-work/ledger/"): git_files += 1 git_bytes += int(size_s) with open(CSV_PATH) as f: csv_rows = [l for l in f.read().splitlines() if l][1:] # drop header csv_files = len(csv_rows) csv_bytes = sum(int(r.split(",")[1]) for r in csv_rows) json_manifest = j.get("manifest", []) json_csv_consistency = (len(json_manifest) == csv_files) print("pinned_rev=%s" % rev) print("git_files=%d git_bytes=%d" % (git_files, git_bytes)) print("json_files=%d json_bytes=%d" % (json_files, json_bytes)) print("csv_files=%d csv_bytes=%d json_manifest_matches_csv=%s" % (csv_files, csv_bytes, json_csv_consistency)) ok = True if (json_files, json_bytes) != (git_files, git_bytes): ok = False print("MISMATCH: json(%d,%d) != git(%d,%d)" % (json_files, json_bytes, git_files, git_bytes)) if (csv_files, csv_bytes) != (git_files, git_bytes): ok = False print("MISMATCH: csv(%d,%d) != git(%d,%d)" % (csv_files, csv_bytes, git_files, git_bytes)) if not json_csv_consistency: ok = False print("MISMATCH: json manifest rows != csv rows") # Confirm the recorded revision actually resolves in the repo (no fabricated rev). if git(["rev-parse", rev]) != "": pass else: ok = False print("MISMATCH: recorded revision %s does not resolve" % rev) print("VERDICT: %s" % ("PASS" if ok else "FAIL")) sys.exit(0 if ok else 1) if __name__ == "__main__": main()