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,585 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Sweep — what the pipeline should ideally look like (a construction, not a justification for markdown)"
|
|
3
|
+
created: 2026-08-09
|
|
4
|
+
updated: 2026-08-09
|
|
5
|
+
tags:
|
|
6
|
+
[
|
|
7
|
+
paper-pipeline,
|
|
8
|
+
design-space,
|
|
9
|
+
sweep,
|
|
10
|
+
mechanisms,
|
|
11
|
+
unrepresentable,
|
|
12
|
+
claims,
|
|
13
|
+
provenance,
|
|
14
|
+
]
|
|
15
|
+
findings: 8
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Sweep — the ideal pipeline construction
|
|
19
|
+
|
|
20
|
+
**The author's question:** "the fact that the pipeline uses markdown doesn't mean anything by
|
|
21
|
+
itself — the question is what it should look like **ideally**."
|
|
22
|
+
|
|
23
|
+
**The defect-state that should become unrepresentable:** a manuscript goes out for review carrying
|
|
24
|
+
a claim that is not backed by what it cites.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## The short answer (originally written in Russian, 10 lines)
|
|
29
|
+
|
|
30
|
+
1. **The form is already right, and that's not our opinion — two other groups independently arrived
|
|
31
|
+
at it in 2026.**
|
|
32
|
+
`arXiv:2606.09500` (MedSci Skills, June 8) — "decompose the work into **skills**, gate every
|
|
33
|
+
transition with **halt-on-failure**, resolve each question with the **cheapest sufficient
|
|
34
|
+
mechanism**: a deterministic recheck where that suffices, a prose-level probe only where
|
|
35
|
+
interpretation is unavoidable." This is, word for word, our fact-gate / judgement-gate split from
|
|
36
|
+
`run-mechanical.mjs`, published two months earlier.
|
|
37
|
+
`arXiv:2605.28282` (ResearchLoop, May 27) — "claim ledgers", "paper bindings", "claim-admission
|
|
38
|
+
algorithm". This is our `CLAIMS.md` + `ledger.mjs`. **The architecture can no longer be claimed as
|
|
39
|
+
novel.**
|
|
40
|
+
2. **Ideal ≠ "not a single unbound claim".** Refusal without a replacement is deletion one step
|
|
41
|
+
earlier; framing prose is the most valuable thing in the file. What should become unrepresentable
|
|
42
|
+
is not the _content_ but the **claim of strength** — i.e. the assertion "this is backed" when it
|
|
43
|
+
isn't.
|
|
44
|
+
3. **The measurement that changes the conversation: 46 numbers are bound, 264 are exempted by
|
|
45
|
+
"grandfathering".** The numbers gate covers roughly a third of the paper's bolded numbers, and the
|
|
46
|
+
exemption has **no expiration date**. This is not a hypothetical gap, it is `wc -l` on
|
|
47
|
+
`repro/numbers-grandfathered.txt`.
|
|
48
|
+
4. **The main constructive finding:** the binding mechanism exists for **exactly one carrier** —
|
|
49
|
+
numbers. The same three lines of code close two more: **citations** (a sentence claims that work X
|
|
50
|
+
says Y) and **novelty claims** (a `CLAIMS.md` line that can be retracted). The ideal pipeline is
|
|
51
|
+
**one binding mechanism across three carriers**, not three separate checks.
|
|
52
|
+
|
|
53
|
+
Below is how this was arrived at, what got killed, and by what.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 0. Three findings that matter more than any single candidate
|
|
58
|
+
|
|
59
|
+
### 0.1 🔴 The architecture is OCCUPIED — twice, in 2026, and the repository knew about neither work
|
|
60
|
+
|
|
61
|
+
A `grep` across the whole repo: `2606.09500`, `2605.28282`, `MedSci`, `ResearchLoop` — **zero
|
|
62
|
+
hits**. The 2026-08-06 occupancy pass (`occupancy-2026-08-06-*`) checked **tools** (knitr, Quarto,
|
|
63
|
+
showyourwork, Vale, aclpubcheck) and missed two arXiv papers about **the architecture itself**.
|
|
64
|
+
|
|
65
|
+
**[B] Abstract verbatim, `arXiv:2606.09500`, Nam, Jeong, Kim, submitted 2026-06-08, revision
|
|
66
|
+
06-14:**
|
|
67
|
+
|
|
68
|
+
> «We describe an architecture pairing generation with verification, resting on three principles:
|
|
69
|
+
> decompose the workflow into self-contained skills, gate every stage transition with halt-on-failure,
|
|
70
|
+
> and resolve each integrity question with the cheapest sufficient mechanism, a deterministic,
|
|
71
|
+
> re-executable check where one suffices and a prose-level probe only where interpretation is
|
|
72
|
+
> unavoidable. This determinism-where-possible split, organized as an integrity-gate taxonomy, is the
|
|
73
|
+
> core contribution. It is realized as MedSci Skills, an open-source toolkit of 43 skills with a
|
|
74
|
+
> 21-detector deterministic tier, evaluated on three public-dataset pipelines (STARD, PRISMA, STROBE)
|
|
75
|
+
> and a seeded-defect ablation. […] on 27 identical injected defects the deterministic gates detected
|
|
76
|
+
> all 27 with no false positives on the matched clean fixtures, whereas a single-prompt LLM reviewer
|
|
77
|
+
> detected 11, its misses in code, bibliography, and style defects the prose hides. […] MedSci Skills
|
|
78
|
+
> is MIT-licensed and archived (v3.8.0).»
|
|
79
|
+
|
|
80
|
+
Line-by-line correspondences with ours:
|
|
81
|
+
|
|
82
|
+
| theirs | ours |
|
|
83
|
+
| ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
84
|
+
| «self-contained skills» | 22 paper skills |
|
|
85
|
+
| «gate every stage transition with halt-on-failure» | `run-mechanical.mjs`, exit code of the worst gate |
|
|
86
|
+
| «deterministic check where one suffices, prose-level probe only where interpretation is unavoidable» | the FACT-gate / JUDGEMENT-gate split, `verdict: 'exit'` vs `verdict: 'flags'` |
|
|
87
|
+
| «seeded-defect ablation», 27 injected defects | `*.harness.mjs` + `skills.mutations.mjs`, 21 planted defect |
|
|
88
|
+
| «21-detector deterministic tier» | ~8 mechanical checkers |
|
|
89
|
+
|
|
90
|
+
**[B] Abstract verbatim, `arXiv:2605.28282`, Xia, Wang, submitted 2026-05-27:**
|
|
91
|
+
|
|
92
|
+
> «ResearchLoop treats research questions, task contracts, evidence objects, **claim ledgers**,
|
|
93
|
+
> closeouts, and **paper bindings** as durable project state, realized here as a repository-backed
|
|
94
|
+
> runtime. This technical report provides the complete protocol specification, state model, transition
|
|
95
|
+
> rules, **claim-admission algorithm**, and insight-compounding mechanism.»
|
|
96
|
+
|
|
97
|
+
⚠️ **Being honest about the evidence level:** the abstracts were read verbatim, **[B]**. The full
|
|
98
|
+
PDFs were read by a small model via WebFetch, and its summaries are **[D], not to be trusted**: for
|
|
99
|
+
2606.09500 it said "reports rather than blocks", while the abstract says `halt-on-failure`; for
|
|
100
|
+
ResearchLoop its answer to the question about "unrepresentable claims" reads stylistically like
|
|
101
|
+
confabulation ("Standard metrics for such systems would measure…"). **P0: read both PDFs in full,
|
|
102
|
+
with human eyes.**
|
|
103
|
+
|
|
104
|
+
**What follows from this, practically.** Not "we're too late." Three things follow:
|
|
105
|
+
|
|
106
|
+
- the claim "we built a manuscript-verification architecture" is **dead** — but nobody was making it
|
|
107
|
+
anyway;
|
|
108
|
+
- **their 21 deterministic detectors are a donor list**, better than ARIS (see §2.4);
|
|
109
|
+
- **their 27/27-vs-11/27 number is our citation** in favor of banning a decision-making model. It is
|
|
110
|
+
a published, measured argument for the filter "no model in the decision loop", which for us is
|
|
111
|
+
still resting on our own 84–96% measurement.
|
|
112
|
+
|
|
113
|
+
### 0.2 🔴 Coverage measurement: 46 bound, 264 exempted, no expiration
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
grep -o '{{[a-zA-Z0-9_.]*}}' paper.md | wc -l → 46
|
|
117
|
+
grep -oE '\*\*[^*]*[0-9][^*]*\*\*' paper.md | wc -l → 113
|
|
118
|
+
grep -vc '^\s*#\|^\s*$' repro/numbers-grandfathered.txt → 264
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`numbers-grandfathered.txt` describes itself honestly — _"their presence here is an admission, not
|
|
122
|
+
an exemption"_ — but an admission with no expiration date is exactly **lex imperfecta**, precisely
|
|
123
|
+
the category the author's paper studies in others. Aviation's MEL, where the idea "a defect is
|
|
124
|
+
tolerable with a compensating procedure" comes from in the first place, **always supplies the second
|
|
125
|
+
half: a repair deadline by category, that expires automatically.** We took the first half without the
|
|
126
|
+
second.
|
|
127
|
+
|
|
128
|
+
### 0.3 🔴 The substitution law: it is the STRENGTH of a claim that must become unrepresentable, not its content
|
|
129
|
+
|
|
130
|
+
Inherited from `compile-rules-2026/research/2026-08-02-mechanism-sweep-2.md` §0.1, and it lands
|
|
131
|
+
even harder here: a manuscript's framing prose (the reason anyone reads the paper) **cannot** be
|
|
132
|
+
bound to data, and should not be. A mechanism that refuses to accept an unbound sentence produces the
|
|
133
|
+
same state as deletion: the author wanted to say something — got refused — the file stays silent.
|
|
134
|
+
|
|
135
|
+
> **Law.** Unrepresentability is safe only when the refusal, **in that same authoring action**,
|
|
136
|
+
> returns an accepted substitute.
|
|
137
|
+
|
|
138
|
+
Hence the form of the answer: **gradual typing**, not a flag-day cutover. Bound and unbound coexist,
|
|
139
|
+
**the boundary is declared**, and the ratio is measured and printed. This is the ancestor from group
|
|
140
|
+
I, and it was picked not by taste but by the filter "one author, the migration has to pay for
|
|
141
|
+
itself."
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 1. The defect broken down into five classes, then into four properties
|
|
146
|
+
|
|
147
|
+
| # | Observed instance | What actually failed | Closed? |
|
|
148
|
+
| --- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
149
|
+
| 1 | 22 matched the file perfectly, but sat in a sentence about **a different arm** | the defect lives **in the join** between the sentence and the field path; each check looks at only one side | partial: `paper_numbers.py` `requires`/`forbids` — but that is **a list of phrases matched against open prose** |
|
|
150
|
+
| 2 | 11 unreadable passages survived 6 passes, all within threshold | **a proxy was substituted for the property** and reports as though it settled it | 🔴 **no** |
|
|
151
|
+
| 3 | gate marked passed, input missing/newer | staleness was **declared**, not computed | ✅ `ledger.mjs`, content-addressed key + hash of the checker itself |
|
|
152
|
+
| 4 | a check that never once said "no" was counted as working | **vacuousness** | partial: `everSaidNo` **detects** it but does not forbid it |
|
|
153
|
+
| 5 | every judge in the chain is a model from the same family | **ensemble independence is assumed, not established** | 🔴 **no** |
|
|
154
|
+
|
|
155
|
+
Four properties of the ideal pipeline:
|
|
156
|
+
|
|
157
|
+
- **P1 · Join.** A claim and its backing are **one object**, not two things a human reconciles by eye.
|
|
158
|
+
- **P2 · Proxy honesty.** A gate either settles the property, or **declares** that it is measuring a proxy.
|
|
159
|
+
- **P3 · Freshness.** The backing is provably about **these** bytes and **this** checker. ✅ done.
|
|
160
|
+
- **P4 · Non-vacuousness and independence.** The gate has proven it can say "no"; judge correlation
|
|
161
|
+
is not passed off as confirmation.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 2. An attack on the rejected options (one reason refuted, one fixed, one new donor)
|
|
166
|
+
|
|
167
|
+
The skill requires attacking the reasons, not just keeping the ban on file. Bottom line: **of four
|
|
168
|
+
retired reasons, two are wrong.**
|
|
169
|
+
|
|
170
|
+
### 2.1 "Moving to a LaTeX source — we'd lose 31 prose checks" → **stands, the reason is now stronger**
|
|
171
|
+
|
|
172
|
+
The reason is correct but weakly stated. The strong form: **the join is only representable in the
|
|
173
|
+
source.** `{{annotated.failedContradicted}}` inside the rendered `.tex` is already just `22`, and the
|
|
174
|
+
arm is unrecoverable. Indirectly confirmed by 2606.09500: their deterministic tier also sits
|
|
175
|
+
**before** rendering.
|
|
176
|
+
|
|
177
|
+
### 2.2 "DVC/make/snakemake — a second declaration alongside the prose" → **reason CORRECTED**
|
|
178
|
+
|
|
179
|
+
The "second declaration" objection died the day `status.mjs` showed up: there, **nothing is
|
|
180
|
+
declared**, everything is derived. So keeping them out has to rest on a **different** reason, and it
|
|
181
|
+
is already written down in `ledger.mjs`: they key off timestamps and **do not know the recipe
|
|
182
|
+
changed** — which is exactly our own bug. Keep it retired, but with the right reason, or the next
|
|
183
|
+
session reopens the question and gets an unconvincing answer.
|
|
184
|
+
|
|
185
|
+
### 2.3 "JSON inside markdown — prose readability is lost" → **reason REFUTED**
|
|
186
|
+
|
|
187
|
+
Refuted by our own shipped code. `{{annotated.failedContradicted}}` is **more readable** than the
|
|
188
|
+
`22` it replaced: the name names the arm, the digit named nothing. What destroys readability is not
|
|
189
|
+
structure inside prose, but **unresolved** structure.
|
|
190
|
+
|
|
191
|
+
> **Corrected rule:** structure inside prose is admissible exactly when it **resolves into prose
|
|
192
|
+
> at render time**. A sidecar table of claims next to the file is still a no (§3.F3, the AOP lesson).
|
|
193
|
+
|
|
194
|
+
### 2.4 "ARIS — a LaTeX source + 46/83 skills require the Codex MCP" → **stands, but a better donor has appeared**
|
|
195
|
+
|
|
196
|
+
**MedSci Skills** (2606.09500): MIT, skill-based decomposition, **21 deterministic detectors**, no
|
|
197
|
+
Codex dependency, domain is clinical manuscripts (STARD/PRISMA/STROBE). Its form is closer to ours
|
|
198
|
+
than ARIS's. **P1 action:** pull the list of 21 detectors and diff it against our eight — what they
|
|
199
|
+
have that we don't. That is cheaper than any generation.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 3. A sweep of the catalog (what survived and what was killed)
|
|
204
|
+
|
|
205
|
+
Generation proceeded from the catalog's **named constructions**, not from thin air. An honest
|
|
206
|
+
caveat about method is in §6.
|
|
207
|
+
|
|
208
|
+
### A. Type systems
|
|
209
|
+
|
|
210
|
+
- **A1 · smart constructor: no literal in the source.** ✅ **ALREADY SHIPPED** (`{{name}}` +
|
|
211
|
+
jinja2). Difference from knitr — knitr _allows_ both ways; here the literal is **forbidden**
|
|
212
|
+
(`check_bypass`).
|
|
213
|
+
- **A2 · typestate: the arm declared by a block.** 🟢 **SURVIVED, S2.** Right now the arm is caught
|
|
214
|
+
by phrase lists (`requires`/`forbids`) matched against open prose — a synonym not on the list gets
|
|
215
|
+
through. Strictly stronger: `::: {.arm name=strict}` — and `{{annotated.x}}` inside such a block is
|
|
216
|
+
a **build error by string equality** against a **closed vocabulary** (the arms of your own
|
|
217
|
+
experiment, five of them). No model reads the prose at all.
|
|
218
|
+
- **A3 · affine types: evidence is consumed.** 🟢 **SURVIVED, S7** (see H6 — the same idea from
|
|
219
|
+
medicine).
|
|
220
|
+
- **A4 · instance resolution as a gate.** ❌ the same thing as A2, in someone else's syntax. Killed
|
|
221
|
+
as a mechanism duplicate.
|
|
222
|
+
|
|
223
|
+
### B. Formal verification
|
|
224
|
+
|
|
225
|
+
- **B1 · vacuousness as an admission criterion.** 🟢 **SURVIVED, S4.** `everSaidNo` **detects** a
|
|
226
|
+
vacuous gate. Stronger: a gate **cannot be registered** in `EXPECTED_GATES` without a harness case
|
|
227
|
+
that plants its defect and observes it firing. `skills.harness.mjs` already reads
|
|
228
|
+
`EXPECTED_GATES` — the change is small. There is a published precedent: their seeded-defect
|
|
229
|
+
ablation, 27/27 against 11/27.
|
|
230
|
+
- **B2 · refinement: the manuscript refines `CLAIMS.md`.** 🟢 **SURVIVED, part of S1.** Today
|
|
231
|
+
`CLAIMS.md` and `paper.md` are **mechanically connected by nothing at all** — and `CLAIMS.md`
|
|
232
|
+
already holds RETRACTED wordings ("two wordings are DEAD, must not be used"). Nothing stops a
|
|
233
|
+
retracted wording from ending up in the PDF.
|
|
234
|
+
- **B3 · TLA+/Alloy on the process.** ❌ **NEGATIVE RESULT.** The invariant "no reachable submit
|
|
235
|
+
with a stale gate" is already **computed** by `status.mjs`. A model here would add ceremony, not
|
|
236
|
+
safety.
|
|
237
|
+
- **B4 · blame at the boundary.** 🟢 partial, absorbed into S6 + §0.3 (the boundary is declared,
|
|
238
|
+
blame falls on whoever widened it).
|
|
239
|
+
|
|
240
|
+
### C. Functional programming
|
|
241
|
+
|
|
242
|
+
- **C2 · a claim-strength lattice** (`measured < observed < suggests < shows`), abstract ≤ the join
|
|
243
|
+
of the body. ❌ **KILLED BY OCCUPANCY.** This is the literature on **spin in abstracts**, and it is
|
|
244
|
+
large: 97% of trials in one review contain spin, 84% in another; LLM detectors have already been
|
|
245
|
+
measured (GPT-o1, F1 0.932–0.98). Our version would be "no model, on a closed hedge vocabulary" —
|
|
246
|
+
but it can't be claimed as new, and as a tool it's weaker than what's already shipped. File under
|
|
247
|
+
occupied.
|
|
248
|
+
- **C3 · session types on gate ordering.** ❌ **NEGATIVE.** Absorbed by content-addressed
|
|
249
|
+
staleness.
|
|
250
|
+
- **C4 · one AST, many interpreters.** 🟡 **already half exists, and it is the key.**
|
|
251
|
+
`md2submission.py` parses `paper.md` and emits `.tex` + `.bib`. So **a point of complete mediation
|
|
252
|
+
already exists** — every character reaching the reviewer passes through it. Today it's used only
|
|
253
|
+
for formatting. The strong form (markdown as a pure projection of a claim table) ❌ killed by the
|
|
254
|
+
migration filter.
|
|
255
|
+
|
|
256
|
+
### D. Capabilities
|
|
257
|
+
|
|
258
|
+
- **D1 · grants instead of bans.** 🟡 absorbed into S7: the experiment issues "citable" cells, the
|
|
259
|
+
paper spends them; unspent = unreported, overspent = unbacked.
|
|
260
|
+
- **D2 · a reference monitor, a paragraph only through the CLI.** ❌ **KILLED** by the
|
|
261
|
+
"substitution in the same action" filter: friction destroys the framing prose that is the reason
|
|
262
|
+
anyone reads the paper.
|
|
263
|
+
- **D3 · least privilege for judges.** 🟢 **SURVIVED, S5.** Judge correlation is not just shared
|
|
264
|
+
weights, it is **shared context**. Giving each judge only its own section + the declared backing is
|
|
265
|
+
cheaper than sourcing a second vendor, and it lowers correlation on the one axis available to us.
|
|
266
|
+
|
|
267
|
+
### E. Specification by example
|
|
268
|
+
|
|
269
|
+
- **E2 · a golden file per claim.** 🟡 partially covered by provenance.
|
|
270
|
+
- **E3 · extracting a claim with a cold reader and checking it against a DECLARED ID.** 🟡
|
|
271
|
+
**conditionally alive.** The one place a model is admissible: it **does not decide**, it proposes a
|
|
272
|
+
label from a **closed** set, and the decision is equality against the author's declaration. The
|
|
273
|
+
author fixes a mismatch. Risk, stated honestly: the model can guess the declared ID and produce a
|
|
274
|
+
false negative. Keep it advisory, not a gate.
|
|
275
|
+
- **E4 · metamorphic relations: swap the arm and rebuild.** 🟢 **SURVIVED, S7-adjacent.** If you
|
|
276
|
+
swap `annotated` and `strict` and **every gate is still green** — the sentences are not bound to the
|
|
277
|
+
arm, and that is proof without a single declaration from the author. Occupancy: metamorphic testing
|
|
278
|
+
of scientific software is a large field, but the search found no application **to a manuscript
|
|
279
|
+
against its own data**.
|
|
280
|
+
|
|
281
|
+
### F. Data integrity
|
|
282
|
+
|
|
283
|
+
- **F1 · `ADD CONSTRAINT` validates existing rows / `NOT VALID`.** ✅ **SHIPPED** — and
|
|
284
|
+
**with no expiration**, see §0.2 → that is S3.
|
|
285
|
+
- **F2 · a foreign key `ON DELETE RESTRICT`.** 🟡 a cheap add-on to S1: deleting a data row that a
|
|
286
|
+
sentence references should fail.
|
|
287
|
+
- **F3 · store the claim as data, `.md` is a view.** ❌ **KILLED by the AOP lesson** (see I6):
|
|
288
|
+
reading `paper.md`, you stop being able to see what's backed. Admissible only together with S8
|
|
289
|
+
(a marker at the point of use).
|
|
290
|
+
|
|
291
|
+
### G. Author UX
|
|
292
|
+
|
|
293
|
+
- **G1 · asymmetric cost:** "we show" requires a backing ID, "we observed, informally" is free.
|
|
294
|
+
🟢 absorbed into S1+S6.
|
|
295
|
+
- **G2 · change the DEFAULT, don't add a gate.** 🟢 **SURVIVED, S8 — the cheapest thing in the
|
|
296
|
+
sweep.** The author looks at the PDF dozens of times. Let unbound numbers **render with a marker**
|
|
297
|
+
in the draft build (not the submission build). Zero new discipline, feedback lands in the artifact
|
|
298
|
+
people already read.
|
|
299
|
+
- **G3 · a single entry point:** `claim add --from aggregate.json:path`. 🟡 good, but after S1.
|
|
300
|
+
|
|
301
|
+
### H. Other professions
|
|
302
|
+
|
|
303
|
+
- **H1 · aviation's MEL: a repair deadline by category, expires on its own.** 🟢 **SURVIVED, folded
|
|
304
|
+
into S3.**
|
|
305
|
+
- **H2 · SOX: design effectiveness ≠ operating effectiveness.** ✅ **already borrowed**
|
|
306
|
+
deliberately (the `requires`/`forbids` pair). Under-used: the gate table should have **three**
|
|
307
|
+
states, not one — "the control exists / it's designed correctly / it operated in this period."
|
|
308
|
+
- **H3 · MISRA: a decidable/undecidable label on every rule.** 🟢 **SURVIVED, S6.** The only honest
|
|
309
|
+
answer to instance #2: the gate declares whether it settles the property or a proxy. Cost: zero,
|
|
310
|
+
it's a field.
|
|
311
|
+
- **H4 · DO-178C DAL / ISO 26262 ASIL: assurance levels.** 🟢 folded into S3 (level by **position**,
|
|
312
|
+
see below).
|
|
313
|
+
- **H5 · lex imperfecta.** 🟡 a frame, not a mechanism; §0.2 is its application to ourselves.
|
|
314
|
+
- **H6 · CONSORT: accounting for every participant at every stage.** 🟢 **SURVIVED, S7.** Every
|
|
315
|
+
cell of the grid (arm × metric) is either cited by a claim, or **explicitly marked as not
|
|
316
|
+
reported**. This catches the opposite direction of the defect — **measured and not reported**
|
|
317
|
+
(cherry-picking), which nothing catches today and which a reviewer will ask about.
|
|
318
|
+
|
|
319
|
+
### I. Historical ancestors in software engineering
|
|
320
|
+
|
|
321
|
+
- **I1 · gradual typing.** 🟢 **the form of the whole answer** (§0.3). It caught on across a huge
|
|
322
|
+
installed base precisely because it **required no migration** — the one filter that actually bites
|
|
323
|
+
here.
|
|
324
|
+
- **I2 · SPARK's stone→bronze→silver→gold→platinum.** 🟢 the ladder for S3, the rungs are already
|
|
325
|
+
mechanical and published — don't invent our own.
|
|
326
|
+
- **I3 · lint (1978).** ✅ this is the current construction.
|
|
327
|
+
- **I5 · requirements engineering: _testable requirement_ as a category + a traceability matrix.**
|
|
328
|
+
🟢 `CLAIMS.md` is a traceability matrix with no mechanical leg. S1 attaches the leg.
|
|
329
|
+
- **I6 · AOP, and WHY IT FAILED.** 🔴 the most useful negative in the sweep: cross-cutting
|
|
330
|
+
declarations, pulled out of the code, made the code unreadable — looking at it, you can't tell what
|
|
331
|
+
applies to it. **A direct ban on a sidecar table of claims** (F3), and the reason S8 is mandatory
|
|
332
|
+
next to any such extraction: the projection has to be visible **at the point of use**.
|
|
333
|
+
|
|
334
|
+
### J. Migration
|
|
335
|
+
|
|
336
|
+
Strangler fig · `NOT VALID` with a deadline · advisory-then-enforcing · opt-in tiers. This is the
|
|
337
|
+
**rollout form** for everything selected, not a separate mechanism.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## 4. The ideal construction — five laws
|
|
342
|
+
|
|
343
|
+
Not "a new pipeline." Naming what the construction has already converged on, plus what it's still
|
|
344
|
+
missing.
|
|
345
|
+
|
|
346
|
+
> **Law 1 · Complete mediation at the converter.** Everything that reaches the reviewer passes
|
|
347
|
+
> through `md2submission.py`. That is **where** to check, because it is the one place where "the
|
|
348
|
+
> manuscript cannot be produced" is a reachable state, while "the checker complained" is not.
|
|
349
|
+
>
|
|
350
|
+
> **Law 2 · One binding mechanism, three carriers.** Numbers, **citations**, **novelty claims** are
|
|
351
|
+
> the same join, "sentence ↔ backing record." Today the mechanism exists only for numbers.
|
|
352
|
+
>
|
|
353
|
+
> **Law 3 · Strength is unrepresentable, not content.** Unbound prose is a first-class, cheap,
|
|
354
|
+
> declared category. Its **share** is measured and printed, not its existence forbidden.
|
|
355
|
+
>
|
|
356
|
+
> **Law 4 · A proxy declares itself a proxy.** A gate carries a decidable/undecidable label. A gate
|
|
357
|
+
> measuring a proxy has no right to report as though it settled the property.
|
|
358
|
+
>
|
|
359
|
+
> **Law 5 · A gate without a killed mutant does not exist.** Registration requires a witness.
|
|
360
|
+
> Agreement among N judges of the same family counts as **one** witness.
|
|
361
|
+
|
|
362
|
+
**What the construction stays SILENT on (declared, not concealed):**
|
|
363
|
+
|
|
364
|
+
- Only `paper.md → PDF` is gated. **The rebuttal, the artifact README, the cover letter, a blog
|
|
365
|
+
post** carry the same claims and are gated by nothing.
|
|
366
|
+
- Nothing checks that the cited work **actually says** what it's credited with saying (S1 makes the
|
|
367
|
+
link representable, but a human fills it in).
|
|
368
|
+
- Framing prose is not checked and should not be — that is the price of Law 3, accepted knowingly.
|
|
369
|
+
- A metric that was never computed at all will not show up in any accounting (S7 only sees the grid
|
|
370
|
+
of what was computed).
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## 5. Eight survivors, ranked by (cost → what it kills)
|
|
375
|
+
|
|
376
|
+
| # | Mechanism | Kills | Cost | Occupancy |
|
|
377
|
+
| ------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ----------------------------------- | ------------------------------------------------------------ |
|
|
378
|
+
| **S8** | unbound numbers **render with a marker** in the draft build | the 264 exempted self-liquidate | ~5 lines in `md2submission.py` | unoccupied |
|
|
379
|
+
| **S4** | a gate **cannot be registered** without a killed mutant | instance #4 (vacuousness) | ~20 lines in `skills.harness.mjs` | published as an ablation, the mechanism itself is unoccupied |
|
|
380
|
+
| **S6** | a **decidable/undecidable** label on the gate | instance #2 (proxy as property) | a field + a column | MISRA, take as-is |
|
|
381
|
+
| **S5** | least-privilege judges; N of the same family = **1** witness | instance #5 (correlation) | a ledger field + a narrowed prompt | unoccupied |
|
|
382
|
+
| **S2** | **arm declared by a block** instead of phrase lists | instance #1, no prose heuristics | a block attribute + string equality | no occupancy found |
|
|
383
|
+
| **S1** | **one binding, three carriers** (numbers + citations + `CLAIMS.md`) | a retracted claim ends up in the PDF | medium, a resolver exists | ResearchLoop calls it "paper bindings" — **check the PDF** |
|
|
384
|
+
| **S3** | a ladder by **position** (abstract/section-lead-in = binding required; appendix = optional) + a deadline | the 264 with no expiration | medium | SPARK/DO-178C, take the form |
|
|
385
|
+
| **S7** | **arm × metric** accounting: every cell is either cited or explicitly marked not reported | measured-and-not-reported (cherry-picking) | a diff script | CONSORT — the form; no application found for our case |
|
|
386
|
+
|
|
387
|
+
**Why a ladder by POSITION and not a global deadline:** an unbound number in the abstract and one
|
|
388
|
+
in appendix B differ by an order of magnitude in blast radius. A single author does not convert 264
|
|
389
|
+
positions; they convert the ones a reviewer will quote. This is the DO-178C move (assurance level by
|
|
390
|
+
consequence of failure), not the MEL move (a single deadline), and it is more honest about a real
|
|
391
|
+
budget.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 6. Negative results and honesty about method
|
|
396
|
+
|
|
397
|
+
**Groups that gave nothing** (don't re-sweep these): **B3** (TLA+/Alloy on the process — the
|
|
398
|
+
invariant is already computed), **C3** (session types on ordering — absorbed by staleness), **C2**
|
|
399
|
+
(claim-strength lattice — occupied by the spin literature), **D2** (complete mediation at the
|
|
400
|
+
paragraph level — killed by friction), **F3** (sidecar claims — killed by the AOP lesson), **A4**
|
|
401
|
+
(instance resolution — a duplicate of A2), **C4's strong form** (markdown as a pure projection —
|
|
402
|
+
killed by migration cost).
|
|
403
|
+
|
|
404
|
+
**🔴 Departure from the skill's procedure, stated plainly.** The skill requires generating
|
|
405
|
+
candidates via **a subagent with no thread context**. In this environment there is no
|
|
406
|
+
subagent-spawning tool (`Task` is unavailable; there is only cross-session, asynchronous
|
|
407
|
+
`SendMessage`/`create_session`). Generation was done by me, under the discipline "from the catalog's
|
|
408
|
+
named constructions," **after** reading the pipeline — meaning the thread anchor was **not**
|
|
409
|
+
removed. Practical consequence: §3 should be considered complete by group, but possibly incomplete on
|
|
410
|
+
the "non-obvious" candidates — exactly the class that produced the three best ideas last time.
|
|
411
|
+
Compensated by where the budget actually went: **the occupancy check**, which no anchor fixes and
|
|
412
|
+
which is what turned the picture around here (§0.1).
|
|
413
|
+
|
|
414
|
+
**Evidence levels:** [A] read in full at the primary source · [B] abstract verbatim ·
|
|
415
|
+
[C] search results · [D] a PDF summarized by a small model, **do not trust**.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## 7. What to do (ranked by benefit-to-cost, descending)
|
|
420
|
+
|
|
421
|
+
1. **P0 · Read both PDFs in full** (2606.09500, 2605.28282). Summaries are [D]. How much of
|
|
422
|
+
S1/S4/S7 remains ours depends on their content.
|
|
423
|
+
2. **P0 · Re-check the claim in the `paper_numbers.py` docstring** — _"Not one of them has a hook
|
|
424
|
+
where you could say the sentence around this number must say counterfactual and must not say as
|
|
425
|
+
committed"_ — against **MedSci's 21 detectors**. The claim was written before this work was known
|
|
426
|
+
about; if it's false, it's false **both in shipped code and in the novelty reasoning**.
|
|
427
|
+
3. **P1 · Build S8 and S4** — together that is under fifty lines and closes two of the five
|
|
428
|
+
instances.
|
|
429
|
+
4. **P1 · Diff our eight checkers against their 21** — cheaper than any generation.
|
|
430
|
+
5. **P2 · S2 and S1** — the constructive part; S1 is itself the answer to "how it should be
|
|
431
|
+
ideally."
|
|
432
|
+
6. **P3 · S3 and S7** — require budget, do after submission.
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
# 8. Second pass, FOR REFUTATION (2026-08-09, addendum)
|
|
437
|
+
|
|
438
|
+
A separate `sweep-design-space` run. The goal is not to redo the sweep but to attack its single
|
|
439
|
+
most load-bearing part. §0.1 kills the architecture-novelty claim, is marked **[B]**, and warns
|
|
440
|
+
about confabulation about itself ("stylistically resembles confabulation"). Per the base's own rule
|
|
441
|
+
("a conclusion that changes a decision → a second pass for refutation"), this must be re-checked
|
|
442
|
+
before it is cited as fact.
|
|
443
|
+
|
|
444
|
+
**Method: the model is removed from the decision loop.** The previous pass read the PDF through
|
|
445
|
+
WebFetch, where a small model synthesizes the answer — exactly the mechanism under suspicion here.
|
|
446
|
+
Instead: raw XML from the arXiv API (`export.arxiv.org/api/query?id_list=…`) and **a clone of the
|
|
447
|
+
source repository**. Not a single model summary in the chain. The level rises to **[A]**.
|
|
448
|
+
|
|
449
|
+
## 8.1 ✅ §0.1 HELD — both works are real, quotes are verbatim
|
|
450
|
+
|
|
451
|
+
| field | 2606.09500 | 2605.28282 |
|
|
452
|
+
| -------------- | ------------------------------------------------- | ------------------------------ |
|
|
453
|
+
| `totalResults` | 1 | 1 |
|
|
454
|
+
| version | **v4** | v1 |
|
|
455
|
+
| `published` | **2026-06-08T13:51:04Z** | **2026-05-27T10:29:00Z** |
|
|
456
|
+
| `updated` | 2026-06-14T00:06:13Z | 2026-05-27T10:29:00Z |
|
|
457
|
+
| authors | Yoojin **Nam**, Jinhoon **Jeong**, Namkug **Kim** | Yihan **Xia**, Taotao **Wang** |
|
|
458
|
+
| category | cs.AI (+cs.DL) | cs.AI |
|
|
459
|
+
|
|
460
|
+
The title of 2606.09500 (not given in §0.1): _«Deterministic Integrity Gates for LLM-Assisted
|
|
461
|
+
Clinical Manuscript Preparation: An Auditable Biomedical Informatics Architecture»_.
|
|
462
|
+
Both abstract paragraphs in §0.1 were checked character-by-character against the API output —
|
|
463
|
+
**no discrepancies**. The architecture's occupancy is confirmed. The claim "we built a
|
|
464
|
+
manuscript-verification architecture" remains dead, and it is now [A] rather than [B].
|
|
465
|
+
|
|
466
|
+
From the arXiv comment (absent from §0.1, and it is the key to everything below):
|
|
467
|
+
|
|
468
|
+
> Software (MIT): `https://github.com/Aperivue/medsci-skills` . Archived on Zenodo: concept DOI
|
|
469
|
+
> `10.5281/zenodo.20155321` and version DOI (v3.8.0) `10.5281/zenodo.20582972`
|
|
470
|
+
|
|
471
|
+
## 8.2 🔴 S4 IS OCCUPIED — and its owner has already published it — WHY THAT IS NOT ENOUGH
|
|
472
|
+
|
|
473
|
+
The repository was cloned and checked for identity:
|
|
474
|
+
`aperivue/medsci-skills`, HEAD `b2c120e667d5a329add8ae5bc3371411f739bd60`, origin verified.
|
|
475
|
+
|
|
476
|
+
**S4 in the §5 table** ranked second by cost/benefit: _"a gate cannot be registered without a
|
|
477
|
+
killed mutant, ~20 lines in `skills.harness.mjs`"_, occupancy — _"published as an ablation, the
|
|
478
|
+
mechanism is unoccupied"_.
|
|
479
|
+
|
|
480
|
+
**The mechanism is NOT unoccupied. It has been shipped, under MIT, across 85 detectors.**
|
|
481
|
+
Verbatim, `paper.md:23`:
|
|
482
|
+
|
|
483
|
+
> «Each detector ships a synthetic **challenge card** — a positive case and a negative control —
|
|
484
|
+
> that runs in continuous integration, so **a clean result is meaningful** and a flagged defect is
|
|
485
|
+
> reproducible.»
|
|
486
|
+
|
|
487
|
+
"so a clean result is meaningful" — that is exactly our anti-vacuousness argument, in their prose.
|
|
488
|
+
On top of the card, they have a second leg — `check_detector_crossfire.py` (a detector must **stay
|
|
489
|
+
silent** on clean demo manuscripts).
|
|
490
|
+
|
|
491
|
+
**And that is not even the main thing.** `reverse_engineer/HELDOUT.md:3–17`, verbatim:
|
|
492
|
+
|
|
493
|
+
> «Every detector in this repo is tested against fixtures authored alongside it: a challenge card
|
|
494
|
+
> proving it fires on a planted defect, and `check_detector_crossfire.py` proving it stays silent on
|
|
495
|
+
> the demo manuscripts. Both are necessary. **Neither is independent.** In machine-learning terms
|
|
496
|
+
> they are a **training set**, and a detector passing its own challenge card is a **training accuracy
|
|
497
|
+
> of 100% — true, and uninformative about anything.**»
|
|
498
|
+
|
|
499
|
+
> «An improvement loop whose generator and evaluator share a framing drifts toward the evaluator
|
|
500
|
+
> rather than the goal — the measured quality rises while the unmeasured quality falls. **The
|
|
501
|
+
> counterweight is not another gate. Adding gates is what produces the drift.** The counterweight is
|
|
502
|
+
> a set of cases the gates were never allowed to learn from, scored periodically, whose trend can
|
|
503
|
+
> contradict us.»
|
|
504
|
+
|
|
505
|
+
Their replacement is a held-out corpus with a mandatory `frozen_at` field:
|
|
506
|
+
|
|
507
|
+
> «`frozen_at` is required on every held-out record, because the claim is chronological: a freeze
|
|
508
|
+
> date that **precedes the detector** is what makes it checkable rather than asserted.»
|
|
509
|
+
|
|
510
|
+
**Consequence for S4 — rewrite, don't discard.** A harness case planted by the gate's own author
|
|
511
|
+
gives 100% training accuracy. That is still strictly better than nothing (it catches instance #4 —
|
|
512
|
+
a gate that never once said "no"), but **it cannot be claimed as sufficient**, and even less so as
|
|
513
|
+
novel. The honest form of S4 is two tiers, where the second is the real one — (a) the author's card =
|
|
514
|
+
admission, training; (b) a corpus frozen **before** the gate was written = the one measurement worth
|
|
515
|
+
trusting. We have (b) in no form at all.
|
|
516
|
+
|
|
517
|
+
To be honest about the caveat: their own HELDOUT.md records that the rule **was violated on
|
|
518
|
+
2026-07-31** (three agents reached `_corpus/heldout/`, one ran a detector against the corpus). The
|
|
519
|
+
finding was quarantined and not applied. This does not weaken the mechanism — it shows its cost.
|
|
520
|
+
|
|
521
|
+
## 8.3 🔴 The "21 detectors" number is stale — theirs is **85**, and the catalog is machine-generated
|
|
522
|
+
|
|
523
|
+
`metadata/detectors_catalog.json`, field `detector_count` = **85** (not 21; 21 is the June paper's
|
|
524
|
+
number, the repo has moved on). Breakdown by family, verbatim from the catalog:
|
|
525
|
+
|
|
526
|
+
| n | family_label |
|
|
527
|
+
| --- | --------------------------------------- |
|
|
528
|
+
| 24 | Style & review-process integrity |
|
|
529
|
+
| 17 | Data preparation & validation |
|
|
530
|
+
| 17 | Reporting compliance |
|
|
531
|
+
| 11 | Numerical, cohort & pool arithmetic |
|
|
532
|
+
| 9 | Citation & reference integrity |
|
|
533
|
+
| 7 | Confounding, scope & estimand contracts |
|
|
534
|
+
|
|
535
|
+
The catalog itself is **AUTO-GENERATED** (`scripts/gen_detectors_catalog_json.py` globbing
|
|
536
|
+
`skills/*/scripts/`, with a CI gate on drift). So their registry is **derived, not declared** — the
|
|
537
|
+
same discipline as our `status.mjs`, and confirmation that §2.2 (the retired reason about "a second
|
|
538
|
+
declaration") was closed correctly.
|
|
539
|
+
|
|
540
|
+
**P1 #4 from §7 is reformulated:** the diff is not "our 8 against their 21" but **our 7 against
|
|
541
|
+
their 85** (there are exactly 7 gates in `run-mechanical.mjs`, not 8 — recounted). Diffing by
|
|
542
|
+
family: our seven fall entirely inside "Numerical" + "Style", and **three of their families are
|
|
543
|
+
represented by nothing of ours** — Reporting compliance, Data preparation, Confounding/estimand.
|
|
544
|
+
Directly relevant to our topic is "Citation & reference integrity" (9 detectors) — that is carrier
|
|
545
|
+
#2 from Law 2 (citations), which is listed in our §5/S1 as unwritten.
|
|
546
|
+
|
|
547
|
+
## 8.4 🔴 An attack on the frame of the whole sweep
|
|
548
|
+
|
|
549
|
+
The sentence _«The counterweight is not another gate. Adding gates is what produces the drift»_
|
|
550
|
+
hits not one candidate but the shape of the whole answer: §5 is a list of eight **new gates**. It
|
|
551
|
+
does not invalidate S1–S8 (our instances #1–#5 are real and observed), but it adds a filter that
|
|
552
|
+
wasn't in §2 and that needs to be recorded in the skill:
|
|
553
|
+
|
|
554
|
+
> **Filter: what measures whether a new gate actually helped?** A gate whose effect is observable
|
|
555
|
+
> only through the same gates raises measured quality and says nothing about the unmeasured kind.
|
|
556
|
+
|
|
557
|
+
By this filter, S8 (the marker in the draft build) looks **better** than all the rest: its
|
|
558
|
+
feedback lands on the human, in the PDF, not in a gate table. S8's rank of #1 in §5 is confirmed
|
|
559
|
+
independently.
|
|
560
|
+
|
|
561
|
+
## 8.5 What is still unoccupied (checked by grepping their repo)
|
|
562
|
+
|
|
563
|
+
- **S6** (a `decidable/undecidable` label on the gate) — they have `family`, but there is **no**
|
|
564
|
+
proxy-honesty label: `grep -ri undecidable` over the repo → **zero hits**. Unoccupied, stands.
|
|
565
|
+
- **S3** (the ladder + an expiration date on exemptions) — `grep -ri grandfather` → **zero**.
|
|
566
|
+
Unoccupied.
|
|
567
|
+
- **S1/S2/S7** — no direct matches found, but this was only checked by grepping keywords, not by
|
|
568
|
+
reading all 85 detectors. Level **[C]**, not [A].
|
|
569
|
+
|
|
570
|
+
## 8.6 Occupancy is wider than two papers
|
|
571
|
+
|
|
572
|
+
`paper.md` in their repo is a **third** artifact: a separate software paper that cites 2606.09500
|
|
573
|
+
as a companion (`[@nam2026gates]`, _«conducted on an earlier release of the toolkit»_). So this is
|
|
574
|
+
not "two papers" but an actively developing line of work from 2026-05 to 2026-08. The previous
|
|
575
|
+
occupancy pass did not see this.
|
|
576
|
+
|
|
577
|
+
## 8.7 What this pass did NOT do
|
|
578
|
+
|
|
579
|
+
- **P0 #1 (read both PDFs in full) — still NOT closed.** The abstracts [A] and shipped code [A]
|
|
580
|
+
were checked; the bodies of the papers were not read. Everything §0.1 derives from the bodies
|
|
581
|
+
remains [B]/[D].
|
|
582
|
+
- No generation of new candidates was done — this pass was a verification pass. The gap from §6
|
|
583
|
+
(generation without thread context) **remains open**; `Task` is still unavailable in this
|
|
584
|
+
environment.
|
|
585
|
+
- S1/S2/S7 against their 85 detectors were checked by grepping, not by reading — [C].
|