ledger: commit census by author re-derived from git at pinned HEAD 0f0d02b

This commit is contained in:
ledger committed 2026-10-28 21:08:12 +00:00
1 parent 0f0d02b4b1
commit e4f521aa72
6 files changed
+396

No files matched your search

@@ -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"
@@ -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
1 rank author commits pct
2 1 Timmy 556 26.64
3 2 ledger 219 10.49
4 3 timmy 209 10.01
5 4 Volt 189 9.06
6 5 spark 183 8.77
7 6 Zephyrus Sparkborn 123 5.89
8 7 Merlin 118 5.65
9 8 beam 97 4.65
10 9 sol 77 3.69
11 10 quill 70 3.35
12 11 volt 64 3.07
13 12 forge 62 2.97
14 13 sphinx 32 1.53
15 14 null 28 1.34
16 15 Mercury 20 0.96
17 16 zephyrus-sparkborn 14 0.67
18 17 pipe 11 0.53
19 18 troupe-pipe 6 0.29
20 19 Cassian Assayborn 3 0.14
21 20 argus 3 0.14
22 21 Argus 1 0.05
23 22 rockachopa 1 0.05
24 23 sentinel 1 0.05
@@ -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
}
]
}
@@ -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.
@@ -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()
@@ -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 <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_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()