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,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: submit-paper
|
|
3
|
+
description: End-to-end playbook for submitting a peer-reviewed paper to a double-blind venue (HotCRP workshops/conferences) — from a hardened draft to "ready for review." Covers building and anonymously hosting a reproduction artifact, HotCRP profile + form mechanics, double-blind hygiene, and the authorship/credential angles for an independent researcher. Use when the paper is drafted and reviewed and it's time to actually submit. Compose with pc-panel-review / paper-adversarial-review (harden first), and with the venue data card (references/venues/<venue>.md) for venue specifics.
|
|
4
|
+
allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch, Skill]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- vigiles:sha256:6befc6c0f3e910bd compiled from skills/submit-paper/SKILL.md.spec.ts -->
|
|
8
|
+
|
|
9
|
+
# submit-paper — get a reviewed paper from "done" to "ready for review"
|
|
10
|
+
|
|
11
|
+
## Run me
|
|
12
|
+
|
|
13
|
+
🔴 FIRST, before any other step:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs submit-paper <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
|
+
Assumes the paper is already hardened (run `pc-panel-review` — incl. its venue-fit mode — +
|
|
23
|
+
`paper-adversarial-review` first). This skill is the submission mechanics — the part that bit us with
|
|
24
|
+
avoidable friction the first time. Distilled from the AgenticDev 2026 submission.
|
|
25
|
+
|
|
26
|
+
## Venue specifics — a DATA card, not a skill
|
|
27
|
+
The venue-specific facts (deadline, page limits, tracks, PC-member conflict list, blind model, format
|
|
28
|
+
quirks, whether a supplementary-upload field exists, the extension target) live as **plain reference
|
|
29
|
+
data files** under `references/venues/<venue>.md`:
|
|
30
|
+
- `references/venues/agenticdev.md` — AgenticDev @ ASE (workshop; ACM DL/IEEE Xplore).
|
|
31
|
+
- `references/venues/aisec.md` — AISec @ ACM CCS (security workshop; ACM DL; harder bar).
|
|
32
|
+
|
|
33
|
+
**The pattern (follow it for every new venue):** when you fetch a venue's exact submission instructions,
|
|
34
|
+
save them as a new **data file** `references/venues/<venue>.md` (short `title:` frontmatter only — NOT a
|
|
35
|
+
skill with `name:`/`description:`). This preserves the "save the exact venue instructions" rule while
|
|
36
|
+
keeping the skill namespace from proliferating one card per venue. The *mechanics* stay here; the venue
|
|
37
|
+
file is only the facts.
|
|
38
|
+
|
|
39
|
+
## Publisher specifics — one level ABOVE the venue
|
|
40
|
+
Camera-ready mechanics belong to the **publisher**, not the venue: ACM eRights, the submit-vs-final
|
|
41
|
+
preamble swap, the copyright block, CCS 2012 codes and the mandatory Source-files upload are identical
|
|
42
|
+
for every ACM venue. They live in `references/publishers/<publisher>.md`:
|
|
43
|
+
- `references/publishers/acm.md` — ACM (AgenticDev @ ASE, AISec @ CCS, and every future ACM venue).
|
|
44
|
+
|
|
45
|
+
The venue card keeps only what is genuinely its own: dates, page limits, its DOI/ISBN, its copyright
|
|
46
|
+
line, its blind model. 🔴 **Filing publisher mechanics under one venue is the mistake this split exists
|
|
47
|
+
to prevent** — it was written into `agenticdev-2026/CAMERA-READY-FORM.md` first, where AISec could
|
|
48
|
+
never find it.
|
|
49
|
+
|
|
50
|
+
## 0. Pre-flight
|
|
51
|
+
- PDF compiles clean (`pdflatex; bibtex; pdflatex; pdflatex`), ≤ page limit, 0 undefined refs.
|
|
52
|
+
- **De-anon scan the PDF text AND every shipped file** before submitting — author-identifying strings
|
|
53
|
+
must return zero; identifying the *studied* artifact is fine, identifying *you* is a desk-reject.
|
|
54
|
+
**MECHANICAL GATE (run it, don't eyeball) — greps the PDF text + every artifact file + inside any
|
|
55
|
+
`*.zip` for the identity deny-list, exit non-zero on a hit:**
|
|
56
|
+
```
|
|
57
|
+
bash .claude/skills/submit-paper/check-deanon.sh <paper-dir> [pdf=paper.pdf]
|
|
58
|
+
```
|
|
59
|
+
Must PASS (exit 0) for a double-blind submission. Deny-list: `.claude/skills/submit-paper/deanon-denylist.txt`
|
|
60
|
+
(edit as handles/repos change). This is the sibling of `render-paper/check-render.sh` and guards the
|
|
61
|
+
single highest reject-vector (an artifact README naming real maintainers/repos is invisible to a
|
|
62
|
+
paper-only read). Only run it on *double-blind* papers — a de-anonymized single-blind PDF is supposed
|
|
63
|
+
to carry your name and will (correctly) fail. Canonical deny-list rationale → `paper-pipeline/references/anonymization.md`.
|
|
64
|
+
|
|
65
|
+
## 1. Build a reproduction artifact (empirical papers)
|
|
66
|
+
The single biggest accept-probability lever for a measurement paper — reviewers reward one they can run.
|
|
67
|
+
In short: a stdlib-only script that *recomputes* every headline number from raw data and **exits
|
|
68
|
+
non-zero on drift**; honest badge/scope (don't claim "raw N runs" for per-arm aggregates); a README
|
|
69
|
+
"what reproduces which number" table + LICENSE; scrubbed of `__pycache__` and fingerprints before it
|
|
70
|
+
ships. Canonical build checklist → `paper-pipeline/references/artifact-checklist.md`.
|
|
71
|
+
|
|
72
|
+
## 2. Host the artifact ANONYMOUSLY (double-blind)
|
|
73
|
+
Many workshop HotCRPs have **no supplementary-upload field** — check first; if none, host externally and
|
|
74
|
+
`\url{}` the link in the paper's Availability.
|
|
75
|
+
- **OSF (osf.io) — best; self-upload, no repo needed.** Create a **Private** project (title = paper
|
|
76
|
+
title, no name), upload the files/zip, then **Contributors → View-only Links → Add → check
|
|
77
|
+
"Anonymize" → Create**. Keep the project private; the anonymized view-only link is what reviewers get.
|
|
78
|
+
OSF has a REST API + `osfclient` (`OSF_TOKEN`) → **automatable**: with a personal access token you can
|
|
79
|
+
create the project, upload, and mint the link programmatically. See `osf-artifact-upload` for the API calls; whatever uploader you use must read the token
|
|
80
|
+
from the `OSF_TOKEN` environment variable and never from a file in the repository. Record each
|
|
81
|
+
minted view-only link in your own notes and REUSE it — a second link for the same paper is a
|
|
82
|
+
second thing reviewers can be handed, and only one of them is the one you cited.
|
|
83
|
+
- Alternatives: `anonymous.4open.science` (anonymizes a **GitHub repo** — needs a repo, not file upload;
|
|
84
|
+
use a *private* source repo so the original isn't Google-findable); a throwaway identity-free account.
|
|
85
|
+
Avoid Google Drive / Zenodo / Figshare for blind review — they leak the owner name.
|
|
86
|
+
- **VERIFY in an incognito window** (logged out): the link must show the files with contributors =
|
|
87
|
+
"Anonymous" and your name nowhere. Then put the URL in Availability via `\url{}` and rebuild.
|
|
88
|
+
|
|
89
|
+
## 3. HotCRP profile (do this once, before the form)
|
|
90
|
+
- **Name = your canonical / passport legal name**, identical on every paper you submit. (For
|
|
91
|
+
a dossier, name consistency across papers/LinkedIn/letters is load-bearing — see §6.)
|
|
92
|
+
- **Affiliation**: `None` (or `Unaffiliated`) if independent.
|
|
93
|
+
- **Country/region = where you actually reside**, not citizenship — this sidesteps ACM/IEEE
|
|
94
|
+
sanctions/payment friction for authors from sanctioned countries.
|
|
95
|
+
- **ORCID**: create one (free, 2 min) and reuse it on every paper. It's a permanent ID that ties all
|
|
96
|
+
your work to one identity *regardless of name spelling* — the fix for any name-variant problem.
|
|
97
|
+
- **Collaborators / other affiliations (COI)**: `None` if you have no recent coauthors/advisors.
|
|
98
|
+
|
|
99
|
+
## 4. The submission form
|
|
100
|
+
- **Title**: exactly as it should appear in the proceedings (ACM DL) — plain text, no markup.
|
|
101
|
+
- **Submission**: upload **PDF only**. NEVER upload a source zip of the paper directory — sibling files
|
|
102
|
+
(drafts, READMEs, internal notes) leak identity. Only a scrubbed bundle is safe.
|
|
103
|
+
- **Abstract**: HotCRP makes you paste it into its own box even though it's in the PDF (it indexes it
|
|
104
|
+
separately). Paste plain text; convert LaTeX math to unicode (`~0.6%`, `≈`).
|
|
105
|
+
- **Authors (anonymous)**: enter your **real name + email** here — this metadata is hidden from
|
|
106
|
+
reviewers; the *PDF* is what's anonymized. That's how double-blind works; it's correct, not a leak.
|
|
107
|
+
- **ACM corresponding author**: default (first author).
|
|
108
|
+
- **PC conflicts**: check only genuine COIs (past advisor/student, same affiliation, ≤2-yr coauthor).
|
|
109
|
+
An independent researcher with no ties usually checks **none** — that's honest.
|
|
110
|
+
|
|
111
|
+
## 5. Submit
|
|
112
|
+
- **Save and submit**, then **mark it "ready for review."** A saved draft alone is NOT evaluated — this
|
|
113
|
+
is the step people miss.
|
|
114
|
+
- You can edit until the deadline: use **Replace** on the Submission field to swap the PDF for a late
|
|
115
|
+
fix (e.g. adding the artifact link after you host it). Submit early, upgrade before the deadline.
|
|
116
|
+
|
|
117
|
+
## 6. Independent-researcher / dossier notes
|
|
118
|
+
- **Name consistency** is the quiet risk: publications, LinkedIn, passport, letters must resolve to one
|
|
119
|
+
person. ORCID is the tool; pick one surname and use it everywhere from paper #1.
|
|
120
|
+
- Keep the **organizer review-offer email** + any PC/reviewer confirmation — that's the *judging*
|
|
121
|
+
criterion evidence (separate from authorship).
|
|
122
|
+
- **Space submissions out** — don't cluster all papers in the month before an external
|
|
123
|
+
filing — the FILING-SPACING rule `plan-paper-timeline` applies. A burst right before a filing reads
|
|
124
|
+
as manufactured rather than sustained, and that is an observed, documented refusal ground.
|
|
125
|
+
- After acceptance: plan the **camera-ready de-anonymization** and an **extension to a higher-prestige
|
|
126
|
+
venue** (workshop → conference, ≥30% new) as a second, stronger publication.
|
|
127
|
+
|
|
128
|
+
## 7. Freeze the version you actually uploaded
|
|
129
|
+
|
|
130
|
+
🔴 **The moment the portal accepts the file, download it back and commit it.** The rendered PDF is the
|
|
131
|
+
only artifact git cannot reconstruct — it was built outside the repo and lived on the portal.
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
<paper-dir>/versions/<ISO-date>-submitted.pdf
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
and in `PIPELINE-STATUS.md`, on the Submit row, the source that produced it: the literal word
|
|
138
|
+
**`commit <hash>`**. Stages are `submitted` / `camera-ready` / `arxiv`; each one you *declare* in
|
|
139
|
+
PIPELINE-STATUS needs its own frozen file.
|
|
140
|
+
|
|
141
|
+
**This is enforced, not advised** — `checkFrozenVersions()` in `.claude/hooks/paper-lint.mjs` reads the
|
|
142
|
+
declared stages and reports a paper that declared one without freezing it. The convention itself is
|
|
143
|
+
documented per-paper in `versions/README.md`.
|
|
144
|
+
|
|
145
|
+
**Why it is a step and not hygiene:** `agenticdev-2026` kept a folder for exactly this for a month and
|
|
146
|
+
the file inside was the wrong build (340 952 B vs the real 352 357 B). It surfaced only when a reviewer
|
|
147
|
+
cited `L. 166` and there was nothing to resolve the line against. A folder without a checker is a
|
|
148
|
+
convention with no reader.
|
|
149
|
+
|
|
150
|
+
## 8. Record the verdict
|
|
151
|
+
|
|
152
|
+
🔴 LAST step, once the deliverable exists:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> FINDING <count> <report-path>
|
|
156
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> ABSTAINED <reason> "<one line>"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**FINDING** — `check-deanon.sh` exited non-zero, `access` is not green, the PDF is over the limit, or
|
|
160
|
+
the ready-for-review click never happened; `<count>` is the number of blocking items and
|
|
161
|
+
`<report-path>` names them. Always `--blocking` — every item here stops the submission.
|
|
162
|
+
**ABSTAINED** — `no-witness`: uploaded **and** marked ready for review, with the venue card or the
|
|
163
|
+
submission id in the note. `blocked`: the portal account is not through moderation yet.
|
|
164
|
+
|
|
165
|
+
🔴 **A saved draft must never be recorded as done — and it now cannot be.** A saved-but-not-submitted
|
|
166
|
+
paper is the one failure this skill's provenance names by hand, and it was invisible to every other
|
|
167
|
+
check in the pipeline. There is no constructor for "submitted"; there is only the absence of blocking
|
|
168
|
+
items, plus a submission id in the note that a human can go and look up. The id IS the witness, and
|
|
169
|
+
recording `no-witness` without one is the same lie in a new vocabulary.
|
|
170
|
+
|
|
171
|
+
## Compose with
|
|
172
|
+
- Harden first: `pc-panel-review` (incl. its venue-fit mode), `paper-adversarial-review`, `render-paper`.
|
|
173
|
+
- Publisher mechanics (camera-ready): `references/publishers/<publisher>.md`.
|
|
174
|
+
- Venue specifics: the matching data card `references/venues/<venue>.md` (e.g.
|
|
175
|
+
`references/venues/agenticdev.md`) for deadlines, page limits, PC-member conflict lists, whether
|
|
176
|
+
supplementary upload exists, and the extension target.
|
|
177
|
+
|
|
178
|
+
## Provenance
|
|
179
|
+
Written from the AgenticDev 2026 @ ASE submission (2026-07-13): PC-panel-reviewed, self-checking
|
|
180
|
+
artifact hosted on an OSF anonymized view-only link (no supplementary field at the venue), submitted #20
|
|
181
|
+
ready-for-review. The friction points here — no supplementary slot, 4open needing a repo, the abstract
|
|
182
|
+
re-paste, "ready for review" being a separate step, the PDF-only rule — are the ones that cost time.
|
|
@@ -0,0 +1,199 @@
|
|
|
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: "submit-paper",
|
|
11
|
+
description:
|
|
12
|
+
'End-to-end playbook for submitting a peer-reviewed paper to a double-blind venue (HotCRP workshops/conferences) — from a hardened draft to "ready for review." Covers building and anonymously hosting a reproduction artifact, HotCRP profile + form mechanics, double-blind hygiene, and the authorship/credential angles for an independent researcher. Use when the paper is drafted and reviewed and it\'s time to actually submit. Compose with pc-panel-review / paper-adversarial-review (harden first), and with the venue data card (references/venues/<venue>.md) for venue specifics.',
|
|
13
|
+
tools: [
|
|
14
|
+
"Read",
|
|
15
|
+
"Write",
|
|
16
|
+
"Edit",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Glob",
|
|
19
|
+
"Bash",
|
|
20
|
+
"WebSearch",
|
|
21
|
+
"WebFetch",
|
|
22
|
+
"Skill",
|
|
23
|
+
],
|
|
24
|
+
body: `
|
|
25
|
+
# submit-paper — get a reviewed paper from "done" to "ready for review"
|
|
26
|
+
|
|
27
|
+
## Run me
|
|
28
|
+
|
|
29
|
+
🔴 FIRST, before any other step:
|
|
30
|
+
|
|
31
|
+
\`\`\`
|
|
32
|
+
node .claude/skills/paper-pipeline/scripts/announce.mjs submit-paper <paper-dir>
|
|
33
|
+
\`\`\`
|
|
34
|
+
|
|
35
|
+
An advisory pass cannot be observed failing — silence is both its error state and its normal
|
|
36
|
+
state — so starting is an event, and events get written down.
|
|
37
|
+
|
|
38
|
+
Assumes the paper is already hardened (run \`pc-panel-review\` — incl. its venue-fit mode — +
|
|
39
|
+
\`paper-adversarial-review\` first). This skill is the submission mechanics — the part that bit us with
|
|
40
|
+
avoidable friction the first time. Distilled from the AgenticDev 2026 submission.
|
|
41
|
+
|
|
42
|
+
## Venue specifics — a DATA card, not a skill
|
|
43
|
+
The venue-specific facts (deadline, page limits, tracks, PC-member conflict list, blind model, format
|
|
44
|
+
quirks, whether a supplementary-upload field exists, the extension target) live as **plain reference
|
|
45
|
+
data files** under \`references/venues/<venue>.md\`:
|
|
46
|
+
- \`references/venues/agenticdev.md\` — AgenticDev @ ASE (workshop; ACM DL/IEEE Xplore).
|
|
47
|
+
- \`references/venues/aisec.md\` — AISec @ ACM CCS (security workshop; ACM DL; harder bar).
|
|
48
|
+
|
|
49
|
+
**The pattern (follow it for every new venue):** when you fetch a venue's exact submission instructions,
|
|
50
|
+
save them as a new **data file** \`references/venues/<venue>.md\` (short \`title:\` frontmatter only — NOT a
|
|
51
|
+
skill with \`name:\`/\`description:\`). This preserves the "save the exact venue instructions" rule while
|
|
52
|
+
keeping the skill namespace from proliferating one card per venue. The *mechanics* stay here; the venue
|
|
53
|
+
file is only the facts.
|
|
54
|
+
|
|
55
|
+
## Publisher specifics — one level ABOVE the venue
|
|
56
|
+
Camera-ready mechanics belong to the **publisher**, not the venue: ACM eRights, the submit-vs-final
|
|
57
|
+
preamble swap, the copyright block, CCS 2012 codes and the mandatory Source-files upload are identical
|
|
58
|
+
for every ACM venue. They live in \`references/publishers/<publisher>.md\`:
|
|
59
|
+
- \`references/publishers/acm.md\` — ACM (AgenticDev @ ASE, AISec @ CCS, and every future ACM venue).
|
|
60
|
+
|
|
61
|
+
The venue card keeps only what is genuinely its own: dates, page limits, its DOI/ISBN, its copyright
|
|
62
|
+
line, its blind model. 🔴 **Filing publisher mechanics under one venue is the mistake this split exists
|
|
63
|
+
to prevent** — it was written into \`agenticdev-2026/CAMERA-READY-FORM.md\` first, where AISec could
|
|
64
|
+
never find it.
|
|
65
|
+
|
|
66
|
+
## 0. Pre-flight
|
|
67
|
+
- PDF compiles clean (\`pdflatex; bibtex; pdflatex; pdflatex\`), ≤ page limit, 0 undefined refs.
|
|
68
|
+
- **De-anon scan the PDF text AND every shipped file** before submitting — author-identifying strings
|
|
69
|
+
must return zero; identifying the *studied* artifact is fine, identifying *you* is a desk-reject.
|
|
70
|
+
**MECHANICAL GATE (run it, don't eyeball) — greps the PDF text + every artifact file + inside any
|
|
71
|
+
\`*.zip\` for the identity deny-list, exit non-zero on a hit:**
|
|
72
|
+
\`\`\`
|
|
73
|
+
bash .claude/skills/submit-paper/check-deanon.sh <paper-dir> [pdf=paper.pdf]
|
|
74
|
+
\`\`\`
|
|
75
|
+
Must PASS (exit 0) for a double-blind submission. Deny-list: \`.claude/skills/submit-paper/deanon-denylist.txt\`
|
|
76
|
+
(edit as handles/repos change). This is the sibling of \`render-paper/check-render.sh\` and guards the
|
|
77
|
+
single highest reject-vector (an artifact README naming real maintainers/repos is invisible to a
|
|
78
|
+
paper-only read). Only run it on *double-blind* papers — a de-anonymized single-blind PDF is supposed
|
|
79
|
+
to carry your name and will (correctly) fail. Canonical deny-list rationale → \`paper-pipeline/references/anonymization.md\`.
|
|
80
|
+
|
|
81
|
+
## 1. Build a reproduction artifact (empirical papers)
|
|
82
|
+
The single biggest accept-probability lever for a measurement paper — reviewers reward one they can run.
|
|
83
|
+
In short: a stdlib-only script that *recomputes* every headline number from raw data and **exits
|
|
84
|
+
non-zero on drift**; honest badge/scope (don't claim "raw N runs" for per-arm aggregates); a README
|
|
85
|
+
"what reproduces which number" table + LICENSE; scrubbed of \`__pycache__\` and fingerprints before it
|
|
86
|
+
ships. Canonical build checklist → \`paper-pipeline/references/artifact-checklist.md\`.
|
|
87
|
+
|
|
88
|
+
## 2. Host the artifact ANONYMOUSLY (double-blind)
|
|
89
|
+
Many workshop HotCRPs have **no supplementary-upload field** — check first; if none, host externally and
|
|
90
|
+
\`\\url{}\` the link in the paper's Availability.
|
|
91
|
+
- **OSF (osf.io) — best; self-upload, no repo needed.** Create a **Private** project (title = paper
|
|
92
|
+
title, no name), upload the files/zip, then **Contributors → View-only Links → Add → check
|
|
93
|
+
"Anonymize" → Create**. Keep the project private; the anonymized view-only link is what reviewers get.
|
|
94
|
+
OSF has a REST API + \`osfclient\` (\`OSF_TOKEN\`) → **automatable**: with a personal access token you can
|
|
95
|
+
create the project, upload, and mint the link programmatically. See \`osf-artifact-upload\` for the API calls; whatever uploader you use must read the token
|
|
96
|
+
from the \`OSF_TOKEN\` environment variable and never from a file in the repository. Record each
|
|
97
|
+
minted view-only link in your own notes and REUSE it — a second link for the same paper is a
|
|
98
|
+
second thing reviewers can be handed, and only one of them is the one you cited.
|
|
99
|
+
- Alternatives: \`anonymous.4open.science\` (anonymizes a **GitHub repo** — needs a repo, not file upload;
|
|
100
|
+
use a *private* source repo so the original isn't Google-findable); a throwaway identity-free account.
|
|
101
|
+
Avoid Google Drive / Zenodo / Figshare for blind review — they leak the owner name.
|
|
102
|
+
- **VERIFY in an incognito window** (logged out): the link must show the files with contributors =
|
|
103
|
+
"Anonymous" and your name nowhere. Then put the URL in Availability via \`\\url{}\` and rebuild.
|
|
104
|
+
|
|
105
|
+
## 3. HotCRP profile (do this once, before the form)
|
|
106
|
+
- **Name = your canonical / passport legal name**, identical on every paper you submit. (For
|
|
107
|
+
a dossier, name consistency across papers/LinkedIn/letters is load-bearing — see §6.)
|
|
108
|
+
- **Affiliation**: \`None\` (or \`Unaffiliated\`) if independent.
|
|
109
|
+
- **Country/region = where you actually reside**, not citizenship — this sidesteps ACM/IEEE
|
|
110
|
+
sanctions/payment friction for authors from sanctioned countries.
|
|
111
|
+
- **ORCID**: create one (free, 2 min) and reuse it on every paper. It's a permanent ID that ties all
|
|
112
|
+
your work to one identity *regardless of name spelling* — the fix for any name-variant problem.
|
|
113
|
+
- **Collaborators / other affiliations (COI)**: \`None\` if you have no recent coauthors/advisors.
|
|
114
|
+
|
|
115
|
+
## 4. The submission form
|
|
116
|
+
- **Title**: exactly as it should appear in the proceedings (ACM DL) — plain text, no markup.
|
|
117
|
+
- **Submission**: upload **PDF only**. NEVER upload a source zip of the paper directory — sibling files
|
|
118
|
+
(drafts, READMEs, internal notes) leak identity. Only a scrubbed bundle is safe.
|
|
119
|
+
- **Abstract**: HotCRP makes you paste it into its own box even though it's in the PDF (it indexes it
|
|
120
|
+
separately). Paste plain text; convert LaTeX math to unicode (\`~0.6%\`, \`≈\`).
|
|
121
|
+
- **Authors (anonymous)**: enter your **real name + email** here — this metadata is hidden from
|
|
122
|
+
reviewers; the *PDF* is what's anonymized. That's how double-blind works; it's correct, not a leak.
|
|
123
|
+
- **ACM corresponding author**: default (first author).
|
|
124
|
+
- **PC conflicts**: check only genuine COIs (past advisor/student, same affiliation, ≤2-yr coauthor).
|
|
125
|
+
An independent researcher with no ties usually checks **none** — that's honest.
|
|
126
|
+
|
|
127
|
+
## 5. Submit
|
|
128
|
+
- **Save and submit**, then **mark it "ready for review."** A saved draft alone is NOT evaluated — this
|
|
129
|
+
is the step people miss.
|
|
130
|
+
- You can edit until the deadline: use **Replace** on the Submission field to swap the PDF for a late
|
|
131
|
+
fix (e.g. adding the artifact link after you host it). Submit early, upgrade before the deadline.
|
|
132
|
+
|
|
133
|
+
## 6. Independent-researcher / dossier notes
|
|
134
|
+
- **Name consistency** is the quiet risk: publications, LinkedIn, passport, letters must resolve to one
|
|
135
|
+
person. ORCID is the tool; pick one surname and use it everywhere from paper #1.
|
|
136
|
+
- Keep the **organizer review-offer email** + any PC/reviewer confirmation — that's the *judging*
|
|
137
|
+
criterion evidence (separate from authorship).
|
|
138
|
+
- **Space submissions out** — don't cluster all papers in the month before an external
|
|
139
|
+
filing — the FILING-SPACING rule \`plan-paper-timeline\` applies. A burst right before a filing reads
|
|
140
|
+
as manufactured rather than sustained, and that is an observed, documented refusal ground.
|
|
141
|
+
- After acceptance: plan the **camera-ready de-anonymization** and an **extension to a higher-prestige
|
|
142
|
+
venue** (workshop → conference, ≥30% new) as a second, stronger publication.
|
|
143
|
+
|
|
144
|
+
## 7. Freeze the version you actually uploaded
|
|
145
|
+
|
|
146
|
+
🔴 **The moment the portal accepts the file, download it back and commit it.** The rendered PDF is the
|
|
147
|
+
only artifact git cannot reconstruct — it was built outside the repo and lived on the portal.
|
|
148
|
+
|
|
149
|
+
\`\`\`
|
|
150
|
+
<paper-dir>/versions/<ISO-date>-submitted.pdf
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
and in \`PIPELINE-STATUS.md\`, on the Submit row, the source that produced it: the literal word
|
|
154
|
+
**\`commit <hash>\`**. Stages are \`submitted\` / \`camera-ready\` / \`arxiv\`; each one you *declare* in
|
|
155
|
+
PIPELINE-STATUS needs its own frozen file.
|
|
156
|
+
|
|
157
|
+
**This is enforced, not advised** — \`checkFrozenVersions()\` in \`.claude/hooks/paper-lint.mjs\` reads the
|
|
158
|
+
declared stages and reports a paper that declared one without freezing it. The convention itself is
|
|
159
|
+
documented per-paper in \`versions/README.md\`.
|
|
160
|
+
|
|
161
|
+
**Why it is a step and not hygiene:** \`agenticdev-2026\` kept a folder for exactly this for a month and
|
|
162
|
+
the file inside was the wrong build (340 952 B vs the real 352 357 B). It surfaced only when a reviewer
|
|
163
|
+
cited \`L. 166\` and there was nothing to resolve the line against. A folder without a checker is a
|
|
164
|
+
convention with no reader.
|
|
165
|
+
|
|
166
|
+
## 8. Record the verdict
|
|
167
|
+
|
|
168
|
+
🔴 LAST step, once the deliverable exists:
|
|
169
|
+
|
|
170
|
+
\`\`\`
|
|
171
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> FINDING <count> <report-path>
|
|
172
|
+
node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> ABSTAINED <reason> "<one line>"
|
|
173
|
+
\`\`\`
|
|
174
|
+
|
|
175
|
+
**FINDING** — \`check-deanon.sh\` exited non-zero, \`access\` is not green, the PDF is over the limit, or
|
|
176
|
+
the ready-for-review click never happened; \`<count>\` is the number of blocking items and
|
|
177
|
+
\`<report-path>\` names them. Always \`--blocking\` — every item here stops the submission.
|
|
178
|
+
**ABSTAINED** — \`no-witness\`: uploaded **and** marked ready for review, with the venue card or the
|
|
179
|
+
submission id in the note. \`blocked\`: the portal account is not through moderation yet.
|
|
180
|
+
|
|
181
|
+
🔴 **A saved draft must never be recorded as done — and it now cannot be.** A saved-but-not-submitted
|
|
182
|
+
paper is the one failure this skill's provenance names by hand, and it was invisible to every other
|
|
183
|
+
check in the pipeline. There is no constructor for "submitted"; there is only the absence of blocking
|
|
184
|
+
items, plus a submission id in the note that a human can go and look up. The id IS the witness, and
|
|
185
|
+
recording \`no-witness\` without one is the same lie in a new vocabulary.
|
|
186
|
+
|
|
187
|
+
## Compose with
|
|
188
|
+
- Harden first: \`pc-panel-review\` (incl. its venue-fit mode), \`paper-adversarial-review\`, \`render-paper\`.
|
|
189
|
+
- Publisher mechanics (camera-ready): \`references/publishers/<publisher>.md\`.
|
|
190
|
+
- Venue specifics: the matching data card \`references/venues/<venue>.md\` (e.g.
|
|
191
|
+
\`references/venues/agenticdev.md\`) for deadlines, page limits, PC-member conflict lists, whether
|
|
192
|
+
supplementary upload exists, and the extension target.
|
|
193
|
+
|
|
194
|
+
## Provenance
|
|
195
|
+
Written from the AgenticDev 2026 @ ASE submission (2026-07-13): PC-panel-reviewed, self-checking
|
|
196
|
+
artifact hosted on an OSF anonymized view-only link (no supplementary field at the venue), submitted #20
|
|
197
|
+
ready-for-review. The friction points here — no supplementary slot, 4open needing a repo, the abstract
|
|
198
|
+
re-paste, "ready for review" being a separate step, the PDF-only rule — are the ones that cost time.`,
|
|
199
|
+
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# check-deanon.sh — mechanical double-blind de-anonymization gate.
|
|
3
|
+
#
|
|
4
|
+
# WHY: for a double-blind submission, an author-identifying string leaking into
|
|
5
|
+
# the PDF *or any shipped artifact file* is the single highest reject-vector, and
|
|
6
|
+
# it's invisible to a paper-only read (e.g. an artifact README that names real
|
|
7
|
+
# maintainers/repos). This greps a deny-list across the compiled PDF's TEXT and
|
|
8
|
+
# every artifact file (including inside artifact.zip) so "anonymized" is a checked
|
|
9
|
+
# fact. Sibling to render-paper/check-render.sh. Spirit: prose isn't policy.
|
|
10
|
+
#
|
|
11
|
+
# Usage: check-deanon.sh <paper-dir> [pdf=paper.pdf] [denylist=<skill>/deanon-denylist.txt]
|
|
12
|
+
# It auto-scans, in <paper-dir>: the PDF text, everything under artifact/ (if present),
|
|
13
|
+
# and the contents of any *.zip (artifact bundles). Pass extra paths after the
|
|
14
|
+
# denylist arg to scan additional dirs/zips.
|
|
15
|
+
#
|
|
16
|
+
# Exit: 0 = clean (no identifiers found); 1 = leak(s) found; 2 = usage/tool error.
|
|
17
|
+
# NOTE: run this ONLY on double-blind submissions. A single-blind/de-anonymized
|
|
18
|
+
# paper is SUPPOSED to carry the author name — this gate would (correctly) fail it.
|
|
19
|
+
|
|
20
|
+
set -uo pipefail
|
|
21
|
+
|
|
22
|
+
DIR="${1:?usage: check-deanon.sh <paper-dir> [pdf=paper.pdf] [denylist=...] [extra-paths...]}"
|
|
23
|
+
PDF="${2:-paper.pdf}"
|
|
24
|
+
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
25
|
+
DENY="${3:-$SKILL_DIR/deanon-denylist.txt}"
|
|
26
|
+
shift $(( $# >= 3 ? 3 : $# ))
|
|
27
|
+
EXTRA=("$@")
|
|
28
|
+
|
|
29
|
+
[ -d "$DIR" ] || { echo "FAIL: no dir $DIR"; exit 2; }
|
|
30
|
+
[ -f "$DENY" ] || { echo "FAIL: no deny-list $DENY"; exit 2; }
|
|
31
|
+
|
|
32
|
+
# Build the active pattern (strip comments/blanks).
|
|
33
|
+
PAT="$(grep -vE '^\s*(#|$)' "$DENY" || true)"
|
|
34
|
+
[ -n "$PAT" ] || { echo "FAIL: deny-list $DENY has no patterns"; exit 2; }
|
|
35
|
+
|
|
36
|
+
TMP="$(mktemp -d)"
|
|
37
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
38
|
+
|
|
39
|
+
echo "== check-deanon: $DIR (pdf=$PDF, $(printf '%s\n' "$PAT" | wc -l | tr -d ' ') patterns) =="
|
|
40
|
+
|
|
41
|
+
hits=0
|
|
42
|
+
|
|
43
|
+
scan() { # scan <label> <file-or-textfile>
|
|
44
|
+
local label="$1" file="$2"
|
|
45
|
+
[ -f "$file" ] || return 0
|
|
46
|
+
local m
|
|
47
|
+
# -I skips binary files. REQUIRED since 2026-08-07, when the artifact branch stopped
|
|
48
|
+
# filtering by extension: without it, grep prints "Binary file X matches" for any .so,
|
|
49
|
+
# .map or image whose bytes happen to contain the pattern, and that line would be counted
|
|
50
|
+
# as a LEAK. A gate that cries wolf on a shared object gets muted, and a muted deanon
|
|
51
|
+
# gate is the same as no deanon gate.
|
|
52
|
+
m="$(grep -inEI "$PAT" "$file" 2>/dev/null || true)"
|
|
53
|
+
if [ -n "$m" ]; then
|
|
54
|
+
while IFS= read -r line; do
|
|
55
|
+
echo " LEAK $label:$line"
|
|
56
|
+
hits=$((hits+1))
|
|
57
|
+
done <<< "$m"
|
|
58
|
+
fi
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# 1. PDF text (via pymupdf — same dep render-paper uses)
|
|
62
|
+
if [ -f "$DIR/$PDF" ]; then
|
|
63
|
+
if python3 - "$DIR/$PDF" "$TMP/pdf.txt" <<'PY' 2>/dev/null
|
|
64
|
+
import sys
|
|
65
|
+
try:
|
|
66
|
+
import fitz
|
|
67
|
+
except Exception:
|
|
68
|
+
sys.exit(3)
|
|
69
|
+
d = fitz.open(sys.argv[1])
|
|
70
|
+
open(sys.argv[2], "w").write("".join(p.get_text() for p in d))
|
|
71
|
+
PY
|
|
72
|
+
then scan "PDF[$PDF]" "$TMP/pdf.txt"
|
|
73
|
+
else echo " WARN: could not extract PDF text (pymupdf missing?) — PDF not scanned"; fi
|
|
74
|
+
else
|
|
75
|
+
echo " WARN: $DIR/$PDF not found — PDF not scanned"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# 2. Every file under artifact/ (README, scripts, data) — text files only
|
|
79
|
+
if [ -d "$DIR/artifact" ]; then
|
|
80
|
+
while IFS= read -r f; do
|
|
81
|
+
scan "artifact/${f#"$DIR"/artifact/}" "$f"
|
|
82
|
+
# 🔴 NO EXTENSION FILTER, and that is the fix, not an oversight. Until 2026-08-07 this
|
|
83
|
+
# branch carried an allow-list (*.md *.py *.txt *.json *.js *.ts *.sh *.cfg *.csv *.tex
|
|
84
|
+
# LICENSE README*) and SILENTLY SKIPPED everything else — while printing "PASS: no
|
|
85
|
+
# author-identifying strings found. Safe for double-blind." about files it never opened.
|
|
86
|
+
#
|
|
87
|
+
# Measured, one fixture, identical bytes, three placements:
|
|
88
|
+
# artifact/config.yml (loose) -> exit 0, the affirmative safety sentence
|
|
89
|
+
# config.yml inside artifact.zip -> exit 1, LEAK reported
|
|
90
|
+
# config.yml via an extra path -> exit 1, LEAK reported
|
|
91
|
+
#
|
|
92
|
+
# The other two branches never filtered — the zip branch decodes every member, the
|
|
93
|
+
# extra-path branch is a bare `find -type f` — so the allow-list was an oversight, and
|
|
94
|
+
# the header's own contract says "every artifact file". Unlisted extensions that are
|
|
95
|
+
# ordinary in a real artifact: .yml/.yaml, .toml, Dockerfile, Makefile, .ipynb,
|
|
96
|
+
# .env.example, and .bib — a BibTeX file under artifact/ carrying the author's own name
|
|
97
|
+
# is the sharpest version of the miss.
|
|
98
|
+
#
|
|
99
|
+
# `grep -I` in scan() skips binary files, which is what the zip branch already relies on,
|
|
100
|
+
# so dropping the filter costs a little time and no correctness.
|
|
101
|
+
done < <(find "$DIR/artifact" -type f 2>/dev/null)
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# 3. Contents of any *.zip in the paper dir (and any extra zip paths) — the sneaky one
|
|
105
|
+
scan_zip() { # scan_zip <zip>
|
|
106
|
+
local zip="$1"
|
|
107
|
+
[ -f "$zip" ] || return 0
|
|
108
|
+
python3 - "$zip" "$TMP/zipdump" <<'PY' 2>/dev/null || return 0
|
|
109
|
+
import sys, zipfile, os
|
|
110
|
+
z, out = sys.argv[1], sys.argv[2]
|
|
111
|
+
os.makedirs(out, exist_ok=True)
|
|
112
|
+
zf = zipfile.ZipFile(z)
|
|
113
|
+
for n in zf.namelist():
|
|
114
|
+
if n.endswith("/"): continue
|
|
115
|
+
try:
|
|
116
|
+
data = zf.read(n)
|
|
117
|
+
text = data.decode("utf-8", "ignore")
|
|
118
|
+
except Exception:
|
|
119
|
+
continue
|
|
120
|
+
safe = n.replace("/", "__")
|
|
121
|
+
open(os.path.join(out, safe), "w").write(text)
|
|
122
|
+
PY
|
|
123
|
+
if [ -d "$TMP/zipdump" ]; then
|
|
124
|
+
for f in "$TMP/zipdump"/*; do
|
|
125
|
+
[ -f "$f" ] || continue
|
|
126
|
+
scan "$(basename "$zip")!$(basename "$f" | sed 's/__/\//g')" "$f"
|
|
127
|
+
done
|
|
128
|
+
rm -rf "$TMP/zipdump"
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
while IFS= read -r z; do scan_zip "$z"; done < <(find "$DIR" -maxdepth 2 -name '*.zip' -type f 2>/dev/null)
|
|
132
|
+
|
|
133
|
+
# 4. Extra caller-supplied paths (dirs or zips)
|
|
134
|
+
for p in "${EXTRA[@]:-}"; do
|
|
135
|
+
[ -z "$p" ] && continue
|
|
136
|
+
if [ -d "$p" ]; then
|
|
137
|
+
while IFS= read -r f; do scan "extra:${f}" "$f"; done < <(find "$p" -type f 2>/dev/null)
|
|
138
|
+
elif [[ "$p" == *.zip ]]; then scan_zip "$p"
|
|
139
|
+
elif [ -f "$p" ]; then scan "extra:$p" "$p"; fi
|
|
140
|
+
done
|
|
141
|
+
|
|
142
|
+
echo "-- summary: $hits identifier hit(s) across PDF + artifact + zip"
|
|
143
|
+
if [ "$hits" -eq 0 ]; then
|
|
144
|
+
echo "PASS: no author-identifying strings found. Safe for double-blind."
|
|
145
|
+
exit 0
|
|
146
|
+
else
|
|
147
|
+
echo "FAIL: de-anonymization leak(s) above — scrub before submitting double-blind."
|
|
148
|
+
exit 1
|
|
149
|
+
fi
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ACM — camera-ready mechanics, shared across ALL ACM venues"
|
|
3
|
+
created: 2026-08-24
|
|
4
|
+
updated: 2026-08-24
|
|
5
|
+
tags: [publisher, acm, camera-ready, erights, ccs]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ACM: what camera-ready requires
|
|
9
|
+
|
|
10
|
+
> This is the **publisher** level, not the venue level. Identical for AgenticDev@ASE, AISec@CCS,
|
|
11
|
+
> and any other ACM conference. The venue card (`../venues/<venue>.md`) holds only what's its own:
|
|
12
|
+
> dates, page limit, its own DOI/ISBN, blind model.
|
|
13
|
+
>
|
|
14
|
+
> Captured 2026-08-24 from the live AgenticDev #20 HotCRP form — field by field, not from memory.
|
|
15
|
+
|
|
16
|
+
## 🔴 Order is mandatory, and the first step breaks everything else
|
|
17
|
+
|
|
18
|
+
**eRights is filled in FIRST and requires the FINAL title and author list.** So any decision about
|
|
19
|
+
a title change has to be made **before** it — otherwise the copyright block gets issued under the
|
|
20
|
+
old name.
|
|
21
|
+
|
|
22
|
+
1. **ACM eRights** — a form from ACM, arrives as a link in HotCRP. The final version isn't
|
|
23
|
+
accepted without it.
|
|
24
|
+
2. Update **Title** on the portal if it changed (it still holds the submission version).
|
|
25
|
+
3. Convert the preamble to camera-ready (table below).
|
|
26
|
+
4. Insert the copyright block that eRights returned.
|
|
27
|
+
5. Build the PDF → run the portal's format checker.
|
|
28
|
+
6. Upload the **Final version** (PDF) **and Source files** — both are mandatory.
|
|
29
|
+
7. References: easiest is uploading `.bbl` + `.aux`.
|
|
30
|
+
8. Fill in **ACM keywords** and **CCS codes**.
|
|
31
|
+
9. `Save and resubmit`.
|
|
32
|
+
|
|
33
|
+
## Preamble: submission mode ≠ camera-ready
|
|
34
|
+
|
|
35
|
+
The typical submission preamble is **wrong** for the final. What to change:
|
|
36
|
+
|
|
37
|
+
| in the submission | in camera-ready | why |
|
|
38
|
+
| --------------------------------------- | ---------------------- | ---------------------------------------------------------- |
|
|
39
|
+
| `\settopmatter{printacmref=false}` | remove | the ACM reference line has to print |
|
|
40
|
+
| `\setcopyright{none}` | the value from eRights | otherwise the block is wrong |
|
|
41
|
+
| `\pagestyle{plain}` | remove | the form explicitly says **"Do not include page numbers"** |
|
|
42
|
+
| the `review` option on `\documentclass` | remove | it adds line numbers |
|
|
43
|
+
|
|
44
|
+
Plus: **all fonts must be embedded** in the PDF.
|
|
45
|
+
|
|
46
|
+
The **copyright block** goes in the **bottom-left corner of the first page**, its exact form
|
|
47
|
+
depends on the choice made in eRights:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
<Venue> '<YY>, <dates>, <city>, <country>
|
|
51
|
+
© <year>
|
|
52
|
+
ACM ISBN <ISBN>
|
|
53
|
+
https://doi.org/<DOI>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
⚠️ **DOI and ISBN are assigned in advance** and are visible on the form before upload — there's no
|
|
57
|
+
need to wait for them or make them up.
|
|
58
|
+
|
|
59
|
+
## Portal fields
|
|
60
|
+
|
|
61
|
+
| Field | Req. | What matters |
|
|
62
|
+
| ---------------------- | ---- | --------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| **ACM eRights** | ✱ | before everything else; final title + authors |
|
|
64
|
+
| **Title** | ✱ | "exactly as it should appear in the ACM Digital Library" |
|
|
65
|
+
| **Final version** | ✱ | PDF, up to 600 MB |
|
|
66
|
+
| **Abstract** | ✱ | markdown + LaTeX math, has a Preview |
|
|
67
|
+
| **Source files** | ✱ | **ALL** build files: `.tex`, `.bib`, figures. Best as a single `.zip` |
|
|
68
|
+
| **ACM keywords** | — | one **per line** |
|
|
69
|
+
| **CCS** | — | terms from **2012 CCS** via the CCS Browser: Assign concepts → View your CCS Concept → Generate Code → paste the XML |
|
|
70
|
+
| **References** | — | upload `.bbl` + `.aux`, or as text one per line |
|
|
71
|
+
| **Supplements** | — | an **integral** part of the work (proof, online appendix) |
|
|
72
|
+
| **Auxiliary material** | — | NOT integral, but still lands in ACM DL: **dataset/code**. ACM does not claim copyright, but gets distribution rights |
|
|
73
|
+
|
|
74
|
+
## What to decide deliberately
|
|
75
|
+
|
|
76
|
+
- **Auxiliary material.** Whether to also put the artifact in ACM DL alongside OSF/GitHub. Upside —
|
|
77
|
+
permanence and an extra findability point; downside — ACM gets distribution rights. Decide per
|
|
78
|
+
paper, not per venue.
|
|
79
|
+
- **APC.** If the venue charges one — pay only **after** ACM's author kit, which has the amount and
|
|
80
|
+
the process.
|
|
81
|
+
|
|
82
|
+
## The frozen version
|
|
83
|
+
|
|
84
|
+
Camera-ready is a separate **stage** in the sense of `versions/` (see `checkFrozenVersions()` in
|
|
85
|
+
`paper-lint.mjs`): the uploaded PDF is stored as `versions/<date>-camera-ready.pdf`, and the commit
|
|
86
|
+
of its source is recorded in `PIPELINE-STATUS.md` as `commit <hash>`.
|
|
87
|
+
|
|
88
|
+
**Why this isn't a formality:** the arXiv posting and the extension paper get diffed against
|
|
89
|
+
camera-ready later, and reviewer references to line numbers only resolve against the exact render
|
|
90
|
+
a human read. 🔴 The failure that made this rule exist: `agenticdev-2026` had the wrong submission
|
|
91
|
+
PDF sitting there for a month (340,952 B vs 352,357 B), and when a reviewer cited `L. 166`, there
|
|
92
|
+
was nothing to check it against.
|