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,345 @@
|
|
|
1
|
+
// Compiled to SKILL.md by `vigiles compile`. Edit THIS file, never the markdown.
|
|
2
|
+
//
|
|
3
|
+
// Adopted 2026-08-17 (batch 3). Body carried over VERBATIM so the compiled diff shows
|
|
4
|
+
// only what the compiler adds. No `disallowedTools` fence yet — the field landed on
|
|
5
|
+
// `SkillSpec` in vigiles branch `claude/skill-disallowed-tools` and is not in a release
|
|
6
|
+
// this repo installs, so writing one here would not compile.
|
|
7
|
+
import { experimental_skill } from "vigiles/spec";
|
|
8
|
+
|
|
9
|
+
export default experimental_skill({
|
|
10
|
+
name: "verify-citations",
|
|
11
|
+
description:
|
|
12
|
+
"Verify every citation is a real work with correct metadata, and that the paper states its delta over the NEAREST prior work explicitly — before submit. For each \\cite, confirm the work exists (arXiv id / DOI / venue+year) and that author/title/venue/year are right (WebSearch/WebFetch); never fabricate — mark VERIFY on anything uncertain and flag invented-looking cites; make sure the paper says what it adds over its closest neighbor, and that the one obviously-expected citation a reviewer will miss if absent is present. Use as a pre-submission gate. Compose with draft-paper, map-prior-work, pc-panel-review.",
|
|
13
|
+
tools: [
|
|
14
|
+
"Read",
|
|
15
|
+
"Write",
|
|
16
|
+
"Edit",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Glob",
|
|
19
|
+
"Bash",
|
|
20
|
+
"WebSearch",
|
|
21
|
+
"WebFetch",
|
|
22
|
+
"Agent",
|
|
23
|
+
],
|
|
24
|
+
body: `
|
|
25
|
+
# verify-citations — every cite real, the delta explicit
|
|
26
|
+
|
|
27
|
+
## Run me
|
|
28
|
+
|
|
29
|
+
🔴 FIRST, before any other step:
|
|
30
|
+
|
|
31
|
+
\`\`\`
|
|
32
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs verify-citations <paper-dir>
|
|
33
|
+
\`\`\`
|
|
34
|
+
|
|
35
|
+
An advisory pass cannot be observed failing — silence is both its error state and its normal
|
|
36
|
+
state — so starting is an event, and events get written down.
|
|
37
|
+
|
|
38
|
+
Reviewers reject on a single fabricated or wrong citation — it reads as either sloppiness or a
|
|
39
|
+
hallucinated bibliography, and either one is fatal. And they reject on "this was already done by ___" if
|
|
40
|
+
your delta over the nearest prior work isn't spelled out. This skill closes both holes before submit.
|
|
41
|
+
|
|
42
|
+
## 🔴 This is a CONTINUOUS check, not a step you finish
|
|
43
|
+
|
|
44
|
+
**It re-runs whenever a \`\\cite\` is added or moved.** Not once, not "at the end" — every time the
|
|
45
|
+
bibliography changes, including the edit you make on the last day. Scorecard row **\`cites\`** in
|
|
46
|
+
\`<paper-dir>/PIPELINE-STATUS.md\`; see the CONTINUOUS section of \`paper-pipeline\`.
|
|
47
|
+
|
|
48
|
+
- **A pass dated before the current text is STALE, and stale reads as green.** The date in the \`cites\`
|
|
49
|
+
row is compared against the paper's own mtime, and \`../paper-pipeline/scripts/pipeline-check.mjs\` reports the
|
|
50
|
+
mismatch — because a \`☑\` from three days and forty edits ago is worse than a \`☐\`: it looks closed.
|
|
51
|
+
- **"We checked last cycle" does not count.** Say it plainly, because it is the exact sentence that
|
|
52
|
+
ships a fabricated cite: a review round adds text, added text adds citations, and the run that
|
|
53
|
+
cleared the bibliography never saw them.
|
|
54
|
+
- A single new \`\\cite\` is enough to fire it. There is no batch size below which this is skippable.
|
|
55
|
+
|
|
56
|
+
*This skill used to sit at a number in the middle of a stage list, which made it read like a one-shot
|
|
57
|
+
step you tick off and move past — one of the three concrete errors that numbering produced, and the
|
|
58
|
+
reason the list was replaced on 2026-08-03. The project rule was always that it re-runs every cycle;
|
|
59
|
+
the position contradicted the rule, and the position is what people followed.*
|
|
60
|
+
|
|
61
|
+
## 1. Every \\cite is a real work with correct metadata
|
|
62
|
+
|
|
63
|
+
For EACH reference in the \`.bib\` / bibliography:
|
|
64
|
+
|
|
65
|
+
- **Confirm it exists.** A real **arXiv id**, **DOI**, or **venue + year** that resolves. WebSearch the
|
|
66
|
+
exact title + first author; WebFetch the landing page. "I'm fairly sure this paper exists" is not
|
|
67
|
+
verification.
|
|
68
|
+
- **Confirm the metadata is right** — author list, exact title, venue, year. LLM-drafted bibs love to
|
|
69
|
+
merge two papers, shift a year, or attach the wrong venue to a real title. Check each field.
|
|
70
|
+
- **Confirm it says what you attribute to it.** If you cite a number or claim, open the source and check
|
|
71
|
+
the number is actually in it — cite the source's real range, not a rounded max.
|
|
72
|
+
- **Never invent a citation to fill a gap.** If a claim needs support you don't have, either find real
|
|
73
|
+
support or soften the claim. Do not manufacture a plausible-looking cite.
|
|
74
|
+
|
|
75
|
+
## 2. Mark uncertainty, flag the invented-looking
|
|
76
|
+
|
|
77
|
+
- Anything you couldn't fully confirm → mark **\`% VERIFY\`** in the \`.tex\` at the cite site and resolve it
|
|
78
|
+
before submit. A VERIFY that survives to submission is a bug.
|
|
79
|
+
- **Flag invented-looking cites explicitly** — a too-perfectly-on-topic title, an author+venue combo that
|
|
80
|
+
doesn't turn up, a DOI that 404s. These are the ones that sink the paper; treat a non-resolving cite as
|
|
81
|
+
guilty until proven real.
|
|
82
|
+
- Archive the verified set (id/DOI + one-line "confirms X") so it's reusable across papers in the area.
|
|
83
|
+
|
|
84
|
+
## 3. The delta over the NEAREST prior work must be explicit
|
|
85
|
+
|
|
86
|
+
The most common substantive reject is "this was already done by ___." Defend against it in the prose,
|
|
87
|
+
not just the bibliography:
|
|
88
|
+
|
|
89
|
+
- Identify the **single closest** prior work and state, in one sentence a reviewer can quote, what THIS
|
|
90
|
+
paper adds that it didn't do. Nearest-neighbor, not a vague "unlike prior work."
|
|
91
|
+
- If the nearest work made the *argument* and you supply the *measurement* (or vice versa), say exactly
|
|
92
|
+
that — the delta is the contribution.
|
|
93
|
+
|
|
94
|
+
## 4. The one obviously-expected citation
|
|
95
|
+
|
|
96
|
+
Every subfield has a paper a reviewer expects to see; its absence reads as "the authors don't know the
|
|
97
|
+
area." Ask: what is the one work a reviewer in this exact niche will look for first? Make sure it's cited
|
|
98
|
+
and positioned. If you genuinely shouldn't cite it, know why.
|
|
99
|
+
|
|
100
|
+
## 5. The deterministic reducer — \`scripts/verify-cites.mjs\`
|
|
101
|
+
|
|
102
|
+
Sections 1–4 are LLM judgment: good for the *delta* and the *expected-citation* calls, but non-reproducible
|
|
103
|
+
for the mechanical part — "does this id actually resolve?". \`scripts/verify-cites.mjs\` compiles that part into
|
|
104
|
+
a deterministic, cacheable gate (same "prose isn't policy → make it a self-checking artifact" move as
|
|
105
|
+
\`build-benchmark\`). Ported fresh (own code) from the OSS mining note
|
|
106
|
+
\`papers/research/oss-skill-mining-imbad0202.md\` (STEAL #1) + the CVE/PoC-SHA pinning from
|
|
107
|
+
\`oss-skill-mining-euzun.md\`.
|
|
108
|
+
|
|
109
|
+
**What it does.** For each citation it hits four real databases — Crossref, OpenAlex, Semantic Scholar,
|
|
110
|
+
arXiv — DOI/arXiv-id first, then a title search. Title comparison is **robust**, not raw Levenshtein: it
|
|
111
|
+
also does token-set containment + acronym expansion, so a split subtitle ("Gotta Catch 'Em All" vs the
|
|
112
|
+
subtitled full title), an abbreviation ("Deep CNNs" ↔ "Deep Convolutional Neural Networks"), or a
|
|
113
|
+
preprint→published title drift does **not** read as an unrelated paper. Normalization preserves Unicode
|
|
114
|
+
letters, so two *different* non-Latin titles no longer collapse to the same empty string. A title search
|
|
115
|
+
match still needs year within ±1. A \`CVE-YYYY-NNNNN\` is checked against NVD; a PoC/exploit \`commit\` is
|
|
116
|
+
checked for **exactly** 40 hex chars (short / >40 / malformed → advisory flag, not a verdict).
|
|
117
|
+
|
|
118
|
+
**The DOI-authority gate (M1 — why a 404 is never fabrication).** A 404 from a *content registry*
|
|
119
|
+
(Crossref / OpenAlex / Semantic Scholar) means only "this registry has no metadata," which is the **common
|
|
120
|
+
case** for DataCite/Zenodo DOIs and freshly-minted 2026 DOIs (including a paper's own artifact DOI). It is
|
|
121
|
+
**not** disproof of existence. So before ever emitting \`false\` for a DOI, the reducer requires the DOI
|
|
122
|
+
*authority* — \`doi.org/api/handles/{doi}\` — to say the handle does not exist (\`responseCode 100\`). A DOI
|
|
123
|
+
that resolves at doi.org but has no registry metadata → \`unresolvable\` (exists, metadata unverifiable),
|
|
124
|
+
never \`false\`. For arXiv ids, only a definitive not-found from the *reachable arXiv API itself* is disproof
|
|
125
|
+
(a Semantic-Scholar miss on a fresh arXiv id is not); arXiv's "Error" sentinel entry is detected as
|
|
126
|
+
not-found, not mistaken for an unrelated paper.
|
|
127
|
+
|
|
128
|
+
**The narrowed-false rule (the important part).** The reducer collapses evidence to three verdicts:
|
|
129
|
+
|
|
130
|
+
| verdict | when | meaning |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| \`true\` | any resolver **matched** (match always wins) | found, metadata matches |
|
|
133
|
+
| \`false\` | no match **and** an *authoritative* disproof: doi.org says the DOI is \`responseCode 100\`, the reachable arXiv API definitively rejects the id, NVD has no such CVE, **or** a DOI/arXiv id resolves to a *confidently-different* paper (\`DOI_MISMATCH\`) | fabrication — the only thing we call fabrication |
|
|
134
|
+
| \`unresolvable\` | title-misses, registry-404s with no authority disproof, uncomparable titles, and/or unreachable resolvers | couldn't verify, but **no positive disproof** |
|
|
135
|
+
|
|
136
|
+
The whole point: **a title you simply can't find is NOT fabrication** → \`unresolvable\`, never \`false\`. A
|
|
137
|
+
real-but-unindexed / regional / pre-digital paper looks exactly like a title-miss; a registry-404 without a
|
|
138
|
+
doi.org not-found looks exactly like a DataCite DOI; a network outage looks like neither — all degrade to
|
|
139
|
+
\`unresolvable\`. The reducer never turns a transport failure or a registry-404 into \`false\`. Fabrication
|
|
140
|
+
requires *positive* disproof from the relevant **authority**, or a DOI pointing at a confidently-different
|
|
141
|
+
paper.
|
|
142
|
+
|
|
143
|
+
**How to run.**
|
|
144
|
+
\`\`\`
|
|
145
|
+
node scripts/verify-cites.mjs cites.json # JSON array of {id,doi?,arxiv?,title?,year?,cve?,commit?}
|
|
146
|
+
node scripts/verify-cites.mjs refs.bib # best-effort .bib extraction
|
|
147
|
+
cat cites.json | node scripts/verify-cites.mjs -
|
|
148
|
+
node scripts/verify-cites.mjs cites.json --offline # no network (everything degrades to unresolvable)
|
|
149
|
+
\`\`\`
|
|
150
|
+
It prints per-cite \`{id, verdict, reason, matched_db, matched_title?, flags?}\` + a summary, and **exits 1 iff
|
|
151
|
+
any \`false\` (fabrication)** — \`unresolvable\` alone is advisory and does NOT fail the gate, matching the
|
|
152
|
+
narrowed-false philosophy. API responses are cached to \`scripts/.cite-cache.json\` (gitignored) so re-runs are
|
|
153
|
+
cheap and deterministic.
|
|
154
|
+
|
|
155
|
+
## 5b. The author-list gate — \`scripts/bib-authors.mjs\`
|
|
156
|
+
|
|
157
|
+
\`verify-cites.mjs\` answers *"does this citation exist, and does the id point at it?"*. There is a second
|
|
158
|
+
question it structurally cannot ask, and on 2026-08-24 that gap cost three real defects in a bibliography
|
|
159
|
+
this skill had already reported as **"ALL 23 cites verified real"**:
|
|
160
|
+
|
|
161
|
+
> We write \`@inproceedings{... NeurIPS 2023}\`. Is our author list the **NeurIPS** one — or did we copy the
|
|
162
|
+
> **arXiv preprint's**?
|
|
163
|
+
|
|
164
|
+
The preprint and the published version are frequently **different lists**, and every existence check passes
|
|
165
|
+
either way: the paper is real, the id resolves, the title matches. What was found:
|
|
166
|
+
|
|
167
|
+
| entry | ours | the version we CLAIM to cite |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| \`schick2023toolformer\` | 8 authors | NeurIPS 2023 has **9** — **Eric Hambro** was simply absent |
|
|
170
|
+
| \`dehghani2022efficiency\` | Dehghani, Arnab, Beyer, Vaswani, Tay | ICLR 2022: Dehghani, **Tay**, Arnab, Beyer, Vaswani |
|
|
171
|
+
| \`raji2021benchmark\` | Raji, Bender, Paullada, Denton, Hanna | NeurIPS D&B 2021: Raji, **Denton**, Bender, **Hanna**, **Paullada** |
|
|
172
|
+
|
|
173
|
+
The first is a **real person dropped from a citation in an archival publication** — by our own scale that is
|
|
174
|
+
heavier than a typo, and it is exactly the class §"any regalia about third parties" already warns about.
|
|
175
|
+
|
|
176
|
+
**How to run.**
|
|
177
|
+
\`\`\`
|
|
178
|
+
node scripts/bib-authors.mjs <paper-dir> # or a .bib, or a .tex with a filecontents block
|
|
179
|
+
node scripts/bib-authors.mjs <paper-dir> --json
|
|
180
|
+
\`\`\`
|
|
181
|
+
Exits **1** on any author-set or author-order disagreement, **0** when clean, **2** on usage/IO error.
|
|
182
|
+
|
|
183
|
+
**Source is DBLP, and that choice is the evidence.** DBLP indexes the proceedings record and the CoRR record
|
|
184
|
+
**separately**, so a single query returns both lists side by side — the cleanest proof available that the
|
|
185
|
+
difference is real and not a metadata glitch. Entries that themselves declare a preprint venue are out of
|
|
186
|
+
scope (a preprint entry is allowed to carry preprint metadata).
|
|
187
|
+
|
|
188
|
+
⚠️ **Discovery credit, and why it is NOT a dependency.** The class was found by running **rebiber**
|
|
189
|
+
(\`yuchenlin/rebiber\`), which rewrites bib entries into their DBLP records. We deliberately do not depend on
|
|
190
|
+
it: its install fights modern setuptools (the \`bibtexparser\` wheel dies with \`AttributeError:
|
|
191
|
+
install_layout\`), and its *output* replaces our entries with DBLP's very long official booktitles — wrong for
|
|
192
|
+
a page-limited paper. We needed the **comparison**, not the rewrite, and that is one fetch with zero deps.
|
|
193
|
+
Note also that live DBLP beat rebiber's bundled dump: \`raji2021benchmark\` was found only by the live query.
|
|
194
|
+
|
|
195
|
+
🔴 **Two design decisions that are load-bearing, both learned by measurement the same day:**
|
|
196
|
+
1. **Compare surname SEQUENCES, nothing else.** A first cut reported 13 differences of which **11 were
|
|
197
|
+
"Last, First" vs "First Last"** — pure formatting. A checker that cries 13 when 2 are real is read once
|
|
198
|
+
and then ignored; this repo has already killed a check that way (33 findings, 22 of them live files).
|
|
199
|
+
2. **A failed lookup is NOT a skip.** The first run printed *"PASS: no author-list disagreement"* while
|
|
200
|
+
**9 of 27 entries had never been examined** (DBLP answered 429). Failures now retry with backoff and land
|
|
201
|
+
in a separate bucket that downgrades the verdict to **PARTIAL** — never \`PASS\`.
|
|
202
|
+
|
|
203
|
+
**Tests:** \`node scripts/bib-authors.test.mjs\` — 11 assertions, offline, with the three real entries above
|
|
204
|
+
pinned as regressions. Mutation-checked: collapsing the name normalisation makes it fail.
|
|
205
|
+
|
|
206
|
+
**Pure/impure split + tests.** The verdict logic (\`reduceVerdict\` / \`classifyResolver\` / \`checkNvd\` /
|
|
207
|
+
\`checkCommit\` + the string helpers) is a pure function of \`(citation, evidence)\` — the live HTTP layer only
|
|
208
|
+
shapes raw API responses into that evidence. \`scripts/verify-cites.test.mjs\` exercises the reducer offline with
|
|
209
|
+
injected fixtures (\`node scripts/verify-cites.test.mjs\`); no test touches the network.
|
|
210
|
+
|
|
211
|
+
**Honest limits.** Semantic Scholar rate-limits (HTTP 429) without an API key, and arXiv's export API can be
|
|
212
|
+
unreachable behind some proxies — both degrade to \`unreachable\` (→ contribute nothing, never \`false\`). And,
|
|
213
|
+
by design, the gate **declines** in three situations rather than risk a false accusation:
|
|
214
|
+
|
|
215
|
+
- **A fabrication with no identifier (only a bogus title)** escapes this existence gate → it surfaces as
|
|
216
|
+
\`unresolvable\`, and is caught by the LLM claim-faithfulness check (§1) + human review, not here. Verifying
|
|
217
|
+
a work *exists* is not the same as verifying the paper's *claim about it* is faithful — that's §1's job.
|
|
218
|
+
- **A non-Latin / cross-script or otherwise uncomparable title** on a DOI/arXiv record: we **cannot** assert
|
|
219
|
+
the id landed on an unrelated paper (a Russian work's DOI may record an English title), so we do **not**
|
|
220
|
+
emit \`DOI_MISMATCH\` — the id counts as resolved (\`true\`) or, absent other confirmation, \`unresolvable\`.
|
|
221
|
+
Never \`false\`. The \`doi_mismatch → false\` verdict fires **only** for two confidently-comparable titles that
|
|
222
|
+
are genuinely different.
|
|
223
|
+
- **A DOI that resolves at doi.org but has no content-registry metadata** (DataCite/Zenodo, fresh 2026 DOIs)
|
|
224
|
+
→ \`unresolvable\`, because the work exists but its metadata (title/year) cannot be cross-checked here. This
|
|
225
|
+
is the correct verdict for a paper's own artifact DOI; treat \`unresolvable\` as advisory, not a failure.
|
|
226
|
+
|
|
227
|
+
**Known narrow residue (rare, treat a lone \`DOI_MISMATCH → false\` as advisory, eyeball it).** Two edge cases
|
|
228
|
+
can still mis-fire: (a) a correct DOI whose *every* registry records junk metadata — e.g. the container /
|
|
229
|
+
proceedings title instead of the paper's — reads as "unrelated" (mitigated when any one registry has the real
|
|
230
|
+
title, since a match wins); (b) a translated-journal title in the *same script* (transliterated Latin vs
|
|
231
|
+
English) that shares no tokens. Both need semantics the gate doesn't have; both are near-zero frequency in an
|
|
232
|
+
English CS bib. Identifier-prefix / trailing-punctuation mangling (\`doi:\`, \`arXiv:\`, a bib-swallowed \`.\`) is
|
|
233
|
+
**fixed** — normalized at the verify boundary — so the common real-DOI-→-\`false\` path is closed.
|
|
234
|
+
|
|
235
|
+
## 5b. The ATTRIBUTION gate — \`extract-ref-facts.mjs\` + the \`refs/*\` ESLint rules
|
|
236
|
+
|
|
237
|
+
§5 asks *does this identifier name a real work*. This one asks *is the work it names the one the entry
|
|
238
|
+
describes* — and those are different questions, which is why they are different tools and not one flag.
|
|
239
|
+
Run both; neither replaces the other.
|
|
240
|
+
|
|
241
|
+
🔴 **Moved 2026-08-26 out of a script and into rules** (ladder step 3, the \`CLAUDE.md\` beside the papers).
|
|
242
|
+
It used to be one script, \`verify-refs.mjs\`; the measurement half stayed a script and the judgement half
|
|
243
|
+
became twelve ESLint rules over the facts it writes.
|
|
244
|
+
|
|
245
|
+
\`\`\`
|
|
246
|
+
# 1. measure: parse the bibliography, ask CrossRef/arXiv, write _build/refs.facts.json
|
|
247
|
+
node .claude/skills/paper-pipeline/scripts/extract-ref-facts.mjs <paper-dir>
|
|
248
|
+
node .claude/skills/paper-pipeline/scripts/extract-ref-facts.mjs <paper-dir> --offline # cached responses only
|
|
249
|
+
|
|
250
|
+
# 2. judge: rules over those facts — severity from the config, positions, disable-with-reason
|
|
251
|
+
npx eslint --no-config-lookup --config eslint.config.mjs "<paper-dir>/_build/refs.facts.json"
|
|
252
|
+
\`\`\`
|
|
253
|
+
|
|
254
|
+
**Why it exists, stated plainly: \`verify-cites.mjs\` never compares an author list.** It parses \`author\`
|
|
255
|
+
out of a \`.bib\` into the citation object and then does nothing with it — the string appears twice in 991
|
|
256
|
+
lines, once in a doc comment and once in the extractor. So of the nine broken references this project
|
|
257
|
+
shipped across two nights, the shapes it structurally cannot see are the ones about ATTRIBUTION: seven
|
|
258
|
+
wrong initials on correct surnames, a reversed author order, an invented award. This leg closes that,
|
|
259
|
+
the same one MedSci Skills (arXiv:2606.09500) closes with \`verify_refs.py\`.
|
|
260
|
+
|
|
261
|
+
| | \`verify-cites.mjs\` (§5) | the \`refs/*\` rules (§5b) |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| question | does the id resolve to *something* | is *that* the work the entry describes |
|
|
264
|
+
| registries | Crossref · OpenAlex · Semantic Scholar · arXiv | CrossRef · arXiv (the two that matter for CS) |
|
|
265
|
+
| authors | **never compared** | surname multiset **+ order-sensitive first author** |
|
|
266
|
+
| year | ±1 on a title search | exact, and only against the record that dates the cited version |
|
|
267
|
+
| preprint→published | not asked | arXiv \`journal_ref\`/\`doi\` present and no venue named → say so |
|
|
268
|
+
| what it could not check | folded into \`unresolvable\` | **enumerated, one rule per reason, never counted as verified** |
|
|
269
|
+
| tests | \`verify-cites.test.mjs\` — not a \`*.harness.mjs\`, so \`npx vigiles test\` never runs it | \`eslint-rules/ref-facts.harness.mjs\` + \`.claude/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs\`, plus \`eslint-rules/ref-facts.mutations.mjs\` |
|
|
270
|
+
|
|
271
|
+
**The uncovered set is the point.** A reference with no resolvable identifier is a FINDING here
|
|
272
|
+
(\`refs/no-identifier\`), and every partial comparison is another (\`refs/partial-check\`, one messageId per
|
|
273
|
+
reason). On this project's submitted bibliography that set is 17 entries of 67 — an npm package, a Supreme
|
|
274
|
+
Court dissent, an FAA circular, Dijkstra. None of them is a defect; all of them are things a model checker
|
|
275
|
+
would have reported as fine. Being able to hand a reviewer the list of what was NOT machine-verified is a
|
|
276
|
+
property no model-driven pass has.
|
|
277
|
+
|
|
278
|
+
🔴 **\`.bib\` papers were never checked by the old script — two dead legs, both measured 2026-08-26.**
|
|
279
|
+
\`refs.bib\` was not in its source list (so \`agenticdev-2026\` and \`aisec-2026\` answered "nothing to check"),
|
|
280
|
+
and its \`.bib\` regex required a closing \`}\` on its own line, which neither real file has (\`parsed 0
|
|
281
|
+
references\`). The \`.bib\` half now goes through \`@retorquere/bibtex-parser\`. Two of the three papers are
|
|
282
|
+
therefore being checked for the first time.
|
|
283
|
+
|
|
284
|
+
**Every check is watched failing.** \`node eslint-rules/ref-facts.mutations.mjs\` neuters each rule in turn
|
|
285
|
+
and requires the harness to go red at the named case — 21 mutations, all killed, and three of them were
|
|
286
|
+
findings about the TEST rather than the rule. Run it after any edit to the rules.
|
|
287
|
+
|
|
288
|
+
## 6. Record the verdict
|
|
289
|
+
|
|
290
|
+
🔴 LAST step, once the deliverable exists:
|
|
291
|
+
|
|
292
|
+
\`\`\`
|
|
293
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record verify-citations <paper-dir> FINDING <count> <report-path>
|
|
294
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record verify-citations <paper-dir> ABSTAINED <reason> "<one line>"
|
|
295
|
+
\`\`\`
|
|
296
|
+
|
|
297
|
+
**FINDING** — \`<count>\` is the number of cites still \`% VERIFY\` or \`unresolvable\`; \`<report-path>\`
|
|
298
|
+
lists them. Add \`--blocking\` for a cite an authoritative source disproves, or a missing delta
|
|
299
|
+
sentence; either is a submit blocker.
|
|
300
|
+
**ABSTAINED** — \`no-witness\`: every cite resolved with correct metadata and the delta sentence is in
|
|
301
|
+
the prose. \`crashed\`: the registries were unreachable, so nothing was verified — which is emphatically
|
|
302
|
+
not the same as everything checking out, and under the old vocabulary both came back \`PASS\`.
|
|
303
|
+
|
|
304
|
+
🔴 **There is no PASS.** \`no-witness\` here means every cite the paper makes was looked up and none
|
|
305
|
+
of them came back wrong. It does not mean the bibliography is complete: this check cannot see a work
|
|
306
|
+
that should have been cited and is not. That gap belongs to \`map-prior-work\`, and no row here covers it.
|
|
307
|
+
|
|
308
|
+
Because this check is CONTINUOUS, it writes a row per run and never a final one. That is the point:
|
|
309
|
+
the ledger compares the row against the paper's current bytes, so a pass that predates the last three
|
|
310
|
+
\`\\cite\` additions reports as STALE-PAPER instead of reading as green.
|
|
311
|
+
|
|
312
|
+
## Rules
|
|
313
|
+
- **Re-run on every \`\\cite\` added or moved.** A \`cites\` row older than the paper's text is a stale pass,
|
|
314
|
+
not a green one — "we checked last cycle" is not a verification.
|
|
315
|
+
- No cite ships unverified. Exists + correct metadata + says-what-you-claim, or it's \`% VERIFY\`.
|
|
316
|
+
- Never fabricate to fill a gap — soften the claim instead.
|
|
317
|
+
- The delta over the nearest neighbor is prose, not an implication.
|
|
318
|
+
- Report honestly: a cite you can't confirm is a finding, not something to wave through.
|
|
319
|
+
- A title you can't find is \`unresolvable\`, not a fabrication — \`false\` needs an *authoritative* disproof
|
|
320
|
+
(doi.org \`responseCode 100\`, a reachable arXiv rejection, NVD-has-no-CVE) or a confidently-different title.
|
|
321
|
+
A registry-404, an uncomparable/non-Latin title, or any transport failure is \`unresolvable\`, never \`false\`.
|
|
322
|
+
|
|
323
|
+
## Compose with
|
|
324
|
+
- **draft-paper** — related-work and the delta sentence are drafted there; this skill audits them.
|
|
325
|
+
- **map-prior-work** — fan-out prior-art search; use it to resolve hard-to-find cites and to surface
|
|
326
|
+
the expected-but-missing citation. ⚠️ **Was \`deep-research\` until 2026-08-31 — no such skill has
|
|
327
|
+
ever existed in this base** (0 matches on disk), and the name appeared BOTH here and in this
|
|
328
|
+
skill's own \`description\`. A pointer to a non-existent skill fails silently: the step is simply
|
|
329
|
+
not performed, and the compose line still reads as if coverage were arranged.
|
|
330
|
+
- **analyze-sibling-paper** — when a resolved cite turns out to be a close neighbor, that skill does
|
|
331
|
+
the deep overlap/scoop analysis this one is too shallow for.
|
|
332
|
+
- **pc-panel-review** — its novelty/related-work reviewer will probe the delta and hunt uncited neighbors;
|
|
333
|
+
clear this skill first so that lens finds nothing.
|
|
334
|
+
|
|
335
|
+
## Provenance
|
|
336
|
+
Both papers grounded their novelty delta over the nearest prior work explicitly, and that framing is what
|
|
337
|
+
made them land:
|
|
338
|
+
- **AgenticDev 2026 — "Measuring the Wrong Number":** positioned against Kapoor et al. *"AI Agents That
|
|
339
|
+
Matter"* and Dehghani et al. *"The Efficiency Misnomer"* — the delta being a cost-aware,
|
|
340
|
+
correctness-gated *measurement* where those argued the problem.
|
|
341
|
+
- **AISec 2026 @ CCS — "Safety Theater":** positioned against Ptacek & Newsham (the classic
|
|
342
|
+
evasion-testing framing), **AgentDojo**, and **IsolateGPT** — the delta being a static, mutation-and-
|
|
343
|
+
ablation evaluation of real command-guards rather than a new defense. Each of these was verified real,
|
|
344
|
+
with correct venue/year, before submit.`,
|
|
345
|
+
});
|