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,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* camera-ready β the PAID tier: does this skill's description actually fire?
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE (vigiles decides coverage by placement as of 2026-08-11).
|
|
5
|
+
* The prompts live in `.claude/lib/skill-trigger-cases.mjs` so all 21 cases
|
|
6
|
+
* are reviewed as one table where collisions between siblings are visible;
|
|
7
|
+
* copying them here would recreate the drift that rule exists to prevent.
|
|
8
|
+
*
|
|
9
|
+
* Measures recall (fires on its own territory) AND precision (stays quiet on a
|
|
10
|
+
* colliding sibling's territory), against the REAL `.claude` harness so the skill
|
|
11
|
+
* competes with every other installed description β an isolated run overstates
|
|
12
|
+
* recall and understates false positives.
|
|
13
|
+
*
|
|
14
|
+
* Costs money; not CI.
|
|
15
|
+
* node .claude/skills/camera-ready/camera-ready.eval.mjs [trials]
|
|
16
|
+
*/
|
|
17
|
+
import { runSkillTriggerEval } from "../../lib/skill-eval-kit.mjs";
|
|
18
|
+
|
|
19
|
+
await runSkillTriggerEval("camera-ready");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* camera-ready β the free, deterministic tier. No model, no network.
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE. vigiles decides coverage by PLACEMENT as of 2026-08-11:
|
|
5
|
+
* a test that merely names a surface no longer counts, because that tier was
|
|
6
|
+
* crediting surfaces nothing touched. So each skill needs a file inside its own
|
|
7
|
+
* directory β this one.
|
|
8
|
+
*
|
|
9
|
+
* The assertions live in `.claude/lib/skill-checks.mjs` and are CALLED here with
|
|
10
|
+
* this skill's name. They are not copied: 22 copies of the same checks is the drift that
|
|
11
|
+
* module exists to avoid. (Until 2026-08-11 this was an env-var side channel into a
|
|
12
|
+
* 614-line file named after no surface; it is a function call now.)
|
|
13
|
+
*
|
|
14
|
+
* What this proves: this skill's frontmatter parses as strict YAML, its declared
|
|
15
|
+
* tool contract is sane, its pipeline wiring points at scripts that exist, and it
|
|
16
|
+
* announces/records under ITS OWN identity rather than a sibling's.
|
|
17
|
+
*
|
|
18
|
+
* What it does NOT prove: that the skill fires, or that its guidance produces a
|
|
19
|
+
* good result. Those need a real model β see `camera-ready.eval.mjs`.
|
|
20
|
+
*/
|
|
21
|
+
import { checkSkill } from "../../lib/skill-checks.mjs";
|
|
22
|
+
|
|
23
|
+
await checkSkill("camera-ready");
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cold-read-diff
|
|
3
|
+
description: Send just-changed paper prose to a reader with NO context and ask what each sentence claims β the only check that catches a sentence which is short, true, jargon-free and still meaningless to anyone who does not already know the idea. Run after every prose edit to a paper, before calling the edit done, and before reporting a section as fixed. Scoped to the diff, so it is cheap enough to run every time. Not a writing grade (grade-paper-writing), not a structural pass (tighten-paper), not a defect review.
|
|
4
|
+
context: fork
|
|
5
|
+
allowed-tools: [Bash, Read, Agent]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!-- vigiles:sha256:f3c36e3e56bbd3cd compiled from skills/cold-read-diff/SKILL.md.spec.ts -->
|
|
9
|
+
|
|
10
|
+
# cold-read-diff β the reader who cannot fake understanding
|
|
11
|
+
|
|
12
|
+
## Run me
|
|
13
|
+
|
|
14
|
+
π΄ FIRST, before any other step:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs cold-read-diff <paper-dir>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
21
|
+
state β so starting is an event, and events get written down.
|
|
22
|
+
|
|
23
|
+
## The failure this exists for
|
|
24
|
+
|
|
25
|
+
On 2026-08-05 the author of `the reference paper` found eleven unreadable passages by eye, in a paper
|
|
26
|
+
that had passed six writing grades, four structural passes and five review panels. Every one of them
|
|
27
|
+
was short, factually correct, free of every word on the jargon list, and inside every mechanical
|
|
28
|
+
threshold. Samples, with his reactions:
|
|
29
|
+
|
|
30
|
+
> *"The state to remove is therefore not the rule but its claim about itself"* β **Β«wtfΒ»**
|
|
31
|
+
> *"these files are filled with constructions nobody built"* β **Β«wtfΒ»**
|
|
32
|
+
> *"Three answers, all of them after the fact"* β **Β«VAGUE AFΒ»**
|
|
33
|
+
> *"Both numbers carry a caveatβ¦"* β **Β«WTF.Β»**
|
|
34
|
+
|
|
35
|
+
They share one property: **they parse only for a reader who already holds the idea.** That is not a
|
|
36
|
+
style defect and no metric can see it. Sentence length, number density, hedge share, tic frequency β
|
|
37
|
+
all green on every one of these.
|
|
38
|
+
|
|
39
|
+
## Why the existing pipeline could not catch it
|
|
40
|
+
|
|
41
|
+
Every reader in it knows too much or cannot read at all:
|
|
42
|
+
|
|
43
|
+
| reader | holds the idea? | can judge meaning? |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| the author | maximally β that is the curse of knowledge | yes |
|
|
46
|
+
| the persona subagent | **yes: it is handed the paper and the framing** | yes |
|
|
47
|
+
| the review panel | yes | yes |
|
|
48
|
+
| `prose-lint` | no | **no β it counts patterns** |
|
|
49
|
+
|
|
50
|
+
The gap between "knows too much" and "cannot read" is exactly where these sentences live. Closing it
|
|
51
|
+
needs a reader who is competent and **structurally uninformed**, and the only way to guarantee that
|
|
52
|
+
is to withhold the context rather than ask them to ignore it.
|
|
53
|
+
|
|
54
|
+
## Why the DIFF, and not the paper
|
|
55
|
+
|
|
56
|
+
A full cold read costs a long agent run, so it gets run once a day, which means prose written after
|
|
57
|
+
it ships unread. Scoped to the changed paragraphs it costs a couple of minutes, so it runs every
|
|
58
|
+
time β and coverage beats depth here, because the defect is per-sentence.
|
|
59
|
+
|
|
60
|
+
Scoping also makes the check honest. Hand an agent the whole paper and it reconstructs the idea from
|
|
61
|
+
the surrounding text, then reports that the sentence is clear. Hand it three paragraphs and there is
|
|
62
|
+
nothing to reconstruct from: if the sentence does not carry its own meaning, the agent cannot invent
|
|
63
|
+
one, and its confusion is the finding.
|
|
64
|
+
|
|
65
|
+
## How to run it
|
|
66
|
+
|
|
67
|
+
1. **Take the diff.** `git diff -U0 -- <paper.md>` since the last commit, or the `new_string` of the
|
|
68
|
+
edits just applied. Prose only β skip comments, tables, bibliography.
|
|
69
|
+
2. **Spawn ONE agent with no repository context.** Give it the changed paragraphs **as text in the
|
|
70
|
+
prompt**, not as a file path. A path is an invitation to read the neighbours, and reading the
|
|
71
|
+
neighbours is how the check fails silently. `sonnet` is the right model: competent, cheap,
|
|
72
|
+
and not the one that wrote the sentence.
|
|
73
|
+
3. **Ask exactly two questions per sentence:**
|
|
74
|
+
- *What does this sentence claim? Restate it in your own words.* If restating requires guessing,
|
|
75
|
+
the answer is `CANNOT PARSE` plus what stopped them β an undefined term, a pronoun with no
|
|
76
|
+
referent, a number with no denominator, two clauses that do not connect.
|
|
77
|
+
- *Would a reader who stops here understand it?* Yes / No / Only-if-they-know-X.
|
|
78
|
+
4. **Ask for the dangerous class explicitly:** *which sentences sound clever but say less than they
|
|
79
|
+
appear to?* Those read fine and carry nothing, and they are the ones a knowing reader waves
|
|
80
|
+
through.
|
|
81
|
+
5. **Apply the fixes β as rewrites of the whole thought, never as excisions.** See the rule below.
|
|
82
|
+
6. **Re-run on the fix.** An edit is not done until the same kind of reader parses the replacement.
|
|
83
|
+
One confirming round; do not loop past it.
|
|
84
|
+
|
|
85
|
+
## π΄ Hand the reader WHOLE PARAGRAPHS, never `+` lines
|
|
86
|
+
|
|
87
|
+
Measured on 2026-08-05, first machine run of this skill: about a third of the reader's stalls were
|
|
88
|
+
artefacts of the extract, not defects in the paper β *"`it` has no referent"*, *"this sentence is cut
|
|
89
|
+
off mid-clause"*, *"those populations have no antecedent"*. The neighbouring sentences simply had not
|
|
90
|
+
changed, so they were not in the diff.
|
|
91
|
+
|
|
92
|
+
Two more things the same run proved:
|
|
93
|
+
|
|
94
|
+
- **Expand build-time macros first.** The reader saw seven raw `{{placeholders}}` and correctly
|
|
95
|
+
reported that every headline number was missing. That is a true statement about the extract and a
|
|
96
|
+
false one about the paper.
|
|
97
|
+
- **Strip working comments.** He graded `<!-- JUSTIFY β¦ -->` notes as prose because he could not tell
|
|
98
|
+
them apart β and said so, which is itself a finding about the extract.
|
|
99
|
+
|
|
100
|
+
**So:** take the changed lines, then widen each to its enclosing paragraph, expand macros, drop
|
|
101
|
+
comments, and hand the reader continuous prose. The findings that survive that are worth the run; the
|
|
102
|
+
ones that do not are noise, and noise is how this check gets muted.
|
|
103
|
+
|
|
104
|
+
## Record the verdict
|
|
105
|
+
|
|
106
|
+
π΄ LAST step, once the deliverable exists:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> FINDING <count> <report-path>
|
|
110
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> ABSTAINED <reason> "<one line>"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**FINDING** β `<count>` is the number of changed sentences the cold reader could not restate (every
|
|
114
|
+
`CANNOT PARSE` counts), `<report-path>` is the `reviews/*cold-read*.md` file.
|
|
115
|
+
**ABSTAINED** β `no-witness`: every changed sentence came back restated correctly.
|
|
116
|
+
`input-missing`: the diff held no prose to read.
|
|
117
|
+
|
|
118
|
+
π΄ These two are different answers and the difference is the whole reason the vocabulary is closed:
|
|
119
|
+
one says a reader read it and found nothing, the other says there was nothing to hand a reader.
|
|
120
|
+
Prose collapses them and the old `PASS`/`ABSENT` pair only half-separated them, because `PASS` also
|
|
121
|
+
got recorded when nobody had run a reader at all. There is no `PASS` now; the reason is the answer.
|
|
122
|
+
|
|
123
|
+
## Rules
|
|
124
|
+
|
|
125
|
+
- π΄ **No context in the prompt. Ever.** Not the title, not the abstract, not "this is a paper about
|
|
126
|
+
agent rules files". Every sentence of background handed to the reader is a sentence of confusion
|
|
127
|
+
they will no longer report.
|
|
128
|
+
- π΄ **A fix that removes the flagged construction and keeps the compression is not a fix.** Proven
|
|
129
|
+
twice in one hour: *"not through any defect in how we write it, but because that is what English
|
|
130
|
+
is"* β *"that is what English is for"* (tic gone, meaning inverted into nonsense); *"the agent
|
|
131
|
+
turns out not to be the weak link"* β *"The agent obeys"* (three words, zero flags, wrong finding).
|
|
132
|
+
Rewrite the **thought** in plain words. The tic is usually a symptom of a compressed idea, and
|
|
133
|
+
decompressing removes it as a side effect.
|
|
134
|
+
- **Length is not the constraint here β meaning is.** If plain language needs more words, take them
|
|
135
|
+
and pay from an appendix, which is outside the page limit. Paying by shortening another sentence
|
|
136
|
+
is what created the problem.
|
|
137
|
+
- **`CANNOT PARSE` is a result, not a failure of the reader.** Never argue with it. The author's
|
|
138
|
+
ability to understand his own sentence is not evidence about anyone else's.
|
|
139
|
+
- **Run it on your own fixes too.** The author is the least qualified judge of whether his repair
|
|
140
|
+
reads, and that is exactly when he feels most certain.
|
|
141
|
+
|
|
142
|
+
## Enforcement
|
|
143
|
+
|
|
144
|
+
`pipeline-check.mjs` raises `stale-cold-read` when the newest `reviews/*cold-read*.md` is older than
|
|
145
|
+
the paper source, and `no-cold-read` when none exists. The date comparison is the whole mechanism:
|
|
146
|
+
a cold read that predates the current text describes prose that no longer exists.
|
|
147
|
+
|
|
148
|
+
## Compose with
|
|
149
|
+
|
|
150
|
+
- `grade-paper-writing` β the batch readability gate; this is its continuous counterpart. That one
|
|
151
|
+
produces a stall inventory over the whole paper; this one asks whether the last edit means anything.
|
|
152
|
+
- `tighten-paper` β structural cuts. Note the interaction: a tighten pass that pays for an addition
|
|
153
|
+
by shortening sentences elsewhere is precisely what generates work for this skill.
|
|
154
|
+
- `paper-pipeline` β owns the text-pass / evidence-pass split; this belongs to the text pass.
|
|
155
|
+
|
|
156
|
+
## Provenance
|
|
157
|
+
|
|
158
|
+
Built 2026-08-05, the day before the `the reference paper` deadline, after the corpus owner read the built PDF and
|
|
159
|
+
found eleven unreadable passages in twenty minutes β none of which any automated check had flagged,
|
|
160
|
+
and several of which had been introduced that same morning by fixes to other automated checks.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Compiled to SKILL.md by `vigiles compile`. Edit THIS file, never the markdown.
|
|
2
|
+
//
|
|
3
|
+
// Adopted 2026-08-17. Body VERBATIM from the previous SKILL.md. This is the only one
|
|
4
|
+
// of the batch that runs FORKED β `context: "fork"` is what gives a skill a real
|
|
5
|
+
// callβreturn boundary, so it is carried explicitly rather than dropped.
|
|
6
|
+
import { experimental_skill } from "vigiles/spec";
|
|
7
|
+
|
|
8
|
+
export default experimental_skill({
|
|
9
|
+
name: "cold-read-diff",
|
|
10
|
+
description:
|
|
11
|
+
"Send just-changed paper prose to a reader with NO context and ask what each sentence claims β the only check that catches a sentence which is short, true, jargon-free and still meaningless to anyone who does not already know the idea. Run after every prose edit to a paper, before calling the edit done, and before reporting a section as fixed. Scoped to the diff, so it is cheap enough to run every time. Not a writing grade (grade-paper-writing), not a structural pass (tighten-paper), not a defect review.",
|
|
12
|
+
context: "fork",
|
|
13
|
+
tools: ["Bash", "Read", "Agent"],
|
|
14
|
+
body: `
|
|
15
|
+
# cold-read-diff β the reader who cannot fake understanding
|
|
16
|
+
|
|
17
|
+
## Run me
|
|
18
|
+
|
|
19
|
+
π΄ FIRST, before any other step:
|
|
20
|
+
|
|
21
|
+
\`\`\`
|
|
22
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs cold-read-diff <paper-dir>
|
|
23
|
+
\`\`\`
|
|
24
|
+
|
|
25
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
26
|
+
state β so starting is an event, and events get written down.
|
|
27
|
+
|
|
28
|
+
## The failure this exists for
|
|
29
|
+
|
|
30
|
+
On 2026-08-05 the author of \`the reference paper\` found eleven unreadable passages by eye, in a paper
|
|
31
|
+
that had passed six writing grades, four structural passes and five review panels. Every one of them
|
|
32
|
+
was short, factually correct, free of every word on the jargon list, and inside every mechanical
|
|
33
|
+
threshold. Samples, with his reactions:
|
|
34
|
+
|
|
35
|
+
> *"The state to remove is therefore not the rule but its claim about itself"* β **Β«wtfΒ»**
|
|
36
|
+
> *"these files are filled with constructions nobody built"* β **Β«wtfΒ»**
|
|
37
|
+
> *"Three answers, all of them after the fact"* β **Β«VAGUE AFΒ»**
|
|
38
|
+
> *"Both numbers carry a caveatβ¦"* β **Β«WTF.Β»**
|
|
39
|
+
|
|
40
|
+
They share one property: **they parse only for a reader who already holds the idea.** That is not a
|
|
41
|
+
style defect and no metric can see it. Sentence length, number density, hedge share, tic frequency β
|
|
42
|
+
all green on every one of these.
|
|
43
|
+
|
|
44
|
+
## Why the existing pipeline could not catch it
|
|
45
|
+
|
|
46
|
+
Every reader in it knows too much or cannot read at all:
|
|
47
|
+
|
|
48
|
+
| reader | holds the idea? | can judge meaning? |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| the author | maximally β that is the curse of knowledge | yes |
|
|
51
|
+
| the persona subagent | **yes: it is handed the paper and the framing** | yes |
|
|
52
|
+
| the review panel | yes | yes |
|
|
53
|
+
| \`prose-lint\` | no | **no β it counts patterns** |
|
|
54
|
+
|
|
55
|
+
The gap between "knows too much" and "cannot read" is exactly where these sentences live. Closing it
|
|
56
|
+
needs a reader who is competent and **structurally uninformed**, and the only way to guarantee that
|
|
57
|
+
is to withhold the context rather than ask them to ignore it.
|
|
58
|
+
|
|
59
|
+
## Why the DIFF, and not the paper
|
|
60
|
+
|
|
61
|
+
A full cold read costs a long agent run, so it gets run once a day, which means prose written after
|
|
62
|
+
it ships unread. Scoped to the changed paragraphs it costs a couple of minutes, so it runs every
|
|
63
|
+
time β and coverage beats depth here, because the defect is per-sentence.
|
|
64
|
+
|
|
65
|
+
Scoping also makes the check honest. Hand an agent the whole paper and it reconstructs the idea from
|
|
66
|
+
the surrounding text, then reports that the sentence is clear. Hand it three paragraphs and there is
|
|
67
|
+
nothing to reconstruct from: if the sentence does not carry its own meaning, the agent cannot invent
|
|
68
|
+
one, and its confusion is the finding.
|
|
69
|
+
|
|
70
|
+
## How to run it
|
|
71
|
+
|
|
72
|
+
1. **Take the diff.** \`git diff -U0 -- <paper.md>\` since the last commit, or the \`new_string\` of the
|
|
73
|
+
edits just applied. Prose only β skip comments, tables, bibliography.
|
|
74
|
+
2. **Spawn ONE agent with no repository context.** Give it the changed paragraphs **as text in the
|
|
75
|
+
prompt**, not as a file path. A path is an invitation to read the neighbours, and reading the
|
|
76
|
+
neighbours is how the check fails silently. \`sonnet\` is the right model: competent, cheap,
|
|
77
|
+
and not the one that wrote the sentence.
|
|
78
|
+
3. **Ask exactly two questions per sentence:**
|
|
79
|
+
- *What does this sentence claim? Restate it in your own words.* If restating requires guessing,
|
|
80
|
+
the answer is \`CANNOT PARSE\` plus what stopped them β an undefined term, a pronoun with no
|
|
81
|
+
referent, a number with no denominator, two clauses that do not connect.
|
|
82
|
+
- *Would a reader who stops here understand it?* Yes / No / Only-if-they-know-X.
|
|
83
|
+
4. **Ask for the dangerous class explicitly:** *which sentences sound clever but say less than they
|
|
84
|
+
appear to?* Those read fine and carry nothing, and they are the ones a knowing reader waves
|
|
85
|
+
through.
|
|
86
|
+
5. **Apply the fixes β as rewrites of the whole thought, never as excisions.** See the rule below.
|
|
87
|
+
6. **Re-run on the fix.** An edit is not done until the same kind of reader parses the replacement.
|
|
88
|
+
One confirming round; do not loop past it.
|
|
89
|
+
|
|
90
|
+
## π΄ Hand the reader WHOLE PARAGRAPHS, never \`+\` lines
|
|
91
|
+
|
|
92
|
+
Measured on 2026-08-05, first machine run of this skill: about a third of the reader's stalls were
|
|
93
|
+
artefacts of the extract, not defects in the paper β *"\`it\` has no referent"*, *"this sentence is cut
|
|
94
|
+
off mid-clause"*, *"those populations have no antecedent"*. The neighbouring sentences simply had not
|
|
95
|
+
changed, so they were not in the diff.
|
|
96
|
+
|
|
97
|
+
Two more things the same run proved:
|
|
98
|
+
|
|
99
|
+
- **Expand build-time macros first.** The reader saw seven raw \`{{placeholders}}\` and correctly
|
|
100
|
+
reported that every headline number was missing. That is a true statement about the extract and a
|
|
101
|
+
false one about the paper.
|
|
102
|
+
- **Strip working comments.** He graded \`<!-- JUSTIFY β¦ -->\` notes as prose because he could not tell
|
|
103
|
+
them apart β and said so, which is itself a finding about the extract.
|
|
104
|
+
|
|
105
|
+
**So:** take the changed lines, then widen each to its enclosing paragraph, expand macros, drop
|
|
106
|
+
comments, and hand the reader continuous prose. The findings that survive that are worth the run; the
|
|
107
|
+
ones that do not are noise, and noise is how this check gets muted.
|
|
108
|
+
|
|
109
|
+
## Record the verdict
|
|
110
|
+
|
|
111
|
+
π΄ LAST step, once the deliverable exists:
|
|
112
|
+
|
|
113
|
+
\`\`\`
|
|
114
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> FINDING <count> <report-path>
|
|
115
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> ABSTAINED <reason> "<one line>"
|
|
116
|
+
\`\`\`
|
|
117
|
+
|
|
118
|
+
**FINDING** β \`<count>\` is the number of changed sentences the cold reader could not restate (every
|
|
119
|
+
\`CANNOT PARSE\` counts), \`<report-path>\` is the \`reviews/*cold-read*.md\` file.
|
|
120
|
+
**ABSTAINED** β \`no-witness\`: every changed sentence came back restated correctly.
|
|
121
|
+
\`input-missing\`: the diff held no prose to read.
|
|
122
|
+
|
|
123
|
+
π΄ These two are different answers and the difference is the whole reason the vocabulary is closed:
|
|
124
|
+
one says a reader read it and found nothing, the other says there was nothing to hand a reader.
|
|
125
|
+
Prose collapses them and the old \`PASS\`/\`ABSENT\` pair only half-separated them, because \`PASS\` also
|
|
126
|
+
got recorded when nobody had run a reader at all. There is no \`PASS\` now; the reason is the answer.
|
|
127
|
+
|
|
128
|
+
## Rules
|
|
129
|
+
|
|
130
|
+
- π΄ **No context in the prompt. Ever.** Not the title, not the abstract, not "this is a paper about
|
|
131
|
+
agent rules files". Every sentence of background handed to the reader is a sentence of confusion
|
|
132
|
+
they will no longer report.
|
|
133
|
+
- π΄ **A fix that removes the flagged construction and keeps the compression is not a fix.** Proven
|
|
134
|
+
twice in one hour: *"not through any defect in how we write it, but because that is what English
|
|
135
|
+
is"* β *"that is what English is for"* (tic gone, meaning inverted into nonsense); *"the agent
|
|
136
|
+
turns out not to be the weak link"* β *"The agent obeys"* (three words, zero flags, wrong finding).
|
|
137
|
+
Rewrite the **thought** in plain words. The tic is usually a symptom of a compressed idea, and
|
|
138
|
+
decompressing removes it as a side effect.
|
|
139
|
+
- **Length is not the constraint here β meaning is.** If plain language needs more words, take them
|
|
140
|
+
and pay from an appendix, which is outside the page limit. Paying by shortening another sentence
|
|
141
|
+
is what created the problem.
|
|
142
|
+
- **\`CANNOT PARSE\` is a result, not a failure of the reader.** Never argue with it. The author's
|
|
143
|
+
ability to understand his own sentence is not evidence about anyone else's.
|
|
144
|
+
- **Run it on your own fixes too.** The author is the least qualified judge of whether his repair
|
|
145
|
+
reads, and that is exactly when he feels most certain.
|
|
146
|
+
|
|
147
|
+
## Enforcement
|
|
148
|
+
|
|
149
|
+
\`pipeline-check.mjs\` raises \`stale-cold-read\` when the newest \`reviews/*cold-read*.md\` is older than
|
|
150
|
+
the paper source, and \`no-cold-read\` when none exists. The date comparison is the whole mechanism:
|
|
151
|
+
a cold read that predates the current text describes prose that no longer exists.
|
|
152
|
+
|
|
153
|
+
## Compose with
|
|
154
|
+
|
|
155
|
+
- \`grade-paper-writing\` β the batch readability gate; this is its continuous counterpart. That one
|
|
156
|
+
produces a stall inventory over the whole paper; this one asks whether the last edit means anything.
|
|
157
|
+
- \`tighten-paper\` β structural cuts. Note the interaction: a tighten pass that pays for an addition
|
|
158
|
+
by shortening sentences elsewhere is precisely what generates work for this skill.
|
|
159
|
+
- \`paper-pipeline\` β owns the text-pass / evidence-pass split; this belongs to the text pass.
|
|
160
|
+
|
|
161
|
+
## Provenance
|
|
162
|
+
|
|
163
|
+
Built 2026-08-05, the day before the \`the reference paper\` deadline, after the corpus owner read the built PDF and
|
|
164
|
+
found eleven unreadable passages in twenty minutes β none of which any automated check had flagged,
|
|
165
|
+
and several of which had been introduced that same morning by fixes to other automated checks.`,
|
|
166
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cold-read-diff β the PAID tier: does this skill's description actually fire?
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE (vigiles decides coverage by placement as of 2026-08-11).
|
|
5
|
+
* The prompts live in `.claude/lib/skill-trigger-cases.mjs` so all 21 cases
|
|
6
|
+
* are reviewed as one table where collisions between siblings are visible;
|
|
7
|
+
* copying them here would recreate the drift that rule exists to prevent.
|
|
8
|
+
*
|
|
9
|
+
* Measures recall (fires on its own territory) AND precision (stays quiet on a
|
|
10
|
+
* colliding sibling's territory), against the REAL `.claude` harness so the skill
|
|
11
|
+
* competes with every other installed description β an isolated run overstates
|
|
12
|
+
* recall and understates false positives.
|
|
13
|
+
*
|
|
14
|
+
* Costs money; not CI.
|
|
15
|
+
* node .claude/skills/cold-read-diff/cold-read-diff.eval.mjs [trials]
|
|
16
|
+
*/
|
|
17
|
+
import { runSkillTriggerEval } from "../../lib/skill-eval-kit.mjs";
|
|
18
|
+
|
|
19
|
+
await runSkillTriggerEval("cold-read-diff");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cold-read-diff β the free, deterministic tier. No model, no network.
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE. vigiles decides coverage by PLACEMENT as of 2026-08-11:
|
|
5
|
+
* a test that merely names a surface no longer counts, because that tier was
|
|
6
|
+
* crediting surfaces nothing touched. So each skill needs a file inside its own
|
|
7
|
+
* directory β this one.
|
|
8
|
+
*
|
|
9
|
+
* The assertions live in `.claude/lib/skill-checks.mjs` and are CALLED here with
|
|
10
|
+
* this skill's name. They are not copied: 22 copies of the same checks is the drift that
|
|
11
|
+
* module exists to avoid. (Until 2026-08-11 this was an env-var side channel into a
|
|
12
|
+
* 614-line file named after no surface; it is a function call now.)
|
|
13
|
+
*
|
|
14
|
+
* What this proves: this skill's frontmatter parses as strict YAML, its declared
|
|
15
|
+
* tool contract is sane, its pipeline wiring points at scripts that exist, and it
|
|
16
|
+
* announces/records under ITS OWN identity rather than a sibling's.
|
|
17
|
+
*
|
|
18
|
+
* What it does NOT prove: that the skill fires, or that its guidance produces a
|
|
19
|
+
* good result. Those need a real model β see `cold-read-diff.eval.mjs`.
|
|
20
|
+
*/
|
|
21
|
+
import { checkSkill } from "../../lib/skill-checks.mjs";
|
|
22
|
+
|
|
23
|
+
await checkSkill("cold-read-diff");
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: draft-paper
|
|
3
|
+
description: Use when the numbers exist and it's time to WRITE the paper β "draft the paper", "turn these findings into a submission", "write the abstract/intro/threats". Gives the section skeleton of a measurement/benchmark paper plus what gets it accepted AND cited β precise claim-sizing (including an explicit "what we do NOT claim"), a construct-validity frame, an honest threats-to-validity section that turns limitations in your favor, and one memorable stat that travels. Encodes the two theses that carried real measurement papers ("measuring the wrong number", "safety theater"). NOT for grading finished prose (grade-paper-writing) or structural editing (tighten-paper) β this is the generative counterpart. Compose with build-benchmark (numbers), grade-paper-writing (prose QA), render-paper, verify-citations, then the review skills.
|
|
4
|
+
allowed-tools: [Read, Write, Edit, Grep, Glob, Agent, Skill, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- vigiles:sha256:1b6a7bdc0ea402ec compiled from skills/draft-paper/SKILL.md.spec.ts -->
|
|
8
|
+
|
|
9
|
+
# draft-paper β prose that survives review and gets cited
|
|
10
|
+
|
|
11
|
+
## Run me
|
|
12
|
+
|
|
13
|
+
π΄ FIRST, before any other step:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs draft-paper <paper-dir>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
20
|
+
state β so starting is an event, and events get written down.
|
|
21
|
+
|
|
22
|
+
A measurement paper lives or dies on two things reviewers actually reward: a **reusable method/norm**
|
|
23
|
+
they can apply to the next system, and **claim-sizing so precise it can't be attacked**. Numbers alone
|
|
24
|
+
are a blog post. This skill turns `build-benchmark`'s output into that kind of draft.
|
|
25
|
+
|
|
26
|
+
The bar is not "is the result true" β it's "will a stranger cite this in two years." That happens when
|
|
27
|
+
you gave them a *way to measure something* or a *bound they can quote*, not a verdict on one tool.
|
|
28
|
+
|
|
29
|
+
## Section skeleton (measurement/benchmark paper)
|
|
30
|
+
Write in this order; it's also roughly the read order a reviewer skims.
|
|
31
|
+
|
|
32
|
+
π΄ **Decide body vs appendix as you write, not when the page limit forces it** β
|
|
33
|
+
`paper-pipeline/references/body-vs-appendix.md`. A page limit with no rule behind it evicts whatever
|
|
34
|
+
was written last, which is reliably the honest qualification nobody had room for. The rule in one
|
|
35
|
+
line: the body carries everything a reviewer's decision depends on, and **a bound that narrows a
|
|
36
|
+
number in the body stays in the body**.
|
|
37
|
+
|
|
38
|
+
1. **Abstract** β the ONE contribution, sized. Problem β the method/insight β the single headline
|
|
39
|
+
number β what it means. Tight (see "Scope the abstract" below).
|
|
40
|
+
2. **Introduction + contributions** β the gap (what everyone measures / assumes today and why it's
|
|
41
|
+
wrong or unmeasured), then a bulleted **contributions** list. Each contribution is a *thing you
|
|
42
|
+
built or established* (a method, a benchmark, a bound, a norm), not "we ran experiments."
|
|
43
|
+
3. **Background + threat model** (security) / **Setup** (non-security) β define terms, the system under
|
|
44
|
+
study, and β for security β the explicit threat model (attacker goals/capabilities/knowledge). A
|
|
45
|
+
fuzzy threat model is the fastest reject at a security venue.
|
|
46
|
+
4. **Method** β the reusable core. How the measurement/benchmark is *constructed* so someone else can
|
|
47
|
+
run it on a different target. This is the part that gets cited; give it the most care.
|
|
48
|
+
5. **Results** β the numbers from `build-benchmark`, each tied to a claim. Report ranges/CIs, not
|
|
49
|
+
rounded maxes. One figure or table carries the paper β make it legible standalone.
|
|
50
|
+
6. **Threats to validity** β construct / internal / external, honestly (see below). This section is a
|
|
51
|
+
trust signal, not a confession.
|
|
52
|
+
7. **Related work** β position against the *nearest* neighbor explicitly ("X measures A; we measure B
|
|
53
|
+
because A is the wrong number"). Credit generously; that's where the framing lands.
|
|
54
|
+
8. **Ethics** (security papers) β responsible disclosure, who could be harmed, punching-down check.
|
|
55
|
+
Point to `paper-pipeline/references/anonymization.md` before naming any real system/maintainer.
|
|
56
|
+
9. **Conclusion** β restate the method and the one insight; no new claims.
|
|
57
|
+
10. **Availability** β the anonymized artifact link (see `submit-paper`). Reviewers reward a runnable
|
|
58
|
+
artifact more than another paragraph.
|
|
59
|
+
|
|
60
|
+
## What makes it ACCEPTED and CITED
|
|
61
|
+
- **A reusable method/norm over a one-off result.** "Tool Y scores 40%" dies; "here's how to measure
|
|
62
|
+
Z, and by it Y scores 40%" survives, because the method outlives Y. Frame every result as an instance
|
|
63
|
+
of a general procedure.
|
|
64
|
+
- **A crisp, generalizable bound or insight** the reader can quote without your paper open β one
|
|
65
|
+
sentence they'll paraphrase back to you in review. That sentence is the abstract's spine.
|
|
66
|
+
- **Precise claim-sizing.** Say exactly how big the claim is and no bigger. Include an explicit
|
|
67
|
+
**"What we do NOT claim"** paragraph β it pre-empts Reviewer 2's whole attack surface and reads as
|
|
68
|
+
rigor, not weakness. (Both real papers have one; it's the highest-leverage paragraph in the draft.)
|
|
69
|
+
- **A construct-validity frame.** State plainly what quantity you're measuring and why it's the *right*
|
|
70
|
+
quantity β "measuring the wrong number" only works if you've defined the right one. Make the mapping
|
|
71
|
+
from concept β metric explicit; that's what separates a benchmark from a leaderboard.
|
|
72
|
+
- **An honest threats section that turns limitations in your favor.** Every limitation you name first,
|
|
73
|
+
bounded, is one a reviewer can't wield against you. "N is small, so we claim a lower bound not a
|
|
74
|
+
point estimate" converts a weakness into a scoped claim. Don't hide; scope.
|
|
75
|
+
- **One memorable stat or figure that travels.** Pick the single number/image that survives out of
|
|
76
|
+
context (a tweet, a related-work sentence in someone else's paper). Everything else supports it.
|
|
77
|
+
- **Credit-the-humans tone.** Dunk on the *claim or the metric*, never the authors. "The field measures
|
|
78
|
+
X; X is the wrong number" β not "prior work is naive." Punching down reads as insecurity and invites
|
|
79
|
+
a hostile review; generous framing invites a citation.
|
|
80
|
+
|
|
81
|
+
## Scope the abstract tightly
|
|
82
|
+
The abstract sells ONE contribution and ONE headline number. Do **not** cram every hedged sub-result β
|
|
83
|
+
each extra qualified number dilutes the one that matters and invites nitpicks before the reviewer
|
|
84
|
+
reaches the method. Hedge in Results/Threats, not the abstract. If you can't say the contribution in one
|
|
85
|
+
sentence, you haven't found it yet β go back to the method. Structure it against the five-move template
|
|
86
|
+
(context β gap β approach β one number β so-what) in `../paper-pipeline/references/writing-craft.md`, which
|
|
87
|
+
also holds the craft rules and the writing rubric `grade-paper-writing` grades against β write toward the
|
|
88
|
+
grade.
|
|
89
|
+
|
|
90
|
+
## Run the prose through the PAPER suite's QA (do not skip β and do not use the blog skills)
|
|
91
|
+
Before any review pass, run the draft through the paper-side prose QA β it catches what a self-read won't:
|
|
92
|
+
- **`grade-paper-writing`** β the 9-dim rubric + the PERSONA cold-read stall pass (a committed
|
|
93
|
+
non-academic persona, per-section β the localized "wait, what does that even mean?" axis authors are
|
|
94
|
+
blind to). Its avoid-list grep also strips the AI-writing tropes (hedge-stacking, "it's worth
|
|
95
|
+
noting", limp connectives, fake balance) that make a draft read unserious to a human PC.
|
|
96
|
+
- **`../paper-pipeline/references/writing-craft.md`** β write toward the rubric; its
|
|
97
|
+
register-calibration buckets decide which jargon to keep / gloss / rename for the venue's actual reader.
|
|
98
|
+
|
|
99
|
+
**Boundary:** the site repo's `writing-quality` + `audience-test` skills are for **blog posts only**.
|
|
100
|
+
For papers they duplicate β and are superseded by β `grade-paper-writing` + writing-craft's persona
|
|
101
|
+
pass (the blog skills lack the persona fix, so they under-fire on paper prose). Never route paper
|
|
102
|
+
prose QA to them.
|
|
103
|
+
|
|
104
|
+
## Record the verdict
|
|
105
|
+
|
|
106
|
+
π΄ LAST step, once the deliverable exists:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> FINDING <count> <report-path>
|
|
110
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> ABSTAINED <reason> "<one line>"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This skill generates rather than judges, so what it records is about the run, not about the paper.
|
|
114
|
+
|
|
115
|
+
**FINDING** β it declined to draft because a required input was missing: no numbers from
|
|
116
|
+
`build-benchmark`, or an empty `frame` paragraph from `argument-arc`. `--blocking`, always, because
|
|
117
|
+
drafting past it produces prose about numbers that do not exist.
|
|
118
|
+
**ABSTAINED** β `no-witness`: sections were written and the generator has nothing to report about
|
|
119
|
+
the paper. Put the drafted sections in the note; they are the deliverable, not evidence of a defect.
|
|
120
|
+
|
|
121
|
+
π΄ **Design smell, stated plainly: this gate will almost always record an abstention**, and
|
|
122
|
+
`status.mjs` will flag it as one that has never returned a finding. Leave the flag standing β it is
|
|
123
|
+
telling the truth. A generator is not a gate, and the only honest negative it can produce is the
|
|
124
|
+
refusal above. If a run ever ends with prose written from numbers that do not exist, that is a
|
|
125
|
+
`FINDING --blocking` and must be recorded as one rather than quietly upgraded.
|
|
126
|
+
|
|
127
|
+
π΄ Deleting `PASS` did not fix this skill and was never going to: the old vocabulary let it write
|
|
128
|
+
down "I produced sections" as though that were an answer about the manuscript, and the new one
|
|
129
|
+
simply refuses to. The generator is still not a gate. `draft-paper/population-map` β a real check β
|
|
130
|
+
is the row that can say no about this skill's output.
|
|
131
|
+
|
|
132
|
+
## Compose with
|
|
133
|
+
- **`build-benchmark`** β its numbers/CIs are the Results section's raw material; never hand-type a
|
|
134
|
+
number that isn't in its output (that's how paperβartifact mismatches get born).
|
|
135
|
+
- **`grade-paper-writing`** (+ `../paper-pipeline/references/writing-craft.md`) β the paper-side prose
|
|
136
|
+
QA, above. (Site-repo `writing-quality` / `audience-test` = blog posts only.)
|
|
137
|
+
- **`render-paper`** β compile + eyeball pages 1β2 once prose is in.
|
|
138
|
+
- **`verify-citations`** β every cite in Related Work must exist AND say what you claim.
|
|
139
|
+
- Then the review loop: **`paper-adversarial-review`** β **`pc-panel-review`** (venue-fit mode for a
|
|
140
|
+
quick fit score, then the full panel as the gate).
|
|
141
|
+
|
|
142
|
+
## Provenance (two real papers)
|
|
143
|
+
- **AgenticDev 2026 @ ASE β "Measuring the Wrong Number."** The thesis IS the construct-validity frame:
|
|
144
|
+
the field optimizes a metric that isn't the thing anyone cares about. The method (how to measure the
|
|
145
|
+
*right* number) is the contribution; the tool verdict is just the demonstration. Its "what we do NOT
|
|
146
|
+
claim" paragraph and lower-bound-not-point-estimate threats framing are what moved it through review.
|
|
147
|
+
- **AISec 2026 @ ACM CCS β "Safety Theater."** A security-venue measurement paper: a defense that
|
|
148
|
+
*looks* like safety without measurably being it. Needs the explicit threat model + ethics/disclosure
|
|
149
|
+
sections above, and dunks on the *defense pattern*, never the maintainers who shipped it β the
|
|
150
|
+
credit-the-humans rule is load-bearing at a top-tier security venue where a hostile framing draws a
|
|
151
|
+
hostile review. Both papers win on precise claim-sizing and an honest threats section, not on the
|
|
152
|
+
size of the effect.
|