[v0.4.0] Research report PDF pipeline #47

Closed
opened 2026-09-29 18:25:00 +00:00 by Winnie · 6 comments
Owner

Prerequisite for the researcher-grade PDF report Robert requested on #39. Builds a professional PDF from the structured iteration log (#46) + game-rulings + issue history: title page, abstract, methodology (game model, Lisp AI architecture, bench harness with fixed seeds, 13 punishing presets), results (full hypothesis/experiment tables, per-preset mains table, per-specialist gauntlet table, before/after comparisons vs v0.3.0 via --bench-vs), key findings, accounting-validation notes (ACCT/CF divergence checks), future work (central bank, replay, churn economy). Must be presentable to a professional researcher. Deliverable: the generated PDF emailed to robert@machinetele.com as part of the #34 ship gate, and the generator checked into the repo for future releases.

Prerequisite for the researcher-grade PDF report Robert requested on #39. Builds a professional PDF from the structured iteration log (#46) + game-rulings + issue history: title page, abstract, methodology (game model, Lisp AI architecture, bench harness with fixed seeds, 13 punishing presets), results (full hypothesis/experiment tables, per-preset mains table, per-specialist gauntlet table, before/after comparisons vs v0.3.0 via --bench-vs), key findings, accounting-validation notes (ACCT/CF divergence checks), future work (central bank, replay, churn economy). Must be presentable to a professional researcher. Deliverable: the generated PDF emailed to robert@machinetele.com as part of the #34 ship gate, and the generator checked into the repo for future releases.
Winnie self-assigned this 2026-09-29 18:25:00 +00:00
Author
Owner

Step 1/6 — dispatched, starting now. I'm the subagent on this issue.

