Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .claude/skills/visual-audit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ Perform a thorough visual layout audit of a slide deck.
- If it exits 2 (usually Playwright is missing — the script prints the one-time venv install and the `SLIDE_QA_PYTHON` line to set), say so, fall back to reading the rendered HTML of the dense slides and any screenshot the user supplies, and name the slides the user should eyeball

3. **For Beamer (.tex) files:**
- Compile (see `/compile-latex`), check the log for overfull hbox warnings, and Read the PDF pages that carry figures or dense content
- Compile (see `/compile-latex`), then run `python3 scripts/beamer-qa.py Slides/<deck>.pdf`. It saves one screenshot per page to `quality_reports/audits/beamer-qa/<deck>/`, prints which frame and overlay step each page is, and lists the errors and the warnings that matter from the `.log` beside the PDF (overfull boxes, undefined references, missing characters). Read the screenshots of dense pages and of every page the log names.
- A frame whose content runs into the footline often compiles with no warning. To flag it, add `--band-mm FROM TO`: any ink between FROM and TO mm above the bottom edge is reported. The band depends on the theme, so measure it once on a screenshot: pick a strip just above the footline that a correct page leaves empty, and add `--band-x-max PCT` to skip a page number or navigation symbols on the right.
- If it exits 2 (no PDF, or poppler missing; the script prints the install line), fall back to reading the PDF pages that carry figures or dense content

4. **Audit every slide for:**

Expand Down
4 changes: 2 additions & 2 deletions .render-stamp
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
guide/workflow-guide.html:c2c7434f27171ddc:544ac54f58ee0f82
docs/workflow-guide.html:c2c7434f27171ddc:544ac54f58ee0f82
guide/workflow-guide.html:0bc283c0b000845b:dd57a16e1ed58502
docs/workflow-guide.html:0bc283c0b000845b:dd57a16e1ed58502
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ If you have forked this template, see the **Upgrading** section at the bottom fo

## v2.9.0 — 2026-11-06

An **adoption release** carrying what the 2026-11-06 audit found worth building or linking: a `verify` skill that Claude Code runs before it commits, a triangulation-ledger template, guidance on using the template rather than forking it for unpublished work, an AI-generated-outputs section for replication packages, and readiness for the hook launcher on #180.
An **adoption release** carrying what the 2026-11-06 audit found worth building or linking. Everything in it is additive: a new skill, new scripts and a template, guidance, and links to outside work, each listed below.

### Added

