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,220 @@
|
|
|
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: "build-benchmark",
|
|
11
|
+
description:
|
|
12
|
+
"Design and run the empirical study behind a measurement paper, and ship a reviewer-proof reproduction artifact. Covers the study design (invert the pitfall you're critiquing), honest statistics (paired/Welch t, CIs, Bonferroni, small-n spread as a result, not noise), a structural bound that outlives the specific artifacts tested, and a self-checking artifact that recomputes every headline number and exits non-zero on drift. Use when the paper's contribution is a way to MEASURE something and you're building the evidence + the thing reviewers will run. Compose with research-ideate (upstream), draft-paper, pc-panel-review (its artifact-runner executes this), submit-paper.",
|
|
13
|
+
context: "fork",
|
|
14
|
+
tools: ["Read", "Write", "Edit", "Grep", "Glob", "Bash", "Agent"],
|
|
15
|
+
body: `
|
|
16
|
+
# build-benchmark β the study + the artifact reviewers can run
|
|
17
|
+
|
|
18
|
+
## Run me
|
|
19
|
+
|
|
20
|
+
π΄ FIRST, before any other step:
|
|
21
|
+
|
|
22
|
+
\`\`\`
|
|
23
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs build-benchmark <paper-dir>
|
|
24
|
+
\`\`\`
|
|
25
|
+
|
|
26
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
27
|
+
state β so starting is an event, and events get written down.
|
|
28
|
+
|
|
29
|
+
A measurement paper is only as strong as the artifact a reviewer can \`cd\` into and re-run. This skill
|
|
30
|
+
covers both halves: the study design that makes the finding true, and the self-checking artifact that
|
|
31
|
+
makes it *verifiable*. The contribution is the **method**, not the one tool you happened to test β build
|
|
32
|
+
so both survive review.
|
|
33
|
+
|
|
34
|
+
## 0. π΄ READ THE STATED CLAIM FIRST β and refuse to design without it
|
|
35
|
+
|
|
36
|
+
**Before designing anything, open \`<paper-dir>/PIPELINE-STATUS.md\` and read row \`frame\`** β the one
|
|
37
|
+
paragraph saying what this paper will claim (written by \`argument-arc\` in **frame mode**, in SETUP).
|
|
38
|
+
|
|
39
|
+
π΄ **If \`frame\` is empty, stop. Do not design the study.** Go run \`argument-arc\` frame mode, get the
|
|
40
|
+
paragraph, then come back. This is a refusal, not a recommendation:
|
|
41
|
+
|
|
42
|
+
- **The frame decides which results matter.** A study designed without a stated claim measures
|
|
43
|
+
whatever the available harness can already see, and the claim gets fitted afterwards to whatever
|
|
44
|
+
came out. That is backwards, and it is expensive in exactly one direction β **reframing after the
|
|
45
|
+
data is collected is how runs get thrown away**, observed on \`compile-rules-2026\`.
|
|
46
|
+
- **The claim is what makes Β§1 answerable.** "What would make the critiqued pitfall impossible here?"
|
|
47
|
+
has no answer until you have written down what you are claiming.
|
|
48
|
+
- **It costs a paragraph and it saves a study.** There is no version of this trade that favours
|
|
49
|
+
starting the runs first.
|
|
50
|
+
|
|
51
|
+
Cross-check the claim against the prevention rule in the \`CLAUDE.md\` beside the papers: if the claim is
|
|
52
|
+
about *preventing* something, write the one sentence saying **what physically stops the bad outcome in
|
|
53
|
+
the experimental arm**. "There is different text in it" means you are measuring persuasion, not
|
|
54
|
+
prevention, and the design is wrong before a single run.
|
|
55
|
+
|
|
56
|
+
## 1. Design that inverts the pitfall you're critiquing
|
|
57
|
+
|
|
58
|
+
The strongest measurement papers are a corrected version of the mistake they name. Pick the design that
|
|
59
|
+
is the *inverse* of the flaw:
|
|
60
|
+
|
|
61
|
+
- **Critiquing a proxy metric?** Measure the real thing, gated on correctness. The cost study is a
|
|
62
|
+
**cost-aware, correctness-gated A/B**: two arms Γ two tools, every run scored pass/fail first, then
|
|
63
|
+
the *dollar* bill compared β because the whole point was that the token-proxy and the dollar disagree.
|
|
64
|
+
Never let a cheaper-but-broken run count as a win; correctness is the gate before cost is even read.
|
|
65
|
+
- **Measuring something that runs untrusted/destructive code?** **Parse, don't execute.** The guard eval
|
|
66
|
+
is a **SAFE STATIC evaluation**: transcribe each guard's predicate by hand and reason over it against a
|
|
67
|
+
disaster battery β never run the guard or the attack. See Safety below; this is non-negotiable.
|
|
68
|
+
|
|
69
|
+
Write the design as the answer to "what would make the critiqued pitfall impossible here?"
|
|
70
|
+
|
|
71
|
+
## 2. Honest statistics β the part reviewers attack first
|
|
72
|
+
|
|
73
|
+
- **Paired where the design is paired; Welch where variances differ.** Use a **paired-t** when the same
|
|
74
|
+
task is run under both arms (blocks task difficulty); use **Welch's t** for unequal-variance unpaired
|
|
75
|
+
comparisons. Do NOT label a test "paired" unless the pairing is real β a mislabeled test is a blocker.
|
|
76
|
+
- **Report CIs and k/n, never bare percentages over tiny n.** "2/10 guards covered" beats "20% coverage";
|
|
77
|
+
"median 2/10 (range 0β5)" beats a single mean. A percentage over n=10 hides the n.
|
|
78
|
+
- **Report the SOURCE CONCENTRATION of a mined corpus β the single-source share is a number, not a
|
|
79
|
+
caveat.** For any corpus mined from several repositories / trackers / vendors, compute and print
|
|
80
|
+
**n per source and the max single-source share**, and put it in the paper (a table row or one
|
|
81
|
+
sentence), not only in Threats. A corpus advertised as covering *k* sources but dominated by one is
|
|
82
|
+
a top reason a mined-corpus paper gets rejected, and it is invisible to every other check β the
|
|
83
|
+
totals, the percentages and the internal consistency all pass, because the cut was simply never
|
|
84
|
+
made. **Mechanical leg:** the artifact emits \`source, n, share\` for the corpus and the top share
|
|
85
|
+
appears in the paper. If the top source exceeds ~50%, say so in the abstract's scope or narrow the
|
|
86
|
+
claimed population to what you actually sampled.
|
|
87
|
+
- **Inter-rater agreement is void if the rater was trained by, and scored against, the codebook's
|
|
88
|
+
author.** Agreement with the person who wrote the scheme measures *trainability*, not construct
|
|
89
|
+
reliability β it is the human form of the failure this suite already names in code (a checker and
|
|
90
|
+
its self-test written in one pass by one model). Requirements, all mechanical: (i) reference labels
|
|
91
|
+
come from a rater who did **not** author the codebook and did **not** see the hypothesis; (ii)
|
|
92
|
+
report the agreement **denominator as a share of the full corpus** β "ΞΊ=0.93 on 69 of 547 (12.6%)",
|
|
93
|
+
never a bare ΞΊ; (iii) use a coefficient that matches the design β Cohen's ΞΊ is single-label, so
|
|
94
|
+
multi-label coding needs per-label ΞΊ or Krippendorff's Ξ±; (iv) treat **ΞΊ = 1.00 as a red flag to
|
|
95
|
+
investigate, not a result to report** β perfect agreement on a many-category scheme usually means
|
|
96
|
+
the validation set was easy or calibration was de-facto joint coding.
|
|
97
|
+
- **Correct for the family.** Multiple comparisons across a family of tasks/tools β **Bonferroni** (or
|
|
98
|
+
state the correction you used). Report it; don't p-hack the one significant cell.
|
|
99
|
+
- **Small-n spread is a first-class result, not noise.** If five trials of the same task swing wildly,
|
|
100
|
+
that variance IS the finding (the thing under test is unstable) β report it, don't average it away.
|
|
101
|
+
- Repeated trials: fix trial count up front (e.g. per-task Γ trials Γ arms Γ tools), report the full n,
|
|
102
|
+
and treat every run β including failures β as data.
|
|
103
|
+
|
|
104
|
+
## 3. A structural bound that outlives the artifacts
|
|
105
|
+
|
|
106
|
+
Numbers about today's tools rot. A **mechanism or structural bound** doesn't. Give the paper one claim
|
|
107
|
+
that holds regardless of which specific tool/version you measured:
|
|
108
|
+
|
|
109
|
+
- the cost study's bound: token-efficiency and dollar cost are decoupled by pricing structure, so a
|
|
110
|
+
token-optimizing tool *cannot* be assumed to cut the bill β a property of the pricing, not the tool.
|
|
111
|
+
- the guard eval's axes: **mutation-evasion** (does a trivial rephrase of the attack slip the guard?),
|
|
112
|
+
**held-out generalization** (does coverage transfer to commands the guard wasn't written for?), and
|
|
113
|
+
**per-step causal ablation** (remove one guard step, measure the coverage delta β which step actually
|
|
114
|
+
does the work). These are properties of the *defense class*, reusable against the next guard set.
|
|
115
|
+
|
|
116
|
+
State the bound explicitly; it's what makes the paper a benchmark and not a product review.
|
|
117
|
+
|
|
118
|
+
## 4. Build a SELF-CHECKING artifact
|
|
119
|
+
|
|
120
|
+
This is the single biggest accept-probability lever, and pc-panel-review's artifact-runner WILL execute
|
|
121
|
+
it. Do **not** restate the requirements here β build to the canonical checklist:
|
|
122
|
+
|
|
123
|
+
β **\`paper-pipeline/references/artifact-checklist.md\`** (self-recompute from raw data, exit non-zero on
|
|
124
|
+
drift, stdlib-only, no network, a README that maps each paper-number to where it prints, LICENSE, honest
|
|
125
|
+
badge scope, de-anon scanned).
|
|
126
|
+
|
|
127
|
+
The load-bearing property: each script **recomputes** every headline number from raw data and
|
|
128
|
+
**self-asserts** β exit non-zero the moment a cell drifts from the paper (\`reproduce.py\` on the cost
|
|
129
|
+
study; \`evaluate.py\`/\`mutate.py\`/\`reproduce.mjs\`/\`ablation.mjs\` on the guard eval). Derive from base
|
|
130
|
+
fields, never echo a stored/precomputed field β a reviewer calls that circular and they're right. For
|
|
131
|
+
de-anonymization before hosting, follow **\`paper-pipeline/references/anonymization.md\`**; host per
|
|
132
|
+
\`submit-paper\` (OSF anonymized view-only link; automation at \`papers/osf_upload.py\`).
|
|
133
|
+
|
|
134
|
+
## Safety β never execute untrusted or destructive commands to measure them
|
|
135
|
+
|
|
136
|
+
If the object of study is code that could delete, exfiltrate, or run attacker-controlled input, you
|
|
137
|
+
**transcribe and parse its predicate** β you never execute it, and you never run the attack against it.
|
|
138
|
+
The guard eval scores 46 real command-guards by reading each guard's logic against a 10-command disaster
|
|
139
|
+
battery statically; nothing in the battery is ever run. A benchmark that has to detonate the payload to
|
|
140
|
+
score it is a liability, not evidence. Same rule inside the artifact: no network, no shelling out to the
|
|
141
|
+
thing under test.
|
|
142
|
+
|
|
143
|
+
## Validate the transcription against real-code execution, not just a blind re-derivation
|
|
144
|
+
|
|
145
|
+
When you score third-party code by **transcribing its logic** (e.g. a guard's regexes) into your own
|
|
146
|
+
evaluator, a *blind re-derivation* (a second person re-reads the code and re-transcribes it) only checks
|
|
147
|
+
transcription-vs-human-reading β it does **not** check transcription-vs-real-behavior. There's a cheap,
|
|
148
|
+
zero-execution-risk way to close that gap: **run the actual scraped code against its REAL agent input
|
|
149
|
+
contract** and reconcile its live verdict with your static prediction.
|
|
150
|
+
|
|
151
|
+
- **Feed the real contract, not a bare string.** For Claude Code PreToolUse hooks, the command arrives as
|
|
152
|
+
a **JSON envelope on stdin** with the command at \`.tool_input.command\`. Feed each battery/benign command
|
|
153
|
+
as a **string inside that envelope** to the real guard's stdin and read its verdict (exit 2 = block; or
|
|
154
|
+
stdout JSON \`permissionDecision\` deny/ask/block). The command is **never executed** β the guard only
|
|
155
|
+
inspects the string.
|
|
156
|
+
- **SAFETY: sandbox + stub-PATH first.** Run inside a throwaway sandbox with a **stub PATH** (fake
|
|
157
|
+
\`rm\`/\`dd\`/\`git\`/\`curl\`/β¦ β \`exit 0\`) as defense-in-depth, so even a guard that shells out can't do
|
|
158
|
+
damage. Invoke the real interpreters by absolute path.
|
|
159
|
+
- **Reconcile per codeΓinput pair.** Every mismatch between live verdict and static prediction is a
|
|
160
|
+
**finding** β either a transcription nit to fix, or a real behavior your static model structurally
|
|
161
|
+
cannot capture.
|
|
162
|
+
|
|
163
|
+
**Concrete payoff (the motivating example):** this method surfaced a **"whole-stdin confound"** β a
|
|
164
|
+
widely-copied guard that greps its **entire raw stdin** rather than the extracted command. The JSON
|
|
165
|
+
envelope's trailing bytes defeated its anchored \`rm β¦/$\` rule, so it **FAILED TO BLOCK \`rm -rf /\`** live,
|
|
166
|
+
even though it "blocked" the bare string. A pure transcription/static model can't see this; only
|
|
167
|
+
real-code-through-real-contract execution reveals it.
|
|
168
|
+
|
|
169
|
+
Before submitting, verify the artifact you built with the reviewer-side reproduction protocol:
|
|
170
|
+
**\`references/adversarial-cold-repro.md\`** (cold re-run, three-way reconcile, robustness attacks).
|
|
171
|
+
|
|
172
|
+
## Record the verdict
|
|
173
|
+
|
|
174
|
+
π΄ LAST step, once the deliverable exists:
|
|
175
|
+
|
|
176
|
+
\`\`\`
|
|
177
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> FINDING <count> <report-path>
|
|
178
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> ABSTAINED <reason> "<one line>"
|
|
179
|
+
\`\`\`
|
|
180
|
+
|
|
181
|
+
π΄ **There is no PASS.** An artifact that recomputes every headline number and exits 0 has produced
|
|
182
|
+
no finding; it has not certified the study. Record the absence, do not name it a success.
|
|
183
|
+
|
|
184
|
+
**FINDING** β \`<count>\` numbers did not reproduce, or reproduce only with caveats; \`<report-path>\`
|
|
185
|
+
is the artifact output. Add \`--blocking\` for the Β§0 refusal: \`frame\` is empty, so the study was not
|
|
186
|
+
designed.
|
|
187
|
+
**ABSTAINED** β \`no-witness\`: the artifact ran and every number reproduced. \`input-missing\`: the
|
|
188
|
+
raw data is not in the repo. \`crashed\`: the harness itself died.
|
|
189
|
+
|
|
190
|
+
π΄ That Β§0 refusal is a **finding, not an aborted run** β it is a fact about the work, so it is a
|
|
191
|
+
FINDING and not an abstention. Record it and stop. A study that was never designed leaves exactly
|
|
192
|
+
the same silence as one that is still running, and the difference costs a week to rediscover.
|
|
193
|
+
|
|
194
|
+
π΄ **THREE MECHANICAL CHECKS FILE UNDER THIS SKILL** and each has its own ledger row:
|
|
195
|
+
\`build-benchmark/check-provenance\`, \`build-benchmark/arm-permutation\`,
|
|
196
|
+
\`build-benchmark/delivered-pdf\` (see \`.claude/skills/paper-pipeline/scripts/run-mechanical.mjs\`). Until 2026-08-10 the
|
|
197
|
+
ledger keyed on the SKILL, so a clean run of one erased a finding of another from every derived
|
|
198
|
+
view β which is why two of the three sat unwired. This block records the JUDGEMENT pass, under the
|
|
199
|
+
bare key \`build-benchmark\`; never file a mechanical result here.
|
|
200
|
+
|
|
201
|
+
## Compose with
|
|
202
|
+
- **argument-arc (frame mode)** β π΄ **hard input.** Owns row \`frame\`, the stated claim. No \`frame\`, no study.
|
|
203
|
+
- **research-ideate** (upstream) β supplies the contribution and the pitfall to invert; this skill turns
|
|
204
|
+
it into evidence.
|
|
205
|
+
- **draft-paper** β the study's stats, bound, and artifact-number table feed Methods/Results/Availability.
|
|
206
|
+
- **pc-panel-review** β its artifact-runner reviewer \`cd\`s in and re-executes every harness; build so
|
|
207
|
+
that pass is deterministic.
|
|
208
|
+
- **submit-paper** β hosts the scrubbed artifact anonymously and links it in Availability.
|
|
209
|
+
|
|
210
|
+
## Provenance
|
|
211
|
+
- **AgenticDev 2026 @ ASE β "Measuring the Wrong Number":** a cost-aware, correctness-gated A/B harness
|
|
212
|
+
over 140 runs (7 tasks Γ 5 trials Γ 2 arms Γ 2 tools); Welch t + paired-t CIs + Bonferroni; the finding
|
|
213
|
+
that token-efficiency tools don't cut the dollar bill. Artifact = a stdlib-only \`reproduce.py\` that
|
|
214
|
+
recomputes every headline number from raw data and exits non-zero on drift.
|
|
215
|
+
- **AISec 2026 @ ACM CCS β "Safety Theater":** a 10-command disaster battery against 46 real
|
|
216
|
+
command-guards, SAFE STATIC evaluation (transcribe each predicate, never execute), median coverage
|
|
217
|
+
2/10, plus mutation-evasion, held-out generalization, and per-step causal ablation axes. Artifact =
|
|
218
|
+
\`evaluate.py\`/\`mutate.py\`/\`reproduce.mjs\`/\`ablation.mjs\`, each self-asserting on run. Both artifacts
|
|
219
|
+
are hosted anonymized on OSF.`,
|
|
220
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-benchmark β the PAID tier: does this skill's description actually fire?
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE (vigiles decides coverage by placement as of 2026-08-11).
|
|
5
|
+
* The prompts live in `.claude/lib/skill-trigger-cases.mjs` so all 21 cases
|
|
6
|
+
* are reviewed as one table where collisions between siblings are visible;
|
|
7
|
+
* copying them here would recreate the drift that rule exists to prevent.
|
|
8
|
+
*
|
|
9
|
+
* Measures recall (fires on its own territory) AND precision (stays quiet on a
|
|
10
|
+
* colliding sibling's territory), against the REAL `.claude` harness so the skill
|
|
11
|
+
* competes with every other installed description β an isolated run overstates
|
|
12
|
+
* recall and understates false positives.
|
|
13
|
+
*
|
|
14
|
+
* Costs money; not CI.
|
|
15
|
+
* node .claude/skills/build-benchmark/build-benchmark.eval.mjs [trials]
|
|
16
|
+
*/
|
|
17
|
+
import { runSkillTriggerEval } from "../../lib/skill-eval-kit.mjs";
|
|
18
|
+
|
|
19
|
+
await runSkillTriggerEval("build-benchmark");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-benchmark β the free, deterministic tier. No model, no network.
|
|
3
|
+
*
|
|
4
|
+
* COLOCATED ON PURPOSE. vigiles decides coverage by PLACEMENT as of 2026-08-11:
|
|
5
|
+
* a test that merely names a surface no longer counts, because that tier was
|
|
6
|
+
* crediting surfaces nothing touched. So each skill needs a file inside its own
|
|
7
|
+
* directory β this one.
|
|
8
|
+
*
|
|
9
|
+
* The assertions live in `.claude/lib/skill-checks.mjs` and are CALLED here with
|
|
10
|
+
* this skill's name. They are not copied: 22 copies of the same checks is the drift that
|
|
11
|
+
* module exists to avoid. (Until 2026-08-11 this was an env-var side channel into a
|
|
12
|
+
* 614-line file named after no surface; it is a function call now.)
|
|
13
|
+
*
|
|
14
|
+
* What this proves: this skill's frontmatter parses as strict YAML, its declared
|
|
15
|
+
* tool contract is sane, its pipeline wiring points at scripts that exist, and it
|
|
16
|
+
* announces/records under ITS OWN identity rather than a sibling's.
|
|
17
|
+
*
|
|
18
|
+
* What it does NOT prove: that the skill fires, or that its guidance produces a
|
|
19
|
+
* good result. Those need a real model β see `build-benchmark.eval.mjs`.
|
|
20
|
+
*/
|
|
21
|
+
import { checkSkill } from "../../lib/skill-checks.mjs";
|
|
22
|
+
|
|
23
|
+
await checkSkill("build-benchmark");
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Adversarial cold-repro protocol β reviewer-side reproduction of a measurement paper
|
|
2
|
+
|
|
3
|
+
**Purpose.** Before submitting a measurement paper that ships an artifact, reproduce it _as a hostile
|
|
4
|
+
evaluator_. Default stance is **SKEPTIC**: your job is to **refute** the paper, not to confirm it. Rate a
|
|
5
|
+
claim **CONFIRMED** only if a cold reproduction _forces_ you to. "The prose says so" and "results.json says
|
|
6
|
+
so" are **not** sufficient evidence β both were written by the author you're trying to catch.
|
|
7
|
+
|
|
8
|
+
Run this once the paper + artifact are drafted, before `submit-paper`. One honest **REFUTED** beats ten
|
|
9
|
+
hand-wavy **CONFIRMED**s.
|
|
10
|
+
|
|
11
|
+
## Protocol
|
|
12
|
+
|
|
13
|
+
1. **Reproduce cold.** Run the evaluator(s) from a _clean checkout_, capturing output **without reading the
|
|
14
|
+
committed results first**. THEN diff your fresh output against the committed JSON. Never overwrite the
|
|
15
|
+
committed outputs β always run to stdout or a temp file. (Reading the committed numbers first biases you
|
|
16
|
+
into pattern-matching them instead of independently deriving them.)
|
|
17
|
+
|
|
18
|
+
**Clean checkout means clean ENVIRONMENT β a self-checking artifact you never ran clean is
|
|
19
|
+
UNVERIFIED.** Unzip the exact `artifact.zip` (or `git clone` fresh) into a scratch dir and follow the
|
|
20
|
+
artifact's own README step-by-step; every self-check must exit 0 and print numbers matching the paper.
|
|
21
|
+
The trap that hides until a reviewer hits it: **missing/uninstalled dependencies** β a harness that
|
|
22
|
+
needs `npm install` / `pip install` / a build step the _release script_ doesn't run, so it crashes with
|
|
23
|
+
`MODULE_NOT_FOUND` on a fresh unzip even though it "passes" in the author's dirty tree (where
|
|
24
|
+
`node_modules` lingers). Fix: make the release/self-check script install deps itself, and make the
|
|
25
|
+
README's quick-start the exact commands you just ran clean. A "functional artifact" that isn't
|
|
26
|
+
functional out of the box is a benchmark-track reject. (Real catch: GateBench's `check-release.sh` ran
|
|
27
|
+
the Node harnesses without `npm install` β green in the dirty tree, `ERR_MODULE_NOT_FOUND` on a clean
|
|
28
|
+
one.)
|
|
29
|
+
|
|
30
|
+
2. **Three-way reconcile EVERY headline number.** For each number the paper leans on, line up:
|
|
31
|
+
(a) the value in the **paper source** (abstract/intro/results/table),
|
|
32
|
+
(b) the value in **results.json** (or whatever the artifact commits),
|
|
33
|
+
(c) your **fresh re-run**.
|
|
34
|
+
Any drift, off-by-one, or stale number left over from an earlier corpus size is a **finding**. These
|
|
35
|
+
three must agree exactly; if they don't, the paper is inconsistent until fixed.
|
|
36
|
+
|
|
37
|
+
3. **Attack robustness, not just arithmetic.** Recompute under stress:
|
|
38
|
+
- **The paper's OWN stated caveats, taken STRICTLY** β if it says "excluding X," actually exclude X and
|
|
39
|
+
see if the headline survives.
|
|
40
|
+
- **Dedup / weighting sensitivity** β does the headline move under a plausible alternative aggregation
|
|
41
|
+
(per-item vs per-source, weighted vs unweighted, dedup vs raw)? If a different-but-defensible rollup
|
|
42
|
+
flips the story, the story is fragile.
|
|
43
|
+
- **Convenience-sample sensitivity** β drop the strongest / outlier item(s). Does the narrative hold, or
|
|
44
|
+
was it carried by one datapoint?
|
|
45
|
+
|
|
46
|
+
4. **Attack the arms reviewers hit hardest.**
|
|
47
|
+
- **Nondeterministic / LLM components** β is any claimed instability _real_, and is the paper careful to
|
|
48
|
+
claim only the _shape_ (e.g. "unstable," "median 2/10, range 0β5") rather than exact per-cell values a
|
|
49
|
+
re-run can't reproduce?
|
|
50
|
+
- **By-construction / "always/never" claims** β are they scoped to a _declared scope_, not stated as
|
|
51
|
+
unconditional absolutes?
|
|
52
|
+
|
|
53
|
+
5. **Transcription integrity.** If the evaluator transcribes third-party logic (regexes, predicates, rules)
|
|
54
|
+
into your own scorer, spot-check a few items against their **real source**. If there's a validation set
|
|
55
|
+
of corrections, confirm every correction runs in the **claimed direction** (a validation set whose
|
|
56
|
+
"fixes" cut both ways is a red flag). See the live-contract execution method in `SKILL.md` β a blind
|
|
57
|
+
re-derivation only validates transcription-vs-human-reading, not transcription-vs-real-behavior.
|
|
58
|
+
|
|
59
|
+
## Output β one verdict per claim
|
|
60
|
+
|
|
61
|
+
For each headline claim, emit:
|
|
62
|
+
|
|
63
|
+
- **VERDICT: CONFIRMED | REFUTED | NEEDS-FIX**
|
|
64
|
+
- The **three numbers** (paper source / results.json / fresh re-run).
|
|
65
|
+
- The **single command** that reproduces it from a clean checkout.
|
|
66
|
+
- If not CONFIRMED: the **minimal fix** + the exact **source file:line** to change.
|
|
67
|
+
|
|
68
|
+
Keep it terse and adversarial. The deliverable is the list of findings, not reassurance.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: camera-ready
|
|
3
|
+
description: On acceptance, turn the anonymized-for-review paper into the de-anonymized camera-ready that actually enters the proceedings (ACM DL / IEEE Xplore). Reverses double-blind anonymization, swaps the OSF view-only artifact for a real public repo + an archival DOI, and β for security papers β completes responsible disclosure BEFORE any de-anonymized public release. Use after a notification email says Accept and the venue gives a camera-ready deadline. Compose with submit-paper (upstream) and extend-paper (next).
|
|
4
|
+
allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- vigiles:sha256:8fa0190054cc5314 compiled from skills/camera-ready/SKILL.md.spec.ts -->
|
|
8
|
+
|
|
9
|
+
# camera-ready β de-anonymize an accepted paper into the final proceedings version
|
|
10
|
+
|
|
11
|
+
## Run me
|
|
12
|
+
|
|
13
|
+
π΄ FIRST, before any other step:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs camera-ready <paper-dir>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
20
|
+
state β so starting is an event, and events get written down.
|
|
21
|
+
|
|
22
|
+
The reviewed PDF was anonymized on purpose. Acceptance flips that: the camera-ready carries your
|
|
23
|
+
real name, your real repo, and an archival DOI β and it's the version that gets indexed, so it's the
|
|
24
|
+
actual authorship evidence. This skill is the reverse of the anonymization you did at
|
|
25
|
+
submission. Work from `paper-pipeline/references/anonymization.md` and undo each move it lists.
|
|
26
|
+
|
|
27
|
+
## 0. Pre-flight
|
|
28
|
+
- Confirm the **camera-ready deadline** and the **format instructions** in the acceptance email
|
|
29
|
+
(some venues ship a specific `acmart` template version or a copyright block to paste β use theirs).
|
|
30
|
+
- Read the reviews once more: camera-ready is your one cheap chance to fold in the must-fix comments
|
|
31
|
+
the meta-review flagged. Do those edits now, not "later."
|
|
32
|
+
- **Security papers only**: do not start the public de-anonymized release until Β§3 (disclosure) is
|
|
33
|
+
logged as complete. The de-anon repo is public and Google-findable the moment you push it.
|
|
34
|
+
|
|
35
|
+
## 1. Reverse the anonymization
|
|
36
|
+
Undo, one by one, everything `../paper-pipeline/references/anonymization.md` told you to hide:
|
|
37
|
+
- **Class options**: `\documentclass[sigconf,review,anonymous]{acmart}` β `\documentclass[sigconf]{acmart}`.
|
|
38
|
+
Dropping `review` also drops line numbers and the review-mode banner; dropping `anonymous` un-hides
|
|
39
|
+
the author block.
|
|
40
|
+
|
|
41
|
+
π΄ **Dropping `review` ARMS a gate that was exempt until this second β run it NOW, in the same
|
|
42
|
+
pass, not at push time:**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx eslint --no-config-lookup --config eslint.config.mjs <paper.tex>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`tex/future-promise` exempts review builds deliberately: while a paper is under review, "the
|
|
49
|
+
harness will be released at camera-ready" is true and expected. The moment `review` comes off,
|
|
50
|
+
the same sentence becomes a contradiction with the Availability paragraph β and that is exactly
|
|
51
|
+
the defect this rule was created for, on a real submitted paper, where a reviewer had already
|
|
52
|
+
listed the missing artifact as a weakness and the printed camera-ready went on asserting it.
|
|
53
|
+
|
|
54
|
+
β οΈ **Why it must run HERE and not be left to CI** (measured 2026-09-11): the check lives in
|
|
55
|
+
ESLint, and no local hook runs ESLint on `.tex` β `paper-lint.mjs` stopped carrying it on
|
|
56
|
+
2026-09-07. CI does run it, but CI runs *after a push*, while a camera-ready gets built and
|
|
57
|
+
uploaded to HotCRP before that. Between "dropped `review`" and "pushed" the gate does not
|
|
58
|
+
exist. Measured on a fixture: in review mode 0 findings, with `review` removed 1 finding β
|
|
59
|
+
the rule flips instantly, so the only question is whether anyone looks.
|
|
60
|
+
|
|
61
|
+
β οΈ And re-run it after the LAST edit to `paper.tex`, not once at the start. The original
|
|
62
|
+
defect survived because the promise was swept out of the artifact (`README`, `reproduce.py`)
|
|
63
|
+
the same day and nobody made the same pass over `paper.tex`: one class of defect, two
|
|
64
|
+
carriers, one cleaned.
|
|
65
|
+
- **Author block**: replace `Anonymous Author(s)` with your real name, affiliation (`None` /
|
|
66
|
+
`Unaffiliated` if independent β that's honest, not a weakness), city/country, email, and
|
|
67
|
+
`\orcid{...}`. Keep the **ORCID identical** to your prior papers β it's the permanent thread that
|
|
68
|
+
ties every version to one identity regardless of name spelling.
|
|
69
|
+
- **Un-blind self-citations**: the "[anonymized for review]" / "our prior work [redacted]" placeholders
|
|
70
|
+
become the real citations. Grep the `.tex` for `anonym`, `redact`, `blinded`.
|
|
71
|
+
- **"Our tool" naming**: the studied artifact and your own tool get their real names back everywhere β
|
|
72
|
+
title, abstract, figures, captions, artifact README. (For AISec: the anonymized hook names get their
|
|
73
|
+
real names back **only after** disclosure, Β§3.)
|
|
74
|
+
- **Acknowledgements / funding**: add the section that was omitted for blind review (thanks, grant
|
|
75
|
+
numbers, compute credits). None to declare is fine β say nothing rather than invent a funder.
|
|
76
|
+
|
|
77
|
+
## 2. Swap the artifact: real repo + ARCHIVAL DOI
|
|
78
|
+
The review artifact was an OSF anonymized view-only link. The camera-ready needs two things:
|
|
79
|
+
- **A real public repo** (your GitHub, de-anonymized, with the generation layer / de-anon code that you
|
|
80
|
+
promised "lands at camera-ready" in the submission README).
|
|
81
|
+
- **An archival DOI** β mint it on **Zenodo or Figshare** (GitHubβZenodo release integration is the
|
|
82
|
+
easy path). A zip sitting in a repo does **not** earn the ACM "Artifacts Available" badge; a DOI'd,
|
|
83
|
+
immutable deposit does. Put the DOI (not just the repo URL) in the Availability section via `\url{}`
|
|
84
|
+
or `\doi{}`.
|
|
85
|
+
- Keep the artifact **self-checking** (it still recomputes every headline number and exits non-zero on
|
|
86
|
+
drift) β de-anonymizing it doesn't excuse it from reproducing the paper.
|
|
87
|
+
|
|
88
|
+
## 3. Responsible disclosure (security papers β BEFORE public release)
|
|
89
|
+
For the AISec "Safety Theater" paper the studied hooks are named-but-anonymized, and disclosure to the
|
|
90
|
+
maintainers is **owed before** any de-anonymized public release. Do this, in order:
|
|
91
|
+
- Identify the named parties (maintainers of each studied hook / tool).
|
|
92
|
+
- Send a private disclosure (email / security advisory) with the finding, repro, and a fix suggestion.
|
|
93
|
+
Give a reasonable remediation window (the venue or a 90-day norm).
|
|
94
|
+
- **Log it**: who, when, via what channel, and their response β keep the thread. This log is both
|
|
95
|
+
ethics evidence and "impact" material.
|
|
96
|
+
- Only after disclosure is sent (and ideally acknowledged) do you push the de-anonymized repo and
|
|
97
|
+
restore real hook names in the camera-ready. If a maintainer needs more time, hold the public release
|
|
98
|
+
and coordinate β the indexed paper can go out with names still generalized if disclosure is pending.
|
|
99
|
+
|
|
100
|
+
## 4. Re-check the page limit
|
|
101
|
+
De-anonymizing **adds lines** β the author block, acknowledgements, un-abbreviated self-cites, real
|
|
102
|
+
URLs all grow the paper. Camera-ready page limits are often the same as (or one page more than) review,
|
|
103
|
+
and going over is a hard reject at the proceedings stage. Recompile
|
|
104
|
+
(`pdflatex; bibtex; pdflatex; pdflatex`), confirm 0 undefined refs, and check you're within the limit.
|
|
105
|
+
If tight, ACM allows references to spill into the reference-only extra pages.
|
|
106
|
+
|
|
107
|
+
## 5. Ship
|
|
108
|
+
- Rebuild the final PDF, upload to the camera-ready system (often the same HotCRP, or an ACM eRights /
|
|
109
|
+
TAPS pipeline β follow the copyright email).
|
|
110
|
+
- Complete the **ACM/IEEE eRights** copyright form β paste the returned copyright block + DOI into the
|
|
111
|
+
`.tex` before the final build (ACM validates this).
|
|
112
|
+
- Verify the public artifact link resolves and the DOI is live before you submit the final PDF.
|
|
113
|
+
- Record the paper's DOI, the artifact DOI, and the ORCID in the paper's HANDOFF β those three IDs are
|
|
114
|
+
the authorship evidence and the anchor the extension (`extend-paper`) builds on.
|
|
115
|
+
|
|
116
|
+
## 6. Record the verdict
|
|
117
|
+
|
|
118
|
+
π΄ LAST step, once the deliverable exists:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> FINDING <count> <report-path>
|
|
122
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> ABSTAINED <reason> "<one line>"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**FINDING** β `<count>` residual items still open; `<report-path>` names them. Add `--blocking` for
|
|
126
|
+
anything that must not be pushed past: anonymization residue, a dead artifact link, or β on a
|
|
127
|
+
security paper β disclosure not yet complete.
|
|
128
|
+
**ABSTAINED** β `no-witness`: shipped, de-anonymized, DOI live, page limit re-checked, with the DOI
|
|
129
|
+
in the note. `blocked`: the acceptance notice has not arrived, so there is nothing to make ready.
|
|
130
|
+
|
|
131
|
+
π΄ That blocking finding is the only one in this pipeline whose consequence is **irreversible**. The
|
|
132
|
+
public de-anonymized repo is Google-findable the moment it is pushed, so record it before, not after.
|
|
133
|
+
|
|
134
|
+
π΄ **There is no PASS**, and on this skill that is not a formality: a stored "shipped" would have
|
|
135
|
+
been the one row in the pipeline that could be true of a repo nobody had looked at. The DOI in the
|
|
136
|
+
note is the witness. Without it there is nothing to check the row against.
|
|
137
|
+
|
|
138
|
+
## Compose with
|
|
139
|
+
- **submit-paper** (upstream β this reverses what it anonymized).
|
|
140
|
+
- **paper-pipeline/references/anonymization.md** β the canonical list of anonymization moves; undo each.
|
|
141
|
+
- **extend-paper** (next β the accepted+indexed paper is the base for a second, stronger publication).
|
|
142
|
+
|
|
143
|
+
## Provenance
|
|
144
|
+
Both portfolio papers are anonymized-for-review and **defer de-anonymization + the public artifact to
|
|
145
|
+
camera-ready by design**: AgenticDev "Measuring the Wrong Number" (submitted, camera-ready 28 Aug if
|
|
146
|
+
accepted) and AISec "Safety Theater" (ships an anonymized artifact; hook names anonymized; responsible
|
|
147
|
+
disclosure to named maintainers owed before any de-anonymized public release). ORCID is identical
|
|
148
|
+
across both so every indexed version resolves to one researcher.
|
|
@@ -0,0 +1,164 @@
|
|
|
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: "camera-ready",
|
|
11
|
+
description:
|
|
12
|
+
"On acceptance, turn the anonymized-for-review paper into the de-anonymized camera-ready that actually enters the proceedings (ACM DL / IEEE Xplore). Reverses double-blind anonymization, swaps the OSF view-only artifact for a real public repo + an archival DOI, and β for security papers β completes responsible disclosure BEFORE any de-anonymized public release. Use after a notification email says Accept and the venue gives a camera-ready deadline. Compose with submit-paper (upstream) and extend-paper (next).",
|
|
13
|
+
tools: [
|
|
14
|
+
"Read",
|
|
15
|
+
"Write",
|
|
16
|
+
"Edit",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Glob",
|
|
19
|
+
"Bash",
|
|
20
|
+
"WebSearch",
|
|
21
|
+
"WebFetch",
|
|
22
|
+
],
|
|
23
|
+
body: `
|
|
24
|
+
# camera-ready β de-anonymize an accepted paper into the final proceedings version
|
|
25
|
+
|
|
26
|
+
## Run me
|
|
27
|
+
|
|
28
|
+
π΄ FIRST, before any other step:
|
|
29
|
+
|
|
30
|
+
\`\`\`
|
|
31
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs camera-ready <paper-dir>
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
An advisory pass cannot be observed failing β silence is both its error state and its normal
|
|
35
|
+
state β so starting is an event, and events get written down.
|
|
36
|
+
|
|
37
|
+
The reviewed PDF was anonymized on purpose. Acceptance flips that: the camera-ready carries your
|
|
38
|
+
real name, your real repo, and an archival DOI β and it's the version that gets indexed, so it's the
|
|
39
|
+
actual authorship evidence. This skill is the reverse of the anonymization you did at
|
|
40
|
+
submission. Work from \`paper-pipeline/references/anonymization.md\` and undo each move it lists.
|
|
41
|
+
|
|
42
|
+
## 0. Pre-flight
|
|
43
|
+
- Confirm the **camera-ready deadline** and the **format instructions** in the acceptance email
|
|
44
|
+
(some venues ship a specific \`acmart\` template version or a copyright block to paste β use theirs).
|
|
45
|
+
- Read the reviews once more: camera-ready is your one cheap chance to fold in the must-fix comments
|
|
46
|
+
the meta-review flagged. Do those edits now, not "later."
|
|
47
|
+
- **Security papers only**: do not start the public de-anonymized release until Β§3 (disclosure) is
|
|
48
|
+
logged as complete. The de-anon repo is public and Google-findable the moment you push it.
|
|
49
|
+
|
|
50
|
+
## 1. Reverse the anonymization
|
|
51
|
+
Undo, one by one, everything \`../paper-pipeline/references/anonymization.md\` told you to hide:
|
|
52
|
+
- **Class options**: \`\\documentclass[sigconf,review,anonymous]{acmart}\` β \`\\documentclass[sigconf]{acmart}\`.
|
|
53
|
+
Dropping \`review\` also drops line numbers and the review-mode banner; dropping \`anonymous\` un-hides
|
|
54
|
+
the author block.
|
|
55
|
+
|
|
56
|
+
π΄ **Dropping \`review\` ARMS a gate that was exempt until this second β run it NOW, in the same
|
|
57
|
+
pass, not at push time:**
|
|
58
|
+
|
|
59
|
+
\`\`\`bash
|
|
60
|
+
npx eslint --no-config-lookup --config eslint.config.mjs <paper.tex>
|
|
61
|
+
\`\`\`
|
|
62
|
+
|
|
63
|
+
\`tex/future-promise\` exempts review builds deliberately: while a paper is under review, "the
|
|
64
|
+
harness will be released at camera-ready" is true and expected. The moment \`review\` comes off,
|
|
65
|
+
the same sentence becomes a contradiction with the Availability paragraph β and that is exactly
|
|
66
|
+
the defect this rule was created for, on a real submitted paper, where a reviewer had already
|
|
67
|
+
listed the missing artifact as a weakness and the printed camera-ready went on asserting it.
|
|
68
|
+
|
|
69
|
+
β οΈ **Why it must run HERE and not be left to CI** (measured 2026-09-11): the check lives in
|
|
70
|
+
ESLint, and no local hook runs ESLint on \`.tex\` β \`paper-lint.mjs\` stopped carrying it on
|
|
71
|
+
2026-09-07. CI does run it, but CI runs *after a push*, while a camera-ready gets built and
|
|
72
|
+
uploaded to HotCRP before that. Between "dropped \`review\`" and "pushed" the gate does not
|
|
73
|
+
exist. Measured on a fixture: in review mode 0 findings, with \`review\` removed 1 finding β
|
|
74
|
+
the rule flips instantly, so the only question is whether anyone looks.
|
|
75
|
+
|
|
76
|
+
β οΈ And re-run it after the LAST edit to \`paper.tex\`, not once at the start. The original
|
|
77
|
+
defect survived because the promise was swept out of the artifact (\`README\`, \`reproduce.py\`)
|
|
78
|
+
the same day and nobody made the same pass over \`paper.tex\`: one class of defect, two
|
|
79
|
+
carriers, one cleaned.
|
|
80
|
+
- **Author block**: replace \`Anonymous Author(s)\` with your real name, affiliation (\`None\` /
|
|
81
|
+
\`Unaffiliated\` if independent β that's honest, not a weakness), city/country, email, and
|
|
82
|
+
\`\\orcid{...}\`. Keep the **ORCID identical** to your prior papers β it's the permanent thread that
|
|
83
|
+
ties every version to one identity regardless of name spelling.
|
|
84
|
+
- **Un-blind self-citations**: the "[anonymized for review]" / "our prior work [redacted]" placeholders
|
|
85
|
+
become the real citations. Grep the \`.tex\` for \`anonym\`, \`redact\`, \`blinded\`.
|
|
86
|
+
- **"Our tool" naming**: the studied artifact and your own tool get their real names back everywhere β
|
|
87
|
+
title, abstract, figures, captions, artifact README. (For AISec: the anonymized hook names get their
|
|
88
|
+
real names back **only after** disclosure, Β§3.)
|
|
89
|
+
- **Acknowledgements / funding**: add the section that was omitted for blind review (thanks, grant
|
|
90
|
+
numbers, compute credits). None to declare is fine β say nothing rather than invent a funder.
|
|
91
|
+
|
|
92
|
+
## 2. Swap the artifact: real repo + ARCHIVAL DOI
|
|
93
|
+
The review artifact was an OSF anonymized view-only link. The camera-ready needs two things:
|
|
94
|
+
- **A real public repo** (your GitHub, de-anonymized, with the generation layer / de-anon code that you
|
|
95
|
+
promised "lands at camera-ready" in the submission README).
|
|
96
|
+
- **An archival DOI** β mint it on **Zenodo or Figshare** (GitHubβZenodo release integration is the
|
|
97
|
+
easy path). A zip sitting in a repo does **not** earn the ACM "Artifacts Available" badge; a DOI'd,
|
|
98
|
+
immutable deposit does. Put the DOI (not just the repo URL) in the Availability section via \`\\url{}\`
|
|
99
|
+
or \`\\doi{}\`.
|
|
100
|
+
- Keep the artifact **self-checking** (it still recomputes every headline number and exits non-zero on
|
|
101
|
+
drift) β de-anonymizing it doesn't excuse it from reproducing the paper.
|
|
102
|
+
|
|
103
|
+
## 3. Responsible disclosure (security papers β BEFORE public release)
|
|
104
|
+
For the AISec "Safety Theater" paper the studied hooks are named-but-anonymized, and disclosure to the
|
|
105
|
+
maintainers is **owed before** any de-anonymized public release. Do this, in order:
|
|
106
|
+
- Identify the named parties (maintainers of each studied hook / tool).
|
|
107
|
+
- Send a private disclosure (email / security advisory) with the finding, repro, and a fix suggestion.
|
|
108
|
+
Give a reasonable remediation window (the venue or a 90-day norm).
|
|
109
|
+
- **Log it**: who, when, via what channel, and their response β keep the thread. This log is both
|
|
110
|
+
ethics evidence and "impact" material.
|
|
111
|
+
- Only after disclosure is sent (and ideally acknowledged) do you push the de-anonymized repo and
|
|
112
|
+
restore real hook names in the camera-ready. If a maintainer needs more time, hold the public release
|
|
113
|
+
and coordinate β the indexed paper can go out with names still generalized if disclosure is pending.
|
|
114
|
+
|
|
115
|
+
## 4. Re-check the page limit
|
|
116
|
+
De-anonymizing **adds lines** β the author block, acknowledgements, un-abbreviated self-cites, real
|
|
117
|
+
URLs all grow the paper. Camera-ready page limits are often the same as (or one page more than) review,
|
|
118
|
+
and going over is a hard reject at the proceedings stage. Recompile
|
|
119
|
+
(\`pdflatex; bibtex; pdflatex; pdflatex\`), confirm 0 undefined refs, and check you're within the limit.
|
|
120
|
+
If tight, ACM allows references to spill into the reference-only extra pages.
|
|
121
|
+
|
|
122
|
+
## 5. Ship
|
|
123
|
+
- Rebuild the final PDF, upload to the camera-ready system (often the same HotCRP, or an ACM eRights /
|
|
124
|
+
TAPS pipeline β follow the copyright email).
|
|
125
|
+
- Complete the **ACM/IEEE eRights** copyright form β paste the returned copyright block + DOI into the
|
|
126
|
+
\`.tex\` before the final build (ACM validates this).
|
|
127
|
+
- Verify the public artifact link resolves and the DOI is live before you submit the final PDF.
|
|
128
|
+
- Record the paper's DOI, the artifact DOI, and the ORCID in the paper's HANDOFF β those three IDs are
|
|
129
|
+
the authorship evidence and the anchor the extension (\`extend-paper\`) builds on.
|
|
130
|
+
|
|
131
|
+
## 6. Record the verdict
|
|
132
|
+
|
|
133
|
+
π΄ LAST step, once the deliverable exists:
|
|
134
|
+
|
|
135
|
+
\`\`\`
|
|
136
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> FINDING <count> <report-path>
|
|
137
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> ABSTAINED <reason> "<one line>"
|
|
138
|
+
\`\`\`
|
|
139
|
+
|
|
140
|
+
**FINDING** β \`<count>\` residual items still open; \`<report-path>\` names them. Add \`--blocking\` for
|
|
141
|
+
anything that must not be pushed past: anonymization residue, a dead artifact link, or β on a
|
|
142
|
+
security paper β disclosure not yet complete.
|
|
143
|
+
**ABSTAINED** β \`no-witness\`: shipped, de-anonymized, DOI live, page limit re-checked, with the DOI
|
|
144
|
+
in the note. \`blocked\`: the acceptance notice has not arrived, so there is nothing to make ready.
|
|
145
|
+
|
|
146
|
+
π΄ That blocking finding is the only one in this pipeline whose consequence is **irreversible**. The
|
|
147
|
+
public de-anonymized repo is Google-findable the moment it is pushed, so record it before, not after.
|
|
148
|
+
|
|
149
|
+
π΄ **There is no PASS**, and on this skill that is not a formality: a stored "shipped" would have
|
|
150
|
+
been the one row in the pipeline that could be true of a repo nobody had looked at. The DOI in the
|
|
151
|
+
note is the witness. Without it there is nothing to check the row against.
|
|
152
|
+
|
|
153
|
+
## Compose with
|
|
154
|
+
- **submit-paper** (upstream β this reverses what it anonymized).
|
|
155
|
+
- **paper-pipeline/references/anonymization.md** β the canonical list of anonymization moves; undo each.
|
|
156
|
+
- **extend-paper** (next β the accepted+indexed paper is the base for a second, stronger publication).
|
|
157
|
+
|
|
158
|
+
## Provenance
|
|
159
|
+
Both portfolio papers are anonymized-for-review and **defer de-anonymization + the public artifact to
|
|
160
|
+
camera-ready by design**: AgenticDev "Measuring the Wrong Number" (submitted, camera-ready 28 Aug if
|
|
161
|
+
accepted) and AISec "Safety Theater" (ships an anonymized artifact; hook names anonymized; responsible
|
|
162
|
+
disclosure to named maintainers owed before any de-anonymized public release). ORCID is identical
|
|
163
|
+
across both so every indexed version resolves to one researcher.`,
|
|
164
|
+
});
|