Files
troupe-standup/wizard-work/ledger/2026-11-04-daily-commit-census/verify_daily_commit_census.py
T

91 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""CHECK gate for the daily-commit-census extraction.
Re-derives the daily commit census from git at the PINNED head recorded in the
committed extraction_manifest.json, re-renders the CSV with the identical
format the extractor uses, and diffs it against the committed file. Exits 0 only
when every check matches exactly. This is a re-derivation, not an assertion of a
stored number.
Usage: python3 verify_daily_commit_census.py <artifact_dir>
"""
import difflib
import json
import os
import subprocess
import sys
REPO = "/root/troupe-standup"
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
from extract_daily_commit_census import render_csv, build_rows # noqa: E402
CSV_NAME = "daily-commit-census.csv"
def git(*args):
return subprocess.run(
["git", "-C", REPO] + list(args), check=True, capture_output=True, text=True
).stdout
def read_bytes(name):
with open(name, "rb") as f:
return f.read()
def main():
artdir = sys.argv[1] if len(sys.argv) > 1 else "."
os.chdir(artdir)
with open("extraction_manifest.json", encoding="utf-8") as f:
manifest = json.load(f)
head = manifest.get("head_full")
if not head:
print("FAIL: manifest has no head_full")
sys.exit(1)
# Re-derive from the pinned head.
raw = git("log", "--date=short", "--pretty=format:%ad", head).splitlines()
from collections import Counter
counts = Counter(d for d in raw if d)
rows = [{"date": d, "commits": c} for d, c in sorted(counts.items())]
expected = render_csv(rows)
ok = True
with open(CSV_NAME, encoding="utf-8") as f:
committed = f.read()
if committed == expected:
print("PASS: daily-commit-census.csv re-derives byte-identically from git "
"at pinned head %s" % head)
else:
ok = False
print("FAIL: daily-commit-census.csv diverges from re-derivation at "
"pinned head %s" % head)
exp = expected.splitlines()
obs = committed.splitlines()
for line in list(difflib.unified_diff(exp, obs, "expected@", "committed@"))[:12]:
print(" " + line)
# Independent integrity: the TOTAL row must equal the sum of the day rows.
day_sum = sum(int(r["commits"]) for r in rows)
total_lines = [ln for ln in committed.splitlines() if ln.startswith("TOTAL,")]
if total_lines == ["TOTAL,%d" % day_sum]:
print("PASS: TOTAL row %r == sum of day rows %d" % (total_lines[0], day_sum))
else:
ok = False
print("FAIL: TOTAL row %r != sum of day rows %d" % (total_lines, day_sum))
if ok:
print("ALL CHECKS PASSED")
sys.exit(0)
sys.exit(1)
if __name__ == "__main__":
main()