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
2 changes: 1 addition & 1 deletion .claude/skills/replication-package/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Write `replication_package/README.md` (the AEA template, fields below). Leave a

- **Overview / paper citation** — title, authors, abstract one-liner.
- **Data Availability Statement** — for each dataset: public / restricted / proprietary, and whether it is redistributed in the package. This is the single most-rejected DCAS field; be explicit.
- **Dataset manifest** — a table, one row per file: `filename | description | source (URL/citation) | access (public / DUA / purchase) | license | provided in package? (Y/N)`.
- **Dataset manifest** — a table, one row per file: `filename | description | source (URL/citation) | access (public / DUA / purchase) | license | provided in package? (Y/N)`. Start it from `python3 scripts/data-inventory.py data/raw --format md` (add `--header` once you have checked that each CSV's first row is a header), which lists each file's size, SHA-256, rows, column names, and the columns whose *names* suggest personal data, and never a value. Everything in it is still derived from the data. On restricted data the author runs it on the permitted machine, and the **whole** manifest (file names, sizes, row counts, column names) goes through the agreement's disclosure review (`/disclosure-check`) before it leaves that machine or reaches a model. `--no-counts` drops the row counts.
- **Computational requirements** — OS, software + versions (R / Stata / Python), key packages, approximate runtime, RAM, any HPC/cluster need.
- **AI-generated analytical outputs** (only if the analysis used a model to *produce data*, such as variables coded by an LLM, classified text, or extracted fields) — for each output: the exact model ID or snapshot and the date it ran, the prompts verbatim, the parameters, where the raw model output is kept, the post-processing applied, and who checked a sample and how. AI help with *writing code* is not an analytical output; it is disclosed under the journal's AI policy (`/submission-disclosures`). The distinction follows the World Bank's reproducibility guidance (`worldbank/wb-reproducible-research-repository`).
- **Step-by-step run instructions** — the single master-script invocation, then the expected outputs.
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ An **adoption release** carrying what the 2026-11-06 audit found worth building
- **`/verify`** (62nd skill). Since 2.1.286, Claude Code tells Claude to run a project skill named `verify` right before committing; docs-only and tests-only commits are exempt. This one runs the backtest, and the quality score on staged `.qmd`/`.tex`/`.R` files, and stops the commit on a failure. It skips itself when the git pre-commit hook will run the same gates. It is a reminder, not enforcement: the hook and `/commit` remain the gates. It is bridged for Codex and Antigravity.
- **`templates/triangulation-ledger.md`.** For each robustness check, write down and commit what result would support the claim, weaken it or leave it undecided, before the check runs; the result is filled in afterwards in a new commit. It is method-neutral and joins `spec-ledger.md` on date and `Script:line`.
- **Template, not fork, for unpublished work** (README and guide, step 1, placed before the clone commands). The repository is now a GitHub template repository, so a copy can be made private; a fork of a public repository cannot.
- **`scripts/data-inventory.py`: a dataset manifest that never carries a value.** For each file it lists the path, size and SHA-256 and, for tables, the row count, the column names, and the columns whose *names* suggest personal data (name, email, address, birth date, ...).
- **CSV and TSV** use the standard library. A first row is listed as column names only with `--header`, your check that every file given has a header, because no rule can tell `Alice,London` from a header. Even with `--header`, a numeric first row is withheld.
- **`.dta`, `.sav` and `.sas7bdat`** use pyreadstat's metadata-only read, and **Parquet** uses its footer, when those packages are installed.
- **`--no-counts`** drops the row counts.
- **On restricted data**, the author runs it, and the whole manifest goes through the agreement's disclosure review before it leaves the machine or reaches a model.
- `/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.
- **`/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: 233 cases).
(standing hook battery: 322 cases, seconds to run; portability suite: 239 cases).

---

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 @@ -62,6 +62,7 @@ meaningless:
| 2026-11-06 | `scripts/file-issue.py` (PR #177 review, #174: `--repo` pinned to `origin` as HOST/OWNER/NAME in any spelling — `GitHub.com`, `host:/owner/name`, an ssh-config alias resolved with `ssh -G`, a GitHub Enterprise host; an origin that is neither local nor identifiable stops the script, exit 2, without repeating the URL; the printed duplicate follow-ups carry the same pin) | `scripts/hook-battery.sh` run with `FILE_ISSUE` pointing at the first version (0bd456d), at the first repair (the copy an external GPT-6 Pro review read — `quality_reports/oracle_audits/2026-11-06_pr177-fork-safety/`), and at a mutant that passes `--repo X` as one argument | case-varied host · ssh alias to github.com · ssh alias to an Enterprise host · Enterprise host · the template's owner/name on another host · scp absolute path · unreadable origin carrying a token · fused `--repo` argument · unpinned follow-ups | 9 (i11–i14, i16–i18, i20, plus the fused mutant) | 0bd456d red on i11–i14, i16–i18, i20; the first repair red on i11, i12, i14, i16–i18, i20 (and on i19, which it mis-pinned); the fused mutant red on i11–i13, i16–i18 | 0/2 controls on the final version (i15: the template on github.com; i19: a `file://` origin) | Codex (P1) found the first class; the GPT-6 Pro review found the rest in the first repair | **PASS** |
| 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-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