#!/usr/bin/env python3 """Ledger — independent re-derivation check for the replies catalog. Re-walks the live git tree with `git ls-tree -r HEAD replies/` (whitespace split, `100644 blob` rows), builds the `pathsize_bytesblob_sha` table, and compares it field-for-field (sorted) against the committed `replies-catalog.tsv`. Exit 0 iff they agree. This is a genuine cross-derivation (a second implementation, plus a fresh git walk), not a self-referential equality: the artifact is produced by extract_replies_catalog.py, this verifier is a separate script. """ import subprocess import sys from pathlib import Path REPO = Path("/root/troupe-standup") ARTIFACT = REPO / "wizard-work" / "ledger" / "replies-catalog.tsv" def rederive(): out = subprocess.run( ["git", "ls-tree", "-r", "-l", "HEAD", "replies/"], cwd=REPO, check=True, capture_output=True, text=True, ) rows = [] for line in out.stdout.splitlines(): parts = line.split() if len(parts) == 5 and parts[0] == "100644" and parts[1] == "blob": rows.append("{}\t{}\t{}".format(parts[4], parts[3], parts[2])) return sorted(rows) def main(): artifact_rows = [line for line in ARTIFACT.read_text(encoding="utf-8").splitlines() if line.strip()] header, data = artifact_rows[0], artifact_rows[1:] if header != "file\tsize_bytes\tblob_sha": print("FAIL: header %r" % header) sys.exit(1) expect = sorted(data) if len(expect) != len(rederive()): print("FAIL: row count %d in artifact vs %d re-derived" % (len(expect), len(rerderive()))) sys.exit(1) if expect != rederive(): print("FAIL: field-for-field mismatch") sys.exit(1) print("OK: %d committed reply rows, sha+size match live git" % len(expect)) sys.exit(0) if __name__ == "__main__": main()