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,517 @@
|
|
|
1
|
+
// Compiled to SKILL.md by `vigiles compile`. Edit THIS file, never the markdown.
|
|
2
|
+
//
|
|
3
|
+
// Adopted 2026-08-17 (batch 3). Body carried over VERBATIM so the compiled diff shows
|
|
4
|
+
// only what the compiler adds. No `disallowedTools` fence yet — the field landed on
|
|
5
|
+
// `SkillSpec` in vigiles branch `claude/skill-disallowed-tools` and is not in a release
|
|
6
|
+
// this repo installs, so writing one here would not compile.
|
|
7
|
+
import { experimental_skill } from "vigiles/spec";
|
|
8
|
+
|
|
9
|
+
export default experimental_skill({
|
|
10
|
+
name: "paper-pipeline",
|
|
11
|
+
description:
|
|
12
|
+
"The orchestrator for writing a research paper end-to-end, from idea to accepted-and-extended, with every stage graded for the credit it earns a body of work. START HERE when writing/hardening a paper (AgenticDev, AISec, and future ones) and want the whole lifecycle driven, not one step. Routes to the stage skills — research-ideate, find-venue, plan-paper-timeline, build-benchmark, draft-paper, render-paper, verify-citations, the review skills, submit-paper (+ venue cards), camera-ready, extend-paper — and owns the shared references.",
|
|
13
|
+
tools: [
|
|
14
|
+
"Read",
|
|
15
|
+
"Write",
|
|
16
|
+
"Edit",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Glob",
|
|
19
|
+
"Bash",
|
|
20
|
+
"WebSearch",
|
|
21
|
+
"WebFetch",
|
|
22
|
+
"Agent",
|
|
23
|
+
"Skill",
|
|
24
|
+
],
|
|
25
|
+
body: `
|
|
26
|
+
# paper-pipeline — the conductor for the whole organism
|
|
27
|
+
|
|
28
|
+
This is the entry point. Each lifecycle stage is its own skill; this routes through them in order and
|
|
29
|
+
owns the shared reference docs the others cite. **These papers are written to COUNT as credentials** —
|
|
30
|
+
every stage is graded against \`references/credit-criteria.md\`, not abstract "impact." The personal half
|
|
31
|
+
of that — who is filing what, and when — stays in the author's own private notes, never in a public repo.
|
|
32
|
+
|
|
33
|
+
## Shared references (single source of truth — all skills cite these)
|
|
34
|
+
- \`references/credit-criteria.md\` — which criteria a paper feeds; where venue quality bites; the
|
|
35
|
+
decisions credit value forces on the pipeline.
|
|
36
|
+
- \`references/artifact-checklist.md\` — the self-checking reproduction artifact.
|
|
37
|
+
- \`references/anonymization.md\` — the double-blind deny-list + hygiene (and its reverse at camera-ready).
|
|
38
|
+
- \`references/writing-craft.md\` — how well-written papers read (craft rules + exemplar lessons + the
|
|
39
|
+
gradeable 9-dim writing rubric); cited by \`draft-paper\`, \`grade-paper-writing\`, and \`harden-paper\`.
|
|
40
|
+
- \`references/review-ratchet.md\` — how to fix a caught overclaim (tighten → cut → Threats → hedge)
|
|
41
|
+
and why every review round must be paid back with a \`tighten-paper\` pass; cited by
|
|
42
|
+
\`paper-adversarial-review\`, \`pc-panel-review\`, \`harden-paper\`.
|
|
43
|
+
- \`references/pipeline-status-template.md\` — the per-paper **readiness scorecard** (which stages ran,
|
|
44
|
+
grades, open findings, submit-ready verdict). Copied into \`<paper-dir>/PIPELINE-STATUS.md\`.
|
|
45
|
+
- \`references/acl-venue-rules.md\` — what holds at **every** ACL-family venue and workshop: the
|
|
46
|
+
page-limit map, the appendix rule and the trap inside it, Limitations/Ethics as free-but-restricted
|
|
47
|
+
space, anonymity, OpenReview mechanics. Fetch once, not per paper. Venue-specific facts stay in
|
|
48
|
+
\`submit-paper/references/venues/<venue>.md\`. (No equivalent yet for ACM or IEEE — write one when
|
|
49
|
+
the next paper goes there.)
|
|
50
|
+
|
|
51
|
+
## The readiness scorecard (which boxes are checked)
|
|
52
|
+
Stages run in subagents and report into chat, which evaporates — so "did everything run?" becomes
|
|
53
|
+
unanswerable. Fix: every paper carries a **\`<paper-dir>/PIPELINE-STATUS.md\`** (template in
|
|
54
|
+
\`references/pipeline-status-template.md\`), the durable colocated source-of-truth for *which stages ran,
|
|
55
|
+
their grade/result, what's open,* and a one-line **submit-ready verdict**. Rules:
|
|
56
|
+
- **When any stage runs (here or in a subagent), update its row in the same commit** — status, date,
|
|
57
|
+
result, open findings, artifact link. The scorecard is only trustworthy if it's kept live.
|
|
58
|
+
- **Never inflate:** a stage not run *this* cycle is \`☐\`, even if a prior submission ran it — don't
|
|
59
|
+
borrow credit you can't point to. Approximate/from-memory grades get \`≈\`.
|
|
60
|
+
- **"Is paper X ready / what's checked?"** = read this file (verdict + any \`☐\`/\`◐\`/\`⚠\` rows), don't
|
|
61
|
+
reconstruct from chat.
|
|
62
|
+
- Distinct from \`SUBMIT-CHECKLIST.md\` (venue-format compliance); both must be green before upload.
|
|
63
|
+
- 🔴 **Enforcement leg (prose-isn't-policy), and it is a script, not a paragraph.**
|
|
64
|
+
\`scripts/pipeline-check.mjs\` reads this file on every paper edit and reports the failures that
|
|
65
|
+
actually happened on real papers: a CONTINUOUS check whose last run predates the current text, a GATE
|
|
66
|
+
that ran without its required input, **a \`Requires\` cell that omits an edge the pipeline declares**
|
|
67
|
+
(the canonical set is \`scripts/pipeline-edges.mjs\`, with the admitting sentence per edge), a study
|
|
68
|
+
that ran with no stated claim, the \`access\` row not green inside the moderation window, and a verdict
|
|
69
|
+
line that is just an accept probability. Run it directly
|
|
70
|
+
with \`node .claude/skills/paper-pipeline/scripts/pipeline-check.mjs <paper-dir>\`; it is wired into
|
|
71
|
+
\`.claude/hooks/paper-status-gates.sh\` and asserted in \`.claude/hooks/hooks.harness.mjs\`.
|
|
72
|
+
**The grading itself stays judgment** (that is the skills' job) — only the mechanically checkable
|
|
73
|
+
parts are compiled. *Added 2026-08-03, the day three hooks in this repo were found to have been dead
|
|
74
|
+
for weeks: an advisory that is never exercised is indistinguishable from one that works.*
|
|
75
|
+
|
|
76
|
+
🔴 **As of 2026-08-26, this file is read by TWO things.** Sixteen checks over it live as
|
|
77
|
+
\`@eslint/markdown\` rules in \`eslint-rules/pipeline-status.mjs\` (run:
|
|
78
|
+
\`npx eslint <paper-dir>/PIPELINE-STATUS.md\`; five of them are \`error\`), while
|
|
79
|
+
\`scripts/pipeline-check.mjs\` holds six whose input lies OUTSIDE the file — git, the clock, the
|
|
80
|
+
\`reviews/\` directory, \`process.env\`. The classification of all 22 lives in the
|
|
81
|
+
author's private notes (\`<papers-root>/research/2026-08-26-klassifikatsiya-pipeline-check.md\`).
|
|
82
|
+
|
|
83
|
+
⚠️ The paragraph above lived for a day NOT HERE but directly in \`SKILL.md\` — i.e. in the
|
|
84
|
+
generated file. The very first \`vigiles compile\` (27.08) ate it, and it was not a human who
|
|
85
|
+
noticed but an agent whose compile had just erased someone else's edit. **An edit to \`SKILL.md\`
|
|
86
|
+
without \`.spec.ts\` is an edit with an expiration date: the next compile.**
|
|
87
|
+
|
|
88
|
+
## 🗺️ Where every check actually runs — and where it can be walked around
|
|
89
|
+
|
|
90
|
+
\`\`\`
|
|
91
|
+
YOU EDIT YOU COMMIT YOU BUILD YOU PUSH
|
|
92
|
+
│ │ │ │
|
|
93
|
+
▼ ▼ ▼ ▼
|
|
94
|
+
┌──────────────┐ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐
|
|
95
|
+
│ PostToolUse │ │ .githooks/ │ │ build- │ │ GitHub Actions │
|
|
96
|
+
│ paper-lint │ BLOCKS │ pre-commit │REFUSES│ submission.sh │ │ paper-gates │
|
|
97
|
+
│ pre >55 wds │ │ │ │ │ │ │
|
|
98
|
+
│ paper-lint │ nudges │ numbers gate │ │ numbers gate │REFUSES numbers+self│
|
|
99
|
+
│ post │ │ │ │ │ │ │
|
|
100
|
+
│ prose-lint │ │ prose-lint │ nudge │ page count │ │ prose-lint │
|
|
101
|
+
│ SHAVE │ │ self-test if │ │ overfull │ │ check-anon │
|
|
102
|
+
│ numbers │ │ you touched │ │ unresolved │ │ verify-cites │
|
|
103
|
+
│ paper-edit- │ BLOCKS │ a gate │ │ refs │ │ provenance │
|
|
104
|
+
│ guard │ bash │ harness if │ │ dropped glyphs│ │ scorecard │
|
|
105
|
+
└──────────────┘ │ you touched │ │ anon grep │ │ harness │
|
|
106
|
+
│ │ a hook │ └────────────────┘ │ LaTeX build │
|
|
107
|
+
│ │ RAW DNA │REFUSES │ └────────────────┘
|
|
108
|
+
│ └────────────────┘ │ │
|
|
109
|
+
│ │ │ │
|
|
110
|
+
watches EVENTS watches STATE watches OUTPUT watches EVERYTHING
|
|
111
|
+
(Edit/Write fired) (what is staged) (the actual PDF) (after the fact)
|
|
112
|
+
│ │
|
|
113
|
+
│ │
|
|
114
|
+
🕳 BYPASSABLE: 🛡 NOT bypassable by that route: it does not care
|
|
115
|
+
write from Bash and HOW the bytes got there. However you wrote the
|
|
116
|
+
no event fires, so file, you still have to commit it.
|
|
117
|
+
every PostToolUse
|
|
118
|
+
check silently
|
|
119
|
+
does not run.
|
|
120
|
+
\`\`\`
|
|
121
|
+
|
|
122
|
+
**Read the bottom row, it is the whole point.** Each column watches a different KIND of thing, and
|
|
123
|
+
that is why they are not three copies of one check:
|
|
124
|
+
|
|
125
|
+
- **Editor hooks watch events.** Fast, and the only layer that can stop a bad edit *before* it lands.
|
|
126
|
+
Bypassable by construction — an event that never fires cannot be checked, and writing the file from
|
|
127
|
+
Bash produces no event. Documented in \`papers/CLAUDE.md\`, open since 2026-08-04.
|
|
128
|
+
- **The git hook watches state.** Immune to that whole class, because it reads what is staged and has
|
|
129
|
+
no opinion about how it got staged. This is the layer that was missing, and the one to reach for
|
|
130
|
+
when an editor check turns out to be walkable-around.
|
|
131
|
+
- **The build watches output.** Only it can see page count, overfull boxes, and glyphs pdflatex
|
|
132
|
+
silently dropped — none of which exist until the PDF does.
|
|
133
|
+
- **CI watches everything, but after the fact.** Its real job is the slow checks nobody will wait for
|
|
134
|
+
locally (the anonymity self-test copies a 24 MB bundle per leak category) and the self-tests, which
|
|
135
|
+
are what catch a gate that has quietly stopped catching things.
|
|
136
|
+
|
|
137
|
+
🔴 **A fifth kind, and none of the four columns can see it: does the MODEL call these skills at all?**
|
|
138
|
+
Every column above watches something the repository produced — an event, staged bytes, a PDF, a commit.
|
|
139
|
+
None watches *selection*: whether a real model, reading 37 competing descriptions, picks \`tighten-paper\`
|
|
140
|
+
over \`grade-paper-writing\` when the draft is bloated. A harness test proves a skill works once invoked;
|
|
141
|
+
it cannot prove it gets invoked. That needs the real CLI and it costs money, so it is a measurement, not
|
|
142
|
+
a gate — \`.claude/skills/paper-pipeline/pipeline-firing.eval.mjs\`, run manually or by the weekly
|
|
143
|
+
\`skill-firing\` job (\`workflow_dispatch\` + \`schedule\`, deliberately NOT on push). It installs every skill
|
|
144
|
+
in this repo natively so selection is *competitive*, feeds each skill 4 prompts it should fire on plus 4
|
|
145
|
+
its colliding sibling owns, and reports recall / false-positive / precision per skill against a committed
|
|
146
|
+
baseline. **What it measures drifts without a commit here** — a model update can change routing while
|
|
147
|
+
every file stays byte-identical, which is exactly the regression no check in the diagram can see.
|
|
148
|
+
Prior art is named in the file header (\`adewale/skill-eval-harness\` does this too); the idea is not ours.
|
|
149
|
+
|
|
150
|
+
🔴 **Still manual, and no mechanism has been found for it:** the **cold read** — a reader with no
|
|
151
|
+
context restating each sentence — is the only check that catches a sentence that is short, true,
|
|
152
|
+
threshold-passing and meaningless. It needs a fresh subagent, so no hook can run it. What IS
|
|
153
|
+
mechanised is noticing that it is *overdue*: \`pipeline-check.mjs\` reports \`stale-cold-read\` when the
|
|
154
|
+
prose changed after the last one.
|
|
155
|
+
|
|
156
|
+
Install the git hook once per clone: \`git config core.hooksPath .githooks\`.
|
|
157
|
+
|
|
158
|
+
## 🔴 There is no stage 7. Four kinds of work, four shapes.
|
|
159
|
+
|
|
160
|
+
**This section replaced a single numbered list running 0 → 12, on 2026-08-03.** That list had a
|
|
161
|
+
paragraph on top explaining that the numbers were dependencies rather than turns — and underneath it,
|
|
162
|
+
a table numbered straight through, which every reader (including this pipeline's own author) read as a
|
|
163
|
+
waterfall. The paragraph was the tell: a document that needs a disclaimer explaining how not to read
|
|
164
|
+
it is mis-shaped, and the fix is to change the shape, not to add a second disclaimer. That is the
|
|
165
|
+
argument \`compile-rules-2026\` makes about instruction files, applied here.
|
|
166
|
+
|
|
167
|
+
Three concrete errors the numbering produced, all real:
|
|
168
|
+
|
|
169
|
+
- **\`verify-citations\` sat at 7**, looking like a one-shot step, while the project rule is that it runs
|
|
170
|
+
every cycle — an edit on the last day adds a \`\\cite\` that "we checked last cycle" does not cover.
|
|
171
|
+
- **\`render-paper\` sat at 6**, as a stage. It is a command you run twenty times a day.
|
|
172
|
+
- **\`map-prior-work\` sat at 1.5** and its own description told you to re-run it as a cheap delta before
|
|
173
|
+
submit — so it was simultaneously a stage and a continuous check, and the table could only show one.
|
|
174
|
+
|
|
175
|
+
Work is now grouped by **how it runs**, and only the groups that are genuinely ordered carry an order.
|
|
176
|
+
|
|
177
|
+
| kind | shape | how to read it |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| **SETUP** | ordered | Each genuinely gates the next. Runs once, before the study is malleable. |
|
|
180
|
+
| **LOOP** | unordered cycle | Draft ↔ study ↔ arc ↔ review. No numbers, because there are no turns. |
|
|
181
|
+
| **CONTINUOUS** | trigger table | Fires when the thing it checks changes. Never "done". |
|
|
182
|
+
| **GATES** | ordered by input | Late, expensive, each hard-blocked on a named input. |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## SETUP — once, before anything is expensive to change
|
|
187
|
+
|
|
188
|
+
Ordered, because each really does gate the next. Two pairs run in parallel; that is marked.
|
|
189
|
+
|
|
190
|
+
| Step | Skill | What it settles |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| **Orient** | — | Read \`<papers-root>/HANDOFF.md\` + \`<papers-root>/research/README.md\`. Never restart from scratch. |
|
|
193
|
+
| **Validate the idea** | **\`research-ideate\`** | Is it a reusable method (survives review) in your lane, and does it feed the credit criteria? Go/no-go + the MVP finding. |
|
|
194
|
+
| **Map the competition** ‖ | **\`map-prior-work\`** | 🔴 **Who already did this?** Multi-angle sweep; date each hit against your submission (5 months = prior, not concurrent); triage by which layer of your claim it threatens; deep-read the dangerous ones. Output: **what you can still claim** + a related-work skeleton. *Added 2026-07-27 after a five-month-older paper surfaced at T−10 days on a finished draft.* |
|
|
195
|
+
| **Pick the venue** ‖ | **\`find-venue\`** | Rank by credit-weight (peer-reviewed + indexed) × fit × accept-odds × deadline × remote. |
|
|
196
|
+
| **Learn the venue's bar** | **\`study-accepted-papers\`** | 🔴 **What does an ACCEPTED paper look like HERE?** Measure the venue's whole accepted volume, deep-read 8–12 of your contribution type, and extract what made them strong: evidence scale, figures, artifact release, how the abstract is built. File the venue card (\`submit-paper/references/venues/<venue>.md\`) and confirm family rules (\`references/acl-venue-rules.md\`). *Promoted to its own step 2026-08-03: on \`compile-rules-2026\` every judgement of the paper's quality — rubric, persona, simulated panel, accept probability — came from instruments this pipeline itself generated, with no external grounding, and the author had to say so at T−3 days. A closed loop optimises against its own model of a reviewer.* |
|
|
197
|
+
| 🔴 **Can you physically submit?** | **\`plan-paper-timeline\`** | **The step that owns the question no stage used to own.** Create the portal account NOW; drive the profile to **ACTIVE**, not "pending moderation"; confirm the form's fields and the artifact-hosting requirement. OpenReview moderation runs **up to two weeks**, and an author with no institutional email has no expedite route. Scorecard row \`access\`. *Added 2026-08-03, when this was the sole critical-path item on a finished paper at T−4 days: the science was done and there was nowhere to put it.* |
|
|
198
|
+
| **Schedule it** | **\`plan-paper-timeline\`** | Deadlines → calendar with buffers, in the author's own zone (AoE − 12h ≠ your clock). Space papers apart. |
|
|
199
|
+
| 🔴 **State the claim** | **\`argument-arc\`** (frame mode) | **One paragraph: what will this paper claim, and what would have to be true?** Before any run. The frame decides which results matter, and reframing after the data is collected is how experiments get thrown away — observed on \`compile-rules-2026\`, and the reason \`argument-arc\` has a rebuild mode at all. Costs a paragraph; saves a study. Scorecard row \`frame\`. |
|
|
200
|
+
|
|
201
|
+
## LOOP — iterates until it settles
|
|
202
|
+
|
|
203
|
+
No numbers. Nothing here happens once, and nothing here is "next".
|
|
204
|
+
|
|
205
|
+
\`\`\`
|
|
206
|
+
study ──────────► draft
|
|
207
|
+
build-benchmark draft-paper
|
|
208
|
+
▲ │
|
|
209
|
+
│ ▼
|
|
210
|
+
argument-arc ◄──── the arc
|
|
211
|
+
(rebuild mode) 5.5 verdict
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
- **\`build-benchmark\`** — a design that inverts the pitfall; honest stats; a self-checking artifact
|
|
215
|
+
(\`references/artifact-checklist.md\`).
|
|
216
|
+
- **\`draft-paper\`** — section skeleton + the accept-and-get-cited properties
|
|
217
|
+
(\`references/writing-craft.md\`).
|
|
218
|
+
- **\`argument-arc\`** — 🔴 **does the draft carry the reader to ONE conclusion?** One sentence per
|
|
219
|
+
section (*what does the reader now believe*), then a bottom-up pass asking whether each section makes
|
|
220
|
+
the conclusion harder to escape. Owns **rebuild mode**: the only protocol here for *the frame is
|
|
221
|
+
wrong, start the arc over*. Every other gate assumes a settled draft and patches it. *Added
|
|
222
|
+
2026-07-30 after a full-day rewrite in which the author said five times that the paper threw ideas at
|
|
223
|
+
him and got five local edits back.*
|
|
224
|
+
|
|
225
|
+
**Leaving the loop** means the arc holds and the numbers are in. Not that the prose is pretty — that
|
|
226
|
+
is what the gates are for.
|
|
227
|
+
|
|
228
|
+
## CONTINUOUS — fires when its input changes, never "done"
|
|
229
|
+
|
|
230
|
+
These have no position, because a position is what made them look finished. Each is a trigger.
|
|
231
|
+
|
|
232
|
+
| When this changes | Run | Why it cannot be a stage |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| any \`\\cite\` added or moved | **\`verify-citations\`** | An edit on the last day adds a citation the last run never saw. "We checked last cycle" does not count — the project rule, and it was numbered as a one-shot anyway. |
|
|
235
|
+
| a genuine sibling surfaces | **\`analyze-sibling-paper\`** | Deep-read, scoop/delta, saved in \`<paper-dir>/siblings/\`. |
|
|
236
|
+
| the contribution's framing moves | **\`map-prior-work\`** (delta mode) | A cheap re-sweep. ⚠️ If a rival first surfaces during citation checking, the SETUP sweep was skipped and you are reshaping the contribution under deadline. |
|
|
237
|
+
| any \`.tex\` / \`paper.md\` edit | **\`render-paper\`** + page count | **Not a stage — a command.** Render, then eyeball pages 1–2 before believing anything about the paper. 🔴 **Rendering is continuous; ACTING on the page count is not** — see the rule below. |
|
|
238
|
+
| the deadline approaches | the \`access\` row | Re-check that the profile is still ACTIVE and the portal still opens. External state rots without telling you. |
|
|
239
|
+
|
|
240
|
+
## GATES — late, expensive, each blocked on a named input
|
|
241
|
+
|
|
242
|
+
Ordered, and the order is real: every one refuses to run without the output of the one before it.
|
|
243
|
+
|
|
244
|
+
| Gate | Skill | Requires (hard) |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| **Structure** | **\`tighten-paper\`** | A rendered PDF and a page count. Produces the cut plan + structural verdict. *Before 2026-07-30 this appeared only INSIDE the harden stage — i.e. after the gate that requires it — so a literal reading sent you into a hard-blocked gate.* |
|
|
247
|
+
| **Writing craft** | **\`grade-paper-writing\`** | The current draft. Produces the **persona stall inventory**, which the panel cannot run without. |
|
|
248
|
+
| **Review decision** | **\`pc-panel-review\`** | 🔴 **Both of the above.** N independent lenses (incl. an artifact-runner that executes the artifact) + a chair meta-review — predicts the PC's accept/reject. Its venue-fit mode is the one-reviewer CFP-fit spot-check. |
|
|
249
|
+
| **Claim preservation** | Fable diff (\`claims\`) | The pre-pass baseline. Run after **every** aggressive rewrite, before committing. |
|
|
250
|
+
| **Harden** | **\`harden-paper\`** | The panel's verdict. Closes the desk-reject axes a reviewer-sim misses: threat-model, ethics/dual-use, page-fit, citability, double-blind hygiene, artifact-runs-clean. Its structure and writing axes are the **re-run/confirm** pass, not the first invocation. |
|
|
251
|
+
| **Submit** | **\`submit-paper\`** (+ the venue card) | 🔴 **The \`access\` row green.** Portal mechanics, PDF-only, artifact hosted anonymously, "ready for review" marked. |
|
|
252
|
+
|
|
253
|
+
## AFTER — only reachable by acceptance
|
|
254
|
+
|
|
255
|
+
**\`camera-ready\`** — de-anonymize; public repo + archival DOI; complete disclosure. Then
|
|
256
|
+
**\`extend-paper\`** — extend (≥30% new) to a higher-prestige venue, the "second, stronger publication."
|
|
257
|
+
|
|
258
|
+
**Which review skill?** \`paper-adversarial-review\` = one hostile reviewer, fast defect hunt;
|
|
259
|
+
\`pc-panel-review\` = the full panel + meta-review that makes the accept/reject **decision** (its
|
|
260
|
+
**venue-fit mode** is the one-reviewer CFP-fit spot-check — formerly the standalone \`venue-review-sim\`).
|
|
261
|
+
Use an atom for a quick spot-check; **run the panel for the decision.**
|
|
262
|
+
|
|
263
|
+
**Four grading axes — don't confuse them.** A draft is judged on four independent axes, each its own
|
|
264
|
+
skill: 🔴 **argument architecture** — does the whole thing carry the reader to one conclusion
|
|
265
|
+
(\`argument-arc\`, in the LOOP; the axis that failed on \`compile-rules-2026\` precisely because it was
|
|
266
|
+
nobody's) · **content strength** — does the contribution clear *this venue's* bar (\`study-accepted-papers\`,
|
|
267
|
+
mines the accepted corpus for Accept→Strong levers; in SETUP, before the prose is set) ·
|
|
268
|
+
**scientific defects** — what a hostile reviewer attacks (\`paper-adversarial-review\` / \`pc-panel-review\`)
|
|
269
|
+
· **writing craft** — does it read like a human wrote it (\`grade-paper-writing\`, the 9-dim rubric in
|
|
270
|
+
\`references/writing-craft.md\`; called by \`harden-paper\`). A paper can ace one and fail another — grade all four.
|
|
271
|
+
**The arc axis comes first**, because tightening length and polishing sentences inside a broken arc is
|
|
272
|
+
how a day disappears and the same paper ships.
|
|
273
|
+
|
|
274
|
+
**Panel vs harden — not rival gates, they're sequential.** \`pc-panel-review\` is the review DECISION
|
|
275
|
+
gate: it predicts what the PC does. \`harden-paper\` is the pre-submit ORCHESTRATOR: it *calls* the review
|
|
276
|
+
skills and then closes the desk-reject axes a reviewer-sim doesn't systematically hit (threat-model,
|
|
277
|
+
ethics/dual-use, page-fit, citability, double-blind hygiene). Order is **review (decide) → harden (close
|
|
278
|
+
every other axis) → submit** — neither is "the one final gate" alone.
|
|
279
|
+
|
|
280
|
+
## The review round (a cycle inside GATES)
|
|
281
|
+
Review → **apply the consensus fixes → re-run the panel to confirm**. The artifact-runner re-executes
|
|
282
|
+
the artifact each round. Stop when the panel converges to accept and the artifact reproduces clean —
|
|
283
|
+
**don't loop past one confirming round**, and don't chase the last notch into the deadline. A defensible
|
|
284
|
+
**Accept shipped on time beats a risky Strong that misses it**.
|
|
285
|
+
|
|
286
|
+
## 📝 Text pass vs evidence pass — two independent axes, ask which one you want
|
|
287
|
+
|
|
288
|
+
The author, 2026-08-05 (translated from Russian): *"can we just run the gate on the text? we just
|
|
289
|
+
checked the numbers, and now I want to grade the text — assume the numbers are fine."* He is right that these are separable, and
|
|
290
|
+
running both when only one is wanted burns an hour for nothing.
|
|
291
|
+
|
|
292
|
+
Every gate belongs to exactly one axis. **Sort by what invalidates it**, not by what it reads:
|
|
293
|
+
|
|
294
|
+
| axis | invalidated by | gates |
|
|
295
|
+
|---|---|---|
|
|
296
|
+
| **TEXT** — does the argument land? | a change to the **prose**: any edit, cut, reorder | \`structure\` tighten-paper · \`writing\` grade-paper-writing · \`arc\` argument-arc · the prose lenses of \`panel\` pc-panel-review |
|
|
297
|
+
| **EVIDENCE** — is it true? | a change to the **data, code, or artifact** | \`claims\` claim-preservation · \`cites\` verify-citations · \`artifact\` the artifact-runner lens · the numeric half of \`harden\` harden-paper |
|
|
298
|
+
|
|
299
|
+
**Why this matters more than it looks.** The two axes expire on completely different clocks. Rewriting
|
|
300
|
+
a paragraph invalidates every TEXT gate and no EVIDENCE gate. Re-running an experiment does the exact
|
|
301
|
+
reverse. Conflating them produces both classic wastes: re-verifying numbers nobody touched, and — worse
|
|
302
|
+
— trusting a readability verdict on prose that has since been rewritten.
|
|
303
|
+
|
|
304
|
+
**Text-only pass** (the common request, and the right default after a cut, a reorder, or a rewrite where
|
|
305
|
+
the numbers did not move): run \`structure\` and \`writing\` in parallel, then \`panel\` with its artifact lens **explicitly
|
|
306
|
+
disabled**, and hand each agent the sentence *"assume every number is correct and already verified — do
|
|
307
|
+
not re-derive anything; judge the writing, the structure and the argument."* Roughly halves the wall
|
|
308
|
+
clock and removes the single most expensive stage.
|
|
309
|
+
|
|
310
|
+
**Evidence-only pass** is the mirror: a new experiment landed, the prose around it is stable. Run \`claims\`
|
|
311
|
+
and the artifact-runner; skip readability entirely.
|
|
312
|
+
|
|
313
|
+
🔴 **State which pass you ran, in the scorecard row and in the reply.** A gate row that does not say
|
|
314
|
+
which axis it covered will be read as covering both — which is how a paper ends up believed to be
|
|
315
|
+
checked on a dimension nobody looked at.
|
|
316
|
+
|
|
317
|
+
### 🔢 The one defect neither axis can see: a number correct on both axes and wrong anyway
|
|
318
|
+
|
|
319
|
+
**Observed 2026-08-05, on page 1, 29 hours before a deadline.** The abstract read *"147 real rules
|
|
320
|
+
files exactly as their projects committed them, 22 fail admission"*. The data has two arms over the
|
|
321
|
+
same 147 files: **strict** (files byte-for-byte as committed — nothing fails) and **annotated** (the
|
|
322
|
+
same files with the tool's proposed pointers written in — 22 fail). The 22 was from the annotated arm
|
|
323
|
+
and was described in the strict arm's words. Five more numbers had the same defect; a sixth was found
|
|
324
|
+
later in an appendix by machine, after two people had searched by hand.
|
|
325
|
+
|
|
326
|
+
**Every gate passed, and each for a good reason.** \`cites\` checks the reference is real. \`claims\` checks the
|
|
327
|
+
claim did not grow — and it did not, 22 was always 22. The artifact-runner recomputes the number from
|
|
328
|
+
the data and it reconciles, *because the number is correct*. The reading panel takes "unmodified" as a
|
|
329
|
+
fact about the world, which is what a reader does. **The defect lives only in the join between a
|
|
330
|
+
sentence and a field path, and nothing was holding both.** It is not a TEXT defect and not an EVIDENCE
|
|
331
|
+
defect; it is a defect of the edge between them, so no pass on either axis can be made to see it.
|
|
332
|
+
|
|
333
|
+
**The construction, not another pass.** A registered quantity is not written as digits at all:
|
|
334
|
+
|
|
335
|
+
\`\`\`
|
|
336
|
+
Over {{corpus.n}} real rules files, with the extractor's proposed mapping
|
|
337
|
+
taken as if an author had written it, {{annotated.failedContradicted}} fail admission.
|
|
338
|
+
\`\`\`
|
|
339
|
+
|
|
340
|
+
\`<paper>/repro/numbers.tsv\` gives each name its value, the JSON path or **formula** that recomputes
|
|
341
|
+
it, and two guards. The build refuses a PDF unless: the name resolves · the value still matches the
|
|
342
|
+
data · the **paragraph** names the arm (\`requires\`) · the **sentence** does not claim a different one
|
|
343
|
+
(\`forbids\`). Requires and forbids are separate on purpose — the pairing is auditing's, where a control
|
|
344
|
+
is tested once for *design* and once for *operating effectiveness*.
|
|
345
|
+
|
|
346
|
+
**Why paragraph for one and sentence for the other.** *"Every figure in this paragraph is the
|
|
347
|
+
counterfactual arm"* is good writing, and a sentence-scoped \`requires\` would forbid it. But *"exactly
|
|
348
|
+
as committed"* nine words from the number is the defect itself, so \`forbids\` has to be tight.
|
|
349
|
+
|
|
350
|
+
**Coverage without a migration.** \`numbers-grandfathered.txt\` lists every quantity that predates the
|
|
351
|
+
gate; adding a new raw one fails the build. This is \`ADD CONSTRAINT ... NOT VALID\` — the constraint
|
|
352
|
+
binds every row from now on, and the existing rows are *enumerated rather than exempted*, so the file
|
|
353
|
+
says out loud how many figures still have no machine-checked path to data. On the paper that has it:
|
|
354
|
+
7 guarded, 248 grandfathered. That ratio is a finding, not a score.
|
|
355
|
+
|
|
356
|
+
**Adopting it in another paper:** copy \`repro/paper_numbers.py\`, \`repro/paper_numbers.selftest.py\` and
|
|
357
|
+
the three lines in \`md2submission.py\` that call \`expand()\`; generate the grandfather list from the
|
|
358
|
+
current draft; register the numbers a reviewer will actually check first. \`check-provenance.mjs\`
|
|
359
|
+
reports \`no-numbers-gate\` for any paper that has not.
|
|
360
|
+
|
|
361
|
+
🔴 **Do not write the substitution half — it is \`jinja2\`, and \`{{name}}\` is already its syntax.**
|
|
362
|
+
Eleven candidates were installed and run on a real markdown-source ACL paper on 2026-08-05. The
|
|
363
|
+
result is not a matter of taste:
|
|
364
|
+
|
|
365
|
+
| candidate | verdict, from an actual run |
|
|
366
|
+
|---|---|
|
|
367
|
+
| **jinja2** | **adopt.** Our \`{{annotated.failRate}}\` was already valid Jinja2; dotted names are attribute access. Zero characters changed in the paper, byte-identical \`.tex\`. This is Manubot's mechanism, taken without Manubot. Use \`StrictUndefined\`, and move the block/comment delimiters off \`{%\`/\`{#\` if the paper might ever quote a config file |
|
|
368
|
+
| **knitr** | equally proven, also byte-identical. Rejected only for putting an R runtime into an artifact that otherwise needs \`python3\` + \`pdflatex\` |
|
|
369
|
+
| \`\\newcommand\` + \`numbers.tex\` | works (1 line in the converter); the folk convention, ~12 GitHub hits, all hand-rolled. No package exists |
|
|
370
|
+
| **Quarto**, **pandoc lua filters** | ❌ **destroy the paper.** Markdown→markdown is a pandoc AST round-trip: HTML comments become raw blocks and \`[58]\` becomes \`\\[58\\]\`, so every citation renders as literal \`\\textbackslash{}[58]\`. 3,120 diff lines on the real source. No ACL format exists for Quarto either |
|
|
371
|
+
| **cog.py** | ❌ line-oriented; cannot substitute mid-sentence |
|
|
372
|
+
| **pythontex** | ❌ not in Ubuntu TeX Live at any level, not on PyPI; CTAN zip + \`.ins\` build |
|
|
373
|
+
| **showyourwork** | ❌ LaTeX-only, and it manages *figures*, not in-text numbers |
|
|
374
|
+
| **Pweave** | ❌ dead — the one candidate with a markdown native format, broken against modern IPython |
|
|
375
|
+
| DVC · datalad · papermill | orthogonal and **worth adding**: they pin the data file to the pipeline that made it, a layer below anything here |
|
|
376
|
+
|
|
377
|
+
**🔴 Computing the value DISSOLVES the freshness problem — do not build a checker for it.** With no
|
|
378
|
+
recorded value there is nothing that can go stale, so there is nothing to verify. Adopting jinja2
|
|
379
|
+
deleted 137 lines of ours outright: a hand-rolled expression language with an \`eval()\` sandbox, a
|
|
380
|
+
renderer guessing which of six formattings the paper meant, a JSON-path walker and the comparison.
|
|
381
|
+
Recording-plus-verifying is the trap; computing is the wheel.
|
|
382
|
+
|
|
383
|
+
**Binding a number to its CONDITION is genuinely unoccupied**, and the reason is structural rather
|
|
384
|
+
than an accident of packaging: **every literate-programming tool models the paper as a program that
|
|
385
|
+
prints text**, so the prose is opaque *output*, not an input to a check. None of them has a hook
|
|
386
|
+
where you could say "and the sentence around this must say *counterfactual* and must not say *as
|
|
387
|
+
committed*". The near-misses read the manuscript but never the data — \`statcheck\` recomputes
|
|
388
|
+
p-values from statistics printed in the same sentence; \`RegCheck\` compares a paper to a study
|
|
389
|
+
registration with an LLM and reports to a human instead of failing a build. Searched and empty:
|
|
390
|
+
GitHub repo search (0 results), the Actions marketplace, the pre-commit hook ecosystem, PyPI, and
|
|
391
|
+
the Claude skill marketplaces.
|
|
392
|
+
|
|
393
|
+
🔴 **And it is not a number-keyed table**: the first version keyed rules on the digits, and a paper
|
|
394
|
+
printing two unrelated 22s broke it the same hour. Key on the occurrence.
|
|
395
|
+
|
|
396
|
+
🔴 **Hand the gate to a red team the same day you build it.** This one was, and seven holes came
|
|
397
|
+
back, the worst being that the original defect could simply be **retyped as digits** — its value was
|
|
398
|
+
grandfathered, so the guard applied to the macro and not to the claim. Every hole is now a case in
|
|
399
|
+
\`repro/paper_numbers.selftest.py\` (18/18, including three that must stay **quiet** — a gate that
|
|
400
|
+
fires on ordinary writing gets muted, and then its silence reads as coverage).
|
|
401
|
+
|
|
402
|
+
## 🔴 The page limit is a SUBMISSION gate, not an EDIT gate
|
|
403
|
+
|
|
404
|
+
**Observed failure, \`compile-rules-2026\`, 2026-08-02/03.** The body oscillated 8 ↔ 9 pages for roughly
|
|
405
|
+
fifty iterations. Each time content went in, the page count read 9, and prose came out to get back to
|
|
406
|
+
8 — sixty characters at a time. Every individual cut looked harmless. Their sum is the unanimous 2/5
|
|
407
|
+
for clarity: the first compression took real repetition, the second had none left and took
|
|
408
|
+
transitions, antecedents and the conclusion's honest half. The structural pass named the arithmetic —
|
|
409
|
+
780 words of genuine repetition removed, then 880 words in and 480 out, leaving the paper 51 words
|
|
410
|
+
*heavier* than before the pass that cut 780.
|
|
411
|
+
|
|
412
|
+
**The rule.** Content work runs OVER the limit on purpose. Compression is **one pass, at the end**,
|
|
413
|
+
when the content has settled — with a whole-draft view, so it can move a section instead of shaving a
|
|
414
|
+
clause. Going over during drafting is not a problem to fix; it is the normal state of a paper that is
|
|
415
|
+
still growing.
|
|
416
|
+
|
|
417
|
+
**The trigger to catch yourself:** you just added something, ran the page count, saw it over, and
|
|
418
|
+
started looking for words to remove **in the section you were just editing**. That is the failure, in
|
|
419
|
+
progress. The page count is information for the end of the work, not an alarm during it. (The author's
|
|
420
|
+
own words on catching it, translated from Russian: *"you're cutting the text right away — dunno if that really needs doing immediately."*)
|
|
421
|
+
|
|
422
|
+
**What is still continuous:** rendering, and looking at pages 1–2. Seeing the number is fine. Acting
|
|
423
|
+
on it is what waits.
|
|
424
|
+
|
|
425
|
+
🔴 **Every round adds text; pay it back — in ONE pass.** Review is a ratchet — fixes are additive, so a
|
|
426
|
+
paper that survives three rounds is longer and denser than the one that entered them. On \`compile-rules-2026\` the
|
|
427
|
+
body oscillated 8 ↔ 9 pages for ~50 iterations, and the squeezing is what produced the unanimous 2/5 on
|
|
428
|
+
clarity: the first compression took real repetition, the second had none left and took transitions,
|
|
429
|
+
antecedents and the conclusion's honest half. After each round's fixes, run \`tighten-paper\` — and if the
|
|
430
|
+
page limit is binding, **move** rather than delete (Limitations and Ethics do not count toward ACL page
|
|
431
|
+
limits). The trap in that move is real and named in \`references/acl-venue-rules.md\`: relocating a caveat
|
|
432
|
+
while its flattering number stays in the body is exactly the asymmetry reviewers punish.
|
|
433
|
+
|
|
434
|
+
**Anti-churn ≠ skipping unrun gates.** "Don't loop past one confirming round" forbids *re-polishing prose
|
|
435
|
+
that already passed a gate* — it does NOT license *skipping a gate that never ran*. A \`☐\` row in
|
|
436
|
+
\`PIPELINE-STATUS.md\` for **study-accepted-papers, pc-panel-review, or full harden-paper** is an unrun
|
|
437
|
+
quality gate, not churn: **if capacity exists, run it before calling the paper done.** (This session
|
|
438
|
+
skipped those three under an "anti-churn" rationalization on a submitted paper; when the user forced them,
|
|
439
|
+
the pc-panel caught real must-fixes — a release overclaim and an unsupported number — that the skip would
|
|
440
|
+
have shipped.) Churn is re-touching FINE prose; a never-run gate is a hole. If a real
|
|
441
|
+
objection is out of scope, name it in Threats to Validity (adversarial reviewers read Threats first; an
|
|
442
|
+
honest limitation reads as strength).
|
|
443
|
+
|
|
444
|
+
**A \`☐\` in GATES is a hole. A \`☐\` in CONTINUOUS is worse** — it means the check exists, ran once, and
|
|
445
|
+
has been silently stale ever since. That is the shape of every failure this pipeline has actually had.
|
|
446
|
+
|
|
447
|
+
## ⏱️ What each stage actually costs — MEASURED, not estimated
|
|
448
|
+
|
|
449
|
+
The author, 2026-08-05, watching a run he could not size (translated from Russian): *"is it worth
|
|
450
|
+
writing the timing problem into the pipeline skill?"*. Yes — because the project already forbids guessing here. The rule in the papers tree's own \`CLAUDE.md\`
|
|
451
|
+
says an estimate must be decomposed into labour / calendar / result-risk / access and **spiked
|
|
452
|
+
rather than guessed**, and the same session it was written I still launched an experiment with no
|
|
453
|
+
upper bound and had to cut it four hours later.
|
|
454
|
+
|
|
455
|
+
Every number below is subagent **wall clock, measured on 2026-08-04/05** while finishing
|
|
456
|
+
\`compile-rules-2026\`. They are one machine, one paper, one day — treat them as an order of
|
|
457
|
+
magnitude, not a promise. Re-measure rather than inherit.
|
|
458
|
+
|
|
459
|
+
| stage | measured | note |
|
|
460
|
+
|---|--:|---|
|
|
461
|
+
| \`verify-citations\`, one reference | **3 min** | sonnet; a fetch and a comparison |
|
|
462
|
+
| \`verify-citations\`, eight references | **3 min** | the fetches parallelise; count barely matters |
|
|
463
|
+
| a single reconciliation ("do these two numbers agree?") | **4 min** | sonnet, over committed data |
|
|
464
|
+
| a second-rater pass over ~20 rows | **8 min** | opens every cited file |
|
|
465
|
+
| a process/mechanism research pass (docs + source + issue tracker) | **10 min** | |
|
|
466
|
+
| \`pc-panel-review\`, full panel + chair | **17 min** | unchanged for the confirming round |
|
|
467
|
+
| \`grade-paper-writing\` incl. the persona cold read | **20 min** | |
|
|
468
|
+
| bundling an experiment into the artifact + gate + re-zip | **24–39 min** | scales with directories, not bytes |
|
|
469
|
+
| a design/measurement **spike** (feasibility, a handful of cells) | **27 min** | |
|
|
470
|
+
| \`tighten-paper\` applied, with a loss letter | **34 min** | includes several build round-trips |
|
|
471
|
+
| \`harden-paper\` | **36 min** | the widest gate; it runs the artifact |
|
|
472
|
+
| **an experiment with real checkouts and installed dependencies** | **≈4 h for 143 cells** | median cell **76 s**; the outlier by an order of magnitude |
|
|
473
|
+
|
|
474
|
+
**What the shape tells you, which matters more than the rows.**
|
|
475
|
+
|
|
476
|
+
- **A full gate cycle — \`tighten\` → \`grade\` → \`panel\` — is about 1.2 hours.** That is cheap enough
|
|
477
|
+
to run after any substantial edit, and there is no excuse for a stale gate on a paper you are
|
|
478
|
+
still touching.
|
|
479
|
+
- **Reading, checking and reviewing are all minutes.** Anything whose cost is dominated by fetching,
|
|
480
|
+
parsing or judging text lands in the 3–40 minute band regardless of how important it feels.
|
|
481
|
+
- 🔴 **Anything that installs dependencies and runs an agent inside a real checkout is hours, and
|
|
482
|
+
that is the only class that is.** Its cost is *per cell*: rows × arms × seeds × ~76 s. Compute
|
|
483
|
+
that product **before launching**, and say it out loud. 6 rows × 5 arms × 4 seeds = 120 cells ≈
|
|
484
|
+
2.5 h; carrying the same design to 21 rows would have been ≈ 9 h.
|
|
485
|
+
- **Therefore: bound experiments by a cell budget, never by "run it and see".** Pick the number of
|
|
486
|
+
rows from the time available, decide up front what a complete balanced design is, and stop at the
|
|
487
|
+
last complete row. A design closed at six rows is a result; a design abandoned at eleven is a mess.
|
|
488
|
+
|
|
489
|
+
## Model policy (which model runs which stage)
|
|
490
|
+
Single home for the whole suite — stage skills point here instead of each re-deciding. Default:
|
|
491
|
+
- **Adversarial / red-team / verify a claim** → **Fable** (a separate model; never the author grading
|
|
492
|
+
itself): \`paper-adversarial-review\`, \`pc-panel-review\` reviewers, \`harden-paper\` threat-model +
|
|
493
|
+
citability red-team, disputed \`verify-citations\` verdicts.
|
|
494
|
+
- **Heavy generation / synthesis** → the session's main model (**Opus**): \`draft-paper\`,
|
|
495
|
+
\`build-benchmark\` design, \`extend-paper\`, \`research-ideate\`.
|
|
496
|
+
- **Cheap bulk fetch / extraction** → **Haiku** (or Sonnet): \`study-accepted-papers\` corpus pull,
|
|
497
|
+
\`plan-paper-timeline\`.
|
|
498
|
+
- **No model at all (mechanical)** → \`verify-citations\`'s \`../verify-citations/scripts/verify-cites.mjs\` reducer,
|
|
499
|
+
\`harden-paper\`'s \`check-*.sh\` linters, \`render-paper\` toolchain.
|
|
500
|
+
- **Judge panels use DIVERSE models, not N copies of one** → \`grade-paper-writing\`, \`pc-panel-review\`:
|
|
501
|
+
mix Opus + Fable + Sonnet so independent lenses catch what redundancy can't.
|
|
502
|
+
|
|
503
|
+
Override per call when a stage clearly needs otherwise; this is the default, not a straitjacket.
|
|
504
|
+
|
|
505
|
+
## Rules
|
|
506
|
+
- **Fable (a separate model) is always the reviewer** — never let the author grade itself.
|
|
507
|
+
- **Never fabricate** a citation, number, or result. Mark \`% VERIFY\` and check (\`verify-citations\`).
|
|
508
|
+
- **Commit + push after each stage**, keep the tree clean (resume-safe across \`/compact\`); update
|
|
509
|
+
\`<papers-root>/research/README.md\` in the same commit as any new research file (its CLAUDE.md enforces this).
|
|
510
|
+
- **Two roles, never double-counted:** authoring = the *authorship* criterion; reviewing others at the
|
|
511
|
+
venue (the organizer review-offer email) = the *judging* criterion — a separate credential.
|
|
512
|
+
|
|
513
|
+
## Provenance
|
|
514
|
+
Two real papers this session ran this pipeline end-to-end: **AgenticDev 2026 @ ASE** ("Measuring the
|
|
515
|
+
Wrong Number," ~90%, submitted #20) and **AISec 2026 @ ACM CCS** ("Safety Theater," Weak-Accept→~87–88%
|
|
516
|
+
after a panel round + confirm). The stage skills and shared refs are distilled from exactly those runs.`,
|
|
517
|
+
});
|