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,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* population-map.selftest.mjs — planted defects, both directions.
|
|
4
|
+
*
|
|
5
|
+
* This repository has been burned three times by checkers and hooks that were green and dead, and
|
|
6
|
+
* the rule that came out of it is that a checker which has never failed is not a checker.
|
|
7
|
+
*
|
|
8
|
+
* 🔴 SHRUNK 2026-08-26 TOGETHER WITH THE CHECKER ITSELF. Nine of the thirteen cases checked
|
|
9
|
+
* `untied` and `undeclared` — both findings moved into ESLint rules (`paper/population-untied`,
|
|
10
|
+
* `paper/population-undeclared`), and their cases moved there too, into
|
|
11
|
+
* `eslint-rules/paper-registry.harness.mjs`, where they sit next to a run against a REAL paper.
|
|
12
|
+
* What is left here are the two findings that speak about the registry itself: `stale` and `badref`.
|
|
13
|
+
*
|
|
14
|
+
* 🔴 ONE CASE WAS DELETED, NOT MOVED, and that is worth remembering. It looked like this:
|
|
15
|
+
*
|
|
16
|
+
* check('189 does not match inside 1,189',
|
|
17
|
+
* !sentences('x 1,189 y').some((s) => /(?<![\d,.])189(?!\d|[,.]\d)/.test(s)));
|
|
18
|
+
*
|
|
19
|
+
* that is, it ran a HAND-COPIED COPY of the checker's regex over a string and asserted about a
|
|
20
|
+
* literal inside the test itself. A mutation of the body of `printed()` does not touch such a test
|
|
21
|
+
* by construction — which is exactly what the `eslint-rules/paper-registry.mutations.mjs` battery
|
|
22
|
+
* showed, where that mutation SURVIVED the first run. The property is now pinned by a fixture that
|
|
23
|
+
* checks BEHAVIOUR, not the agreement of two copies of a regex.
|
|
24
|
+
*/
|
|
25
|
+
import { findings, bodyOf } from "./population-map.mjs";
|
|
26
|
+
|
|
27
|
+
const doc = (bodyLines) =>
|
|
28
|
+
`## Abstract\n\n${bodyLines}\n\n## References\n\n[1] x.\n`;
|
|
29
|
+
let pass = 0,
|
|
30
|
+
fail = 0;
|
|
31
|
+
const check = (name, cond) => {
|
|
32
|
+
if (cond) {
|
|
33
|
+
pass++;
|
|
34
|
+
} else {
|
|
35
|
+
fail++;
|
|
36
|
+
console.log(` FAIL ${name}`);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const kinds = (md, reg) =>
|
|
40
|
+
findings(md, reg).map((f) => `${f.kind}:${f.row?.print ?? f.print}`);
|
|
41
|
+
|
|
42
|
+
const REG = [
|
|
43
|
+
"id\tprinted\trelation\trelated_to\tgloss",
|
|
44
|
+
"broad\t1,921\troot\t\tthe corpus",
|
|
45
|
+
"sub\t1,836\tsubset\tbroad\tthose it could read",
|
|
46
|
+
].join("\n");
|
|
47
|
+
|
|
48
|
+
// 1. Everything the registry declares is printed -> silence. The direction that matters more:
|
|
49
|
+
// a checker firing on a paper that already obeys gets muted the same week, and a muted checker
|
|
50
|
+
// is indistinguishable from an absent one.
|
|
51
|
+
check(
|
|
52
|
+
"a registry that matches the body is silent",
|
|
53
|
+
kinds(
|
|
54
|
+
doc(
|
|
55
|
+
"The resolver ran over all 1,921 repositories, and read 1,836 of them.",
|
|
56
|
+
),
|
|
57
|
+
REG,
|
|
58
|
+
).length === 0,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// 2. A registry row for a quantity the paper no longer prints. The registry shrinks when the
|
|
62
|
+
// paper does; a row nobody removed is a claim nobody can check.
|
|
63
|
+
check(
|
|
64
|
+
"stale registry row fires",
|
|
65
|
+
kinds(doc("The resolver ran over all 1,921 repositories."), REG).includes(
|
|
66
|
+
"stale:1,836",
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// 3. ...but a row explicitly marked `retired` is exempt — that is what the marker is FOR.
|
|
71
|
+
// Without this the only way to keep a set declared after cutting it from the paper would be
|
|
72
|
+
// to delete the row, which loses the record.
|
|
73
|
+
check(
|
|
74
|
+
"a retired row does not fire",
|
|
75
|
+
!kinds(
|
|
76
|
+
doc("The resolver ran over all 1,921 repositories."),
|
|
77
|
+
REG + "\ngold\t7,310\tretired\t\ta public gold set",
|
|
78
|
+
).includes("stale:7,310"),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// 4. A relation pointing at an id that does not exist. Purely a defect of the TSV: the row claims
|
|
82
|
+
// a parent that is not a row. This is why the check stayed a script — there is nothing in the
|
|
83
|
+
// paper to point a finding at.
|
|
84
|
+
check(
|
|
85
|
+
"dangling related_to fires",
|
|
86
|
+
findings(
|
|
87
|
+
doc("We read 1,836 repositories."),
|
|
88
|
+
"id\tprinted\trelation\trelated_to\tgloss\nsub\t1,836\tsubset\tnosuch\tx",
|
|
89
|
+
).some((f) => f.kind === "badref"),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// 5. `badref` is reached only for a quantity the body actually prints: a row whose number is
|
|
93
|
+
// absent is `stale`, and reporting both about one row would double-count it.
|
|
94
|
+
check(
|
|
95
|
+
"a row that is absent is stale, not badref",
|
|
96
|
+
kinds(
|
|
97
|
+
doc("Nothing numeric here."),
|
|
98
|
+
"id\tprinted\trelation\trelated_to\tgloss\nsub\t1,836\tsubset\tnosuch\tx",
|
|
99
|
+
).join() === "stale:1,836",
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// 6. `printed()` boundaries, tested through BEHAVIOUR: 189 must not count as printed inside 1,189.
|
|
103
|
+
// Without the guard the row would be considered present and `stale` would go quiet — a silent
|
|
104
|
+
// loss, which is the failure mode this file exists to prevent. (The deleted case asserted the
|
|
105
|
+
// same property against a hand-copied regex, and a mutation of the real one survived it.)
|
|
106
|
+
check(
|
|
107
|
+
'189 is not "printed" inside 1,189',
|
|
108
|
+
kinds(
|
|
109
|
+
doc("A follow-up read covered 1,189 records."),
|
|
110
|
+
"id\tprinted\trelation\trelated_to\tgloss\nbroad\t1,921\troot\t\tthe corpus\nspread\t189\tsubset\tbroad\tenumerable",
|
|
111
|
+
).includes("stale:189"),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// 7. bodyOf must stop at the bibliography. Appendices sit after it and are not under the page
|
|
115
|
+
// limit, so a number printed only there does not reach the reader who stops at References.
|
|
116
|
+
check(
|
|
117
|
+
"bodyOf stops at References",
|
|
118
|
+
!bodyOf(doc("nothing here")).includes("[1] x."),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
console.log(`population-map selftest: ${pass} passed, ${fail} failed`);
|
|
122
|
+
process.exit(fail ? 1 : 0);
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* provenance.harness.mjs — what remains from `check-provenance.mjs` after the move, verified from
|
|
3
|
+
* both sides. `npx vigiles test .claude/skills/paper-pipeline/scripts/provenance.harness.mjs`.
|
|
4
|
+
*
|
|
5
|
+
* 🔴 SCOPE NARROWED 2026-08-26. Three findings out of five moved to ESLint rules:
|
|
6
|
+
* arm-mismatch → `paper/number-arm-mismatch`
|
|
7
|
+
* untraced-number → `paper/number-untraced`
|
|
8
|
+
* arm-unlabelled → `paper/number-arm-unlabelled`
|
|
9
|
+
* Their cases (including the literal defect from 2026-08-05 and "prediction named its own arm — stay quiet")
|
|
10
|
+
* moved to `eslint-rules/paper-registry.harness.mjs`, where they stand alongside runs on real
|
|
11
|
+
* papers. Two checks remain here, which do NOT READ the paper BODY AT ALL — they are given only
|
|
12
|
+
* a directory, and so cannot be lint rules:
|
|
13
|
+
*
|
|
14
|
+
* no-numbers-gate missing `repro/paper_numbers.py`;
|
|
15
|
+
* numbers-coverage how many quantities are sourced against the ratchet `numbers-grandfathered.txt`.
|
|
16
|
+
* This is NOT a finding, but a coverage measurement — and it must always print.
|
|
17
|
+
*
|
|
18
|
+
* 🔴 WHY GUARDS ARE CHECKED SEPARATELY. Both remaining checks have two exit conditions,
|
|
19
|
+
* inherited from the deleted half: no `paper.md` ⇒ silent, no non-empty
|
|
20
|
+
* provenance file ⇒ silent. After the move they look unmotivated ("what does prose have to do with it
|
|
21
|
+
* if we look at a directory?") — and the first person to "remove redundancy" will change behavior. Assertions
|
|
22
|
+
* below pin them as contract.
|
|
23
|
+
*
|
|
24
|
+
* 🔴 Assertions run at MODULE TOP LEVEL. `vigiles test` imports the file and treats "did not throw"
|
|
25
|
+
* as a pass, so a `tests` export or a describe block would report ✓ having run nothing — verified in
|
|
26
|
+
* this repo on a file containing only `assert.equal(1, 2)` inside an exported function.
|
|
27
|
+
*
|
|
28
|
+
* Every fixture is a throwaway in a temp dir. Nothing here reads or writes a real paper.
|
|
29
|
+
*/
|
|
30
|
+
import assert from "node:assert/strict";
|
|
31
|
+
import { execFileSync } from "node:child_process";
|
|
32
|
+
import {
|
|
33
|
+
mkdtempSync,
|
|
34
|
+
mkdirSync,
|
|
35
|
+
writeFileSync,
|
|
36
|
+
rmSync,
|
|
37
|
+
realpathSync,
|
|
38
|
+
} from "node:fs";
|
|
39
|
+
import { tmpdir } from "node:os";
|
|
40
|
+
import { join, dirname } from "node:path";
|
|
41
|
+
import { fileURLToPath } from "node:url";
|
|
42
|
+
import { consumerRoot } from "./consumer.mjs";
|
|
43
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
44
|
+
|
|
45
|
+
const ROOT = consumerRoot();
|
|
46
|
+
const SCRIPT = join(HERE, "check-provenance.mjs");
|
|
47
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), "prov-harness-")));
|
|
48
|
+
|
|
49
|
+
/** Run the gate over a fixture and return the set of finding kinds it reported. */
|
|
50
|
+
function kinds(dir) {
|
|
51
|
+
let out;
|
|
52
|
+
try {
|
|
53
|
+
out = execFileSync("node", [SCRIPT, dir], {
|
|
54
|
+
cwd: ROOT,
|
|
55
|
+
encoding: "utf8",
|
|
56
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
57
|
+
});
|
|
58
|
+
} catch (e) {
|
|
59
|
+
out = (e.stdout || "") + (e.stderr || "");
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
set: new Set([...out.matchAll(/^\s*\[([a-z-]+)\]/gm)].map((m) => m[1])),
|
|
63
|
+
out,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A paper dir with a body, a provenance file, and (unless `gate: false`) the per-paper numbers gate.
|
|
69
|
+
* The gate file must exist or `no-numbers-gate` fires on every fixture and drowns the signal — which
|
|
70
|
+
* is itself a finding worth having, and is asserted on its own below.
|
|
71
|
+
*/
|
|
72
|
+
function paper(
|
|
73
|
+
name,
|
|
74
|
+
{ body, notes, gate = true, numbers, grandfathered, noPaper = false },
|
|
75
|
+
) {
|
|
76
|
+
const d = join(tmp, name);
|
|
77
|
+
mkdirSync(join(d, "repro"), { recursive: true });
|
|
78
|
+
if (!noPaper)
|
|
79
|
+
writeFileSync(
|
|
80
|
+
join(d, "paper.md"),
|
|
81
|
+
`## Abstract\n\n${body}\n\n## References\n\n[1] x.\n`,
|
|
82
|
+
);
|
|
83
|
+
if (notes !== undefined) writeFileSync(join(d, "NOTES.md"), notes);
|
|
84
|
+
if (gate)
|
|
85
|
+
writeFileSync(
|
|
86
|
+
join(d, "repro", "paper_numbers.py"),
|
|
87
|
+
"# the per-paper numbers gate\n",
|
|
88
|
+
);
|
|
89
|
+
if (numbers !== undefined)
|
|
90
|
+
writeFileSync(join(d, "repro", "numbers.tsv"), numbers);
|
|
91
|
+
if (grandfathered !== undefined)
|
|
92
|
+
writeFileSync(join(d, "repro", "numbers-grandfathered.txt"), grandfathered);
|
|
93
|
+
return d;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The provenance rows of the real 2026-08-05 defect: the count of failures is recorded against the
|
|
97
|
+
// ANNOTATED arm, in which the extractor's guesses were written in as if an author had authored them.
|
|
98
|
+
const NOTES = [
|
|
99
|
+
"# where each number comes from",
|
|
100
|
+
"- `.all.strict.compiled` = 147 — rules files that compiled",
|
|
101
|
+
"- `.all.annotated.failedContradicted` = 22 — files failing admission in the annotated arm",
|
|
102
|
+
].join("\n");
|
|
103
|
+
|
|
104
|
+
// ── 1. QUIET ON CORRECT: paper has gate and registry — only coverage measurement, zero findings ──
|
|
105
|
+
// First this half: a check that cries on correct input is worse than no check.
|
|
106
|
+
{
|
|
107
|
+
const d = paper("covered", {
|
|
108
|
+
body: "The headline rate is **15.0%** across the corpus.",
|
|
109
|
+
notes: NOTES,
|
|
110
|
+
numbers: "# id\tvalue\n a\t1\n b\t2\n",
|
|
111
|
+
grandfathered: "# still raw\n42\n",
|
|
112
|
+
});
|
|
113
|
+
const { set, out } = kinds(d);
|
|
114
|
+
assert.ok(
|
|
115
|
+
!set.has("no-numbers-gate"),
|
|
116
|
+
"paper with gate got `no-numbers-gate`:\n" + out,
|
|
117
|
+
);
|
|
118
|
+
assert.ok(
|
|
119
|
+
set.has("numbers-coverage"),
|
|
120
|
+
"coverage measurement must always print:\n" + out,
|
|
121
|
+
);
|
|
122
|
+
assert.match(
|
|
123
|
+
out,
|
|
124
|
+
/2 quantities are sourced and guarded, 1 are still raw/,
|
|
125
|
+
"numbers in coverage measurement do not match — counted registry lines and ratchet lines:\n" +
|
|
126
|
+
out,
|
|
127
|
+
);
|
|
128
|
+
assert.equal(
|
|
129
|
+
set.size,
|
|
130
|
+
1,
|
|
131
|
+
"after three checks moved, this input must give EXACTLY the coverage measurement:\n" +
|
|
132
|
+
out,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ── 2. a paper with no numbers gate at all is told so ──────────────────────────────────
|
|
137
|
+
// The coverage question, not a defect in the prose: without `repro/paper_numbers.py` every printed
|
|
138
|
+
// figure is a hand-typed digit whose only link to its data file is somebody's memory.
|
|
139
|
+
{
|
|
140
|
+
const d = paper("no-gate", {
|
|
141
|
+
body: "Nothing bolded here.",
|
|
142
|
+
notes: NOTES,
|
|
143
|
+
gate: false,
|
|
144
|
+
});
|
|
145
|
+
const { set, out } = kinds(d);
|
|
146
|
+
assert.ok(
|
|
147
|
+
set.has("no-numbers-gate"),
|
|
148
|
+
"a paper with no repro/paper_numbers.py was not told:\n" + out,
|
|
149
|
+
);
|
|
150
|
+
assert.ok(
|
|
151
|
+
!set.has("numbers-coverage"),
|
|
152
|
+
"no gate — nothing to cover, measurement must not print:\n" + out,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ── 3. gate exists, no `numbers.tsv` registry — silence, not zero coverage ─────────────────
|
|
157
|
+
// The distinction is semantic: «gate was copied but no quantity has been registered in it yet» is NOT the same
|
|
158
|
+
// as «0 of 0 sourced», and printing the latter would mean reporting coverage that nobody measured.
|
|
159
|
+
{
|
|
160
|
+
const d = paper("gate-no-registry", {
|
|
161
|
+
body: "Nothing bolded here.",
|
|
162
|
+
notes: NOTES,
|
|
163
|
+
});
|
|
164
|
+
const { set, out } = kinds(d);
|
|
165
|
+
assert.equal(set.size, 0, "gate without registry must stay silent:\n" + out);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ── 4. GUARDS inherited from the deleted half — contract, not a leftover ──────────────────
|
|
169
|
+
// 🔴 After the move both look unmotivated: the check looks at a directory, what has prose to do with it?
|
|
170
|
+
// But removing them means changing behaviour on papers that have no provenance file at all (most of them)
|
|
171
|
+
// — and `no-numbers-gate` will start firing on each one.
|
|
172
|
+
{
|
|
173
|
+
const d = paper("no-prov", {
|
|
174
|
+
body: "Nothing bolded here.",
|
|
175
|
+
notes: undefined,
|
|
176
|
+
gate: false,
|
|
177
|
+
});
|
|
178
|
+
const { set, out } = kinds(d);
|
|
179
|
+
assert.equal(
|
|
180
|
+
set.size,
|
|
181
|
+
0,
|
|
182
|
+
"no provenance file at all — script must stay completely silent:\n" + out,
|
|
183
|
+
);
|
|
184
|
+
// 🔴 Stay silent — yes, but NOT with the voice of success. Before 2026-08-26 both guards printed `clean`, and on
|
|
185
|
+
// the real corpus that gave confident green on three papers out of four (all three in .tex).
|
|
186
|
+
assert.match(
|
|
187
|
+
out,
|
|
188
|
+
/SKIPPED/,
|
|
189
|
+
"skip must name itself as skip, not as a clean run:\n" + out,
|
|
190
|
+
);
|
|
191
|
+
assert.doesNotMatch(
|
|
192
|
+
out,
|
|
193
|
+
/clean/,
|
|
194
|
+
"skip must not print the word `clean`:\n" + out,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
{
|
|
198
|
+
const d = paper("no-paper", {
|
|
199
|
+
body: "",
|
|
200
|
+
notes: NOTES,
|
|
201
|
+
gate: false,
|
|
202
|
+
noPaper: true,
|
|
203
|
+
});
|
|
204
|
+
const { set, out } = kinds(d);
|
|
205
|
+
assert.equal(
|
|
206
|
+
set.size,
|
|
207
|
+
0,
|
|
208
|
+
"no paper.md/draft.md — script must stay completely silent:\n" + out,
|
|
209
|
+
);
|
|
210
|
+
assert.match(out, /SKIPPED/, "skip must name itself as skip:\n" + out);
|
|
211
|
+
assert.match(
|
|
212
|
+
out,
|
|
213
|
+
/\.tex/,
|
|
214
|
+
"the reason must name WHAT exactly is not covered — otherwise the reader\n" +
|
|
215
|
+
"will think it is a breakage:\n" +
|
|
216
|
+
out,
|
|
217
|
+
);
|
|
218
|
+
assert.doesNotMatch(
|
|
219
|
+
out,
|
|
220
|
+
/clean/,
|
|
221
|
+
"skip must not print the word `clean`:\n" + out,
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── 5. clean run SPEAKS that it is clean ──────────────────────────────────────────────────
|
|
226
|
+
// Silence and success must not look the same — this is the same class as «0 checks» vs
|
|
227
|
+
// «checks passed» in the PR interface.
|
|
228
|
+
{
|
|
229
|
+
const d = paper("clean-voice", {
|
|
230
|
+
body: "Nothing bolded here.",
|
|
231
|
+
notes: NOTES,
|
|
232
|
+
});
|
|
233
|
+
const { out } = kinds(d);
|
|
234
|
+
assert.match(out, /clean/, "clean run did not print a verdict:\n" + out);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
238
|
+
console.log(
|
|
239
|
+
"✓ check-provenance: no-numbers-gate fires, coverage is measured, both guards are pinned, clean run speaks",
|
|
240
|
+
);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* provenance.mutations.mjs — plant each defect `provenance.harness.mjs` claims to catch, and require it to die.
|
|
3
|
+
*
|
|
4
|
+
* Run: `node skills/paper-pipeline/scripts/provenance.mutations.mjs` (~1 min; it rewrites the source and
|
|
5
|
+
* restores it, so it is not part of the plain test run).
|
|
6
|
+
*
|
|
7
|
+
* WHY IT EXISTS. A harness whose success state is silence cannot be observed working: «it passed»
|
|
8
|
+
* and «it cannot fail» produce identical output. This battery is the difference. It was written on
|
|
9
|
+
* 2026-09-12, when the mechanism moved into this package and `scripts/run-mutations.mjs` reported
|
|
10
|
+
* this harness as one nothing could kill — a gap that had been open for as long as the harness had
|
|
11
|
+
* existed, invisible because nothing asked the question.
|
|
12
|
+
*
|
|
13
|
+
* Every replacement below differs from the text it replaces (the driver refuses a no-op, which
|
|
14
|
+
* would leave a green harness proving nothing), every case names the assertion that must fire, and
|
|
15
|
+
* the driver verifies the patch actually landed before believing a result.
|
|
16
|
+
*/
|
|
17
|
+
import { dirname, join } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { runMutations } from "../../../lib/mutation-driver.mjs";
|
|
20
|
+
import { consumerRoot } from "./consumer.mjs";
|
|
21
|
+
|
|
22
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const SRC = join(HERE, "check-provenance.mjs");
|
|
24
|
+
const HARNESS = join(HERE, "provenance.harness.mjs");
|
|
25
|
+
|
|
26
|
+
const MUTATIONS = [
|
|
27
|
+
[
|
|
28
|
+
"the scope gate is inverted",
|
|
29
|
+
[
|
|
30
|
+
[
|
|
31
|
+
SRC,
|
|
32
|
+
"if (!provenanceScope(dir).covered) return [];",
|
|
33
|
+
"if (provenanceScope(dir).covered) return [];",
|
|
34
|
+
],
|
|
35
|
+
],
|
|
36
|
+
"coverage measurement must always print",
|
|
37
|
+
"the in-scope/out-of-scope distinction: covered papers stop being checked and the report still prints",
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"the numbers gate is removed",
|
|
41
|
+
[[SRC, "return [...checkNumbersGate(dir)];", "return [];"]],
|
|
42
|
+
"coverage measurement must always print",
|
|
43
|
+
"the only finding this checker can make — it becomes a script that always says clean",
|
|
44
|
+
],
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
process.exit(
|
|
48
|
+
runMutations({
|
|
49
|
+
root: consumerRoot(),
|
|
50
|
+
runner: "vigiles",
|
|
51
|
+
cases: MUTATIONS.map(([name, edits, expect, disables]) => ({
|
|
52
|
+
name,
|
|
53
|
+
disables,
|
|
54
|
+
edits,
|
|
55
|
+
harness: HARNESS,
|
|
56
|
+
expect,
|
|
57
|
+
})),
|
|
58
|
+
}),
|
|
59
|
+
);
|