From e4f521aa726c597aa8442a4e3ee58c11fa7990dc Mon Sep 17 00:00:00 2001 From: ledger Date: Wed, 28 Oct 2026 21:08:12 +0000 Subject: [PATCH] ledger: commit census by author re-derived from git at pinned HEAD 0f0d02b --- .../ledger/2026-10-28-commits-by-author/CHECK | 12 ++ .../commits_by_author.csv | 24 ++++ .../commits_by_author.json | 122 ++++++++++++++++++ .../commits_by_author.md | 33 +++++ .../extract_commits_by_author.py | 100 ++++++++++++++ .../verify_commits_by_author.py | 105 +++++++++++++++ 6 files changed, 396 insertions(+) create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/CHECK create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.csv create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.json create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.md create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/extract_commits_by_author.py create mode 100644 wizard-work/ledger/2026-10-28-commits-by-author/verify_commits_by_author.py diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/CHECK b/wizard-work/ledger/2026-10-28-commits-by-author/CHECK new file mode 100644 index 0000000..7ad860c --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/CHECK @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# CHECK -- ledger commit census (2026-10-28) extraction verification gate. +# +# Re-derives the committed census from git at the pinned head (committed +# commits_by_author.json 'head' field), re-renders csv/json/md with the same +# functions the extraction uses, and diffs each against the committed file. +# Exits 0 only when every file matches byte-identically. +set -u + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$DIR" || exit 1 +exec python3 "$DIR/verify_commits_by_author.py" "$DIR" diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.csv b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.csv new file mode 100644 index 0000000..f447a89 --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.csv @@ -0,0 +1,24 @@ +rank author commits pct +1 Timmy 556 26.64 +2 ledger 219 10.49 +3 timmy 209 10.01 +4 Volt 189 9.06 +5 spark 183 8.77 +6 Zephyrus Sparkborn 123 5.89 +7 Merlin 118 5.65 +8 beam 97 4.65 +9 sol 77 3.69 +10 quill 70 3.35 +11 volt 64 3.07 +12 forge 62 2.97 +13 sphinx 32 1.53 +14 null 28 1.34 +15 Mercury 20 0.96 +16 zephyrus-sparkborn 14 0.67 +17 pipe 11 0.53 +18 troupe-pipe 6 0.29 +19 Cassian Assayborn 3 0.14 +20 argus 3 0.14 +21 Argus 1 0.05 +22 rockachopa 1 0.05 +23 sentinel 1 0.05 diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.json b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.json new file mode 100644 index 0000000..c098be4 --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.json @@ -0,0 +1,122 @@ +{ + "repo": "/root/troupe-standup", + "head": "0f0d02b4b1fb1f4a63a13d6732f4c5b0f970b1a4", + "commits": 23, + "by_author": [ + { + "author": "Timmy", + "commits": 556, + "pct": 26.64 + }, + { + "author": "ledger", + "commits": 219, + "pct": 10.49 + }, + { + "author": "timmy", + "commits": 209, + "pct": 10.01 + }, + { + "author": "Volt", + "commits": 189, + "pct": 9.06 + }, + { + "author": "spark", + "commits": 183, + "pct": 8.77 + }, + { + "author": "Zephyrus Sparkborn", + "commits": 123, + "pct": 5.89 + }, + { + "author": "Merlin", + "commits": 118, + "pct": 5.65 + }, + { + "author": "beam", + "commits": 97, + "pct": 4.65 + }, + { + "author": "sol", + "commits": 77, + "pct": 3.69 + }, + { + "author": "quill", + "commits": 70, + "pct": 3.35 + }, + { + "author": "volt", + "commits": 64, + "pct": 3.07 + }, + { + "author": "forge", + "commits": 62, + "pct": 2.97 + }, + { + "author": "sphinx", + "commits": 32, + "pct": 1.53 + }, + { + "author": "null", + "commits": 28, + "pct": 1.34 + }, + { + "author": "Mercury", + "commits": 20, + "pct": 0.96 + }, + { + "author": "zephyrus-sparkborn", + "commits": 14, + "pct": 0.67 + }, + { + "author": "pipe", + "commits": 11, + "pct": 0.53 + }, + { + "author": "troupe-pipe", + "commits": 6, + "pct": 0.29 + }, + { + "author": "Cassian Assayborn", + "commits": 3, + "pct": 0.14 + }, + { + "author": "argus", + "commits": 3, + "pct": 0.14 + }, + { + "author": "Argus", + "commits": 1, + "pct": 0.05 + }, + { + "author": "rockachopa", + "commits": 1, + "pct": 0.05 + }, + { + "author": "sentinel", + "commits": 1, + "pct": 0.05 + } + ] +} diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.md b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.md new file mode 100644 index 0000000..f883e83 --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/commits_by_author.md @@ -0,0 +1,33 @@ +# Commit census by author + +Source: `git log --format=%an` over every commit reachable from HEAD. +Counts grouped verbatim on the author name string (git default, case-aware); `Timmy`/`timmy`, `Volt`/`volt` remain separate buckets. No commits are created, moved or deleted. + +| Rank | Author (%an) | Commits | Share | +|---|---|---|---| +| 1 | Timmy | 556 | 26.64% | +| 2 | ledger | 219 | 10.49% | +| 3 | timmy | 209 | 10.01% | +| 4 | Volt | 189 | 9.06% | +| 5 | spark | 183 | 8.77% | +| 6 | Zephyrus Sparkborn | 123 | 5.89% | +| 7 | Merlin | 118 | 5.65% | +| 8 | beam | 97 | 4.65% | +| 9 | sol | 77 | 3.69% | +| 10 | quill | 70 | 3.35% | +| 11 | volt | 64 | 3.07% | +| 12 | forge | 62 | 2.97% | +| 13 | sphinx | 32 | 1.53% | +| 14 | null | 28 | 1.34% | +| 15 | Mercury | 20 | 0.96% | +| 16 | zephyrus-sparkborn | 14 | 0.67% | +| 17 | pipe | 11 | 0.53% | +| 18 | troupe-pipe | 6 | 0.29% | +| 19 | Cassian Assayborn | 3 | 0.14% | +| 20 | argus | 3 | 0.14% | +| 21 | Argus | 1 | 0.05% | +| 22 | rockachopa | 1 | 0.05% | +| 23 | sentinel | 1 | 0.05% | + +Total commits: 23. + diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/extract_commits_by_author.py b/wizard-work/ledger/2026-10-28-commits-by-author/extract_commits_by_author.py new file mode 100644 index 0000000..28fa15b --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/extract_commits_by_author.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# Extract the ranked-by-author commit census of the troupe repo as of HEAD. +# +# Method (evidence): for every commit reachable from a pinned head, `git log +# --format=%an` reports the author name verbatim (git's default, case-aware; +# 'Timmy' and 'timmy', 'Volt' and 'volt' are separate buckets and are not +# normalized). Counts are grouped verbatim on that string. No commits are +# created, moved or deleted. +# +# Outputs (canonical): commits_by_author.csv | .json | .md, plus this script. +# The committed files are rendered by the SAME functions the CHECK gate +# re-derives, so regeneration is byte-identical by construction. +import json +import subprocess +from collections import Counter +from pathlib import Path + +REPO = '/root/troupe-standup' +OUT = Path(__file__).resolve().parent + + +def git(*args): + return subprocess.run( + ['git', '-C', REPO] + list(args), + check=True, + capture_output=True, + text=True, + ).stdout + + +def build_rows(head): + """Re-derive author-census rows from a pinned (or any) git head.""" + names = git('log', '--format=%an', head).splitlines() + total = len(names) + counts = Counter(names) + rows = [] + for i, (name, n) in enumerate( + sorted(counts.items(), key=lambda kv: (-kv[1], kv[0])), 1 + ): + rows.append({ + 'rank': i, + 'author': name, + 'commits': n, + 'pct': round(n / total * 100.0, 2) if total else 0.0, + }) + return rows + + +def render_csv(rows): + lines = ['rank\tauthor\tcommits\tpct'] + for r in rows: + lines.append('%d\t%s\t%d\t%.2f' % ( + r['rank'], r['author'].replace('\t', ' '), r['commits'], r['pct'])) + return '\n'.join(lines) + '\n' + + +def render_json(rows, head): + data = { + 'repo': REPO, + 'head': head, + 'commits': len(rows), + 'by_author': [ + {'author': r['author'], 'commits': r['commits'], 'pct': r['pct']} + for r in rows + ], + } + return json.dumps(data, indent=2) + '\n' + + +def render_md(rows): + lines = [] + lines.append('# Commit census by author') + lines.append('') + lines.append('Source: `git log --format=%an` over every commit reachable from HEAD.') + lines.append('Counts grouped verbatim on the author name string (git default, case-aware); ' + '`Timmy`/`timmy`, `Volt`/`volt` remain separate buckets. No commits are created, ' + 'moved or deleted.') + lines.append('') + lines.append('| Rank | Author (%an) | Commits | Share |') + lines.append('|---|---|---|---|') + for r in rows: + lines.append('| %d | %s | %d | %.2f%% |' % ( + r['rank'], r['author'].replace('\t', ' '), r['commits'], r['pct'])) + lines.append('') + lines.append('Total commits: %d.' % len(rows)) + lines.append('') + return '\n'.join(lines) + '\n' + + +def main(): + head = git('rev-parse', 'HEAD').strip() + rows = build_rows(head) + (OUT / 'commits_by_author.csv').write_text(render_csv(rows)) + (OUT / 'commits_by_author.json').write_text(render_json(rows, head)) + (OUT / 'commits_by_author.md').write_text(render_md(rows)) + print('total=%d head=%s rows=%d' % (len(rows), head, len(rows))) + + +if __name__ == '__main__': + main() diff --git a/wizard-work/ledger/2026-10-28-commits-by-author/verify_commits_by_author.py b/wizard-work/ledger/2026-10-28-commits-by-author/verify_commits_by_author.py new file mode 100644 index 0000000..1897188 --- /dev/null +++ b/wizard-work/ledger/2026-10-28-commits-by-author/verify_commits_by_author.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# CHECK gate for the ledger commit census (2026-10-28) extraction. +# +# Re-derives the committed census from git at the PINNED HEAD (the `head` field +# of the committed commits_by_author.json), re-renders the three output files +# with the identical functions the extraction uses, and diffs each against the +# committed file in this directory. Exits 0 only when every file matches +# byte-identically. +# +# Convention: the gate is a re-derivation, not an assertion of a stored +# number. It runs `git log --format=%an` at the pinned head, rebuilds the rows, +# re-renders csv/json/md with the same code the extraction uses, and requires +# byte-identical output against what was committed. +# +# Usage: python3 verify_commits_by_author.py +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_commits_by_author import ( # noqa: E402 + build_rows, + render_csv, + render_json, + render_md, +) + +FILES = [ + 'commits_by_author.csv', + 'commits_by_author.json', + 'commits_by_author.md', +] + + +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('commits_by_author.json') as f: + fixed = json.load(f) + head = fixed.get('head') or fixed.get('head_sha') + if not head: + print('FAIL: committed commits_by_author.json carries no head pin') + sys.exit(1) + + rows = build_rows(head) + + ok = True + + def report(name, observed_bytes, expected_bytes): + nonlocal ok + if observed_bytes == expected_bytes: + print('PASS: %s matches re-derivation from git at pinned head %s' + % (name, head)) + else: + ok = False + print('FAIL: %s differs from re-derivation at pinned head %s' + % (name, head)) + exp = expected_bytes.decode('utf-8', 'replace').splitlines() + obs = observed_bytes.decode('utf-8', 'replace').splitlines() + diff = difflib.unified_diff( + exp, obs, + fromfile='expected@' + head[:8], + tofile='committed@' + head[:8], + lineterm='', + ) + for line in list(diff)[:12]: + print(' ' + line) + + # row count + if len(rows) == fixed.get('commits'): + print('PASS: committed row count %d == re-derived %d' + % (fixed.get('commits'), len(rows))) + else: + ok = False + print('FAIL: committed row count %s != re-derived %d' + % (fixed.get('commits'), len(rows))) + + for name in FILES: + committed = read_bytes(name) + expected = { + 'commits_by_author.csv': render_csv(rows), + 'commits_by_author.json': render_json(rows, head), + 'commits_by_author.md': render_md(rows), + }[name] + report(name, committed, expected.encode('utf-8')) + + if ok: + print('ALL CHECKS PASSED: census re-derives byte-identically from ' + 'git at pinned head %s' % head) + sys.exit(0) + sys.exit(1) + + +if __name__ == '__main__': + main()