paperlint 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +72 -0
- package/.github/workflows/ci.yml +297 -0
- package/.github/workflows/dependabot-automerge.yml +70 -0
- package/.github/workflows/pr-title.yml +59 -0
- package/.github/workflows/release.yml +54 -0
- package/CLAUDE.md +598 -0
- package/CONTRIBUTING.md +159 -0
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/action.harness.mjs +287 -0
- package/action.mutations.mjs +162 -0
- package/action.yml +138 -0
- package/bin/rpp.mjs +43 -0
- package/dist/action-ref.d.ts +12 -0
- package/dist/action-ref.d.ts.map +1 -0
- package/dist/action-ref.js +16 -0
- package/dist/action-ref.js.map +1 -0
- package/dist/adapters/banal/failure.d.ts +73 -0
- package/dist/adapters/banal/failure.d.ts.map +1 -0
- package/dist/adapters/banal/failure.js +58 -0
- package/dist/adapters/banal/failure.js.map +1 -0
- package/dist/adapters/banal/index.d.ts +17 -0
- package/dist/adapters/banal/index.d.ts.map +1 -0
- package/dist/adapters/banal/index.js +56 -0
- package/dist/adapters/banal/index.js.map +1 -0
- package/dist/adapters/banal/install.d.ts +26 -0
- package/dist/adapters/banal/install.d.ts.map +1 -0
- package/dist/adapters/banal/install.js +15 -0
- package/dist/adapters/banal/install.js.map +1 -0
- package/dist/adapters/banal/invocation.d.ts +48 -0
- package/dist/adapters/banal/invocation.d.ts.map +1 -0
- package/dist/adapters/banal/invocation.js +43 -0
- package/dist/adapters/banal/invocation.js.map +1 -0
- package/dist/adapters/banal/locate.d.ts +50 -0
- package/dist/adapters/banal/locate.d.ts.map +1 -0
- package/dist/adapters/banal/locate.js +34 -0
- package/dist/adapters/banal/locate.js.map +1 -0
- package/dist/adapters/banal/output.d.ts +27 -0
- package/dist/adapters/banal/output.d.ts.map +1 -0
- package/dist/adapters/banal/output.js +112 -0
- package/dist/adapters/banal/output.js.map +1 -0
- package/dist/adapters/banal/pin.d.ts +19 -0
- package/dist/adapters/banal/pin.d.ts.map +1 -0
- package/dist/adapters/banal/pin.js +15 -0
- package/dist/adapters/banal/pin.js.map +1 -0
- package/dist/adapters/banal/probe.d.ts +12 -0
- package/dist/adapters/banal/probe.d.ts.map +1 -0
- package/dist/adapters/banal/probe.js +27 -0
- package/dist/adapters/banal/probe.js.map +1 -0
- package/dist/adapters/banal/run.d.ts +89 -0
- package/dist/adapters/banal/run.d.ts.map +1 -0
- package/dist/adapters/banal/run.js +104 -0
- package/dist/adapters/banal/run.js.map +1 -0
- package/dist/adapters/banal/settings.d.ts +18 -0
- package/dist/adapters/banal/settings.d.ts.map +1 -0
- package/dist/adapters/banal/settings.js +29 -0
- package/dist/adapters/banal/settings.js.map +1 -0
- package/dist/adapters/banal/xml.d.ts +48 -0
- package/dist/adapters/banal/xml.d.ts.map +1 -0
- package/dist/adapters/banal/xml.js +67 -0
- package/dist/adapters/banal/xml.js.map +1 -0
- package/dist/adapters/curl/download.io.d.ts +14 -0
- package/dist/adapters/curl/download.io.d.ts.map +1 -0
- package/dist/adapters/curl/download.io.js +69 -0
- package/dist/adapters/curl/download.io.js.map +1 -0
- package/dist/adapters/curl/index.d.ts +6 -0
- package/dist/adapters/curl/index.d.ts.map +1 -0
- package/dist/adapters/curl/index.js +6 -0
- package/dist/adapters/curl/index.js.map +1 -0
- package/dist/adapters/memory/index.d.ts +43 -0
- package/dist/adapters/memory/index.d.ts.map +1 -0
- package/dist/adapters/memory/index.js +79 -0
- package/dist/adapters/memory/index.js.map +1 -0
- package/dist/adapters/node/files.io.d.ts +3 -0
- package/dist/adapters/node/files.io.d.ts.map +1 -0
- package/dist/adapters/node/files.io.js +31 -0
- package/dist/adapters/node/files.io.js.map +1 -0
- package/dist/adapters/node/host.io.d.ts +3 -0
- package/dist/adapters/node/host.io.d.ts.map +1 -0
- package/dist/adapters/node/host.io.js +14 -0
- package/dist/adapters/node/host.io.js.map +1 -0
- package/dist/adapters/node/index.d.ts +25 -0
- package/dist/adapters/node/index.d.ts.map +1 -0
- package/dist/adapters/node/index.js +14 -0
- package/dist/adapters/node/index.js.map +1 -0
- package/dist/adapters/node/process.io.d.ts +14 -0
- package/dist/adapters/node/process.io.d.ts.map +1 -0
- package/dist/adapters/node/process.io.js +41 -0
- package/dist/adapters/node/process.io.js.map +1 -0
- package/dist/adapters/node/workspace.io.d.ts +4 -0
- package/dist/adapters/node/workspace.io.d.ts.map +1 -0
- package/dist/adapters/node/workspace.io.js +33 -0
- package/dist/adapters/node/workspace.io.js.map +1 -0
- package/dist/adapters/pdfjs/fill.d.ts +42 -0
- package/dist/adapters/pdfjs/fill.d.ts.map +1 -0
- package/dist/adapters/pdfjs/fill.js +91 -0
- package/dist/adapters/pdfjs/fill.js.map +1 -0
- package/dist/build-engine.d.ts +48 -0
- package/dist/build-engine.d.ts.map +1 -0
- package/dist/build-engine.js +148 -0
- package/dist/build-engine.js.map +1 -0
- package/dist/build.d.ts +163 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +575 -0
- package/dist/build.js.map +1 -0
- package/dist/cli.d.ts +151 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +951 -0
- package/dist/cli.js.map +1 -0
- package/dist/doctor.d.ts +42 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +280 -0
- package/dist/doctor.js.map +1 -0
- package/dist/domain/geometry.d.ts +71 -0
- package/dist/domain/geometry.d.ts.map +1 -0
- package/dist/domain/geometry.js +35 -0
- package/dist/domain/geometry.js.map +1 -0
- package/dist/domain/host.d.ts +16 -0
- package/dist/domain/host.d.ts.map +1 -0
- package/dist/domain/host.js +8 -0
- package/dist/domain/host.js.map +1 -0
- package/dist/domain/page-layout.d.ts +34 -0
- package/dist/domain/page-layout.d.ts.map +1 -0
- package/dist/domain/page-layout.js +8 -0
- package/dist/domain/page-layout.js.map +1 -0
- package/dist/domain/paths.d.ts +5 -0
- package/dist/domain/paths.d.ts.map +1 -0
- package/dist/domain/paths.js +2 -0
- package/dist/domain/paths.js.map +1 -0
- package/dist/domain/result.d.ts +23 -0
- package/dist/domain/result.d.ts.map +1 -0
- package/dist/domain/result.js +10 -0
- package/dist/domain/result.js.map +1 -0
- package/dist/domain/sha256.d.ts +7 -0
- package/dist/domain/sha256.d.ts.map +1 -0
- package/dist/domain/sha256.js +14 -0
- package/dist/domain/sha256.js.map +1 -0
- package/dist/domain/text.d.ts +6 -0
- package/dist/domain/text.d.ts.map +1 -0
- package/dist/domain/text.js +7 -0
- package/dist/domain/text.js.map +1 -0
- package/dist/engine.d.ts +93 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +119 -0
- package/dist/engine.js.map +1 -0
- package/dist/exit-code.d.ts +22 -0
- package/dist/exit-code.d.ts.map +1 -0
- package/dist/exit-code.js +10 -0
- package/dist/exit-code.js.map +1 -0
- package/dist/facts-file.d.ts +96 -0
- package/dist/facts-file.d.ts.map +1 -0
- package/dist/facts-file.js +134 -0
- package/dist/facts-file.js.map +1 -0
- package/dist/hooks-settings.d.ts +141 -0
- package/dist/hooks-settings.d.ts.map +1 -0
- package/dist/hooks-settings.js +306 -0
- package/dist/hooks-settings.js.map +1 -0
- package/dist/init.d.ts +201 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +579 -0
- package/dist/init.js.map +1 -0
- package/dist/latex-log.d.ts +80 -0
- package/dist/latex-log.d.ts.map +1 -0
- package/dist/latex-log.js +187 -0
- package/dist/latex-log.js.map +1 -0
- package/dist/latex-loop.d.ts +129 -0
- package/dist/latex-loop.d.ts.map +1 -0
- package/dist/latex-loop.js +113 -0
- package/dist/latex-loop.js.map +1 -0
- package/dist/link-skills.d.ts +51 -0
- package/dist/link-skills.d.ts.map +1 -0
- package/dist/link-skills.js +199 -0
- package/dist/link-skills.js.map +1 -0
- package/dist/new-paper.d.ts +48 -0
- package/dist/new-paper.d.ts.map +1 -0
- package/dist/new-paper.js +110 -0
- package/dist/new-paper.js.map +1 -0
- package/dist/pdf-facts.d.ts +44 -0
- package/dist/pdf-facts.d.ts.map +1 -0
- package/dist/pdf-facts.js +239 -0
- package/dist/pdf-facts.js.map +1 -0
- package/dist/pdf-geometry.d.ts +170 -0
- package/dist/pdf-geometry.d.ts.map +1 -0
- package/dist/pdf-geometry.js +158 -0
- package/dist/pdf-geometry.js.map +1 -0
- package/dist/ports/download.d.ts +9 -0
- package/dist/ports/download.d.ts.map +1 -0
- package/dist/ports/download.js +2 -0
- package/dist/ports/download.js.map +1 -0
- package/dist/ports/files.d.ts +11 -0
- package/dist/ports/files.d.ts.map +1 -0
- package/dist/ports/files.js +2 -0
- package/dist/ports/files.js.map +1 -0
- package/dist/ports/measure-geometry.d.ts +8 -0
- package/dist/ports/measure-geometry.d.ts.map +1 -0
- package/dist/ports/measure-geometry.js +2 -0
- package/dist/ports/measure-geometry.js.map +1 -0
- package/dist/ports/process.d.ts +45 -0
- package/dist/ports/process.d.ts.map +1 -0
- package/dist/ports/process.js +2 -0
- package/dist/ports/process.js.map +1 -0
- package/dist/ports/tool-installer.d.ts +29 -0
- package/dist/ports/tool-installer.d.ts.map +1 -0
- package/dist/ports/tool-installer.js +2 -0
- package/dist/ports/tool-installer.js.map +1 -0
- package/dist/ports/workspace.d.ts +18 -0
- package/dist/ports/workspace.d.ts.map +1 -0
- package/dist/ports/workspace.js +2 -0
- package/dist/ports/workspace.js.map +1 -0
- package/dist/rules-config.d.ts +34 -0
- package/dist/rules-config.d.ts.map +1 -0
- package/dist/rules-config.js +132 -0
- package/dist/rules-config.js.map +1 -0
- package/dist/structure.d.ts +34 -0
- package/dist/structure.d.ts.map +1 -0
- package/dist/structure.js +149 -0
- package/dist/structure.js.map +1 -0
- package/dist/tex-requirements.d.ts +43 -0
- package/dist/tex-requirements.d.ts.map +1 -0
- package/dist/tex-requirements.js +127 -0
- package/dist/tex-requirements.js.map +1 -0
- package/dist/toolchain.d.ts +159 -0
- package/dist/toolchain.d.ts.map +1 -0
- package/dist/toolchain.js +542 -0
- package/dist/toolchain.js.map +1 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/configuration.md +235 -0
- package/docs/e2e.md +152 -0
- package/docs/incidents.md +59 -0
- package/docs/install.md +170 -0
- package/docs/optional-rules.md +107 -0
- package/docs/package-shape-options.md +262 -0
- package/docs/prior-art/README.md +76 -0
- package/docs/prior-art/blocking-vs-advisory.md +83 -0
- package/docs/prior-art/content-delivery.md +124 -0
- package/docs/prior-art/multi-mode-tools.md +106 -0
- package/docs/prior-art/nondeterministic-checks.md +99 -0
- package/docs/prior-art/package-location.md +422 -0
- package/docs/prior-art/paper-folder-scaffolding.md +538 -0
- package/docs/prior-art/readme-structure.md +69 -0
- package/docs/prior-art/repro/README.md +92 -0
- package/docs/prior-art/repro/claim1-allowedtools.mjs +66 -0
- package/docs/prior-art/repro/claim1-at2.mjs +40 -0
- package/docs/prior-art/repro/claim1-crosschannel.mjs +54 -0
- package/docs/prior-art/repro/claim1-frontmatter.mjs +76 -0
- package/docs/prior-art/repro/claim1-hook-payload-reporter.mjs +10 -0
- package/docs/prior-art/repro/claim1-plugin-frontmatter.mjs +27 -0
- package/docs/prior-art/repro/claim1-plugin-skill.mjs +52 -0
- package/docs/prior-art/repro/claim1-project-skill.mjs +81 -0
- package/docs/prior-art/repro/claim2-marketplace-flat-asclaimed.json +1 -0
- package/docs/prior-art/repro/claim2-marketplace-negative-control.json +1 -0
- package/docs/prior-art/repro/claim2-marketplace-nested-exact.json +9 -0
- package/docs/prior-art/repro/claim2-marketplace-nested-noversion.json +9 -0
- package/docs/prior-art/repro/claim2-marketplace-nested-range.json +1 -0
- package/docs/prior-art/repro/claim3-imports.mjs +50 -0
- package/docs/prior-art/repro/claim4-find-package-json.mjs +8 -0
- package/docs/prior-art/repro/claim4-package-dir.mjs +39 -0
- package/docs/prior-art/repro/claim4-parent-arg.mjs +17 -0
- package/docs/prior-art/repro/claim4-resolve-apis.mjs +21 -0
- package/docs/prior-art/repro/claim4-setup-consumers.mjs +45 -0
- package/docs/prior-art/repro/claim4-yarn-pnp.mjs +70 -0
- package/docs/prior-art/repro/claim5-bin-launch.mjs +39 -0
- package/docs/prior-art/repro/claim5-exports-mutation.mjs +57 -0
- package/docs/prior-art/repro/claim5-resolved-location-and-bin.mjs +33 -0
- package/docs/prior-art/repro/claim6-candidate-ambiguity.mjs +17 -0
- package/docs/prior-art/repro/claim6-doc-path-candidates.mjs +27 -0
- package/docs/prior-art/test-tooling.md +131 -0
- package/docs/rules.md +58 -0
- package/docs/texlive-install-decision.md +230 -0
- package/docs/toolchain.md +152 -0
- package/eslint-rules/doc-fields.harness.mjs +336 -0
- package/eslint-rules/doc-fields.mjs +186 -0
- package/eslint-rules/doc-fields.mutations.mjs +96 -0
- package/eslint-rules/install-path-literals.harness.mjs +121 -0
- package/eslint-rules/install-path-literals.mjs +108 -0
- package/eslint-rules/install-path-literals.mutations.mjs +62 -0
- package/eslint-rules/latex-language.harness.mjs +599 -0
- package/eslint-rules/latex-language.mjs +591 -0
- package/eslint-rules/latex-language.mutations.mjs +196 -0
- package/eslint-rules/paper-research-question.harness.mjs +146 -0
- package/eslint-rules/paper-research-question.mjs +180 -0
- package/eslint-rules/paper-research-question.mutations.mjs +127 -0
- package/eslint-rules/paper-stages.harness.mjs +356 -0
- package/eslint-rules/paper-stages.mjs +455 -0
- package/eslint-rules/paper-stages.mutations.mjs +157 -0
- package/eslint-rules/paper-typography.harness.mjs +291 -0
- package/eslint-rules/paper-typography.mjs +313 -0
- package/eslint-rules/paper-typography.mutations.mjs +131 -0
- package/eslint-rules/papers.harness.mjs +259 -0
- package/eslint-rules/papers.mjs +166 -0
- package/eslint-rules/papers.mutations.mjs +186 -0
- package/eslint-rules/pdf-last-page-balance.harness.mjs +206 -0
- package/eslint-rules/pdf-last-page-balance.mjs +208 -0
- package/eslint-rules/review-findings-cause.harness.mjs +228 -0
- package/eslint-rules/review-findings-cause.mjs +135 -0
- package/eslint-rules/review-findings-cause.mutations.mjs +72 -0
- package/eslint-rules/temp-root-realpath.harness.mjs +176 -0
- package/eslint-rules/temp-root-realpath.mjs +129 -0
- package/eslint-rules/temp-root-realpath.mutations.mjs +99 -0
- package/eslint-rules/tex-build.harness.mjs +753 -0
- package/eslint-rules/tex-build.mjs +322 -0
- package/eslint-rules/tex-build.mutations.mjs +258 -0
- package/eslint.config.mjs +521 -0
- package/fixtures/build-e2e/acmart/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/acmart/paper.tex +11 -0
- package/fixtures/build-e2e/acmart/venue.json +1 -0
- package/fixtures/build-e2e/broken/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/broken/paper.tex +7 -0
- package/fixtures/build-e2e/cite/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/cite/build.sh +5 -0
- package/fixtures/build-e2e/cite/paper.tex +10 -0
- package/fixtures/build-e2e/cite/refs.bib +9 -0
- package/fixtures/build-e2e/empty/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/empty/paper.tex +6 -0
- package/fixtures/build-e2e/fallback/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/fallback/paper.tex +11 -0
- package/fixtures/build-e2e/guards/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/guards/paper.tex +10 -0
- package/fixtures/build-e2e/no-source/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/unbalanced/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/unbalanced/paper.tex +28 -0
- package/fixtures/build-e2e/unbalanced/refs.bib +269 -0
- package/fixtures/install-path-literals/clean.fixture.mjs +3 -0
- package/fixtures/install-path-literals/clean.md +15 -0
- package/fixtures/install-path-literals/defect.fixture.mjs +3 -0
- package/fixtures/install-path-literals/defect.md +14 -0
- package/fixtures/latex-language/clean.tex +50 -0
- package/fixtures/latex-language/defect.tex +52 -0
- package/fixtures/paper-research-question/comment-only/PIPELINE-STATUS.md +9 -0
- package/fixtures/paper-research-question/comment-only/paper.tex +7 -0
- package/fixtures/paper-research-question/declared-not-in-paper/PIPELINE-STATUS.md +10 -0
- package/fixtures/paper-research-question/declared-not-in-paper/paper.tex +6 -0
- package/fixtures/paper-research-question/draft/PIPELINE-STATUS.md +6 -0
- package/fixtures/paper-research-question/draft/paper.tex +2 -0
- package/fixtures/paper-research-question/markdown-no-rq/PIPELINE-STATUS.md +9 -0
- package/fixtures/paper-research-question/markdown-no-rq/paper.md +4 -0
- package/fixtures/paper-research-question/shipped-no-rq/PIPELINE-STATUS.md +12 -0
- package/fixtures/paper-research-question/shipped-no-rq/paper.tex +3 -0
- package/fixtures/paper-research-question/shipped-with-rq/PIPELINE-STATUS.md +10 -0
- package/fixtures/paper-research-question/shipped-with-rq/paper.tex +2 -0
- package/fixtures/paper-stages/authors-ran/PIPELINE-STATUS.md +16 -0
- package/fixtures/paper-stages/marker-in-prose/PIPELINE-STATUS.md +17 -0
- package/fixtures/paper-stages/nofile/PIPELINE-STATUS.md +8 -0
- package/fixtures/paper-stages/noheader/PIPELINE-STATUS.md +1 -0
- package/fixtures/paper-stages/noheader/versions/2026-07-22-submitted.pdf +0 -0
- package/fixtures/paper-stages/nothing/PIPELINE-STATUS.md +3 -0
- package/fixtures/paper-stages/ok/PIPELINE-STATUS.md +9 -0
- package/fixtures/paper-stages/ok/versions/2026-07-22-submitted.pdf +0 -0
- package/fixtures/paper-stages/stale/PIPELINE-STATUS.md +1 -0
- package/fixtures/paper-stages/stale/versions/2026-07-22-submitted.STALE-WRONG-FILE.pdf +0 -0
- package/fixtures/paper-stages/twice/PIPELINE-STATUS.md +14 -0
- package/fixtures/paper-stages/twice/versions/2026-08-06-submitted.pdf +0 -0
- package/fixtures/paper-stages/twice/versions/2026-10-24-submitted.pdf +0 -0
- package/fixtures/paper-stages/undeclared/PIPELINE-STATUS.md +8 -0
- package/fixtures/paper-stages/undeclared/versions/2026-07-22-submitted.pdf +0 -0
- package/fixtures/paper-stages/undeclared/versions/2026-08-29-camera-ready.pdf +0 -0
- package/fixtures/paper-stages/wrongsize/PIPELINE-STATUS.md +8 -0
- package/fixtures/paper-stages/wrongsize/versions/2026-07-22-submitted.pdf +0 -0
- package/fixtures/paper-typography/clean-paper/paper.tex +29 -0
- package/fixtures/paper-typography/messy-paper/paper.tex +27 -0
- package/fixtures/pdf-facts/README.md +22 -0
- package/fixtures/pdf-facts/corrupt-font.pdf +0 -0
- package/fixtures/pdf-facts/encrypted.pdf +0 -0
- package/fixtures/pdf-facts/hidden-text.pdf +0 -0
- package/fixtures/pdf-facts/hidden-text.tex +28 -0
- package/fixtures/pdf-facts/t3-all.pdf +0 -0
- package/fixtures/pdf-facts/t3-all.tex +8 -0
- package/fixtures/pdf-facts/t3-mixed.pdf +0 -0
- package/fixtures/pdf-facts/t3-mixed.tex +9 -0
- package/fixtures/pdf-facts/ttf.pdf +2240 -1
- package/fixtures/pdf-facts/ttf.tex +6 -0
- package/fixtures/real-markdown-paper/baseline.json +24 -0
- package/fixtures/real-markdown-paper/baseline.mjs +48 -0
- package/fixtures/render-paper/build-clean.sh +25 -0
- package/fixtures/render-paper/build-defect.sh +15 -0
- package/fixtures/review-findings-cause/clean.md +17 -0
- package/fixtures/review-findings-cause/defect.md +14 -0
- package/fixtures/review-findings-cause/old-debt.md +14 -0
- package/fixtures/review-findings-cause/quiet-in-fence.md +16 -0
- package/fixtures/tex-build/clean.tex +21 -0
- package/fixtures/tex-build/defect.tex +24 -0
- package/fixtures/tex-build/frontmatter-clean.tex +25 -0
- package/fixtures/tex-build/frontmatter-defect.tex +23 -0
- package/fixtures/toolchain-mirror/catalog.txt +5 -0
- package/fixtures/toolchain-mirror/install-tl +27 -0
- package/fixtures/toolchain-mirror/release-texlive.txt +3 -0
- package/fixtures/toolchain-mirror/release-year +1 -0
- package/fixtures/toolchain-mirror/stub-kpsewhich +8 -0
- package/fixtures/toolchain-mirror/stub-pdflatex +3 -0
- package/fixtures/toolchain-mirror/stub-tlmgr +44 -0
- package/hooks/hooks.harness.mjs +713 -0
- package/hooks/hooks.mutations.mjs +337 -0
- package/hooks/paper-edit-guard.hook.d.mts +13 -0
- package/hooks/paper-edit-guard.hook.mjs +457 -0
- package/hooks/paper-skills-nudge.hook.mjs +136 -0
- package/hooks/paper-status-gates.hook.mjs +156 -0
- package/hooks/paper-status-gates.sh +91 -0
- package/lib/agent-cli-version.harness.mjs +165 -0
- package/lib/agent-cli-version.mjs +106 -0
- package/lib/agent-cli-version.mutations.mjs +109 -0
- package/lib/markdown.mjs +386 -0
- package/lib/mutation-driver.harness.mjs +227 -0
- package/lib/mutation-driver.mjs +397 -0
- package/lib/mutation-driver.mutations.mjs +68 -0
- package/lib/paper-config.d.mts +34 -0
- package/lib/paper-config.harness.mjs +286 -0
- package/lib/paper-config.mjs +142 -0
- package/lib/paper-config.mutations.mjs +143 -0
- package/lib/skill-checks.mjs +701 -0
- package/lib/skill-corpus.mjs +403 -0
- package/lib/skill-eval-fixture.mjs +63 -0
- package/lib/skill-eval-kit.mjs +257 -0
- package/lib/skill-trigger-cases.harness.mjs +170 -0
- package/lib/skill-trigger-cases.mjs +446 -0
- package/lib/skill-trigger-cases.mutations.mjs +65 -0
- package/lib/trigger-ledger.mjs +215 -0
- package/package.json +97 -0
- package/plugin/.claude-plugin/plugin.json +8 -0
- package/plugin/hooks/hooks.json +30 -0
- package/scripts/check.harness.mjs +177 -0
- package/scripts/check.mjs +239 -0
- package/scripts/check.mutations.mjs +110 -0
- package/scripts/eslint-report-guard.mjs +82 -0
- package/scripts/exclusive.mjs +138 -0
- package/scripts/harness-api.frozen.json +76 -0
- package/scripts/harness-api.test.ts +175 -0
- package/scripts/layer-legacy-frozen.d.mts +28 -0
- package/scripts/layer-legacy-frozen.mjs +152 -0
- package/scripts/layer-legacy-frozen.test.ts +115 -0
- package/scripts/layer-legacy.frozen.json +50 -0
- package/scripts/mutation-batteries-frozen.harness.mjs +204 -0
- package/scripts/mutation-batteries-frozen.mjs +238 -0
- package/scripts/mutation-batteries.frozen.json +117 -0
- package/scripts/release-config.test.ts +90 -0
- package/scripts/rules-are-content-only.harness.mjs +113 -0
- package/scripts/rules-are-content-only.mjs +138 -0
- package/scripts/rules-are-content-only.mutations.mjs +81 -0
- package/scripts/rules-see-files.harness.mjs +115 -0
- package/scripts/rules-see-files.mjs +99 -0
- package/scripts/rules-see-files.mutations.mjs +131 -0
- package/scripts/run-mutations.mjs +100 -0
- package/scripts/semantic-release-plugins.d.ts +16 -0
- package/skills/README.md +15 -0
- package/skills/analyze-sibling-paper/SKILL.md +170 -0
- package/skills/analyze-sibling-paper/SKILL.md.spec.ts +186 -0
- package/skills/analyze-sibling-paper/analyze-sibling-paper.eval.mjs +19 -0
- package/skills/analyze-sibling-paper/analyze-sibling-paper.harness.mjs +23 -0
- package/skills/argument-arc/SKILL.md +177 -0
- package/skills/argument-arc/SKILL.md.spec.ts +192 -0
- package/skills/argument-arc/argument-arc.eval.mjs +19 -0
- package/skills/argument-arc/argument-arc.harness.mjs +23 -0
- package/skills/build-benchmark/SKILL.md +213 -0
- package/skills/build-benchmark/SKILL.md.spec.ts +220 -0
- package/skills/build-benchmark/build-benchmark.eval.mjs +19 -0
- package/skills/build-benchmark/build-benchmark.harness.mjs +23 -0
- package/skills/build-benchmark/references/adversarial-cold-repro.md +68 -0
- package/skills/camera-ready/SKILL.md +148 -0
- package/skills/camera-ready/SKILL.md.spec.ts +164 -0
- package/skills/camera-ready/camera-ready.eval.mjs +19 -0
- package/skills/camera-ready/camera-ready.harness.mjs +23 -0
- package/skills/cold-read-diff/SKILL.md +160 -0
- package/skills/cold-read-diff/SKILL.md.spec.ts +166 -0
- package/skills/cold-read-diff/cold-read-diff.eval.mjs +19 -0
- package/skills/cold-read-diff/cold-read-diff.harness.mjs +23 -0
- package/skills/draft-paper/SKILL.md +152 -0
- package/skills/draft-paper/SKILL.md.spec.ts +169 -0
- package/skills/draft-paper/draft-paper.eval.mjs +19 -0
- package/skills/draft-paper/draft-paper.harness.mjs +23 -0
- package/skills/extend-paper/SKILL.md +99 -0
- package/skills/extend-paper/SKILL.md.spec.ts +116 -0
- package/skills/extend-paper/extend-paper.eval.mjs +19 -0
- package/skills/extend-paper/extend-paper.harness.mjs +23 -0
- package/skills/find-venue/SKILL.md +128 -0
- package/skills/find-venue/SKILL.md.spec.ts +145 -0
- package/skills/find-venue/find-venue.eval.mjs +19 -0
- package/skills/find-venue/find-venue.harness.mjs +23 -0
- package/skills/grade-paper-writing/SKILL.md +436 -0
- package/skills/grade-paper-writing/SKILL.md.spec.ts +453 -0
- package/skills/grade-paper-writing/fixtures/control_gopen.txt +1 -0
- package/skills/grade-paper-writing/fixtures/control_human_paper.txt +1 -0
- package/skills/grade-paper-writing/fixtures/rewrite.txt +1 -0
- package/skills/grade-paper-writing/fixtures/specimen.txt +1 -0
- package/skills/grade-paper-writing/fixtures/structure-checks.md +22 -0
- package/skills/grade-paper-writing/grade-paper-writing.eval.mjs +19 -0
- package/skills/grade-paper-writing/grade-paper-writing.harness.mjs +23 -0
- package/skills/grade-paper-writing/prose-lint.mjs +713 -0
- package/skills/harden-paper/SKILL.md +318 -0
- package/skills/harden-paper/SKILL.md.spec.ts +336 -0
- package/skills/harden-paper/check-numbers.sh +33 -0
- package/skills/harden-paper/check-release-claims.sh +35 -0
- package/skills/harden-paper/fixtures/uncited-assertions-sample.md +43 -0
- package/skills/harden-paper/fixtures/uncited-assertions-sample.tex +77 -0
- package/skills/harden-paper/harden-paper.eval.mjs +19 -0
- package/skills/harden-paper/harden-paper.harness.mjs +23 -0
- package/skills/map-prior-work/SKILL.md +211 -0
- package/skills/map-prior-work/SKILL.md.spec.ts +227 -0
- package/skills/map-prior-work/map-prior-work.eval.mjs +19 -0
- package/skills/map-prior-work/map-prior-work.harness.mjs +23 -0
- package/skills/osf-artifact-upload/SKILL.md +52 -0
- package/skills/osf-artifact-upload/SKILL.md.spec.ts +59 -0
- package/skills/osf-artifact-upload/osf-artifact-upload.eval.mjs +22 -0
- package/skills/osf-artifact-upload/osf-artifact-upload.harness.mjs +103 -0
- package/skills/paper-adversarial-review/SKILL.md +126 -0
- package/skills/paper-adversarial-review/SKILL.md.spec.ts +142 -0
- package/skills/paper-adversarial-review/paper-adversarial-review.eval.mjs +19 -0
- package/skills/paper-adversarial-review/paper-adversarial-review.harness.mjs +23 -0
- package/skills/paper-pipeline/PIPELINE-MAP.md +371 -0
- package/skills/paper-pipeline/SKILL.md +499 -0
- package/skills/paper-pipeline/SKILL.md.spec.ts +517 -0
- package/skills/paper-pipeline/description-language.eval.mjs +347 -0
- package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +891 -0
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1254 -0
- package/skills/paper-pipeline/paper-pipeline.eval.mjs +22 -0
- package/skills/paper-pipeline/paper-pipeline.harness.mjs +143 -0
- package/skills/paper-pipeline/pipeline-firing.baseline.json +270 -0
- package/skills/paper-pipeline/pipeline-firing.eval.mjs +664 -0
- package/skills/paper-pipeline/pipeline-language.eval.mjs +672 -0
- package/skills/paper-pipeline/references/acceptance-gate.md +329 -0
- package/skills/paper-pipeline/references/acl-venue-rules.md +142 -0
- package/skills/paper-pipeline/references/anonymization.md +68 -0
- package/skills/paper-pipeline/references/artifact-checklist.md +93 -0
- package/skills/paper-pipeline/references/body-vs-appendix.md +97 -0
- package/skills/paper-pipeline/references/credit-criteria.md +69 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/README.md +35 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/run_retext.mjs +24 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/sentences.txt +11 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/test_sentences.py +25 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-prose-checkers.md +538 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-reproducible-tooling.md +431 -0
- package/skills/paper-pipeline/references/occupancy-2026-08-06-staleness-and-orchestration.md +592 -0
- package/skills/paper-pipeline/references/pipeline-status-template.md +162 -0
- package/skills/paper-pipeline/references/review-ratchet.md +36 -0
- package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +585 -0
- package/skills/paper-pipeline/references/writing-craft.md +448 -0
- package/skills/paper-pipeline/repro/2026-08-07-description-language-control.log +63 -0
- package/skills/paper-pipeline/repro/2026-08-07-fork-check.log +52 -0
- package/skills/paper-pipeline/repro/2026-08-07-fork-check2.log +33 -0
- package/skills/paper-pipeline/repro/2026-08-07-language-eval-pilot.log +33 -0
- package/skills/paper-pipeline/repro/2026-08-07-language-eval-raw.log +166 -0
- package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-oracle.json +338 -0
- package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-oracle.log +118 -0
- package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-raw.log +245 -0
- package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary.json +776 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-A6-oracle.log +53 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-A6-raw.log +89 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-oracle.json +450 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-oracle.log +136 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-raw.log +242 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-setupdiff.log +59 -0
- package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation.json +1032 -0
- package/skills/paper-pipeline/repro/2026-08-08-parent-replication-gpw.json +139 -0
- package/skills/paper-pipeline/repro/2026-08-08-parent-replication-gpw.log +98 -0
- package/skills/paper-pipeline/repro/2026-08-08-parent-replication.mjs +92 -0
- package/skills/paper-pipeline/repro/README.md +129 -0
- package/skills/paper-pipeline/repro/analyze-language-eval.py +116 -0
- package/skills/paper-pipeline/scripts/README.md +344 -0
- package/skills/paper-pipeline/scripts/announce.mjs +67 -0
- package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +496 -0
- package/skills/paper-pipeline/scripts/artifact-coverage.mjs +397 -0
- package/skills/paper-pipeline/scripts/artifact-coverage.mutations.mjs +218 -0
- package/skills/paper-pipeline/scripts/check-provenance.mjs +184 -0
- package/skills/paper-pipeline/scripts/consumer.d.mts +32 -0
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +562 -0
- package/skills/paper-pipeline/scripts/consumer.mjs +535 -0
- package/skills/paper-pipeline/scripts/consumer.mutations.mjs +190 -0
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +457 -0
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +656 -0
- package/skills/paper-pipeline/scripts/extract-ref-facts.mutations.mjs +54 -0
- package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +51 -0
- package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +52 -0
- package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +6 -0
- package/skills/paper-pipeline/scripts/fixtures/real-bib/refs.bib +153 -0
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +466 -0
- package/skills/paper-pipeline/scripts/generated-code.mjs +338 -0
- package/skills/paper-pipeline/scripts/generated-code.mutations.mjs +254 -0
- package/skills/paper-pipeline/scripts/ledger.mjs +623 -0
- package/skills/paper-pipeline/scripts/ledger.selftest.mjs +286 -0
- package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +389 -0
- package/skills/paper-pipeline/scripts/pipeline-check.mjs +737 -0
- package/skills/paper-pipeline/scripts/pipeline-check.mutations.mjs +54 -0
- package/skills/paper-pipeline/scripts/pipeline-edges.mjs +169 -0
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +178 -0
- package/skills/paper-pipeline/scripts/population-map.mjs +181 -0
- package/skills/paper-pipeline/scripts/population-map.mutations.mjs +65 -0
- package/skills/paper-pipeline/scripts/population-map.selftest.mjs +122 -0
- package/skills/paper-pipeline/scripts/provenance.harness.mjs +240 -0
- package/skills/paper-pipeline/scripts/provenance.mutations.mjs +59 -0
- package/skills/paper-pipeline/scripts/round-diff.harness.mjs +881 -0
- package/skills/paper-pipeline/scripts/round-diff.mjs +576 -0
- package/skills/paper-pipeline/scripts/round-diff.mutations.mjs +276 -0
- package/skills/paper-pipeline/scripts/run-mechanical.mjs +633 -0
- package/skills/paper-pipeline/scripts/status.mjs +295 -0
- package/skills/paper-status/SKILL.md +183 -0
- package/skills/paper-status/SKILL.md.spec.ts +190 -0
- package/skills/paper-status/paper-status.eval.mjs +22 -0
- package/skills/paper-status/paper-status.harness.mjs +25 -0
- package/skills/pc-panel-review/SKILL.md +263 -0
- package/skills/pc-panel-review/SKILL.md.spec.ts +280 -0
- package/skills/pc-panel-review/pc-panel-review.eval.mjs +19 -0
- package/skills/pc-panel-review/pc-panel-review.harness.mjs +23 -0
- package/skills/plan-paper-timeline/SKILL.md +182 -0
- package/skills/plan-paper-timeline/SKILL.md.spec.ts +200 -0
- package/skills/plan-paper-timeline/fixtures/fake-google-calendar.mjs +239 -0
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +431 -0
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.mutations.mjs +65 -0
- package/skills/plan-paper-timeline/plan-paper-timeline.eval.mjs +19 -0
- package/skills/plan-paper-timeline/plan-paper-timeline.harness.mjs +23 -0
- package/skills/render-paper/SKILL.md +159 -0
- package/skills/render-paper/SKILL.md.spec.ts +166 -0
- package/skills/render-paper/check-render.sh +419 -0
- package/skills/render-paper/checkers-requirements.txt +55 -0
- package/skills/render-paper/ensure-checkers.sh +69 -0
- package/skills/render-paper/extract-pdf-facts.harness.mjs +166 -0
- package/skills/render-paper/extract-pdf-facts.mjs +144 -0
- package/skills/render-paper/render-paper.eval.mjs +19 -0
- package/skills/render-paper/render-paper.harness.mjs +339 -0
- package/skills/research-ideate/SKILL.md +136 -0
- package/skills/research-ideate/SKILL.md.spec.ts +152 -0
- package/skills/research-ideate/research-ideate.eval.mjs +19 -0
- package/skills/research-ideate/research-ideate.harness.mjs +23 -0
- package/skills/skill-contract.mutations.mjs +179 -0
- package/skills/study-accepted-papers/SKILL.md +206 -0
- package/skills/study-accepted-papers/SKILL.md.spec.ts +223 -0
- package/skills/study-accepted-papers/study-accepted-papers.eval.mjs +19 -0
- package/skills/study-accepted-papers/study-accepted-papers.harness.mjs +23 -0
- package/skills/submit-paper/SKILL.md +182 -0
- package/skills/submit-paper/SKILL.md.spec.ts +199 -0
- package/skills/submit-paper/check-deanon.sh +149 -0
- package/skills/submit-paper/references/publishers/acm.md +92 -0
- package/skills/submit-paper/references/venues/agenticdev.jsonc +108 -0
- package/skills/submit-paper/references/venues/agenticdev.md +139 -0
- package/skills/submit-paper/references/venues/agenticdev.tex +19 -0
- package/skills/submit-paper/references/venues/aisec.jsonc +101 -0
- package/skills/submit-paper/references/venues/aisec.md +105 -0
- package/skills/submit-paper/references/venues/paper-guards.tex +41 -0
- package/skills/submit-paper/references/venues/realm.jsonc +81 -0
- package/skills/submit-paper/references/venues/realm.md +155 -0
- package/skills/submit-paper/references/venues/tex-base.jsonc +50 -0
- package/skills/submit-paper/references/venues/venue-profile.schema.json +74 -0
- package/skills/submit-paper/submit-paper.eval.mjs +19 -0
- package/skills/submit-paper/submit-paper.harness.mjs +23 -0
- package/skills/sweep-design-space/SKILL.md +269 -0
- package/skills/sweep-design-space/SKILL.md.spec.ts +285 -0
- package/skills/sweep-design-space/sweep-design-space.eval.mjs +19 -0
- package/skills/sweep-design-space/sweep-design-space.harness.mjs +23 -0
- package/skills/tighten-paper/SKILL.md +368 -0
- package/skills/tighten-paper/SKILL.md.spec.ts +384 -0
- package/skills/tighten-paper/structure.mjs +371 -0
- package/skills/tighten-paper/tighten-paper.eval.mjs +19 -0
- package/skills/tighten-paper/tighten-paper.harness.mjs +23 -0
- package/skills/verify-citations/SKILL.md +328 -0
- package/skills/verify-citations/SKILL.md.spec.ts +345 -0
- package/skills/verify-citations/scripts/bib-authors.mjs +479 -0
- package/skills/verify-citations/scripts/bib-authors.test.mjs +175 -0
- package/skills/verify-citations/scripts/verify-cites.mjs +1108 -0
- package/skills/verify-citations/scripts/verify-cites.test.mjs +735 -0
- package/skills/verify-citations/verify-citations.eval.mjs +19 -0
- package/skills/verify-citations/verify-citations.harness.mjs +23 -0
- package/src/CLAUDE.md +51 -0
- package/src/action-ref.test.ts +26 -0
- package/src/action-ref.ts +15 -0
- package/src/adapters/banal/failure.test.ts +63 -0
- package/src/adapters/banal/failure.ts +118 -0
- package/src/adapters/banal/index.test.ts +119 -0
- package/src/adapters/banal/index.ts +100 -0
- package/src/adapters/banal/install.test.ts +20 -0
- package/src/adapters/banal/install.ts +41 -0
- package/src/adapters/banal/invocation.test.ts +74 -0
- package/src/adapters/banal/invocation.ts +95 -0
- package/src/adapters/banal/locate.test.ts +52 -0
- package/src/adapters/banal/locate.ts +84 -0
- package/src/adapters/banal/output.test.ts +140 -0
- package/src/adapters/banal/output.ts +141 -0
- package/src/adapters/banal/pin.ts +30 -0
- package/src/adapters/banal/probe.ts +35 -0
- package/src/adapters/banal/run.test.ts +191 -0
- package/src/adapters/banal/run.ts +244 -0
- package/src/adapters/banal/settings.test.ts +31 -0
- package/src/adapters/banal/settings.ts +55 -0
- package/src/adapters/banal/xml.test.ts +111 -0
- package/src/adapters/banal/xml.ts +112 -0
- package/src/adapters/curl/download.io.ts +73 -0
- package/src/adapters/curl/download.test.ts +55 -0
- package/src/adapters/curl/index.ts +5 -0
- package/src/adapters/memory/index.ts +131 -0
- package/src/adapters/node/files.io.ts +39 -0
- package/src/adapters/node/files.test.ts +28 -0
- package/src/adapters/node/host.io.ts +15 -0
- package/src/adapters/node/index.ts +36 -0
- package/src/adapters/node/process.io.ts +49 -0
- package/src/adapters/node/process.test.ts +46 -0
- package/src/adapters/node/workspace.io.ts +40 -0
- package/src/adapters/node/workspace.test.ts +58 -0
- package/src/adapters/pdfjs/fill.test.ts +111 -0
- package/src/adapters/pdfjs/fill.ts +141 -0
- package/src/build-engine.harness.mjs +314 -0
- package/src/build-engine.ts +219 -0
- package/src/build.harness.mjs +631 -0
- package/src/build.mutations.mjs +195 -0
- package/src/build.ts +793 -0
- package/src/cli.harness.mjs +2007 -0
- package/src/cli.mutations.mjs +448 -0
- package/src/cli.ts +1189 -0
- package/src/doctor.harness.mjs +396 -0
- package/src/doctor.mutations.mjs +175 -0
- package/src/doctor.ts +356 -0
- package/src/domain/geometry.ts +108 -0
- package/src/domain/host.ts +23 -0
- package/src/domain/page-layout.ts +32 -0
- package/src/domain/paths.ts +5 -0
- package/src/domain/result.test.ts +26 -0
- package/src/domain/result.ts +29 -0
- package/src/domain/sha256.test.ts +12 -0
- package/src/domain/sha256.ts +21 -0
- package/src/domain/text.ts +11 -0
- package/src/engine.harness.mjs +252 -0
- package/src/engine.ts +176 -0
- package/src/exit-code.test.ts +21 -0
- package/src/exit-code.ts +38 -0
- package/src/facts-file.test.ts +240 -0
- package/src/facts-file.ts +241 -0
- package/src/hooks-settings.harness.mjs +386 -0
- package/src/hooks-settings.mutations.mjs +116 -0
- package/src/hooks-settings.ts +434 -0
- package/src/init.ts +900 -0
- package/src/latex-log.harness.mjs +226 -0
- package/src/latex-log.ts +234 -0
- package/src/latex-loop.harness.mjs +449 -0
- package/src/latex-loop.ts +211 -0
- package/src/link-skills.harness.mjs +273 -0
- package/src/link-skills.mutations.mjs +136 -0
- package/src/link-skills.ts +258 -0
- package/src/new-paper.harness.mjs +216 -0
- package/src/new-paper.mutations.mjs +79 -0
- package/src/new-paper.ts +158 -0
- package/src/pdf-facts.harness.mjs +188 -0
- package/src/pdf-facts.ts +327 -0
- package/src/pdf-geometry.harness.mjs +254 -0
- package/src/pdf-geometry.ts +300 -0
- package/src/ports/download.ts +10 -0
- package/src/ports/files.ts +11 -0
- package/src/ports/measure-geometry.ts +8 -0
- package/src/ports/process.ts +46 -0
- package/src/ports/tool-installer.ts +33 -0
- package/src/ports/workspace.ts +20 -0
- package/src/rules-config.harness.mjs +114 -0
- package/src/rules-config.ts +178 -0
- package/src/structure.harness.mjs +179 -0
- package/src/structure.mutations.mjs +83 -0
- package/src/structure.ts +166 -0
- package/src/tex-requirements.harness.mjs +238 -0
- package/src/tex-requirements.ts +181 -0
- package/src/toolchain.harness.mjs +651 -0
- package/src/toolchain.ts +755 -0
- package/src/types.ts +106 -0
- package/templates/paper/PIPELINE-STATUS.md +72 -0
- package/templates/paper/paper.md +4 -0
- package/templates/paper/paper.tex +8 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"trials": 3,
|
|
3
|
+
"competitors": 36,
|
|
4
|
+
"results": [
|
|
5
|
+
{
|
|
6
|
+
"skill": "grade-paper-writing",
|
|
7
|
+
"cell": "AH",
|
|
8
|
+
"prompt": "grade the writing craft in this draft and name the offending sentence in each dimension",
|
|
9
|
+
"trials": 3,
|
|
10
|
+
"rate": 1,
|
|
11
|
+
"errored": 0,
|
|
12
|
+
"overlap": 0.875,
|
|
13
|
+
"lexArgmax": "grade-paper-writing",
|
|
14
|
+
"buckets": [
|
|
15
|
+
"TARGET",
|
|
16
|
+
"TARGET",
|
|
17
|
+
"TARGET"
|
|
18
|
+
],
|
|
19
|
+
"othersFired": []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"skill": "grade-paper-writing",
|
|
23
|
+
"cell": "AH",
|
|
24
|
+
"prompt": "run the blind multi-grader panel over the prose clarity and jargon discipline",
|
|
25
|
+
"trials": 3,
|
|
26
|
+
"rate": 1,
|
|
27
|
+
"errored": 0,
|
|
28
|
+
"overlap": 1,
|
|
29
|
+
"lexArgmax": "grade-paper-writing",
|
|
30
|
+
"buckets": [
|
|
31
|
+
"TARGET",
|
|
32
|
+
"TARGET",
|
|
33
|
+
"TARGET"
|
|
34
|
+
],
|
|
35
|
+
"othersFired": []
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"skill": "grade-paper-writing",
|
|
39
|
+
"cell": "AH",
|
|
40
|
+
"prompt": "score the title, the abstract and the intro architecture one to five",
|
|
41
|
+
"trials": 3,
|
|
42
|
+
"rate": 1,
|
|
43
|
+
"errored": 0,
|
|
44
|
+
"overlap": 0.667,
|
|
45
|
+
"lexArgmax": "grade-paper-writing",
|
|
46
|
+
"buckets": [
|
|
47
|
+
"TARGET",
|
|
48
|
+
"TARGET",
|
|
49
|
+
"TARGET"
|
|
50
|
+
],
|
|
51
|
+
"othersFired": []
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"skill": "grade-paper-writing",
|
|
55
|
+
"cell": "AH",
|
|
56
|
+
"prompt": "grade how well this reads, hedge stacking included, and give me the fix for each",
|
|
57
|
+
"trials": 3,
|
|
58
|
+
"rate": 0,
|
|
59
|
+
"errored": 0,
|
|
60
|
+
"overlap": 0.857,
|
|
61
|
+
"lexArgmax": "grade-paper-writing",
|
|
62
|
+
"buckets": [
|
|
63
|
+
"SILENT",
|
|
64
|
+
"SILENT",
|
|
65
|
+
"SILENT"
|
|
66
|
+
],
|
|
67
|
+
"othersFired": []
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"skill": "grade-paper-writing",
|
|
71
|
+
"cell": "SH",
|
|
72
|
+
"prompt": "the abstract reads like a wall of jargon",
|
|
73
|
+
"trials": 3,
|
|
74
|
+
"rate": 0.6666666666666666,
|
|
75
|
+
"errored": 0,
|
|
76
|
+
"overlap": 1,
|
|
77
|
+
"lexArgmax": "grade-paper-writing",
|
|
78
|
+
"buckets": [
|
|
79
|
+
"SILENT",
|
|
80
|
+
"TARGET",
|
|
81
|
+
"TARGET"
|
|
82
|
+
],
|
|
83
|
+
"othersFired": []
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"skill": "grade-paper-writing",
|
|
87
|
+
"cell": "SH",
|
|
88
|
+
"prompt": "the intro architecture is fine but the prose clarity is not",
|
|
89
|
+
"trials": 3,
|
|
90
|
+
"rate": 0,
|
|
91
|
+
"errored": 0,
|
|
92
|
+
"overlap": 0.8,
|
|
93
|
+
"lexArgmax": "grade-paper-writing",
|
|
94
|
+
"buckets": [
|
|
95
|
+
"SILENT",
|
|
96
|
+
"SILENT",
|
|
97
|
+
"OTHER"
|
|
98
|
+
],
|
|
99
|
+
"othersFired": [
|
|
100
|
+
"cold-read-diff"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"skill": "grade-paper-writing",
|
|
105
|
+
"cell": "SH",
|
|
106
|
+
"prompt": "there is hedge stacking everywhere and the point never lands",
|
|
107
|
+
"trials": 3,
|
|
108
|
+
"rate": 0.3333333333333333,
|
|
109
|
+
"errored": 0,
|
|
110
|
+
"overlap": 0.667,
|
|
111
|
+
"lexArgmax": "grade-paper-writing",
|
|
112
|
+
"buckets": [
|
|
113
|
+
"OTHER",
|
|
114
|
+
"TARGET",
|
|
115
|
+
"OTHER"
|
|
116
|
+
],
|
|
117
|
+
"othersFired": [
|
|
118
|
+
"tighten-paper",
|
|
119
|
+
"tighten-paper"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"skill": "grade-paper-writing",
|
|
124
|
+
"cell": "SH",
|
|
125
|
+
"prompt": "the writing does not read well even though the draft is finished",
|
|
126
|
+
"trials": 3,
|
|
127
|
+
"rate": 0,
|
|
128
|
+
"errored": 0,
|
|
129
|
+
"overlap": 0.667,
|
|
130
|
+
"lexArgmax": "grade-paper-writing",
|
|
131
|
+
"buckets": [
|
|
132
|
+
"SILENT",
|
|
133
|
+
"SILENT",
|
|
134
|
+
"SILENT"
|
|
135
|
+
],
|
|
136
|
+
"othersFired": []
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
patched: filter the MAIN LOOP to grade-paper-writing, cells AH+SH (guards untouched)
|
|
2
|
+
patched: redirect the JSON output so the parent's own result file survives
|
|
3
|
+
|
|
4
|
+
running the PARENT'S code, grade-paper-writing AH+SH only, 3 trials = 24 runs
|
|
5
|
+
parent : /home/user/mine/.claude/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs
|
|
6
|
+
patched: /tmp/claude-0/-home-user-mine/8268acb1-66a2-55ac-858e-2b9e3c81f84e/scratchpad/parent-repl/replication.mjs
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
37 skills installed → 36 competitors per run
|
|
10
|
+
|
|
11
|
+
MEASURED VOCABULARY OVERLAP (prompt content-words found in the target description)
|
|
12
|
+
skill AH AL SH SL HIGH-LOW
|
|
13
|
+
tighten-paper 0.81 0.00 0.79 0.04 +0.78
|
|
14
|
+
grade-paper-writing 0.85 0.14 0.78 0.05 +0.72
|
|
15
|
+
argument-arc 0.86 0.00 0.69 0.00 +0.77
|
|
16
|
+
|
|
17
|
+
mode=main 3 skills x 4 cells x 4 prompts x 3 trials = 144 runs
|
|
18
|
+
|
|
19
|
+
=== grade-paper-writing [ACTION / HIGH overlap]
|
|
20
|
+
Spent: 404,155 tokens (18 in · 1.6k out · 357.3k cache) · ~$0.40 API-equivalent
|
|
21
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
22
|
+
1.00 T3 O0 S0 ov=0.88 grade the writing craft in this draft and name the offen
|
|
23
|
+
Spent: 498,692 tokens (22 in · 2.7k out · 448.8k cache) · ~$0.46 API-equivalent
|
|
24
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
25
|
+
Session so far: 902,847 tokens · ~$0.86 API-equivalent
|
|
26
|
+
1.00 T3 O0 S0 ov=1.00 run the blind multi-grader panel over the prose clarity
|
|
27
|
+
Spent: 499,035 tokens (22 in · 3.4k out · 448.3k cache) · ~$0.47 API-equivalent
|
|
28
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
29
|
+
Session so far: 1,401,882 tokens · ~$1.33 API-equivalent
|
|
30
|
+
1.00 T3 O0 S0 ov=0.67 score the title, the abstract and the intro architecture
|
|
31
|
+
Spent: 133,709 tokens (6 in · 778 out · 90.1k cache) · ~$0.30 API-equivalent
|
|
32
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
33
|
+
Session so far: 1,535,591 tokens · ~$1.63 API-equivalent
|
|
34
|
+
0.00 T0 O0 S3 ov=0.86 grade how well this reads, hedge stacking included, and
|
|
35
|
+
|
|
36
|
+
=== grade-paper-writing [SITUATION / HIGH overlap]
|
|
37
|
+
Spent: 587,085 tokens (26 in · 2.4k out · 537.8k cache) · ~$0.48 API-equivalent
|
|
38
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
39
|
+
Session so far: 2,122,676 tokens · ~$2.10 API-equivalent
|
|
40
|
+
0.67 T2 O0 S1 ov=1.00 the abstract reads like a wall of jargon
|
|
41
|
+
Spent: 894,628 tokens (38 in · 13.9k out · 821.6k cache) · ~$0.91 API-equivalent
|
|
42
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
43
|
+
Session so far: 3,017,304 tokens · ~$3.02 API-equivalent
|
|
44
|
+
0.00 T0 O1 S2 ov=0.80 the intro architecture is fine but the prose clarity is
|
|
45
|
+
instead: cold-read-diff
|
|
46
|
+
Spent: 496,058 tokens (21 in · 2.2k out · 448.0k cache) · ~$0.44 API-equivalent
|
|
47
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
48
|
+
Session so far: 3,513,362 tokens · ~$3.46 API-equivalent
|
|
49
|
+
0.33 T1 O2 S0 ov=0.67 there is hedge stacking everywhere and the point never l
|
|
50
|
+
instead: tighten-paper
|
|
51
|
+
Spent: 134,038 tokens (6 in · 1.1k out · 90.1k cache) · ~$0.30 API-equivalent
|
|
52
|
+
Billed to: your Claude subscription — $0 metered ✅
|
|
53
|
+
Session so far: 3,647,400 tokens · ~$3.76 API-equivalent
|
|
54
|
+
0.00 T0 O0 S3 ov=0.67 the writing does not read well even though the draft is
|
|
55
|
+
|
|
56
|
+
==============================================================================
|
|
57
|
+
THE 2x2 — target trigger rate
|
|
58
|
+
|
|
59
|
+
HIGH overlap LOW overlap
|
|
60
|
+
ACTION 75% (9/12) NaN% (0/0)
|
|
61
|
+
SITUATION 25% (3/12) NaN% (0/0)
|
|
62
|
+
|
|
63
|
+
main effect of FRAMING (AH+AL) - (SH+SL) = 50pp
|
|
64
|
+
main effect of VOCABULARY (AH+SH) - (AL+SL) = NaNpp
|
|
65
|
+
|
|
66
|
+
A (lexical) predicts AH high, SH high, AL low, SL low
|
|
67
|
+
B (framing) predicts AH high, AL high, SH low, SL low
|
|
68
|
+
observed AH 75% AL NaN% SH 25% SL NaN%
|
|
69
|
+
|
|
70
|
+
==============================================================================
|
|
71
|
+
WHAT FIRED INSTEAD — the C discriminator
|
|
72
|
+
|
|
73
|
+
cell target other silent
|
|
74
|
+
ACTION / HIGH overlap 75% 0% 25%
|
|
75
|
+
ACTION / LOW overlap NaN% NaN% NaN%
|
|
76
|
+
SITUATION / HIGH overlap 25% 25% 50%
|
|
77
|
+
SITUATION / LOW overlap NaN% NaN% NaN%
|
|
78
|
+
|
|
79
|
+
OTHER = a competitor was selected and the target was not. The prompt routed somewhere;
|
|
80
|
+
the selector disagreed. Ambiguity (C) or a lexically nearer rival (A).
|
|
81
|
+
SILENT = nothing resolved. The target was never selected AND neither was anything else.
|
|
82
|
+
A description that does not cover the phrasing (A or B) — but see caveat 2:
|
|
83
|
+
a run that simply answered the question is also SILENT.
|
|
84
|
+
|
|
85
|
+
WHICH competitors took the runs (all cells):
|
|
86
|
+
2 tighten-paper
|
|
87
|
+
1 cold-read-diff
|
|
88
|
+
|
|
89
|
+
per-skill, target rate by cell:
|
|
90
|
+
skill AH AL SH SL
|
|
91
|
+
tighten-paper NaN% NaN% NaN% NaN%
|
|
92
|
+
grade-paper-writing 75% NaN% 25% NaN%
|
|
93
|
+
argument-arc NaN% NaN% NaN% NaN%
|
|
94
|
+
|
|
95
|
+
per-run rows → repro/2026-08-08-framing-vs-vocabulary.json
|
|
96
|
+
|
|
97
|
+
Run --mode oracle before concluding C is dead: the 2x2 alone cannot tell "the description was
|
|
98
|
+
not a candidate" from "no description could have been", and that is exactly what C claims.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 2026-08-08-parent-replication.mjs — DID THE PARENT'S 12% HOLD, OR WAS IT TIME-BOUND?
|
|
3
|
+
*
|
|
4
|
+
* Run: node .claude/skills/paper-pipeline/repro/2026-08-08-parent-replication.mjs
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS. `grade-paper-writing-ablation.eval.mjs`'s CONTROL ARM (A0 — the verbatim
|
|
7
|
+
* description, the parent's own eight AH+SH prompts, the parent's fixture, the same 37 skills)
|
|
8
|
+
* returned 13/24 = 54%. The parent (`framing-vs-vocabulary.eval.mjs`, same day) measured those same
|
|
9
|
+
* eight prompts at AH 3/12 and SH 2/12 = 5/24 = 21%, and that 21%/12% is the entire premise of the
|
|
10
|
+
* ablation — and of two SKILL.md edits made earlier the same day that cite it as measured fact.
|
|
11
|
+
*
|
|
12
|
+
* A control that contradicts the experiment it was built to explain outranks every arm, so this
|
|
13
|
+
* settles which number is real, and it does it through the PARENT'S OWN CODE, not a reimplementation:
|
|
14
|
+
*
|
|
15
|
+
* - It reads `framing-vs-vocabulary.eval.mjs` and applies exactly TWO textual patches, each of
|
|
16
|
+
* which must match exactly once or this script aborts:
|
|
17
|
+
* 1. the MAIN LOOP is filtered to `grade-paper-writing` and to cells AH + SH;
|
|
18
|
+
* 2. the output JSON path is changed so the parent's own result file is never overwritten.
|
|
19
|
+
* Everything else — fixture, roster, guards, allowedTools, trials, concurrency, spacing, timeout,
|
|
20
|
+
* the `fired` predicate, the skillsDir (the REAL `.claude/skills`) — is the parent's, unmodified.
|
|
21
|
+
* Note patch 1 deliberately filters the LOOP and not `CELLS`/`CASES` themselves: the parent's
|
|
22
|
+
* preflight guards compute overlap contrasts across all four cells and all three skills, and
|
|
23
|
+
* narrowing the constants would disable the guards instead of the runs.
|
|
24
|
+
* - The patched copy is written to the session scratchpad with a `node_modules` symlink, so
|
|
25
|
+
* `.claude/skills/` is not touched and the parent file is read-only throughout.
|
|
26
|
+
*
|
|
27
|
+
* READING IT
|
|
28
|
+
* ~54% the parent's 21% for this skill was time-bound or otherwise unstable, and the "dead skill"
|
|
29
|
+
* premise is about MEASUREMENT STABILITY, not about the description. The two SKILL.md
|
|
30
|
+
* paragraphs citing 12% need correcting.
|
|
31
|
+
* ~21% the difference lives in the ablation's harness setup (a copied skills dir, per-arm
|
|
32
|
+
* packaging) and NO ablation arm is comparable to the parent's numbers — the arms remain
|
|
33
|
+
* internally comparable to each other and to A0, and nothing else.
|
|
34
|
+
*
|
|
35
|
+
* 24 runs, ~$3.4 API-equivalent at the measured rate. n = 24 resolves a factor of two; that is
|
|
36
|
+
* exactly the size of the disagreement (21% vs 54%), which is why 24 is enough here.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import { readFileSync, writeFileSync, mkdirSync, symlinkSync, existsSync, rmSync } from "node:fs";
|
|
40
|
+
import { join } from "node:path";
|
|
41
|
+
import { spawnSync } from "node:child_process";
|
|
42
|
+
|
|
43
|
+
const ROOT = process.env.CLAUDE_PROJECT_DIR ?? "/home/user/mine";
|
|
44
|
+
const PARENT = join(ROOT, ".claude", "skills", "paper-pipeline", "framing-vs-vocabulary.eval.mjs");
|
|
45
|
+
const SCRATCH =
|
|
46
|
+
process.env.ABLATION_SCRATCH ??
|
|
47
|
+
"/tmp/claude-0/-home-user-mine/8268acb1-66a2-55ac-858e-2b9e3c81f84e/scratchpad/parent-repl";
|
|
48
|
+
|
|
49
|
+
const src = readFileSync(PARENT, "utf-8");
|
|
50
|
+
|
|
51
|
+
const PATCHES = [
|
|
52
|
+
{
|
|
53
|
+
what: "filter the MAIN LOOP to grade-paper-writing, cells AH+SH (guards untouched)",
|
|
54
|
+
from: "const results = [];\nfor (const c of CASES) {\n for (const k of CELLS) {",
|
|
55
|
+
to:
|
|
56
|
+
"const results = [];\n" +
|
|
57
|
+
'for (const c of CASES.filter((c) => c.skill === "grade-paper-writing")) {\n' +
|
|
58
|
+
' for (const k of CELLS.filter((k) => k === "AH" || k === "SH")) {',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
what: "redirect the JSON output so the parent's own result file survives",
|
|
62
|
+
from: '"2026-08-08-framing-vs-vocabulary.json"',
|
|
63
|
+
to: '"2026-08-08-parent-replication-gpw.json"',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
let patched = src;
|
|
68
|
+
for (const p of PATCHES) {
|
|
69
|
+
const n = patched.split(p.from).length - 1;
|
|
70
|
+
if (n !== 1)
|
|
71
|
+
throw new Error(`PATCH MATCHED ${n} TIMES (must be exactly 1): ${p.what}\n---\n${p.from}\n---`);
|
|
72
|
+
patched = patched.replace(p.from, p.to);
|
|
73
|
+
console.log(`patched: ${p.what}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
rmSync(SCRATCH, { recursive: true, force: true });
|
|
77
|
+
mkdirSync(SCRATCH, { recursive: true });
|
|
78
|
+
const target = join(SCRATCH, "replication.mjs");
|
|
79
|
+
writeFileSync(target, patched);
|
|
80
|
+
if (!existsSync(join(SCRATCH, "node_modules")))
|
|
81
|
+
symlinkSync(join(ROOT, "node_modules"), join(SCRATCH, "node_modules"), "dir");
|
|
82
|
+
|
|
83
|
+
console.log(`\nrunning the PARENT'S code, grade-paper-writing AH+SH only, 3 trials = 24 runs`);
|
|
84
|
+
console.log(` parent : ${PARENT}`);
|
|
85
|
+
console.log(` patched: ${target}\n`);
|
|
86
|
+
|
|
87
|
+
const r = spawnSync(process.execPath, [target, "--mode", "main"], {
|
|
88
|
+
stdio: "inherit",
|
|
89
|
+
env: { ...process.env, CLAUDE_PROJECT_DIR: ROOT },
|
|
90
|
+
cwd: ROOT,
|
|
91
|
+
});
|
|
92
|
+
process.exit(r.status ?? 1);
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# repro/ — raw runs behind the pipeline's own measurements
|
|
2
|
+
|
|
3
|
+
Every number this directory's evals report has its raw log here. The rule is the repo's: a claim
|
|
4
|
+
whose run lives only in a scratchpad is not reproducible, and the scratchpad is erased at the end of
|
|
5
|
+
the session.
|
|
6
|
+
|
|
7
|
+
| file | what it backs | headline |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `2026-08-07-language-eval-raw.log` | `pipeline-language.eval.mjs`, the full designed run | 32 matched pairs × 3 trials × 2 languages = 192 runs. EN 75/96 (78.1%) vs RU 58/96 (60.4%), −17.7pp; paired sign test 13v2, 17 tied, **p = 0.0074**. Effect present in BOTH translation directions. |
|
|
10
|
+
| `2026-08-07-language-eval-pilot.log` | the same file's one-case pilot | `tighten-paper` at 2 trials, run before committing quota to 192 |
|
|
11
|
+
| `analyze-language-eval.py` | the statistics for the above | Parses the raw log and recomputes everything. Statistics live HERE, downstream of the instrument, so the eval cannot print a number that confirms its own hypothesis. Run: `python3 analyze-language-eval.py 2026-08-07-language-eval-raw.log` |
|
|
12
|
+
| `2026-08-07-description-language-control.log` | `description-language.eval.mjs`, control arm | 12 **fresh** matched pairs × 3 trials × 2 languages = 72 runs. RU 11/36 (31%) vs EN 9/36 (25%). 🔴 **The gap did not appear — and both arms collapsed** from 78%/60% to a quarter. This killed the bilingual-description intervention before it was built. |
|
|
13
|
+
| `2026-08-07-fork-check.log` | the `context: fork` pilot | `cold-read-diff` en 67→75 / ru 67→67; `map-prior-work` en 67→75 / ru 75→75. No regression, which is the point — the risk was that forking changes what the model selects. |
|
|
14
|
+
| `2026-08-07-fork-check2.log` | `context: fork` rollout check | `paper-adversarial-review`, the only one of the five rolled-out skills covered by an eval |
|
|
15
|
+
| `2026-08-08-framing-vs-vocabulary-raw.log` | `framing-vs-vocabulary.eval.mjs`, main 2×2 | 3 skills × 4 cells × 4 prompts × 3 trials = **144 runs, 0 errored**. AH 64% (23/36) · AL 44% (16/36) · SH 61% (22/36) · SL 11% (4/36). Vocabulary main effect **35pp**, framing **18pp**. 🔴 **ONE** competitor misfire in 144 runs; SL is **86% SILENT**. |
|
|
16
|
+
| `2026-08-08-framing-vs-vocabulary.json` | per-run rows for the above | Every run's TARGET/OTHER/SILENT bucket, measured overlap, lexical argmax, and which competitor fired instead. The bucket field is the signal neither earlier eval recorded. |
|
|
17
|
+
| `2026-08-08-framing-vs-vocabulary-oracle.log` | the same file's `--mode oracle`, the C control | 48 closed-book picks over all 37 descriptions, no harness, no skills installed. AH **12/12** · AL 8/12 · SH **12/12** · SL **3/12** (6 answered NONE). Harness sits 14–39pp below the oracle in *every* cell. |
|
|
18
|
+
| `2026-08-08-framing-vs-vocabulary-oracle.json` | per-pick rows for the above | Each prompt's oracle pick vs the intended skill. |
|
|
19
|
+
| `2026-08-08-grade-paper-writing-ablation-raw.log` | `grade-paper-writing-ablation.eval.mjs`, arms A0–A5 | 6 arms × 8 prompts (the parent's AH+SH, verbatim) × 3 trials = **144 runs, 0 errored**. A0 baseline **54% (13/24)** · A1 short 50% · A2 no-subordination 50% · A3 no-negation 54% · A4 no-machinery 46% · A5 renamed **25%**. Every description-text arm inside noise (±~20pp at n=24). |
|
|
20
|
+
| `2026-08-08-grade-paper-writing-ablation-A6-raw.log` | the same file, arm A6 added later | persona-only description (225 chars), 24 runs. **42% (10/24)** vs A1's rubric-only 50% — the pair does not separate the skill's two halves. |
|
|
21
|
+
| `2026-08-08-grade-paper-writing-ablation.json` | per-run rows for both of the above | 56 prompt-rows across 7 arms: TARGET/OTHER/SILENT bucket, measured overlap, description length, competitors fired instead. |
|
|
22
|
+
| `2026-08-08-grade-paper-writing-ablation-oracle.log` | the same file's `--mode oracle`, all 7 arms | 56 closed-book picks. 7/8 or 8/8 on every arm **except A5 at 0/8** — and on 7 of those 8 the oracle answered `grade-paper-writing`, a name absent from the roster it was shown. |
|
|
23
|
+
| `2026-08-08-grade-paper-writing-ablation-oracle.json` | per-pick rows for the above | Each arm × prompt: the oracle's pick vs the arm's intended id. |
|
|
24
|
+
| `2026-08-08-grade-paper-writing-ablation-setupdiff.log` | `--mode setupdiff`, **free** | The mechanical answer to "is the ablation's harness the same as the parent's": options, fixture block, `fired` predicate and `firedSkills` helper all identical; all 7 arm dirs 37 skills with every frontmatter sha256-identical to the real one bar the deliberate mutation. Plus the parent-vs-A0 row-by-row. |
|
|
25
|
+
| `2026-08-08-parent-replication.mjs` | the replication driver | Runs `framing-vs-vocabulary.eval.mjs` **itself** with two asserted patches (main loop → this skill + AH/SH; output path), everything else untouched, against the real `.claude/skills`. Written because the ablation's control contradicted the parent. |
|
|
26
|
+
| `2026-08-08-parent-replication-gpw.log` | that driver's run | 🔴 **The parent's own code returns AH 9/12 + SH 3/12 = 12/24 (50%)** hours after the same code returned 3/12 + 2/12 = 5/24 (21%). |
|
|
27
|
+
| `2026-08-08-parent-replication-gpw.json` | per-run rows for the above | The parent's own row schema, so it diffs directly against `2026-08-08-framing-vs-vocabulary.json`. |
|
|
28
|
+
|
|
29
|
+
## How to read these, and the trap in them
|
|
30
|
+
|
|
31
|
+
**The two evals disagree, and the disagreement is the finding.** Same three skills, same fixture,
|
|
32
|
+
same method:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
prompts that NAME the action ("paper got bloated, what to cut?") 78% EN / 60% RU
|
|
36
|
+
prompts that describe a SITUATION ("text won't fit, need to decide
|
|
37
|
+
what to sacrifice and where to move it") 25% EN / 31% RU
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
A factor of two to three. The second set was written deliberately to share **no vocabulary** with the
|
|
41
|
+
skill descriptions — because a prompt reusing a description's words measures how well the description
|
|
42
|
+
was copied, not whether it works. Remove the shared vocabulary and recall falls off a cliff.
|
|
43
|
+
|
|
44
|
+
So the control does **not** refute the language finding: at 25–31% both arms sit on the floor and a
|
|
45
|
+
6pp difference there has no power behind it. What it establishes is bigger and less welcome — these
|
|
46
|
+
skills mostly fire when the user happens to use the description's own verb.
|
|
47
|
+
|
|
48
|
+
**Do not compare a number from one log against a number from the other as if they were the same
|
|
49
|
+
measurement.** They share a method and differ in the one variable that turned out to dominate.
|
|
50
|
+
|
|
51
|
+
## 2026-08-08 — the disagreement above, explained
|
|
52
|
+
|
|
53
|
+
`framing-vs-vocabulary.eval.mjs` crossed the two factors the disagreement confounded (every
|
|
54
|
+
"names the action" prompt was *also* high-overlap) and recorded, for the first time, **what fired
|
|
55
|
+
instead**. Result, in one line:
|
|
56
|
+
|
|
57
|
+
> The selector fires when it has **either** the description's vocabulary **or** an explicit request
|
|
58
|
+
> for the deliverable. It collapses only when it has neither — which is how people type.
|
|
59
|
+
|
|
60
|
+
- **The symptom-vs-action framing hypothesis is refuted.** Pure symptom statements written in the
|
|
61
|
+
description's own words (`SH`, 61%) fire as well as explicit requests (`AH`, 64%) — 83% vs 83%
|
|
62
|
+
once the one dead skill is excluded. Descriptions already name symptoms; that is not what is
|
|
63
|
+
missing.
|
|
64
|
+
- **Ambiguity is refuted too, in the form it was posed.** If the oblique prompts were losing to
|
|
65
|
+
plausible rivals, competitors would be taking the runs. They are not: **1 misfire in 144 runs**,
|
|
66
|
+
and 86% of the collapsed cell resolves *no skill at all*. Nothing competes; nothing matches.
|
|
67
|
+
- **But the descriptions really are under-determining.** A closed-book reader handed all 37
|
|
68
|
+
descriptions also collapses on those prompts (3/12, six NONE). So the gap is **coverage**, not
|
|
69
|
+
ambiguity — different defect, different fix.
|
|
70
|
+
- **Unexplained and possibly bigger:** the harness runs 14–39pp below that closed-book reader in
|
|
71
|
+
*every* cell, including the ones the reader gets 12/12. A third of the easiest prompts resolve
|
|
72
|
+
nothing. Size measured here; cause not.
|
|
73
|
+
|
|
74
|
+
Full reading, caveats, and what it still cannot settle: the header of
|
|
75
|
+
`../framing-vs-vocabulary.eval.mjs`. **No `SKILL.md` was changed on the strength of this run.**
|
|
76
|
+
|
|
77
|
+
## 🔴 2026-08-08, later the same day — the "dead skill" premise did not replicate
|
|
78
|
+
|
|
79
|
+
`grade-paper-writing-ablation.eval.mjs` set out to explain WHY `grade-paper-writing` fired only
|
|
80
|
+
12% of the time, by mutating its description one factor at a time (7 arms × 8 prompts × 3 trials).
|
|
81
|
+
Its **control arm broke the premise instead**:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
grade-paper-writing, the parent's own eight AH+SH prompts, same fixture, same 36 competitors
|
|
85
|
+
parent, this morning 3/12 AH · 2/12 SH = 5/24 21%
|
|
86
|
+
ablation control A0, hours later, same description 7/12 AH · 6/12 SH = 13/24 54%
|
|
87
|
+
THE PARENT'S OWN CODE, re-run, real .claude/skills 9/12 AH · 3/12 SH = 12/24 50%
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The third line is why this is not a setup bug: it is `framing-vs-vocabulary.eval.mjs` itself,
|
|
91
|
+
patched only to run one skill and two cells, against the real skills directory. `--mode setupdiff`
|
|
92
|
+
separately proved the two harnesses identical option by option and hash by hash.
|
|
93
|
+
|
|
94
|
+
- **Every description-text arm is flat** — short −4pp, no-subordination −4pp, no-negation 0pp,
|
|
95
|
+
no-machinery −8pp, persona-only −12pp, against a ±20pp interval. The cause was not in the text.
|
|
96
|
+
- **The one arm outside noise is an artifact.** Renaming the skill (description byte-identical)
|
|
97
|
+
cost 29pp and collapsed the oracle to 0/8 — because **six other descriptions name
|
|
98
|
+
`grade-paper-writing`** (`cold-read-diff`, `draft-paper`, `harden-paper`,
|
|
99
|
+
`paper-adversarial-review`, `pc-panel-review`, `tighten-paper`) and the reader follows the
|
|
100
|
+
cross-reference to a skill that no longer exists. A rename here is not a local edit.
|
|
101
|
+
- **What did reproduce:** the closed-book oracle scores 7–8 of 8 on every non-artifact arm while
|
|
102
|
+
the harness delivers 42–54% on the same text. That 25–45pp deficit is the parent's point 5, and
|
|
103
|
+
no description edit touched it.
|
|
104
|
+
|
|
105
|
+
⚠️ **The 12% figure is quoted as measured fact inside `harden-paper` and `pc-panel-review`**
|
|
106
|
+
(commit `38a17ef`). The advice there — invoke the skill by name instead of relying on selection —
|
|
107
|
+
survives at 50%; the number does not. Neither file was edited on the strength of this run either.
|
|
108
|
+
|
|
109
|
+
Full reading and the confounds, including the un-pre-registered arm-order one:
|
|
110
|
+
the header of `../grade-paper-writing-ablation.eval.mjs`.
|
|
111
|
+
|
|
112
|
+
## ⚠️ These logs are gitignored — force-add them
|
|
113
|
+
|
|
114
|
+
`.gitignore` line 73 is `*.log`, meant for LaTeX build artifacts. It silently swallows every raw log
|
|
115
|
+
in this directory. The table above says "every number has its raw log here"; git tracks **none** of
|
|
116
|
+
the `.log` files, so a fresh clone has the claims and not the evidence — exactly the artifact loss
|
|
117
|
+
this directory exists to prevent. New logs must be added with:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
git add -f .claude/skills/paper-pipeline/repro/<name>.log
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The `2026-08-08-*` logs were added this way. The four `2026-08-07-*` logs are still untracked and
|
|
124
|
+
should be force-added the next time someone touches this directory.
|
|
125
|
+
|
|
126
|
+
## Cost
|
|
127
|
+
|
|
128
|
+
Billed to a Claude subscription, $0 metered; ~$0.14 API-equivalent per run. The 192-run design cost
|
|
129
|
+
~$26.59. That is why the pilot exists and why the `after` arm of the description A/B was never run.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
analyze-language-eval.py — the statistics behind the language finding, from the raw run log.
|
|
4
|
+
|
|
5
|
+
python3 .claude/skills/paper-pipeline/repro/analyze-language-eval.py \
|
|
6
|
+
.claude/skills/paper-pipeline/repro/2026-08-07-language-eval-raw.log
|
|
7
|
+
|
|
8
|
+
WHY THIS FILE EXISTS. `pipeline-language.eval.mjs` prints rates and deltas; it deliberately does
|
|
9
|
+
NOT print a p-value, because a gate or a statistic inside the measuring instrument is how a check
|
|
10
|
+
that can only confirm its own hypothesis gets written. The inference lives here, downstream, and it
|
|
11
|
+
reads the same log a human reads.
|
|
12
|
+
|
|
13
|
+
WHY A SIGN TEST AND NOT A CHI-SQUARE ON THE TOTALS. The design is MATCHED PAIRS: each prompt exists
|
|
14
|
+
in both languages with the same content, so the two arms are not independent samples and a
|
|
15
|
+
two-proportion test on 96-vs-96 throws away the pairing that the design was built to get. The
|
|
16
|
+
paired test asks the question the design actually poses — for a given question, does the English
|
|
17
|
+
form fire more often than the Russian one — and tied pairs (the majority here) correctly contribute
|
|
18
|
+
no evidence either way.
|
|
19
|
+
|
|
20
|
+
The unpaired Fisher exact is printed alongside only as a sanity check that the two tests agree on
|
|
21
|
+
direction and rough magnitude. It is NOT the headline number.
|
|
22
|
+
|
|
23
|
+
WHAT THE NUMBERS CANNOT SAY, and the run they replace said louder:
|
|
24
|
+
- the prior single-trial run put the gap at 93% English vs 56% Russian (-37pp). This one puts it
|
|
25
|
+
at 78% vs 60% (-18pp). The Russian figure replicated; the ENGLISH one fell by 15 points. The
|
|
26
|
+
original gap was inflated by an English arm of 14 prompts measured once each.
|
|
27
|
+
- the translations in both directions were written by the same model family being measured, and
|
|
28
|
+
no native speaker has reviewed them.
|
|
29
|
+
"""
|
|
30
|
+
import math
|
|
31
|
+
import re
|
|
32
|
+
import sys
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
|
|
35
|
+
TRIALS = 3
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def log_c(n, k):
|
|
39
|
+
return math.lgamma(n + 1) - math.lgamma(k + 1) - math.lgamma(n - k + 1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def fisher_two_sided(a, b, c, d):
|
|
43
|
+
"""Two-sided Fisher exact on the 2x2 [[a,b],[c,d]], summing all tables no likelier than observed."""
|
|
44
|
+
n, r1, c1 = a + b + c + d, a + b, a + c
|
|
45
|
+
|
|
46
|
+
def pmf(x):
|
|
47
|
+
return math.exp(log_c(c1, x) + log_c(n - c1, r1 - x) - log_c(n, r1))
|
|
48
|
+
|
|
49
|
+
p0 = pmf(a)
|
|
50
|
+
lo, hi = max(0, r1 - (n - c1)), min(r1, c1)
|
|
51
|
+
return min(1.0, sum(p for x in range(lo, hi + 1) if (p := pmf(x)) <= p0 * (1 + 1e-9)))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def binom_two_sided(k, m):
|
|
55
|
+
"""Exact two-sided binomial test against p=0.5 — the sign test's p-value."""
|
|
56
|
+
if m == 0:
|
|
57
|
+
return float("nan")
|
|
58
|
+
pk = [math.exp(log_c(m, i) + m * math.log(0.5)) for i in range(m + 1)]
|
|
59
|
+
return min(1.0, sum(x for x in pk if x <= pk[k] * (1 + 1e-9)))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def parse(path):
|
|
63
|
+
"""Recover (skill, origin, en_fired, ru_fired) per matched pair from the run log."""
|
|
64
|
+
cases, cur, lang = [], None, None
|
|
65
|
+
for line in Path(path).read_text(encoding="utf-8").splitlines():
|
|
66
|
+
if m := re.match(r"^=== (\S+) —", line):
|
|
67
|
+
cur = {"skill": m.group(1), "en": [], "ru": []}
|
|
68
|
+
cases.append(cur)
|
|
69
|
+
elif m := re.match(r"^ (en|ru): ", line):
|
|
70
|
+
lang = m.group(1)
|
|
71
|
+
elif (m := re.match(r"^ ([01]\.\d\d) \[(en|ru)\] (.*)$", line)) and cur and lang:
|
|
72
|
+
cur[lang].append((float(m.group(1)), m.group(2)))
|
|
73
|
+
# A case whose two arms did not both record four prompts is a truncated run, not a data point.
|
|
74
|
+
cases = [c for c in cases if len(c["en"]) == 4 and len(c["ru"]) == 4]
|
|
75
|
+
return [
|
|
76
|
+
(c["skill"], c["en"][i][1], round(c["en"][i][0] * TRIALS), round(c["ru"][i][0] * TRIALS))
|
|
77
|
+
for c in cases
|
|
78
|
+
for i in range(4)
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def report(pairs, label):
|
|
83
|
+
en, ru = sum(p[2] for p in pairs), sum(p[3] for p in pairs)
|
|
84
|
+
n = len(pairs) * TRIALS
|
|
85
|
+
pos = sum(1 for p in pairs if p[2] > p[3])
|
|
86
|
+
neg = sum(1 for p in pairs if p[2] < p[3])
|
|
87
|
+
tie = len(pairs) - pos - neg
|
|
88
|
+
print(
|
|
89
|
+
f"{label:14} EN {en:3}/{n} ({en / n:5.1%}) RU {ru:3}/{n} ({ru / n:5.1%}) "
|
|
90
|
+
f"delta {(ru - en) / n * 100:+5.1f}pp sign {pos}v{neg} (tied {tie}) "
|
|
91
|
+
f"p={binom_two_sided(pos, pos + neg):.4f}"
|
|
92
|
+
)
|
|
93
|
+
return en, ru, n
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def main():
|
|
97
|
+
path = sys.argv[1] if len(sys.argv) > 1 else Path(__file__).with_name("2026-08-07-language-eval-raw.log")
|
|
98
|
+
pairs = parse(path)
|
|
99
|
+
if not pairs:
|
|
100
|
+
sys.exit(f"no matched pairs parsed from {path} — is this a complete run log?")
|
|
101
|
+
print(f"{len(pairs)} matched pairs x {TRIALS} trials x 2 languages = {len(pairs) * TRIALS * 2} runs\n")
|
|
102
|
+
|
|
103
|
+
en, ru, n = report(pairs, "OVERALL")
|
|
104
|
+
print(f"{'':14} unpaired Fisher exact two-sided p = {fisher_two_sided(en, n - en, ru, n - ru):.4f} (sanity check only)\n")
|
|
105
|
+
|
|
106
|
+
print("SPLIT BY ORIGIN — does the gap survive when the RUSSIAN side is the original text?")
|
|
107
|
+
for origin in ("en", "ru"):
|
|
108
|
+
report([p for p in pairs if p[1] == origin], f"{origin}-original")
|
|
109
|
+
|
|
110
|
+
print("\nPER SKILL (read as scenery: n=12 per cell, one run moves a cell 8 points)")
|
|
111
|
+
for skill in dict.fromkeys(p[0] for p in pairs):
|
|
112
|
+
report([p for p in pairs if p[0] == skill], skill)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
main()
|