Plan for the researcher-grade PDF report pipeline (#47):

  1. Post this start comment (comment first, then work)
  2. Create git worktree on 47-report branched from origin/46-iter-log in bankdev
  3. Build the generator under tools/report/ (consumes iterations.json per the #46/#48 schema, plus git history + issue data via the Forgejo API; never fabricates numbers)
  4. End-to-end verification: generate a real PDF from a schema-valid fixture, check %PDF magic, page count, and extracted text
  5. Commit, push 47-report, open PR against master, request review from robertismo
  6. Post completion comment with run instructions + PR link

I will comment again at every intermediate step. No bench runs will be executed.

**Step 1/6 — dispatched, starting now.** I'm the subagent on this issue. Plan for the researcher-grade PDF report pipeline (#47): 1. [x] Post this start comment (comment first, then work) 2. [ ] Create git worktree on `47-report` branched from `origin/46-iter-log` in bankdev 3. [ ] Build the generator under `tools/report/` (consumes `iterations.json` per the #46/#48 schema, plus git history + issue data via the Forgejo API; never fabricates numbers) 4. [ ] End-to-end verification: generate a real PDF from a schema-valid fixture, check `%PDF` magic, page count, and extracted text 5. [ ] Commit, push `47-report`, open PR against `master`, request review from robertismo 6. [ ] Post completion comment with run instructions + PR link I will comment again at every intermediate step. No bench runs will be executed.
Author
Owner

Step 2/6 — worktree ready.

/root/bw-47-report on branch 47-report, branched from origin/46-iter-log @ 4bf460e ([#46] Structured iteration log). Clean tree. This gives me the exact iterlog.go schema for the generator.

Next: read iterlog.go + bench.go (13 punishing presets) + bench-results.md, fetch issue #46/#47 narrative from the API, then build the generator under tools/report/. No bench runs, as promised.

**Step 2/6 — worktree ready.** `/root/bw-47-report` on branch `47-report`, branched from `origin/46-iter-log` @ `4bf460e` ([#46] Structured iteration log). Clean tree. This gives me the exact `iterlog.go` schema for the generator. Next: read `iterlog.go` + `bench.go` (13 punishing presets) + `bench-results.md`, fetch issue #46/#47 narrative from the API, then build the generator under `tools/report/`. No bench runs, as promised.
Author
Owner

Step 3/6 — generator built. tools/report/ is drafted in the worktree:

  • generate_report.py — CLI; consumes iterations.json (schema read straight off iterlog.go on 46-iter-log), reads git history via git log, fetches issue data from the Forgejo API. Never fabricates: unknown values render as '—', schema validation results are reported in the PDF itself.
  • bwpdf.py — vendored pure-stdlib PDF writer (no pip needed; only zlib etc.).
  • templates/ — 7 section templates (abstract, methodology, results, findings, accounting, future, provenance).
  • testdata/iterations.sample.json — schema-valid synthetic fixture (2 records, 13 presets, 10 gauntlet specs, bench-vs rows); real git SHAs/timestamps, synthetic numbers, stamped via --note.
  • README.md — deps, usage, schema, verification commands.

Sections covered: title page, abstract, methodology (game model, Lisp AI architecture, bench harness + fixed seeds, the 13 punishing presets from bench.go), results (per-preset mains, specialist gauntlet, bench-vs before/after), key findings, accounting/validation notes, future work (central bank #15, replay, churn).

Next: end-to-end generation from the fixture + PDF verification (magic bytes, page count, text extraction).

**Step 3/6 — generator built.** `tools/report/` is drafted in the worktree: - `generate_report.py` — CLI; consumes iterations.json (schema read straight off `iterlog.go` on 46-iter-log), reads git history via `git log`, fetches issue data from the Forgejo API. Never fabricates: unknown values render as '—', schema validation results are reported in the PDF itself. - `bwpdf.py` — vendored pure-stdlib PDF writer (no pip needed; only zlib etc.). - `templates/` — 7 section templates (abstract, methodology, results, findings, accounting, future, provenance). - `testdata/iterations.sample.json` — schema-valid synthetic fixture (2 records, 13 presets, 10 gauntlet specs, bench-vs rows); real git SHAs/timestamps, synthetic numbers, stamped via `--note`. - `README.md` — deps, usage, schema, verification commands. Sections covered: title page, abstract, methodology (game model, Lisp AI architecture, bench harness + fixed seeds, the 13 punishing presets from bench.go), results (per-preset mains, specialist gauntlet, bench-vs before/after), key findings, accounting/validation notes, future work (central bank #15, replay, churn). Next: end-to-end generation from the fixture + PDF verification (magic bytes, page count, text extraction).
Author
Owner

Step 4/6 — end-to-end verification PASSED.

Generated three real PDFs from the fixture + repo and verified each with pypdf (skill's method) and gs rasterization:

  • Fixture run (iterations.sample.json, 2 synthetic records): 12 pages, %PDF-1.4 magic ✓, 24,647 chars extracted, every expected token found (Preset/empire/mill/vault/adapt tables, gauntlet, bench-vs, validation table, ACCT DIVERGENCE, Vickrey, SHAs 5d760fc/be367de resolved from git history). Spot-checked fixture numbers: record-2 duel wins 13/47/13/13 all present in extracted text ✓. Visual check of rendered pages 1/3/6/12 via rasterization: title page, banners, ruled tables all clean.
  • Empty-log run (repo's current iterations.json = []): 6 pages, reports "no records" instead of crashing ✓.
  • --all-records run: 15 pages, full detail for both records ✓.
  • TOC page numbers verified against actual pages (Abstract p3, Results p5, ..., Provenance p11) ✓.

Found and fixed two writer bugs during verification (object references in the vendored PDF writer; UTF-16 metadata encoding). Everything runs on pure Python stdlib — no pip.

Next: ship files into the 47-report worktree, commit, push, open the PR.

**Step 4/6 — end-to-end verification PASSED.** Generated three real PDFs from the fixture + repo and verified each with pypdf (skill's method) and gs rasterization: - Fixture run (`iterations.sample.json`, 2 synthetic records): **12 pages**, `%PDF-1.4` magic ✓, 24,647 chars extracted, every expected token found (`Preset/empire/mill/vault/adapt` tables, gauntlet, bench-vs, validation table, `ACCT DIVERGENCE`, `Vickrey`, SHAs `5d760fc`/`be367de` resolved from git history). Spot-checked fixture numbers: record-2 duel wins 13/47/13/13 all present in extracted text ✓. Visual check of rendered pages 1/3/6/12 via rasterization: title page, banners, ruled tables all clean. - Empty-log run (repo's current `iterations.json` = `[]`): 6 pages, reports "no records" instead of crashing ✓. - `--all-records` run: 15 pages, full detail for both records ✓. - TOC page numbers verified against actual pages (Abstract p3, Results p5, ..., Provenance p11) ✓. Found and fixed two writer bugs during verification (object references in the vendored PDF writer; UTF-16 metadata encoding). Everything runs on pure Python stdlib — no pip. Next: ship files into the 47-report worktree, commit, push, open the PR.
Author
Owner

Step 6/6 — done. PR open: #51 (branch 47-report -> master, 12 files, +2,351 lines, review requested from robertismo). Master was not touched; no bench was run.

How to run it

cd bankwars
python3 tools/report/generate_report.py                    # -> bankwars-report.pdf (uses iterations.json)
python3 tools/report/generate_report.py --all-records      # full detail for every record
python3 tools/report/generate_report.py --no-api           # offline (skips issue fetch)
# fixture sanity check (stamped as synthetic):
python3 tools/report/generate_report.py --iterations tools/report/testdata/iterations.sample.json \
    --note 'SYNTHETIC FIXTURE DATA - verification run only'

Requirements: python3 >= 3.8, standard library only — no pip. Verification recipe (pypdf, page count, text extraction) is in tools/report/README.md.

What the PDF contains

Title page, contents, abstract (headline stats computed from the log), methodology (game model, Lisp AI architecture, bench harness + fixed seeds, the 13 punishing presets), results (per-preset mains, specialist gauntlet, bench-vs before/after, iteration history), key findings, accounting/validation notes (schema validation the generator actually runs, reported as PASS/FAIL), future work (central bank #15, replay, churn economy), and a data-provenance appendix. Every number comes from iterations.json / git history / the Forgejo API — nothing is hand-typed; unknown values render as '—'.

Verified

12-page PDF from the synthetic fixture (%PDF-1.4 magic, 24,647 chars extracted via pypdf, fixture numbers spot-checked in extracted text, pages rasterized and inspected), graceful 6-page empty-log report, 15-page --all-records run, TOC page numbers cross-checked. The generator consumes exactly the #46/#48 schema (iterlog.go).

**Step 6/6 — done.** PR open: **https://git.machinetele.com/Winnie/bankwars/pulls/51** (branch `47-report` -> `master`, 12 files, +2,351 lines, review requested from robertismo). Master was not touched; no bench was run. ### How to run it ```bash cd bankwars python3 tools/report/generate_report.py # -> bankwars-report.pdf (uses iterations.json) python3 tools/report/generate_report.py --all-records # full detail for every record python3 tools/report/generate_report.py --no-api # offline (skips issue fetch) # fixture sanity check (stamped as synthetic): python3 tools/report/generate_report.py --iterations tools/report/testdata/iterations.sample.json \ --note 'SYNTHETIC FIXTURE DATA - verification run only' ``` Requirements: python3 >= 3.8, standard library only — no pip. Verification recipe (pypdf, page count, text extraction) is in `tools/report/README.md`. ### What the PDF contains Title page, contents, abstract (headline stats computed from the log), methodology (game model, Lisp AI architecture, bench harness + fixed seeds, the 13 punishing presets), results (per-preset mains, specialist gauntlet, bench-vs before/after, iteration history), key findings, accounting/validation notes (schema validation the generator actually runs, reported as PASS/FAIL), future work (central bank #15, replay, churn economy), and a data-provenance appendix. Every number comes from iterations.json / git history / the Forgejo API — nothing is hand-typed; unknown values render as '—'. ### Verified 12-page PDF from the synthetic fixture (`%PDF-1.4` magic, 24,647 chars extracted via pypdf, fixture numbers spot-checked in extracted text, pages rasterized and inspected), graceful 6-page empty-log report, 15-page `--all-records` run, TOC page numbers cross-checked. The generator consumes exactly the #46/#48 schema (`iterlog.go`).
Author
Owner

Merged: PR #51 (tools/report PDF generator) is on master. It consumes iterations.json + git history + live issue data, enforces no-fabrication, and produces the researcher-grade report. The actual report PDF gets generated and emailed as part of the #34 ship gate once the #39 mains work lands. Closing.

Merged: PR #51 (tools/report PDF generator) is on master. It consumes iterations.json + git history + live issue data, enforces no-fabrication, and produces the researcher-grade report. The actual report PDF gets generated and emailed as part of the #34 ship gate once the #39 mains work lands. Closing.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Winnie/bankwars#47
No description provided.