#!/usr/bin/env python3 """Extract the troupe repo's per-day commit counts as of HEAD (Extract lane). Source: the git repository /root/troupe-standup (HEAD at capture time). Produces: a TSV table (date + count + TOTAL), a CSV, and a markdown landing page. Verified by wizard-work/ledger/CHECK, which re-derives the table from `git log HEAD` independently of this script. """ import csv import subprocess from collections import Counter REPO = "/root/troupe-standup" OUT_DIR = "/root/.hermes/wizard-outputs/ledger" REPO_OUT = "/root/troupe-standup/wizard-work/ledger" MD_HEADER = """# Troupe commit census — as of HEAD """ def git(*args): return subprocess.run( ["git", "-C", REPO] + list(args), check=True, capture_output=True, text=True ).stdout def main(): # Independent per-day counts straight from git HEAD. raw = git("log", "--date=short", "--pretty=format:%ad").splitlines() counts = Counter(line for line in raw if line) rows = sorted(counts.items()) total = sum(counts.values()) # Shared writer for the machine-readable tables. def write_tsv(path): with open(path, "w", newline="") as f: w = csv.writer(f, delimiter="\t", lineterminator="\n") w.writerow(["date", "count"]) for d, c in rows: w.writerow([d, c]) w.writerow(["TOTAL", total]) def write_csv(path): with open(path, "w", newline="") as f: w = csv.writer(f, lineterminator="\n") w.writerow(["date", "count"]) for d, c in rows: w.writerow([d, c]) w.writerow(["TOTAL", total]) # Markdown landing page. head = git("rev-parse", "HEAD").strip() top = ", ".join("%s:%d" % (d, c) for d, c in rows[-5:]) # last 5 days lines = [ MD_HEADER, "Source: git history of " + REPO + " (HEAD " + head[:12] + "), one `git log` pass.", "Extraction: `git log --date=short --pretty=format:%ad | awk 'NF' | sort | uniq -c`.", "Rows: per-calendar-day commit counts for the full history to HEAD.", "Provenance: `git rev-parse HEAD` = " + head, "Last 5 days of the table: " + top + ".", "Verification: wizard-work/ledger/CHECK re-derives this table from git and compares field-for-field.", "", "| date | commits |", "| --- | ---: |", ] for d, c in rows: lines.append("| " + d + " | " + str(c) + " |") lines += [ "", "| TOTAL | " + str(total) + " |", "", "## Notes", "", "- Each row counts commits whose author date (committed by that day, local) starts with that date. A merge commit counts once, under its own author-date.", "- `TOTAL` is the sum of the per-day rows and equals `git rev-list --count HEAD`.", "- History spans " + str(len(rows)) + " distinct calendar days.", "", ] md = "\n".join(lines) for path, fn in [ (OUT_DIR + "/" + "2026-10-27-commit-census.tsv", write_tsv), (REPO_OUT + "/" + "2026-10-27-commit-census.tsv", write_tsv), (OUT_DIR + "/" + "2026-10-27-commit-census.csv", write_csv), (REPO_OUT + "/" + "2026-10-27-commit-census.csv", write_csv), (OUT_DIR + "/" + "2026-10-27-commit-census.md", lambda p: open(p, "w").write(md)), (REPO_OUT + "/" + "2026-10-27-commit-census.md", lambda p: open(p, "w").write(md)), ]: fn(path) print("rows=%d total=%d days=%d head=%s" % (len(rows), total, len(rows), head[:12])) if __name__ == "__main__": main()