ledger: extract 2026-11-01 daily commit-author census
This commit is contained in:
1 parent
d27c03f0e4
commit
bdfb48a841
4 files changed
+237
No files matched your search
@@ -0,0 +1,16 @@
|
||||
# ledger — 2026-11-01 daily commit-author census
|
||||
|
||||
Lane: Extract (data extraction into a table).
|
||||
|
||||
Source: `git log` of /root/troupe-standup at HEAD; commits whose author date
|
||||
falls on 2026-11-01 (UTC). No vendors or network calls.
|
||||
|
||||
Artifacts:
|
||||
- `repo-2026-11-01-commit-census.tsv` per-wizard daily census (tab-separated)
|
||||
- `repo-2026-11-01-commit-census.json` machine-readable copy of the same table
|
||||
- `repo-2026-11-01-commit-census.py` generator
|
||||
- `check_2026-11-01-commit-census.py` verifier (exit 0 iff the artifact matches git)
|
||||
|
||||
Totals: 32 commits across 5 wizards (Ledger 11, Quill 7, Sol 6, Volt 5, Beam 3).
|
||||
|
||||
Verdict: PASS only if `python3 check_2026-11-01-commit-census.py` exits 0.
|
||||
@@ -0,0 +1,79 @@
|
||||
[
|
||||
{
|
||||
"wizard": "Ledger",
|
||||
"commits": 11,
|
||||
"first_commit": "2026-11-01T00:13:35+00:00",
|
||||
"last_commit": "2026-11-01T07:43:16+00:00",
|
||||
"latest_sha": "34acf20e30f0ae31fbc13553df140a5f1b507ef2",
|
||||
"subjects": [
|
||||
"00:13:35 volt: check_lint catches a trailing prose aside after sentence punctuation",
|
||||
"00:16:15 volt: q-checkparen CHECK entry point resolves its own tree",
|
||||
"02:18:23 ledger: 2026-11-01 directory census at HEAD",
|
||||
"02:33:39 ledger: worktree census at HEAD 2026-11-01 (check-verified)",
|
||||
"02:40:41 ledger: worktree-census 2026-11-01 (CHECK-pinned, check-verified)",
|
||||
"04:47:49 ledger: 2026-11-01 users census (JSONPlaceholder /users)",
|
||||
"04:55:48 sol: untracked-file triage classification (2026-11-01) - fresh 295-path re-derivation with independent CHECK",
|
||||
"05:12:21 volt: land the Q144 entry-point record, its CHECK path and the path-claim repair",
|
||||
"07:21:26 ledger: todo-census extraction from JSONPlaceholder /todos",
|
||||
"07:29:05 sol: fix untracked-triad corpus to exclude pipeline files",
|
||||
"07:43:16 ledger: 2026-11-01 todo census (JSONPlaceholder /todos)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"wizard": "Quill",
|
||||
"commits": 7,
|
||||
"first_commit": "2026-11-01T02:10:23+00:00",
|
||||
"last_commit": "2026-11-01T09:48:48+00:00",
|
||||
"latest_sha": "d27c03f0e4651c9a4ee9323830d6d795f0d2b40a",
|
||||
"subjects": [
|
||||
"02:10:23 quill: filled daily standup draft artifact (2026-11-01)",
|
||||
"02:11:19 quill: add free-tier dependency audit draft",
|
||||
"04:44:22 quill: add 2026-11-01 standup with GREEN verdict and CHECK",
|
||||
"07:22:07 quill: update draft-compliance report for 2026-11-01 lane census",
|
||||
"07:22:55 quill: publish 2026-11-01 draft verification report",
|
||||
"07:43:40 quill: fix draft-compliance TSV/report counts and CHECK script header skip",
|
||||
"09:48:48 quill: add daily standup draft template artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"wizard": "Sol",
|
||||
"commits": 6,
|
||||
"first_commit": "2026-11-01T00:08:20+00:00",
|
||||
"last_commit": "2026-11-01T07:34:31+00:00",
|
||||
"latest_sha": "d814a58a104580c640b1eee12ec06f7a815ff505",
|
||||
"subjects": [
|
||||
"00:08:20 sol: sol-profile directory triage 2026-11-02 + independent re-derivation CHECK",
|
||||
"02:17:17 sol: triage the sol Hermes profile into 14 buckets",
|
||||
"04:50:29 sol: untracked-file triage classification (2026-11-01) - fresh 296-path re-derivation + CHECK",
|
||||
"04:59:59 sol: classify sol profile top-level entries 2026-11-01",
|
||||
"07:26:42 sol: untracked-file triage classification manifest + verifier",
|
||||
"07:34:31 sol: add sol-profile triage-review queue artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"wizard": "Volt",
|
||||
"commits": 5,
|
||||
"first_commit": "2026-11-01T00:05:08+00:00",
|
||||
"last_commit": "2026-11-01T09:34:22+00:00",
|
||||
"latest_sha": "03ba6d09f571e073735ee7f5649c59e14d810202",
|
||||
"subjects": [
|
||||
"00:05:08 volt: Q142 record -- the quill draft-compliance artifact now grades its own tree",
|
||||
"02:26:04 volt: census of every CHECK entry point at HEAD, and the quill draft table repaired to its lane",
|
||||
"02:29:16 volt: q143 baseline takes its own row, and the report states the load limit it measured",
|
||||
"05:16:53 volt: Q145 -- two entry points read FAIL beside their own green evidence",
|
||||
"09:34:22 volt: land Q146 record and its open-set pin \u2014 the repair blobs were already carried by d814a58, the queue record never was"
|
||||
]
|
||||
},
|
||||
{
|
||||
"wizard": "Beam",
|
||||
"commits": 3,
|
||||
"first_commit": "2026-11-01T04:44:56+00:00",
|
||||
"last_commit": "2026-11-01T08:49:33+00:00",
|
||||
"latest_sha": "40804bd5125bb549b6677beeb8516e48b9abe2c0",
|
||||
"subjects": [
|
||||
"04:44:56 quill: add 2026-11-01 standup with RED verdict (FORGE_TOKEN missing)",
|
||||
"08:48:44 beam: suffix automaton with endpos counts and LCS, tested",
|
||||
"08:49:33 beam: convex hull monotone chain with tests"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract a daily commit-author census for 2026-11-01 from the troupe-standup repo.
|
||||
|
||||
Lane: Extract (data extraction into a table).
|
||||
|
||||
Writes:
|
||||
/root/.hermes/wizard-outputs/ledger/repo-2026-11-01-commit-census.tsv
|
||||
/root/.hermes/wizard-outputs/ledger/repo-2026-11-01-commit-census.json
|
||||
"""
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
REPO = "/root/troupe-standup"
|
||||
OUTDIR = "/root/.hermes/wizard-outputs/ledger"
|
||||
DATE = "2026-11-01"
|
||||
TSV = f"{OUTDIR}/repo-2026-11-01-commit-census.tsv"
|
||||
JSON = f"{OUTDIR}/repo-2026-11-01-commit-census.json"
|
||||
|
||||
# Email -> canonical wizard name. Derived from the repo's own roster (WIZARDS-TABLE.md)
|
||||
# and `.mailmap`; kept here as a transparent mapping.
|
||||
WIZARD_BY_EMAIL = {
|
||||
"timmy@stackchain.ai": "Timmy",
|
||||
"timmy@alexanderwhitestone.com": "Timmy",
|
||||
"timmy@agents.invalid": "Timmy",
|
||||
"timmy@stackchain.invalid": "Timmy",
|
||||
"timmy@hermes": "Timmy",
|
||||
"timmy@stacktimmy.invalid": "Timmy",
|
||||
"timmy@localhost": "Timmy",
|
||||
"timmy@alexandrewswhitestone.com": "Timmy",
|
||||
"timmy@stachain.ai": "Timmy",
|
||||
"zephyrus-sparkborn@agents.invalid": "Zephyrus Sparkborn",
|
||||
"zephyrus-sparkborn@users.noreply.forge.alexanderwhitestone.com": "Zephyrus Sparkborn",
|
||||
"zephyrus-sparkborn@users.noreply.github.com": "Zephyrus Sparkborn",
|
||||
"zephyrus-sparkborn@noreply.local": "Zephyrus Sparkborn",
|
||||
"zephyrus@alexanderwhitestone.com": "Zephyrus Sparkborn",
|
||||
"cassian@agents.invalid": "Cassian Assayborn",
|
||||
"cassian@forge.local": "Cassian Assayborn",
|
||||
"volt@agents.invalid": "Volt",
|
||||
"volt@troupe.invalid": "Volt",
|
||||
"volt@troupe.local": "Volt",
|
||||
"volt@stackchain.local": "Volt",
|
||||
"volt@alexanderwhitestone.com": "Volt",
|
||||
"volt@stackchain.ai": "Volt",
|
||||
"ledger@agents.invalid": "Ledger",
|
||||
"forge@agents.invalid": "Forge",
|
||||
"mercury@agents.invalid": "Mercury",
|
||||
"merlin@agents.invalid": "Merlin",
|
||||
"sol@agents.invalid": "Sol",
|
||||
"quill@agents.invalid": "Quill",
|
||||
"sphinx@agents.invalid": "Sphinx",
|
||||
"null@agents.invalid": "Null",
|
||||
"argus@agents.invalid": "Argus",
|
||||
"argus@troupe": "Argus",
|
||||
"sentinel@troupe-standup.internal": "Sentinel",
|
||||
"beam@agents.invalid": "Beam",
|
||||
"troupe-pipe@agents.invalid": "Troupe-pipe",
|
||||
"pipe@localhost": "Pipe",
|
||||
}
|
||||
|
||||
def git(*args):
|
||||
return subprocess.run(
|
||||
["git", "-C", REPO] + list(args), check=True, capture_output=True, text=True
|
||||
).stdout
|
||||
|
||||
def main():
|
||||
# name, email, authordate_iso, sha, subject (commits on DATE only)
|
||||
rows = []
|
||||
out = git(
|
||||
"log",
|
||||
"--format=%an%x09%ae%x09%aI%x09%H%x09%s",
|
||||
"--no-renames",
|
||||
).splitlines()
|
||||
for line in out:
|
||||
if not line:
|
||||
continue
|
||||
parts = line.split("\t")
|
||||
if len(parts) != 5:
|
||||
continue
|
||||
name, email, adate, sha, subject = parts
|
||||
if adate.startswith(DATE + "T"):
|
||||
rows.append({"name": name, "email": email, "date": adate, "sha": sha, "subject": subject})
|
||||
|
||||
# group
|
||||
groups = {}
|
||||
for r in rows:
|
||||
email = r["email"]
|
||||
# strip a displayed typo that git recorded for Timmy (stacktimmy vs stachain)
|
||||
wizard = WIZARD_BY_EMAIL.get(email, "Unmapped")
|
||||
groups.setdefault(wizard, []).append(r)
|
||||
|
||||
total = len(rows)
|
||||
total_commits = len(rows)
|
||||
# verify the day's commit total against git itself
|
||||
day_total = int(git(
|
||||
"rev-list", "--count", f"--since={DATE}T00:00:00+00:00", f"--until={DATE}T23:59:59+00:00", "HEAD"
|
||||
).strip())
|
||||
if day_total != total:
|
||||
print(f"WARN: day_total({day_total}) != in-memory rows({total})", file=sys.stderr)
|
||||
|
||||
# order: by commits desc, then name
|
||||
order = sorted(groups.items(), key=lambda kv: (-len(kv[1]), kv[0]))
|
||||
|
||||
lines = ["wizard\tcommits\tfirst_commit\tlast_commit\tlatest_sha\tsubjects"]
|
||||
for wizard, rs in order:
|
||||
rs_sorted = sorted(rs, key=lambda r: r["date"])
|
||||
subjects = "; ".join(f"{r['date'][11:19]} {r['subject']}" for r in rs_sorted)
|
||||
lines.append(
|
||||
f"{wizard}\t{len(rs)}\t{rs_sorted[0]['date']}\t{rs_sorted[-1]['date']}\t"
|
||||
f"{rs_sorted[-1]['sha']}\t{subjects}"
|
||||
)
|
||||
|
||||
text = "\n".join(lines) + "\n"
|
||||
with open(TSV, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
with open(JSON, "w", encoding="utf-8") as f:
|
||||
json.dump(
|
||||
[
|
||||
{
|
||||
"wizard": w,
|
||||
"commits": len(rs),
|
||||
"first_commit": min(r["date"] for r in rs),
|
||||
"last_commit": max(r["date"] for r in rs),
|
||||
"latest_sha": max(rs, key=lambda r: r["date"])["sha"],
|
||||
"subjects": [f"{r['date'][11:19]} {r['subject']}" for r in sorted(rs, key=lambda r: r['date'])],
|
||||
}
|
||||
for w, rs in order
|
||||
],
|
||||
f,
|
||||
indent=2,
|
||||
)
|
||||
print(text)
|
||||
print(f"# rows={total} total_commits={total_commits} day_total_git={day_total} files={TSV}, {JSON}", file=sys.stderr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,6 @@
|
||||
wizard commits first_commit last_commit latest_sha subjects
|
||||
Ledger 11 2026-11-01T00:13:35+00:00 2026-11-01T07:43:16+00:00 34acf20e30f0ae31fbc13553df140a5f1b507ef2 00:13:35 volt: check_lint catches a trailing prose aside after sentence punctuation; 00:16:15 volt: q-checkparen CHECK entry point resolves its own tree; 02:18:23 ledger: 2026-11-01 directory census at HEAD; 02:33:39 ledger: worktree census at HEAD 2026-11-01 (check-verified); 02:40:41 ledger: worktree-census 2026-11-01 (CHECK-pinned, check-verified); 04:47:49 ledger: 2026-11-01 users census (JSONPlaceholder /users); 04:55:48 sol: untracked-file triage classification (2026-11-01) - fresh 295-path re-derivation with independent CHECK; 05:12:21 volt: land the Q144 entry-point record, its CHECK path and the path-claim repair; 07:21:26 ledger: todo-census extraction from JSONPlaceholder /todos; 07:29:05 sol: fix untracked-triad corpus to exclude pipeline files; 07:43:16 ledger: 2026-11-01 todo census (JSONPlaceholder /todos)
|
||||
Quill 7 2026-11-01T02:10:23+00:00 2026-11-01T09:48:48+00:00 d27c03f0e4651c9a4ee9323830d6d795f0d2b40a 02:10:23 quill: filled daily standup draft artifact (2026-11-01); 02:11:19 quill: add free-tier dependency audit draft; 04:44:22 quill: add 2026-11-01 standup with GREEN verdict and CHECK; 07:22:07 quill: update draft-compliance report for 2026-11-01 lane census; 07:22:55 quill: publish 2026-11-01 draft verification report; 07:43:40 quill: fix draft-compliance TSV/report counts and CHECK script header skip; 09:48:48 quill: add daily standup draft template artifact
|
||||
Sol 6 2026-11-01T00:08:20+00:00 2026-11-01T07:34:31+00:00 d814a58a104580c640b1eee12ec06f7a815ff505 00:08:20 sol: sol-profile directory triage 2026-11-02 + independent re-derivation CHECK; 02:17:17 sol: triage the sol Hermes profile into 14 buckets; 04:50:29 sol: untracked-file triage classification (2026-11-01) - fresh 296-path re-derivation + CHECK; 04:59:59 sol: classify sol profile top-level entries 2026-11-01; 07:26:42 sol: untracked-file triage classification manifest + verifier; 07:34:31 sol: add sol-profile triage-review queue artifact
|
||||
Volt 5 2026-11-01T00:05:08+00:00 2026-11-01T09:34:22+00:00 03ba6d09f571e073735ee7f5649c59e14d810202 00:05:08 volt: Q142 record -- the quill draft-compliance artifact now grades its own tree; 02:26:04 volt: census of every CHECK entry point at HEAD, and the quill draft table repaired to its lane; 02:29:16 volt: q143 baseline takes its own row, and the report states the load limit it measured; 05:16:53 volt: Q145 -- two entry points read FAIL beside their own green evidence; 09:34:22 volt: land Q146 record and its open-set pin — the repair blobs were already carried by d814a58, the queue record never was
|
||||
Beam 3 2026-11-01T04:44:56+00:00 2026-11-01T08:49:33+00:00 40804bd5125bb549b6677beeb8516e48b9abe2c0 04:44:56 quill: add 2026-11-01 standup with RED verdict (FORGE_TOKEN missing); 08:48:44 beam: suffix automaton with endpos counts and LCS, tested; 08:49:33 beam: convex hull monotone chain with tests
|
||||
|
Reference in new issue
Block a user