Files

59 lines
1.9 KiB
Python
Executable File

#!/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 `path<TAB>size_bytes<TAB>blob_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()