Files
troupe-standup/wizard-work/ledger/verify_ledger_dir_census.py
T

63 lines
2.3 KiB
Python

#!/usr/bin/env python3
# verify_ledger_dir_census.py
# Real test: re-derive the live inventory of wizard-work/ledger from the
# filesystem and compare byte-for-byte with the committed artifact. Exits 0
# iff identical. The artifact CSV is excluded from both sides so the check is
# self-consistent across regeneration.
import hashlib, os, csv, sys
HERE = os.path.dirname(os.path.abspath(__file__)) # wizard-work/ledger
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", "..")) # troupe-standup root
ARTIFACT = os.path.join(REPO_ROOT, "wizard-work", "ledger", "2026-10-31-ledger-dir-census.csv")
SRC = HERE
def re_derive():
rows = []
for dirpath, dirnames, filenames in os.walk(SRC):
dirnames.sort()
for fn in sorted(filenames):
full = os.path.join(dirpath, fn)
if os.path.abspath(full) == os.path.abspath(ARTIFACT):
continue
rel = os.path.relpath(full, REPO_ROOT)
size = str(os.path.getsize(full))
h = hashlib.sha256()
with open(full, "rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
h.update(chunk)
rows.append((rel, size, h.hexdigest()))
rows.sort(key=lambda r: r[0])
return rows
def read_committed(path):
with open(path, newline="", encoding="utf-8") as f:
r = csv.reader(f)
header = next(r)
assert header == ["rel_path", "size_bytes", "sha256"], f"bad header {header}"
return [tuple(x) for x in r]
committed = read_committed(ARTIFACT)
derived = re_derive()
print(f"artifact: {ARTIFACT}")
print(f"rows committed: {len(committed)} rows re-derived: {len(derived)}")
if committed == derived:
print("PASS: committed artifact matches live re-derivation.")
sys.exit(0)
print("FAIL: mismatch (committed vs re-derived).")
n = min(len(committed), len(derived))
for i in range(n):
if committed[i] != derived[i]:
print(f" first diff at row {i}:")
print(f" committed: {committed[i]}")
print(f" derived: {derived[i]}")
break
else:
if len(committed) < len(derived):
print(f" derived has {len(derived)-len(committed)} extra rows")
else:
print(f" committed has {len(committed)-len(derived)} extra rows")
sys.exit(1)