Files
troupe-standup/wizard-work/ledger/2026-11-03-commit-census/verify.py
T

88 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Independent verification for the troupe-standup commit census artifact.
Cross-checks the artifact against git:
1. internal consistency (summary <-> detail, manifest <-> rows),
2. every commit hash in commits-main.tsv resolves to a real git commit,
3. per-author counts in commits-by-author.tsv match a recomputation
from git, excluding census metadata commits.
Exit 0 only on full match.
"""
import subprocess, sys, os, json
from collections import Counter
OUT = "/root/.hermes/wizard-outputs/ledger"
REPO = "/root/troupe-standup"
def git(*args):
return subprocess.run(["git","-C",REPO]+list(args), capture_output=True, text=True, check=True).stdout
def fail(msg):
print("FAIL:", msg)
sys.exit(1)
if not os.path.exists(os.path.join(OUT,"commits-by-author.tsv")) or not os.path.exists(os.path.join(OUT,"commits-main.tsv")) or not os.path.exists(os.path.join(OUT,"manifest.json")):
fail("missing artifact file")
actual = {}
with open(os.path.join(OUT,"commits-by-author.tsv")) as f:
header = f.readline().rstrip("\n")
if header != "author\temail\tcommits":
fail("bad author header")
for line in f:
line = line.rstrip("\n")
if not line:
continue
p = line.split("\t")
if len(p) != 3:
fail("bad author row: %r" % line)
actual[p[0]] = (p[1], int(p[2]))
detail_count = 0
detail_by_author = Counter()
with open(os.path.join(OUT,"commits-main.tsv")) as f:
header = f.readline().rstrip("\n")
if header != "hash\tshort\tauthor\temail\tdate\tsubject":
fail("bad commits header")
for line in f:
line = line.rstrip("\n")
if not line:
continue
parts = line.split("\t")
if len(parts) != 6:
fail("bad commits row: %r" % line)
h = parts[0]
r = subprocess.run(["git","-C",REPO,"rev-parse","--verify",h], capture_output=True, text=True)
if r.returncode != 0:
fail("invalid commit hash in artifact: %r" % h)
detail_count += 1
detail_by_author[parts[2]] += 1
if detail_count != sum(v[1] for v in actual.values()):
fail("detail rows=%d != summary commits=%d" % (detail_count, sum(v[1] for v in actual.values())))
m = json.load(open(os.path.join(OUT,"manifest.json")))
if m["commit_count"] != detail_count:
fail("manifest.commit_count=%d != detail rows=%d" % (m["commit_count"], detail_count))
if dict(detail_by_author) != {k: v[1] for k, v in actual.items()}:
fail("author counts detail vs summary mismatch")
# metadata-aware cross-check with git (exclude census metadata commits)
data = Counter()
meta = 0
for h in git("rev-list","main").splitlines():
h = h.strip()
if not h: continue
subj = git("show","-s","--pretty=format:%s",h).strip()
if subj.startswith("ledger: commit census"):
meta += 1
continue
data[git("show","-s","--pretty=format:%an",h).strip()] += 1
if len(data) != len(actual):
fail("author count differs: artifact=%d git_data=%d" % (len(actual), len(data)))
for name,(email,c) in actual.items():
if data.get(name,0) != c:
fail("count mismatch author %r: artifact=%d git_data=%d" % (name,c,data.get(name,0)))
print("OK: data_commits=%d authors=%d metadata=%d" % (detail_count, len(actual), meta))