Expand All @@ -24,12 +24,13 @@ An **adoption release** carrying what the 2026-11-06 audit found worth building
- `/replication-package` starts its dataset manifest from it.
- Six portability cases pin it, under cp1252 and with non-ASCII file names. Three mutants each fail their own case: one leaks a value, one drops the numeric-row check, and one lists names without `--header`. Codex's review on PR #184 found the all-text-first-row leak and the clearance gap.
- The idea follows the World Bank's reproducibility skill; the code is our own.
- **`scripts/beamer-qa.py`: what a compiled Beamer deck looks like, page by page.** It saves a screenshot of every page, prints the frame and overlay step each page belongs to (from Beamer's `.nav`), and lists the errors and warnings that matter from the `.log` beside the PDF. With `--band-mm FROM TO` it flags every page with ink in a strip just above the footline: a frame whose content runs into the footline often compiles without a warning. The strip depends on the theme, so it is off unless given. It needs poppler and no Python packages. `/visual-audit` runs it for Beamer decks. A full run deletes the page screenshots an earlier run left in its folder, and nothing else, so a deck that lost pages shows no stale ones (Codex's review on PR #185). Errors are caught in `-file-line-error` form too (also from that review). Six portability cases pin it, and eleven mutants each fail their own case. Adapted, with its MIT notice, from `shoot.py` in claesbackman/AI-research-feedback.
- **`/replication-package`: AI-generated analytical outputs.** When a model produced data, the README records the model ID and date, the prompts, the parameters, the raw outputs, the post-processing and who checked them. AI coding help stays a disclosure matter. The idea follows the World Bank's reproducibility guidance; the wording is our own.
- **Links:** Brodeur et al. 2026 (*PNAS*: AI-assisted teams reproduce about as often as human-only teams but catch fewer major coding errors; AI-led teams reproduce far less) in `verification-ladder.md`; `paulgp/econ-ai-detector` in `writing-with-ai.md` and the ecosystem section; `posit-dev/skills` in README and the guide.
- **TROUBLESHOOTING: "Every Bash, Edit and Write is refused, with a hook error"**, covering a missing hook script (recovery from a terminal) and a missing `python3` on Windows.

**Inventory at release: 62 skills, 18 agents, 37 rules, 11 hooks, 11 gates**
(standing hook battery: 322 cases, seconds to run; portability suite: 239 cases).
(standing hook battery: 322 cases, seconds to run; portability suite: 245 cases).

---

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ Rules use path-scoped loading: **always-on** rules load every session; **path-sc
| R | Figures and analysis (`/data-analysis`, `scripts/R/` template) | [r-project.org](https://www.r-project.org/) |
| pdf2svg | TikZ → SVG for Quarto (`/extract-tikz`) | `brew install pdf2svg` (macOS), `apt install pdf2svg` (Debian) |
| [gh CLI](https://cli.github.com/) | PR / issue workflow | `brew install gh` (macOS), `apt install gh` (Debian) |
| poppler (optional) | Beamer page screenshots, page-to-frame map and log digest (`scripts/beamer-qa.py`, run by `/visual-audit`) | `brew install poppler` (macOS), `apt install poppler-utils` (Debian) |
| Playwright for Python (optional) | Browser-measured slide QA (`scripts/slide-qa.py`, run by `/visual-audit`, `/qa-quarto`, `/slide-excellence`); drives your installed Chrome | `python3 -m venv ~/.venvs/slide-qa && ~/.venvs/slide-qa/bin/pip install playwright`, then `export SLIDE_QA_PYTHON=~/.venvs/slide-qa/bin/python` |

**Minimum to fork this template:** Claude Code + git + Python 3 (Python is already installed on macOS/Linux).
Expand Down
5 changes: 5 additions & 0 deletions docs/workflow-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,11 @@ <h2 data-number="2.1" class="anchored" data-anchor-id="sec-prerequisites"><span
<td><code>brew install gh</code> (macOS)</td>
</tr>
<tr class="odd">
<td>poppler</td>
<td>Beamer page screenshots and log digest (<code>scripts/beamer-qa.py</code>)</td>
<td><code>brew install poppler</code> (macOS), <code>apt install poppler-utils</code> (Debian)</td>
</tr>
<tr class="even">
<td>Playwright for Python</td>
<td>Slide overflow measured in a real browser (<code>scripts/slide-qa.py</code>)</td>
<td><code>python3 -m venv ~/.venvs/slide-qa &amp;&amp; ~/.venvs/slide-qa/bin/pip install playwright</code>, then <code>export SLIDE_QA_PYTHON=~/.venvs/slide-qa/bin/python</code> (uses your installed Chrome)</td>
Expand Down
5 changes: 5 additions & 0 deletions guide/workflow-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,11 @@ <h2 data-number="2.1" class="anchored" data-anchor-id="sec-prerequisites"><span
<td><code>brew install gh</code> (macOS)</td>
</tr>
<tr class="odd">
<td>poppler</td>
<td>Beamer page screenshots and log digest (<code>scripts/beamer-qa.py</code>)</td>
<td><code>brew install poppler</code> (macOS), <code>apt install poppler-utils</code> (Debian)</td>
</tr>
<tr class="even">
<td>Playwright for Python</td>
<td>Slide overflow measured in a real browser (<code>scripts/slide-qa.py</code>)</td>
<td><code>python3 -m venv ~/.venvs/slide-qa &amp;&amp; ~/.venvs/slide-qa/bin/pip install playwright</code>, then <code>export SLIDE_QA_PYTHON=~/.venvs/slide-qa/bin/python</code> (uses your installed Chrome)</td>
Expand Down
1 change: 1 addition & 0 deletions guide/workflow-guide.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ You need four things: install Claude Code, fork the repo, run `./scripts/install
| [Quarto](https://quarto.org) | Web slides | [quarto.org/docs/get-started](https://quarto.org/docs/get-started/) |
| R | Figures & data analysis | [r-project.org](https://www.r-project.org/) |
| [gh CLI](https://cli.github.com/) | PR workflow | `brew install gh` (macOS) |
| poppler | Beamer page screenshots and log digest (`scripts/beamer-qa.py`) | `brew install poppler` (macOS), `apt install poppler-utils` (Debian) |
| Playwright for Python | Slide overflow measured in a real browser (`scripts/slide-qa.py`) | `python3 -m venv ~/.venvs/slide-qa && ~/.venvs/slide-qa/bin/pip install playwright`, then `export SLIDE_QA_PYTHON=~/.venvs/slide-qa/bin/python` (uses your installed Chrome) |

::: {.callout-note}
Expand Down
1 change: 1 addition & 0 deletions quality_reports/qualification/LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ meaningless:
| 2026-11-06 | `check-skill-integrity.py` check 6 — **the `.agents/skills/` bridge is current** (every skill classified in `scripts/sync-agent-skills.py`; every generated wrapper for Codex and Antigravity matches its `.claude/skills/` source) | four copies of the working tree in the session scratchpad, outside the checkout, one seeded defect each; the real script | wrapper description edited by hand · a wrapper deleted · a stray file in the bridge | 3 | 3/3 (exit 1, the file and the fix named) | 0/2 (an unmodified copy: exit 0; a fork's new skill in neither list: a P2 advisory naming the fix, exit 0, by design) | new check; the bridge did not exist before | **PASS** |
| 2026-11-06 | `check-ledger-coverage.py` — **reads the inline hook launcher** `sh -c '<code>' <name> <script>` (#179, #180) as running `<script>` | the pre-change and changed `script_of()` loaded side by side in the session scratchpad, given the launcher drafted for #180 | launcher naming a real hook · launcher naming a misspelt hook · launcher with no script | 3 | the changed parser registers the real hook, flags the misspelt one, refuses the scriptless one; the old parser flagged all three as missing (a false alarm on the valid form) | 0/1 (the plain `python3 <script>` form: registered by both) | needed before the owner applies the launcher patch on #180, or the gate would fail the repository | **PASS** |
| 2026-11-06 | `scripts/data-inventory.py` (new: a dataset manifest that never carries a value; CSV/TSV names only on `--header`; `--no-counts`) | `tests/portability/test_scripts.py::DataInventory` run against the script and three mutants loaded from the session scratchpad | a data value reaches the output · a numeric first row listed as names · any first row listed as names without `--header` (the all-text-row leak Codex found on PR #184) | 3 | 3/3 (each mutant fails only its own case) | 0/6 on the real script, on Python 3.9 and 3.14, with cp1252 output and non-ASCII names | new script | **PASS** |
| 2026-11-06 | `scripts/beamer-qa.py` (new: per-page screenshots of a Beamer PDF, the page→frame/step map from `.nav`, a `.log` digest, an opt-in footline-band ink check) | `tests/portability/test_scripts.py::BeamerQa` run against the script and eleven mutants loaded from the session scratchpad; the band and cleanup cases build their own PDF and skip without poppler | band measured from the top edge · appendix frames numbered as main frames · a wrapped `(hyperref)` continuation dropped · `--band-x-max` ignored · a full run that keeps an earlier build's page screenshots (Codex, PR #185), one that deletes every file in the folder, one that cleans on a `--pages` run too · a `-file-line-error` error dropped because it lacks the word "Error" (Codex, PR #185) · the drive-letter form `C:/…:7:` missed · any `:digits` read as an error · the "Rerun" filter applied before a `(rerunfilecheck)` continuation is joined | 11 | 11/11 (each mutant fails only its own case) | 0/6 on the real script; a deck compiled with `-file-line-error` and an undefined macro reports exactly that one error; also run on a compiled Madrid deck, where it flagged the one frame whose bullets run into the footline and LaTeX logged nothing | new script | **PASS** |
| 2026-09-26 | `slide-qa.py` (new: measures a rendered Reveal.js deck in headless Chrome) | two regression decks in a scratchpad (30 slides MathJax 2 incl. knitr output, 4 slides KaTeX) + the earlier 8-slide seeded deck + `Quarto/HelloWorld.qmd`; Playwright 1.63.0 driving Google Chrome 152 | too-tall list · too-wide box · sideways-scrolling code · too-wide, too-tall and inline-fraction formulas (MathJax and KaTeX) · kable table and plot past the bottom · overflow:hidden wide div · fade-out fragment · scrollable slide · slide with its own transition · auto-animate target · second tab of a tabset · lazily loaded image · uncounted slide | 22 | 22/22 (18 in the regression decks + 4 in the seeded deck, each on its own slide) | 0/23 (16 clean regression slides — math, fragments, columns, small table, small and stretched images, tabset, transition, filler — 4 clean seeded slides, 3 HelloWorld slides) | first version: 4/4 on its own deck, but an adversarial review then found 13 blind spots (chunk output never measured, inline MathJax box, transitions mid-animation, uncounted slides skipped, and others); every one is a slide in the regression decks | **PASS** |
| 2026-09-26 | `validate-findings.py --check-quotes` (every double-quoted span of 12+ characters in a finding's evidence must occur in the cited file, or in another file the evidence names by path) | 24 seeded findings against LaTeX, Quarto, Beamer and PDF fixtures in a scratchpad, plus a binary file | fabricated quote · changed number · text from a file not named · misquoted number after a `%` · swapped notation (`\hat\alpha` for `\hat\beta`) · elided fragments stitched from far apart · parity quote in neither file · fabricated quote from a PDF | 8 | 8/8 (exit 1, each miss listed with the closest line) | 0/16 (exact LaTeX; curly quotes, minus sign, spacing; `...` and `[…]` elisions; hyphenation both ways; backticked command; a short quoted term before a real quote; `\%`; LaTeX quote marks; forced break and `---`; inline code inside a quote; a Beamer quote in a parity finding; a genuine PDF quote) — and an unreadable binary file left unchecked, exit 0 | first version: an adversarial review found PDFs always failing, short quoted terms shifting the pairing, text after `%` never checked, and notation swaps passing; all fixed before this row | **PASS** |
| 2026-09-26 | `check-repo-hygiene.py` (append-only check for the replication log and the specification ledger: every committed line kept, in order; `APPEND_ONLY_BASE` in CI; layout and R/Python environment files allowed) | a throwaway git repository | committed line edited · log deleted · path turned into a directory · edit staged while the working tree is restored · `git rm --cached` · a rewrite committed without the hook, caught with `APPEND_ONLY_BASE` | 6 | 6/6 (exit 1, naming the reference, where, and the first lost line) | 0/5 (an appended entry; a CRLF working tree; a CRLF tree with an appended entry; a co-author's rows inserted by a merge; the same rewrite locally with no base set, which HEAD already contains) | before: append-only was only a request, and `output/` — the layout's own results folder — failed the gate; the first version of this check also failed CRLF checkouts, missed `git rm --cached` and could not fire in CI (all fixed) | **PASS** |
Expand Down
Loading
Loading