paperlint 3.2.0 โ 4.1.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/workflows/ci.yml +16 -23
- package/CLAUDE.md +33 -13
- package/CONTRIBUTING.md +23 -7
- package/README.md +11 -8
- package/dist/adapters/banal/failure.d.ts +1 -7
- package/dist/adapters/banal/failure.d.ts.map +1 -1
- package/dist/adapters/banal/failure.js +5 -7
- package/dist/adapters/banal/failure.js.map +1 -1
- package/dist/adapters/banal/index.d.ts.map +1 -1
- package/dist/adapters/banal/index.js +8 -11
- package/dist/adapters/banal/index.js.map +1 -1
- package/dist/adapters/banal/install.d.ts.map +1 -1
- package/dist/adapters/banal/install.js +4 -3
- package/dist/adapters/banal/install.js.map +1 -1
- package/dist/adapters/banal/invocation.d.ts +10 -5
- package/dist/adapters/banal/invocation.d.ts.map +1 -1
- package/dist/adapters/banal/invocation.js +13 -1
- package/dist/adapters/banal/invocation.js.map +1 -1
- package/dist/adapters/banal/locate.d.ts +12 -9
- package/dist/adapters/banal/locate.d.ts.map +1 -1
- package/dist/adapters/banal/locate.js +19 -12
- package/dist/adapters/banal/locate.js.map +1 -1
- package/dist/adapters/banal/run.d.ts +10 -1
- package/dist/adapters/banal/run.d.ts.map +1 -1
- package/dist/adapters/banal/run.js +8 -4
- package/dist/adapters/banal/run.js.map +1 -1
- package/dist/adapters/banal/settings.d.ts +1 -1
- package/dist/adapters/banal/settings.d.ts.map +1 -1
- package/dist/adapters/banal/settings.js +2 -1
- package/dist/adapters/banal/settings.js.map +1 -1
- package/dist/adapters/latex/document-class.d.ts +22 -0
- package/dist/adapters/latex/document-class.d.ts.map +1 -0
- package/dist/adapters/latex/document-class.js +102 -0
- package/dist/adapters/latex/document-class.js.map +1 -0
- package/dist/adapters/latex/hidden.d.ts +16 -0
- package/dist/adapters/latex/hidden.d.ts.map +1 -0
- package/dist/adapters/latex/hidden.js +49 -0
- package/dist/adapters/latex/hidden.js.map +1 -0
- package/dist/adapters/latex/index.d.ts +29 -0
- package/dist/adapters/latex/index.d.ts.map +1 -0
- package/dist/adapters/latex/index.js +18 -0
- package/dist/adapters/latex/index.js.map +1 -0
- package/dist/adapters/latex/nodes.d.ts +54 -0
- package/dist/adapters/latex/nodes.d.ts.map +1 -0
- package/dist/adapters/latex/nodes.js +93 -0
- package/dist/adapters/latex/nodes.js.map +1 -0
- package/dist/adapters/latex/outline.d.ts +10 -0
- package/dist/adapters/latex/outline.d.ts.map +1 -0
- package/dist/adapters/latex/outline.js +39 -0
- package/dist/adapters/latex/outline.js.map +1 -0
- package/dist/adapters/latex/parse.d.ts +42 -0
- package/dist/adapters/latex/parse.d.ts.map +1 -0
- package/dist/adapters/latex/parse.js +94 -0
- package/dist/adapters/latex/parse.js.map +1 -0
- package/dist/adapters/latex/rendered.d.ts +10 -0
- package/dist/adapters/latex/rendered.d.ts.map +1 -0
- package/dist/adapters/latex/rendered.js +39 -0
- package/dist/adapters/latex/rendered.js.map +1 -0
- package/dist/adapters/memory/index.d.ts.map +1 -1
- package/dist/adapters/memory/index.js +8 -2
- package/dist/adapters/memory/index.js.map +1 -1
- package/dist/adapters/node/process.io.d.ts +6 -3
- package/dist/adapters/node/process.io.d.ts.map +1 -1
- package/dist/adapters/node/process.io.js.map +1 -1
- package/dist/adapters/node/workspace.io.d.ts.map +1 -1
- package/dist/adapters/node/workspace.io.js +4 -2
- package/dist/adapters/node/workspace.io.js.map +1 -1
- package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
- package/dist/adapters/pdfjs/fill.js +12 -12
- package/dist/adapters/pdfjs/fill.js.map +1 -1
- package/dist/adapters/references/index.d.ts.map +1 -1
- package/dist/adapters/references/index.js +4 -2
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/build-engine.d.ts +1 -1
- package/dist/build-engine.d.ts.map +1 -1
- package/dist/build-engine.js +8 -1
- package/dist/build-engine.js.map +1 -1
- package/dist/build.d.ts +2 -3
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +9 -10
- package/dist/build.js.map +1 -1
- package/dist/caller-path.d.ts +3 -0
- package/dist/caller-path.d.ts.map +1 -0
- package/dist/caller-path.js +13 -0
- package/dist/caller-path.js.map +1 -0
- package/dist/cli.d.ts +10 -17
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +91 -17
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +12 -3
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/domain/paths.d.ts +8 -2
- package/dist/domain/paths.d.ts.map +1 -1
- package/dist/domain/paths.js +12 -1
- package/dist/domain/paths.js.map +1 -1
- package/dist/domain/ready.d.ts +24 -0
- package/dist/domain/ready.d.ts.map +1 -0
- package/dist/domain/ready.js +11 -0
- package/dist/domain/ready.js.map +1 -0
- package/dist/domain/record.d.ts +8 -0
- package/dist/domain/record.d.ts.map +1 -0
- package/dist/domain/record.js +8 -0
- package/dist/domain/record.js.map +1 -0
- package/dist/domain/sha256.d.ts.map +1 -1
- package/dist/domain/sha256.js +4 -2
- package/dist/domain/sha256.js.map +1 -1
- package/dist/domain/tex-document.d.ts +84 -0
- package/dist/domain/tex-document.d.ts.map +1 -0
- package/dist/domain/tex-document.js +43 -0
- package/dist/domain/tex-document.js.map +1 -0
- package/dist/engine.d.ts +23 -22
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js.map +1 -1
- package/dist/eslint-rules/bib-reachable-entry.d.ts +1 -1
- package/dist/eslint-rules/bib-reachable-entry.js.map +1 -1
- package/dist/eslint-rules/install-path-literals.d.ts +2 -2
- package/dist/eslint-rules/install-path-literals.js.map +1 -1
- package/dist/eslint-rules/paper-research-question.d.ts +1 -1
- package/dist/eslint-rules/paper-research-question.js.map +1 -1
- package/dist/eslint-rules/paper-stages.d.ts +2 -2
- package/dist/eslint-rules/paper-stages.js.map +1 -1
- package/dist/eslint-rules/paper-typography.d.ts +6 -6
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/pdf-last-page-balance.d.ts +1 -1
- package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -1
- package/dist/eslint-rules/review-frontmatter.d.ts +2 -2
- package/dist/eslint-rules/review-frontmatter.js.map +1 -1
- package/dist/eslint-rules/sibling-frontmatter.d.ts +1 -1
- package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -1
- package/dist/eslint-rules/temp-root-realpath.d.ts +1 -1
- package/dist/eslint-rules/temp-root-realpath.js.map +1 -1
- package/dist/eslint-rules/tex-build.d.ts +2 -2
- package/dist/eslint-rules/tex-build.js.map +1 -1
- package/dist/facts-file.d.ts.map +1 -1
- package/dist/facts-file.js +31 -28
- package/dist/facts-file.js.map +1 -1
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +17 -2
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +3 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +18 -8
- package/dist/init.js.map +1 -1
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +1 -5
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/new-paper.d.ts +5 -0
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +8 -1
- package/dist/new-paper.js.map +1 -1
- package/dist/package-dirs.d.ts +5 -0
- package/dist/package-dirs.d.ts.map +1 -0
- package/dist/package-dirs.js +14 -0
- package/dist/package-dirs.js.map +1 -0
- package/dist/paper-files.d.ts +4 -4
- package/dist/paper-files.d.ts.map +1 -1
- package/dist/paper-files.js +6 -6
- package/dist/paper-files.js.map +1 -1
- package/dist/paper-settings.js +3 -3
- package/dist/paper-settings.js.map +1 -1
- package/dist/pdf-facts.d.ts +51 -1
- package/dist/pdf-facts.d.ts.map +1 -1
- package/dist/pdf-facts.js +23 -15
- package/dist/pdf-facts.js.map +1 -1
- package/dist/pdf-geometry.d.ts.map +1 -1
- package/dist/pdf-geometry.js +2 -3
- package/dist/pdf-geometry.js.map +1 -1
- package/dist/ports/latex.d.ts +24 -0
- package/dist/ports/latex.d.ts.map +1 -0
- package/dist/ports/latex.js +2 -0
- package/dist/ports/latex.js.map +1 -0
- package/dist/ports/tool-installer.d.ts +2 -14
- package/dist/ports/tool-installer.d.ts.map +1 -1
- package/dist/presets.d.ts +15 -2
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +35 -10
- package/dist/presets.js.map +1 -1
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +4 -4
- package/dist/references.js.map +1 -1
- package/dist/rules-config.d.ts +26 -1
- package/dist/rules-config.d.ts.map +1 -1
- package/dist/rules-config.js +9 -9
- package/dist/rules-config.js.map +1 -1
- package/dist/tex-requirements.d.ts +15 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +28 -10
- package/dist/tex-requirements.js.map +1 -1
- package/dist/tex-venue-rules.d.ts +83 -0
- package/dist/tex-venue-rules.d.ts.map +1 -0
- package/dist/tex-venue-rules.js +254 -0
- package/dist/tex-venue-rules.js.map +1 -0
- package/dist/types.d.ts +5 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts +1 -1
- package/dist/venue-rules.d.ts.map +1 -1
- package/dist/venue-rules.js +20 -7
- package/dist/venue-rules.js.map +1 -1
- package/docs/configuration.md +5 -4
- package/docs/e2e.md +69 -40
- package/docs/install.md +1 -1
- package/docs/prior-art/README.md +1 -1
- package/docs/prior-art/package-location.md +5 -5
- package/docs/prior-art/repro/README.md +1 -1
- package/docs/prior-art/test-tooling.md +21 -10
- package/docs/rules/tex/required-section.md +73 -0
- package/docs/rules/tex/template.md +62 -0
- package/docs/rules/tex/venue-leftover.md +71 -0
- package/docs/rules.md +70 -48
- package/docs/testing.md +17 -4
- package/docs/texlive-install-decision.md +1 -1
- package/docs/toolchain.md +2 -2
- package/eslint-rules/bib-reachable-entry.ts +1 -1
- package/eslint-rules/install-path-literals.ts +2 -2
- package/eslint-rules/paper-research-question.ts +1 -1
- package/eslint-rules/paper-stages.ts +2 -2
- package/eslint-rules/paper-typography.ts +2 -2
- package/eslint-rules/pdf-last-page-balance.ts +1 -1
- package/eslint-rules/review-frontmatter.ts +1 -1
- package/eslint-rules/temp-root-realpath.ts +1 -1
- package/eslint-rules/tex-build.ts +2 -2
- package/eslint.config.mjs +162 -15
- package/fixtures/build-e2e/acmart/expect.json +26 -0
- package/fixtures/build-e2e/aidc/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/aidc/expect.json +14 -0
- package/fixtures/build-e2e/aidc/paper.tex +46 -0
- package/fixtures/build-e2e/aidc/paperlint.json +1 -0
- package/fixtures/build-e2e/broken/expect.json +11 -0
- package/fixtures/build-e2e/cite/expect.json +27 -0
- package/fixtures/build-e2e/empty/expect.json +12 -0
- package/fixtures/build-e2e/fallback/expect.json +53 -0
- package/fixtures/build-e2e/guards/expect.json +6 -0
- package/fixtures/build-e2e/no-source/expect.json +10 -0
- package/fixtures/build-e2e/unbalanced/expect.json +60 -0
- package/fixtures/install-path-literals/clean.fixture.mjs +1 -1
- package/fixtures/install-path-literals/clean.md +2 -2
- package/fixtures/install-path-literals/defect.fixture.mjs +1 -1
- package/fixtures/install-path-literals/defect.md +2 -2
- package/fixtures/pdf-facts/README.md +1 -1
- package/fixtures/real-markdown-paper/baseline.ts +1 -1
- package/fixtures/render-paper/build-clean.sh +3 -5
- package/hooks/paper-status-gates.sh +9 -19
- package/lib/paper-config.harness.mjs +1 -1
- package/lib/paper-config.ts +1 -5
- package/lib/skill-checks.mjs +24 -381
- package/lib/skill-checks.test.mjs +63 -115
- package/lib/skill-corpus.mjs +10 -251
- package/lib/skill-corpus.test.mjs +2 -13
- package/lib/skill-trigger-cases.mjs +1 -1
- package/package.json +13 -2
- package/{skills/submit-paper/references/venues โ presets}/acm-sigconf.jsonc +4 -1
- package/{skills/submit-paper/references/venues โ presets}/agenticdev.jsonc +4 -0
- package/presets/aidc.jsonc +73 -0
- package/{skills/submit-paper/references/venues โ presets}/aisec.jsonc +4 -0
- package/presets/ieee-conference.jsonc +66 -0
- package/{skills/submit-paper/references/venues โ presets}/realm.jsonc +8 -1
- package/{skills/submit-paper/references/venues โ presets/tex}/paper-guards.tex +1 -1
- package/{skills/submit-paper/references/venues โ presets}/venue-profile.schema.json +30 -2
- package/scripts/check.harness.ts +64 -10
- package/scripts/check.test.ts +60 -13
- package/scripts/check.ts +83 -30
- package/scripts/coverage-config.test.ts +0 -1
- package/scripts/harness-api.frozen.json +0 -1
- package/scripts/test.test.ts +1 -1
- package/scripts/test.ts +1 -1
- package/skills/analyze-sibling-paper/SKILL.md +1 -39
- package/skills/analyze-sibling-paper/SKILL.md.spec.ts +0 -38
- package/skills/argument-arc/SKILL.md +2 -36
- package/skills/argument-arc/SKILL.md.spec.ts +1 -43
- package/skills/build-benchmark/SKILL.md +1 -41
- package/skills/build-benchmark/SKILL.md.spec.ts +0 -40
- package/skills/camera-ready/SKILL.md +1 -34
- package/skills/camera-ready/SKILL.md.spec.ts +0 -33
- package/skills/cold-read-diff/SKILL.md +1 -35
- package/skills/cold-read-diff/SKILL.md.spec.ts +0 -34
- package/skills/draft-paper/SKILL.md +2 -41
- package/skills/draft-paper/SKILL.md.spec.ts +1 -50
- package/skills/extend-paper/SKILL.md +2 -33
- package/skills/extend-paper/SKILL.md.spec.ts +1 -42
- package/skills/find-venue/SKILL.md +2 -38
- package/skills/find-venue/SKILL.md.spec.ts +1 -47
- package/skills/grade-paper-writing/SKILL.md +3 -38
- package/skills/grade-paper-writing/SKILL.md.spec.ts +2 -47
- package/skills/grade-paper-writing/prose-lint.mjs +2 -3
- package/skills/grade-paper-writing/prose-lint.test.ts +1 -1
- package/skills/harden-paper/SKILL.md +1 -39
- package/skills/harden-paper/SKILL.md.spec.ts +0 -38
- package/skills/map-prior-work/SKILL.md +1 -35
- package/skills/map-prior-work/SKILL.md.spec.ts +0 -34
- package/skills/osf-artifact-upload/osf-artifact-upload.harness.ts +3 -4
- package/skills/paper-adversarial-review/SKILL.md +2 -35
- package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -43
- package/skills/paper-pipeline/PIPELINE-MAP.md +2 -2
- package/skills/paper-pipeline/SKILL.md +3 -29
- package/skills/paper-pipeline/SKILL.md.spec.ts +2 -28
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1 -1
- package/skills/paper-pipeline/paper-pipeline.harness.mjs +25 -40
- package/skills/paper-pipeline/references/acceptance-gate.md +1 -6
- package/skills/paper-pipeline/references/pipeline-status-template.md +8 -35
- package/skills/paper-pipeline/scripts/README.md +30 -225
- package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +4 -8
- package/skills/paper-pipeline/scripts/consumer.d.mts +0 -2
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +6 -104
- package/skills/paper-pipeline/scripts/consumer.mjs +24 -119
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +2 -3
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +3 -3
- package/skills/paper-status/SKILL.md +2 -42
- package/skills/paper-status/SKILL.md.spec.ts +1 -41
- package/skills/pc-panel-review/SKILL.md +2 -46
- package/skills/pc-panel-review/SKILL.md.spec.ts +1 -45
- package/skills/plan-paper-timeline/SKILL.md +2 -36
- package/skills/plan-paper-timeline/SKILL.md.spec.ts +0 -36
- package/skills/render-paper/SKILL.md +2 -38
- package/skills/render-paper/SKILL.md.spec.ts +1 -37
- package/skills/render-paper/check-render.sh +16 -63
- package/skills/render-paper/render-paper.harness.mjs +17 -59
- package/skills/research-ideate/SKILL.md +2 -39
- package/skills/research-ideate/SKILL.md.spec.ts +1 -47
- package/skills/study-accepted-papers/SKILL.md +1 -34
- package/skills/study-accepted-papers/SKILL.md.spec.ts +0 -33
- package/skills/submit-paper/SKILL.md +1 -33
- package/skills/submit-paper/SKILL.md.spec.ts +0 -32
- package/skills/sweep-design-space/SKILL.md +1 -38
- package/skills/sweep-design-space/SKILL.md.spec.ts +0 -37
- package/skills/tighten-paper/SKILL.md +2 -39
- package/skills/tighten-paper/SKILL.md.spec.ts +1 -47
- package/skills/tighten-paper/structure.mjs +4 -11
- package/skills/verify-citations/SKILL.md +2 -38
- package/skills/verify-citations/SKILL.md.spec.ts +1 -37
- package/src/adapters/banal/failure.ts +9 -10
- package/src/adapters/banal/index.test.ts +3 -3
- package/src/adapters/banal/index.ts +8 -10
- package/src/adapters/banal/install.ts +9 -4
- package/src/adapters/banal/invocation.test.ts +20 -8
- package/src/adapters/banal/invocation.ts +24 -9
- package/src/adapters/banal/locate.test.ts +2 -2
- package/src/adapters/banal/locate.ts +27 -21
- package/src/adapters/banal/output.test.ts +1 -1
- package/src/adapters/banal/run.test.ts +3 -3
- package/src/adapters/banal/run.ts +16 -10
- package/src/adapters/banal/settings.ts +2 -2
- package/src/adapters/banal/xml.test.ts +1 -1
- package/src/adapters/curl/download.test.ts +4 -4
- package/src/adapters/latex/document-class.ts +147 -0
- package/src/adapters/latex/hidden.ts +70 -0
- package/src/adapters/latex/index.test.ts +361 -0
- package/src/adapters/latex/index.ts +55 -0
- package/src/adapters/latex/nodes.ts +141 -0
- package/src/adapters/latex/outline.ts +64 -0
- package/src/adapters/latex/parse.ts +136 -0
- package/src/adapters/latex/rendered.ts +59 -0
- package/src/adapters/memory/index.ts +4 -3
- package/src/adapters/node/files.test.ts +5 -3
- package/src/adapters/node/process.io.ts +9 -2
- package/src/adapters/node/process.test.ts +4 -4
- package/src/adapters/node/workspace.io.ts +9 -4
- package/src/adapters/pdfjs/fill.test.ts +1 -1
- package/src/adapters/pdfjs/fill.ts +18 -10
- package/src/adapters/references/index.ts +7 -2
- package/src/build-engine.test.ts +11 -6
- package/src/build-engine.ts +10 -5
- package/src/build.harness.mjs +5 -7
- package/src/build.test.ts +10 -11
- package/src/build.ts +12 -13
- package/src/caller-path.ts +13 -0
- package/src/cli.harness.mjs +1 -3
- package/src/cli.test.ts +21 -16
- package/src/cli.ts +115 -33
- package/src/doctor.test.ts +1 -1
- package/src/doctor.ts +14 -5
- package/src/domain/paths.test.ts +15 -0
- package/src/domain/paths.ts +20 -1
- package/src/domain/ready.ts +31 -0
- package/src/domain/record.test.ts +20 -0
- package/src/domain/record.ts +12 -0
- package/src/domain/sha256.ts +5 -3
- package/src/domain/tex-document.test.ts +80 -0
- package/src/domain/tex-document.ts +110 -0
- package/src/engine.harness.mjs +1 -1
- package/src/engine.ts +30 -2
- package/src/facts-file.test.ts +4 -7
- package/src/facts-file.ts +45 -30
- package/src/hooks-settings.harness.ts +17 -0
- package/src/hooks-settings.ts +28 -4
- package/src/init.test.ts +25 -5
- package/src/init.ts +26 -12
- package/src/latex-loop.harness.ts +1 -1
- package/src/new-paper.harness.mjs +7 -23
- package/src/new-paper.test.ts +28 -3
- package/src/new-paper.ts +15 -3
- package/src/package-dirs.ts +17 -0
- package/src/paper-files.test.ts +22 -19
- package/src/paper-files.ts +16 -27
- package/src/paper-settings-commands.test.ts +6 -1
- package/src/paper-settings.test.ts +2 -2
- package/src/paper-settings.ts +5 -5
- package/src/pdf-facts.test.ts +16 -5
- package/src/pdf-facts.ts +79 -22
- package/src/pdf-geometry.ts +5 -3
- package/src/ports/latex.ts +29 -0
- package/src/ports/tool-installer.ts +2 -17
- package/src/presets.test.ts +65 -4
- package/src/presets.ts +65 -28
- package/src/references.test.ts +25 -19
- package/src/references.ts +4 -5
- package/src/rule-cases.test.ts +474 -0
- package/src/rule-docs.test.ts +159 -0
- package/src/rules-config.ts +40 -11
- package/src/tex-requirements.harness.ts +13 -23
- package/src/tex-requirements.test.ts +21 -0
- package/src/tex-requirements.ts +64 -14
- package/src/tex-venue-rules.test.ts +659 -0
- package/src/tex-venue-rules.ts +429 -0
- package/src/toolchain.harness.mjs +1 -1
- package/src/toolchain.test.ts +9 -5
- package/src/toolchain.ts +2 -2
- package/src/types.ts +5 -3
- package/src/venue-rules.test.ts +104 -8
- package/src/venue-rules.ts +22 -12
- package/templates/paper/paper.tex +2 -1
- package/skills/paper-pipeline/scripts/announce.mjs +0 -67
- package/skills/paper-pipeline/scripts/announce.test.mjs +0 -102
- package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +0 -51
- package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +0 -52
- package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +0 -6
- package/skills/paper-pipeline/scripts/fixtures/scorecard.ts +0 -100
- package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +0 -302
- package/skills/paper-pipeline/scripts/ledger.mjs +0 -623
- package/skills/paper-pipeline/scripts/ledger.test.mjs +0 -254
- package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +0 -474
- package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +0 -328
- package/skills/paper-pipeline/scripts/pipeline-check.mjs +0 -750
- package/skills/paper-pipeline/scripts/pipeline-edges.mjs +0 -169
- package/skills/paper-pipeline/scripts/pipeline-edges.test.mjs +0 -73
- package/skills/paper-pipeline/scripts/run-mechanical.mjs +0 -648
- package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +0 -468
- package/skills/paper-pipeline/scripts/status.mjs +0 -295
- package/skills/paper-pipeline/scripts/status.test.mjs +0 -232
- /package/{skills/submit-paper/references/venues โ presets/tex}/agenticdev.tex +0 -0
- /package/{skills/submit-paper/references/venues โ presets}/tex-base.jsonc +0 -0
|
@@ -4,7 +4,7 @@ description: Use when asking "what would the program committee decide?" / "simul
|
|
|
4
4
|
allowed-tools: [Read, Write, Grep, Glob, Bash, WebSearch, WebFetch, Agent, Skill]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
<!-- vigiles:sha256:
|
|
7
|
+
<!-- vigiles:sha256:b9feb099347291ff compiled from skills/pc-panel-review/SKILL.md.spec.ts -->
|
|
8
8
|
|
|
9
9
|
# pc-panel-review โ model the whole PC, not one reviewer
|
|
10
10
|
|
|
@@ -15,17 +15,6 @@ allowed-tools: [Read, Write, Grep, Glob, Bash, WebSearch, WebFetch, Agent, Skill
|
|
|
15
15
|
> single-lens spot-check (formerly the standalone `venue-review-sim` skill). Reach for Venue-fit mode or
|
|
16
16
|
> `paper-adversarial-review` for a fast spot-check; run the full panel (this) for the decision.
|
|
17
17
|
|
|
18
|
-
## Run me
|
|
19
|
-
|
|
20
|
-
๐ด FIRST, before any other step:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs pc-panel-review <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
18
|
The Venue-fit mode gives ONE reviewer's fit score; `paper-adversarial-review` gives ONE defect hunt.
|
|
30
19
|
A real decision is made by **2โ4 reviewers with different priorities + a meta-review** that weighs
|
|
31
20
|
consensus over any single voice. This skill runs that. The payoff over a single review: a **must-fix
|
|
@@ -61,8 +50,7 @@ prose-only read can.
|
|
|
61
50
|
(proven: ~88% accept on a paper the human reader found exhausting). These two artifacts are the
|
|
62
51
|
panel's only legitimate source for the readability/structure signal.
|
|
63
52
|
*(Scorecard: this gate is row **`panel`**, and it declares **`structure`** (tighten-paper) + **`writing`**
|
|
64
|
-
(grade-paper-writing) as its required inputs
|
|
65
|
-
either input is missing or newer than it.)*
|
|
53
|
+
(grade-paper-writing) as its required inputs.)*
|
|
66
54
|
3. **Pick 3 (or 4) reviewer lenses** that a real PC for THIS venue would field. Menu โ choose by fit:
|
|
67
55
|
- **Methods/stats skeptic** โ sample size, construct validity, multiple comparisons, overclaims,
|
|
68
56
|
whether the CIs support the claims.
|
|
@@ -145,38 +133,6 @@ the claim falsifiable: *TEXT* invites "then write it", and *IMMOVABLE* invites "
|
|
|
145
133
|
๐ด **A deadline is a constraint on how much you rework, never an argument for the current form.** If
|
|
146
134
|
the author invokes it against a TEXT prong, that is the failure this section exists to catch.
|
|
147
135
|
|
|
148
|
-
**Enforced** by `../paper-pipeline/scripts/pipeline-check.mjs` โ `ceiling-unplanned`: a ceiling recorded
|
|
149
|
-
in the scorecard whose prongs carry none of the three labels is a finding.
|
|
150
|
-
|
|
151
|
-
## Record the verdict
|
|
152
|
-
|
|
153
|
-
๐ด LAST step, once the deliverable exists:
|
|
154
|
-
|
|
155
|
-
```
|
|
156
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record pc-panel-review <paper-dir> FINDING <count> <report-path>
|
|
157
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record pc-panel-review <paper-dir> ABSTAINED <reason> "<one line>"
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
**FINDING** โ `<count>` is the number of **consensus** must-fixes (flagged by โฅ2 independent
|
|
161
|
-
reviewers, not the union of everything anyone said), `<report-path>` is the meta-review. Add
|
|
162
|
-
`--blocking` when the chair's decision is reject.
|
|
163
|
-
**ABSTAINED** โ `blocked`: the panel never ran because its required inputs (the persona stall
|
|
164
|
-
inventory, the structural verdict) do not exist. `no-witness`: the panel ran and reached no
|
|
165
|
-
consensus must-fix.
|
|
166
|
-
|
|
167
|
-
๐ด **THIS IS THE SKILL THE DELETION OF `PASS` WAS WRITTEN FOR.** Five model reviewers from one
|
|
168
|
-
vendor agreeing was being recorded as an acquittal โ and correlated agreement between instances of
|
|
169
|
-
one model is not independent evidence of anything. There is now no constructor that can say it.
|
|
170
|
-
"Accept with no must-fix" is `ABSTAINED no-witness`: the panel produced no finding, which is a fact
|
|
171
|
-
about the panel and not a fact about the paper.
|
|
172
|
-
|
|
173
|
-
๐ด **The `blocked` row is the one that matters most here.** A blocked panel and a panel nobody
|
|
174
|
-
launched read identically in prose, and on 2026-08-04 a status line said the panel was running when
|
|
175
|
-
it had never been launched at all. Record the block; do not leave the check silent.
|
|
176
|
-
|
|
177
|
-
Venue-fit mode records under the same skill name with the fit verdict and `<count>` 0 โ it is one
|
|
178
|
-
reviewer's spot-check, and its row should not be mistaken for the panel's decision.
|
|
179
|
-
|
|
180
136
|
## Rules
|
|
181
137
|
- **Independence is non-negotiable** โ never let reviewers see each other's reviews before the
|
|
182
138
|
meta-review; shared context collapses the panel into one voice.
|
|
@@ -31,17 +31,6 @@ export default experimental_skill({
|
|
|
31
31
|
> single-lens spot-check (formerly the standalone \`venue-review-sim\` skill). Reach for Venue-fit mode or
|
|
32
32
|
> \`paper-adversarial-review\` for a fast spot-check; run the full panel (this) for the decision.
|
|
33
33
|
|
|
34
|
-
## Run me
|
|
35
|
-
|
|
36
|
-
๐ด FIRST, before any other step:
|
|
37
|
-
|
|
38
|
-
\`\`\`
|
|
39
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs pc-panel-review <paper-dir>
|
|
40
|
-
\`\`\`
|
|
41
|
-
|
|
42
|
-
An advisory pass cannot be observed failing โ silence is both its error state and its normal
|
|
43
|
-
state โ so starting is an event, and events get written down.
|
|
44
|
-
|
|
45
34
|
The Venue-fit mode gives ONE reviewer's fit score; \`paper-adversarial-review\` gives ONE defect hunt.
|
|
46
35
|
A real decision is made by **2โ4 reviewers with different priorities + a meta-review** that weighs
|
|
47
36
|
consensus over any single voice. This skill runs that. The payoff over a single review: a **must-fix
|
|
@@ -77,8 +66,7 @@ prose-only read can.
|
|
|
77
66
|
(proven: ~88% accept on a paper the human reader found exhausting). These two artifacts are the
|
|
78
67
|
panel's only legitimate source for the readability/structure signal.
|
|
79
68
|
*(Scorecard: this gate is row **\`panel\`**, and it declares **\`structure\`** (tighten-paper) + **\`writing\`**
|
|
80
|
-
(grade-paper-writing) as its required inputs
|
|
81
|
-
either input is missing or newer than it.)*
|
|
69
|
+
(grade-paper-writing) as its required inputs.)*
|
|
82
70
|
3. **Pick 3 (or 4) reviewer lenses** that a real PC for THIS venue would field. Menu โ choose by fit:
|
|
83
71
|
- **Methods/stats skeptic** โ sample size, construct validity, multiple comparisons, overclaims,
|
|
84
72
|
whether the CIs support the claims.
|
|
@@ -161,38 +149,6 @@ the claim falsifiable: *TEXT* invites "then write it", and *IMMOVABLE* invites "
|
|
|
161
149
|
๐ด **A deadline is a constraint on how much you rework, never an argument for the current form.** If
|
|
162
150
|
the author invokes it against a TEXT prong, that is the failure this section exists to catch.
|
|
163
151
|
|
|
164
|
-
**Enforced** by \`../paper-pipeline/scripts/pipeline-check.mjs\` โ \`ceiling-unplanned\`: a ceiling recorded
|
|
165
|
-
in the scorecard whose prongs carry none of the three labels is a finding.
|
|
166
|
-
|
|
167
|
-
## Record the verdict
|
|
168
|
-
|
|
169
|
-
๐ด LAST step, once the deliverable exists:
|
|
170
|
-
|
|
171
|
-
\`\`\`
|
|
172
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record pc-panel-review <paper-dir> FINDING <count> <report-path>
|
|
173
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record pc-panel-review <paper-dir> ABSTAINED <reason> "<one line>"
|
|
174
|
-
\`\`\`
|
|
175
|
-
|
|
176
|
-
**FINDING** โ \`<count>\` is the number of **consensus** must-fixes (flagged by โฅ2 independent
|
|
177
|
-
reviewers, not the union of everything anyone said), \`<report-path>\` is the meta-review. Add
|
|
178
|
-
\`--blocking\` when the chair's decision is reject.
|
|
179
|
-
**ABSTAINED** โ \`blocked\`: the panel never ran because its required inputs (the persona stall
|
|
180
|
-
inventory, the structural verdict) do not exist. \`no-witness\`: the panel ran and reached no
|
|
181
|
-
consensus must-fix.
|
|
182
|
-
|
|
183
|
-
๐ด **THIS IS THE SKILL THE DELETION OF \`PASS\` WAS WRITTEN FOR.** Five model reviewers from one
|
|
184
|
-
vendor agreeing was being recorded as an acquittal โ and correlated agreement between instances of
|
|
185
|
-
one model is not independent evidence of anything. There is now no constructor that can say it.
|
|
186
|
-
"Accept with no must-fix" is \`ABSTAINED no-witness\`: the panel produced no finding, which is a fact
|
|
187
|
-
about the panel and not a fact about the paper.
|
|
188
|
-
|
|
189
|
-
๐ด **The \`blocked\` row is the one that matters most here.** A blocked panel and a panel nobody
|
|
190
|
-
launched read identically in prose, and on 2026-08-04 a status line said the panel was running when
|
|
191
|
-
it had never been launched at all. Record the block; do not leave the check silent.
|
|
192
|
-
|
|
193
|
-
Venue-fit mode records under the same skill name with the fit verdict and \`<count>\` 0 โ it is one
|
|
194
|
-
reviewer's spot-check, and its row should not be mistaken for the panel's decision.
|
|
195
|
-
|
|
196
152
|
## Rules
|
|
197
153
|
- **Independence is non-negotiable** โ never let reviewers see each other's reviews before the
|
|
198
154
|
meta-review; shared context collapses the panel into one voice.
|
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan-paper-timeline
|
|
3
3
|
description: Turn a venue's CFP dates into a scheduled, buffered plan on the Google Calendar โ build the timeline backwards from the AoE submission deadline (harden + panel-review + artifact + anonymized host all land BEFORE it), create calendar events in the author's own time zone for submit-day / deadline / camera-ready, and apply the FILING-SPACING rule so multiple papers don't cluster in the month before a planned external filing. Use right after find-venue hands you real deadlines and before you start drafting. Compose with find-venue (deadline source) and submit-paper.
|
|
4
|
-
allowed-tools: [Read, Write, Grep, Glob, mcp__Google_Calendar__list_events, mcp__Google_Calendar__search_events, mcp__Google_Calendar__create_event, mcp__Google_Calendar__update_event
|
|
4
|
+
allowed-tools: [Read, Write, Grep, Glob, mcp__Google_Calendar__list_events, mcp__Google_Calendar__search_events, mcp__Google_Calendar__create_event, mcp__Google_Calendar__update_event]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
<!-- vigiles:sha256:
|
|
7
|
+
<!-- vigiles:sha256:0f95e8225033cd72 compiled from skills/plan-paper-timeline/SKILL.md.spec.ts -->
|
|
8
8
|
|
|
9
9
|
# plan-paper-timeline โ CFP dates โ a buffered, filing-aware schedule
|
|
10
10
|
|
|
11
|
-
## Run me
|
|
12
|
-
|
|
13
|
-
๐ด FIRST, before any other step:
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs plan-paper-timeline <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
11
|
A deadline is not a plan. This skill converts the four dates every CFP gives you โ **submission (AoE),
|
|
23
12
|
notification, camera-ready, event** โ into calendar events with the buffers that actually keep a
|
|
24
13
|
submission from slipping, and sequences *multiple* papers so the cadence reads as sustained acclaim,
|
|
@@ -58,7 +47,6 @@ institutional email has no expedite route** โ no support queue jump, no "I'm o
|
|
|
58
47
|
That is why `access` is scheduled in the first week rather than the last: it is the one item where the
|
|
59
48
|
only remedy for being late is having started earlier.
|
|
60
49
|
|
|
61
|
-
`pipeline-check.mjs` reports an `access` row still `โ` inside the moderation window as a finding, and
|
|
62
50
|
`submit-paper` is hard-blocked on `access` being green.
|
|
63
51
|
|
|
64
52
|
## 1. Build the timeline backwards from the AoE deadline
|
|
@@ -142,28 +130,6 @@ When scheduling paper N against papers already on the calendar and a known/likel
|
|
|
142
130
|
second, stronger publication lands in a later month on purpose.
|
|
143
131
|
- Prefer a paper with an earlier, safely-past deadline over one that would pile onto the filing month.
|
|
144
132
|
|
|
145
|
-
## 5. Record the verdict
|
|
146
|
-
|
|
147
|
-
๐ด LAST step, once the deliverable exists:
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record plan-paper-timeline <paper-dir> FINDING <count> <report-path>
|
|
151
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record plan-paper-timeline <paper-dir> ABSTAINED <reason> "<one line>"
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**FINDING** โ `<count>` slots have no buffer, or collide with another paper's pre-filing window;
|
|
155
|
-
`<report-path>` is the plan. Add `--blocking` when the deadline cannot be met from here.
|
|
156
|
-
**ABSTAINED** โ `no-witness`: the backwards plan is on the calendar, `access` is green and no slot
|
|
157
|
-
is tight. `input-missing`: `find-venue` has produced no dated deadline to plan against.
|
|
158
|
-
|
|
159
|
-
This is the one skill whose blocking finding is a fact about the calendar rather than about the
|
|
160
|
-
paper: portal moderation runs up to two weeks and an author with no institutional email has no
|
|
161
|
-
expedite route, so one recorded today is still true tomorrow no matter how good the science gets.
|
|
162
|
-
|
|
163
|
-
๐ด **There is no PASS**, so "the plan is on the calendar" is not storable here. Put the event ids in
|
|
164
|
-
the `ABSTAINED` note โ markdown is the source of truth and the calendar is its projection, and a row
|
|
165
|
-
with neither is a claim about a calendar nobody opened.
|
|
166
|
-
|
|
167
133
|
## Scorecard rows this skill owns
|
|
168
134
|
Two, and they fail differently โ see `paper-pipeline/references/pipeline-status-template.md`:
|
|
169
135
|
- **`access`** โ *can you physically submit?* (ยง0). Account ยท profile ACTIVE since `<ISO>` ยท portal
|
|
@@ -19,23 +19,10 @@ export default experimental_skill({
|
|
|
19
19
|
"mcp__Google_Calendar__search_events",
|
|
20
20
|
"mcp__Google_Calendar__create_event",
|
|
21
21
|
"mcp__Google_Calendar__update_event",
|
|
22
|
-
"Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
|
|
23
|
-
"Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
|
|
24
22
|
],
|
|
25
23
|
body: `
|
|
26
24
|
# plan-paper-timeline โ CFP dates โ a buffered, filing-aware schedule
|
|
27
25
|
|
|
28
|
-
## Run me
|
|
29
|
-
|
|
30
|
-
๐ด FIRST, before any other step:
|
|
31
|
-
|
|
32
|
-
\`\`\`
|
|
33
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs plan-paper-timeline <paper-dir>
|
|
34
|
-
\`\`\`
|
|
35
|
-
|
|
36
|
-
An advisory pass cannot be observed failing โ silence is both its error state and its normal
|
|
37
|
-
state โ so starting is an event, and events get written down.
|
|
38
|
-
|
|
39
26
|
A deadline is not a plan. This skill converts the four dates every CFP gives you โ **submission (AoE),
|
|
40
27
|
notification, camera-ready, event** โ into calendar events with the buffers that actually keep a
|
|
41
28
|
submission from slipping, and sequences *multiple* papers so the cadence reads as sustained acclaim,
|
|
@@ -75,7 +62,6 @@ institutional email has no expedite route** โ no support queue jump, no "I'm o
|
|
|
75
62
|
That is why \`access\` is scheduled in the first week rather than the last: it is the one item where the
|
|
76
63
|
only remedy for being late is having started earlier.
|
|
77
64
|
|
|
78
|
-
\`pipeline-check.mjs\` reports an \`access\` row still \`โ\` inside the moderation window as a finding, and
|
|
79
65
|
\`submit-paper\` is hard-blocked on \`access\` being green.
|
|
80
66
|
|
|
81
67
|
## 1. Build the timeline backwards from the AoE deadline
|
|
@@ -159,28 +145,6 @@ When scheduling paper N against papers already on the calendar and a known/likel
|
|
|
159
145
|
second, stronger publication lands in a later month on purpose.
|
|
160
146
|
- Prefer a paper with an earlier, safely-past deadline over one that would pile onto the filing month.
|
|
161
147
|
|
|
162
|
-
## 5. Record the verdict
|
|
163
|
-
|
|
164
|
-
๐ด LAST step, once the deliverable exists:
|
|
165
|
-
|
|
166
|
-
\`\`\`
|
|
167
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record plan-paper-timeline <paper-dir> FINDING <count> <report-path>
|
|
168
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record plan-paper-timeline <paper-dir> ABSTAINED <reason> "<one line>"
|
|
169
|
-
\`\`\`
|
|
170
|
-
|
|
171
|
-
**FINDING** โ \`<count>\` slots have no buffer, or collide with another paper's pre-filing window;
|
|
172
|
-
\`<report-path>\` is the plan. Add \`--blocking\` when the deadline cannot be met from here.
|
|
173
|
-
**ABSTAINED** โ \`no-witness\`: the backwards plan is on the calendar, \`access\` is green and no slot
|
|
174
|
-
is tight. \`input-missing\`: \`find-venue\` has produced no dated deadline to plan against.
|
|
175
|
-
|
|
176
|
-
This is the one skill whose blocking finding is a fact about the calendar rather than about the
|
|
177
|
-
paper: portal moderation runs up to two weeks and an author with no institutional email has no
|
|
178
|
-
expedite route, so one recorded today is still true tomorrow no matter how good the science gets.
|
|
179
|
-
|
|
180
|
-
๐ด **There is no PASS**, so "the plan is on the calendar" is not storable here. Put the event ids in
|
|
181
|
-
the \`ABSTAINED\` note โ markdown is the source of truth and the calendar is its projection, and a row
|
|
182
|
-
with neither is a claim about a calendar nobody opened.
|
|
183
|
-
|
|
184
148
|
## Scorecard rows this skill owns
|
|
185
149
|
Two, and they fail differently โ see \`paper-pipeline/references/pipeline-status-template.md\`:
|
|
186
150
|
- **\`access\`** โ *can you physically submit?* (ยง0). Account ยท profile ACTIVE since \`<ISO>\` ยท portal
|
|
@@ -4,21 +4,10 @@ description: Compile a LaTeX paper (ACM/IEEE/arXiv) to PDF and render its pages
|
|
|
4
4
|
allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, SendUserFile]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
<!-- vigiles:sha256:
|
|
7
|
+
<!-- vigiles:sha256:5e2ee8850c098375 compiled from skills/render-paper/SKILL.md.spec.ts -->
|
|
8
8
|
|
|
9
9
|
# render-paper โ .tex โ PDF โ readable page PNGs
|
|
10
10
|
|
|
11
|
-
## Run me
|
|
12
|
-
|
|
13
|
-
๐ด FIRST, before any other step:
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs render-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
11
|
Turns a LaTeX source into (a) a compiled PDF and (b) per-page PNG images crisp enough to read
|
|
23
12
|
the font on a phone. Encodes the exact toolchain and the failures already debugged, so it works
|
|
24
13
|
first try.
|
|
@@ -45,7 +34,7 @@ That list was replaced on 2026-08-03; nothing about the toolchain below changed.
|
|
|
45
34
|
by `kpsewhich` against the files each profile names. The last line it prints is `bin: <dir>` โ
|
|
46
35
|
put that directory first on PATH before calling `pdflatex` or `check-render.sh` by hand.
|
|
47
36
|
|
|
48
|
-
๐ด The package list lives in the venue profiles (`
|
|
37
|
+
๐ด The package list lives in the venue profiles (`presets/*.jsonc` in the package, the
|
|
49
38
|
`tex` block; `tex-base.jsonc` for every paper) and nowhere else. A new venue that needs a new
|
|
50
39
|
package gets it there โ never in a script, never here. A TeX Live without `libertine` builds an
|
|
51
40
|
acmart paper GREEN in Computer Modern; that is why the files are checked, not the exit code.
|
|
@@ -130,30 +119,5 @@ python3 -c "import fitz; d=fitz.open('paper.pdf'); \
|
|
|
130
119
|
- Send the PNGs with `SendUserFile` (`display: render`) so the user can read on phone; caption what
|
|
131
120
|
changed since the last render. Send the PDF too (`display: attach`) if they want the file.
|
|
132
121
|
|
|
133
|
-
## Record the verdict
|
|
134
|
-
|
|
135
|
-
๐ด LAST step, once the deliverable exists:
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> FINDING <count> <report-path>
|
|
139
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> ABSTAINED <reason> "<one line>"
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
๐ด **There is no PASS**, not even here, where the temptation is strongest โ an exit code of 0 from
|
|
143
|
-
`check-render.sh` means the parser found no defect in the log, which is not the same as the page
|
|
144
|
-
being right, and the delivered-PDF check exists because that difference once put `7 x 10^13` on
|
|
145
|
-
page one.
|
|
146
|
-
|
|
147
|
-
**FINDING** โ `check-render.sh` exited non-zero; `<count>` is Overfull boxes plus undefined
|
|
148
|
-
refs/citations and `<report-path>` is the log. Always `--blocking`: every one of these is a fact
|
|
149
|
-
about the artifact, never a matter of taste.
|
|
150
|
-
**ABSTAINED** โ `no-witness`: it compiled and the log parser found nothing. `input-missing`: there
|
|
151
|
-
is no `.tex` to compile. `crashed`: no LaTeX toolchain on this machine, which must never be read
|
|
152
|
-
as a clean render.
|
|
153
|
-
|
|
154
|
-
It runs twenty times a day, so the ledger fills with rows, and that is fine: each row pins a page count
|
|
155
|
-
to a specific set of paper bytes, which is exactly what the `tighten-paper` structure gate is blocked
|
|
156
|
-
on and what a remembered page count keeps getting wrong.
|
|
157
|
-
|
|
158
122
|
## Compose with
|
|
159
123
|
- `paper-adversarial-review` / `pc-panel-review` (incl. its venue-fit mode) โ review the rendered draft.
|
|
@@ -14,17 +14,6 @@ export default experimental_skill({
|
|
|
14
14
|
body: `
|
|
15
15
|
# render-paper โ .tex โ PDF โ readable page PNGs
|
|
16
16
|
|
|
17
|
-
## Run me
|
|
18
|
-
|
|
19
|
-
๐ด FIRST, before any other step:
|
|
20
|
-
|
|
21
|
-
\`\`\`
|
|
22
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs render-paper <paper-dir>
|
|
23
|
-
\`\`\`
|
|
24
|
-
|
|
25
|
-
An advisory pass cannot be observed failing โ silence is both its error state and its normal
|
|
26
|
-
state โ so starting is an event, and events get written down.
|
|
27
|
-
|
|
28
17
|
Turns a LaTeX source into (a) a compiled PDF and (b) per-page PNG images crisp enough to read
|
|
29
18
|
the font on a phone. Encodes the exact toolchain and the failures already debugged, so it works
|
|
30
19
|
first try.
|
|
@@ -51,7 +40,7 @@ That list was replaced on 2026-08-03; nothing about the toolchain below changed.
|
|
|
51
40
|
by \`kpsewhich\` against the files each profile names. The last line it prints is \`bin: <dir>\` โ
|
|
52
41
|
put that directory first on PATH before calling \`pdflatex\` or \`check-render.sh\` by hand.
|
|
53
42
|
|
|
54
|
-
๐ด The package list lives in the venue profiles (\`
|
|
43
|
+
๐ด The package list lives in the venue profiles (\`presets/*.jsonc\` in the package, the
|
|
55
44
|
\`tex\` block; \`tex-base.jsonc\` for every paper) and nowhere else. A new venue that needs a new
|
|
56
45
|
package gets it there โ never in a script, never here. A TeX Live without \`libertine\` builds an
|
|
57
46
|
acmart paper GREEN in Computer Modern; that is why the files are checked, not the exit code.
|
|
@@ -136,31 +125,6 @@ python3 -c "import fitz; d=fitz.open('paper.pdf'); \\
|
|
|
136
125
|
- Send the PNGs with \`SendUserFile\` (\`display: render\`) so the user can read on phone; caption what
|
|
137
126
|
changed since the last render. Send the PDF too (\`display: attach\`) if they want the file.
|
|
138
127
|
|
|
139
|
-
## Record the verdict
|
|
140
|
-
|
|
141
|
-
๐ด LAST step, once the deliverable exists:
|
|
142
|
-
|
|
143
|
-
\`\`\`
|
|
144
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> FINDING <count> <report-path>
|
|
145
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> ABSTAINED <reason> "<one line>"
|
|
146
|
-
\`\`\`
|
|
147
|
-
|
|
148
|
-
๐ด **There is no PASS**, not even here, where the temptation is strongest โ an exit code of 0 from
|
|
149
|
-
\`check-render.sh\` means the parser found no defect in the log, which is not the same as the page
|
|
150
|
-
being right, and the delivered-PDF check exists because that difference once put \`7 x 10^13\` on
|
|
151
|
-
page one.
|
|
152
|
-
|
|
153
|
-
**FINDING** โ \`check-render.sh\` exited non-zero; \`<count>\` is Overfull boxes plus undefined
|
|
154
|
-
refs/citations and \`<report-path>\` is the log. Always \`--blocking\`: every one of these is a fact
|
|
155
|
-
about the artifact, never a matter of taste.
|
|
156
|
-
**ABSTAINED** โ \`no-witness\`: it compiled and the log parser found nothing. \`input-missing\`: there
|
|
157
|
-
is no \`.tex\` to compile. \`crashed\`: no LaTeX toolchain on this machine, which must never be read
|
|
158
|
-
as a clean render.
|
|
159
|
-
|
|
160
|
-
It runs twenty times a day, so the ledger fills with rows, and that is fine: each row pins a page count
|
|
161
|
-
to a specific set of paper bytes, which is exactly what the \`tighten-paper\` structure gate is blocked
|
|
162
|
-
on and what a remembered page count keeps getting wrong.
|
|
163
|
-
|
|
164
128
|
## Compose with
|
|
165
129
|
- \`paper-adversarial-review\` / \`pc-panel-review\` (incl. its venue-fit mode) โ review the rendered draft.`,
|
|
166
130
|
});
|
|
@@ -25,75 +25,28 @@ set -uo pipefail
|
|
|
25
25
|
# check โ that is, the defect the guard was set up for comes back together with a green report.
|
|
26
26
|
# A broken `import` in JS fails loudly; here we have to fail on our own.
|
|
27
27
|
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
# The order "the declared package โ a sibling inside the package โ the consumer's directory" is
|
|
31
|
-
# deliberate: the package must win silently. It only gets loud when there is NOT A SINGLE ONE.
|
|
32
|
-
# ๐ด THE SCRIPT'S OWN DIRECTORY โ TAKEN ABSOLUTE AND BEFORE ANY `cd` (12.09.2026, evening).
|
|
33
|
-
# Found by a RED HARNESS, `gates.harness.mjs`, not by proofreading, and it is my own regression from
|
|
34
|
-
# the same day: below, the script does `cd "$DIR"` into the paper directory, and the venues resolve
|
|
35
|
-
# stood AFTER that `cd`. So `git rev-parse --show-toplevel` was already running in the fixture's
|
|
36
|
-
# temporary directory, the root was not found, and the build honestly stopped โ on a test that had
|
|
37
|
-
# been passing until then.
|
|
28
|
+
# TWO candidates, in this order: the package by its NAME, from the current directory (a consumer's
|
|
29
|
+
# installed paperlint wins), then the package THIS script ships in. Loud only when neither holds it.
|
|
38
30
|
#
|
|
39
|
-
#
|
|
40
|
-
# the
|
|
41
|
-
# of an old one; still, a test that was green yesterday and is red today is mine to fix.
|
|
42
|
-
#
|
|
43
|
-
# The neighbouring `build.sh` already carries this same lesson in a comment ("The script directory is
|
|
44
|
-
# taken ONCE and ABSOLUTE, before cd") โ CI failed on it there on 30.08. A second instance of the same
|
|
45
|
-
# class in a file right next door.
|
|
31
|
+
# ๐ด THE SCRIPT'S OWN DIRECTORY IS TAKEN ABSOLUTE AND BEFORE ANY `cd`: below, the script `cd`s into
|
|
32
|
+
# the paper directory, and a lookup after that would start from the paper, not from here.
|
|
46
33
|
SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
47
34
|
|
|
48
35
|
resolve_venues() {
|
|
49
|
-
local
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
# depends neither on the current directory nor on whether the caller sits inside a git tree.
|
|
53
|
-
# โ ๏ธ THE PARENTHESES ARE MANDATORY, and the harness caught this a minute after I wrote the line
|
|
54
|
-
# without them. In bash `A || B && C` parses as `(A || B) && C`, so on a SUCCESSFUL `git rev-parse`
|
|
55
|
-
# the `pwd` ran as well, and the substitution returned TWO lines โ the repository root plus the
|
|
56
|
-
# current directory. By hand from a directory outside git this did not reproduce: there git failed,
|
|
57
|
-
# and only one branch ran.
|
|
58
|
-
# โ ๏ธ THE LAST RUNG SEARCHES, IT DOES NOT COUNT LEVELS. `cd "$SELF_DIR/../../.."` used to stand here
|
|
59
|
-
# โ correct for `.claude/skills/render-paper/` (three levels to the root) and silently wrong after
|
|
60
|
-
# the skill moved into the package, where it lies in `skills/render-paper/` (two): the climb
|
|
61
|
-
# overshot ABOVE the repository, and rung 2 looked for venues in someone else's directory. Climbing
|
|
62
|
-
# up to the directory that holds `.claude` does not depend on the depth.
|
|
63
|
-
local probe="$SELF_DIR" fallback=""
|
|
64
|
-
while [ "$probe" != "/" ]; do
|
|
65
|
-
if [ -d "$probe/.claude" ]; then fallback="$probe"; break; fi
|
|
66
|
-
probe=$(dirname "$probe")
|
|
67
|
-
done
|
|
68
|
-
root="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || printf '%s' "$fallback")}"
|
|
69
|
-
|
|
70
|
-
# 1) the package, if it already carries venues/ (after step 5)
|
|
71
|
-
pkg=$(node -e 'try{process.stdout.write(require.resolve("paperlint/venues/paper-guards.tex"))}catch{}' 2>/dev/null || true)
|
|
36
|
+
local pkg own
|
|
37
|
+
# 1) the package by its name. `node -e` resolves from the current directory.
|
|
38
|
+
pkg=$(node -e 'try{process.stdout.write(require.resolve("paperlint/presets/tex/paper-guards.tex"))}catch{}' 2>/dev/null || true)
|
|
72
39
|
if [ -n "$pkg" ] && [ -f "$pkg" ]; then
|
|
73
40
|
dirname "$pkg"
|
|
74
41
|
return 0
|
|
75
42
|
fi
|
|
76
43
|
|
|
77
|
-
# 2)
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# leaves the logical path)
|
|
84
|
-
# Rung 1 depends on cwd (`node -e` resolves from the current directory), rung 3 depends on the
|
|
85
|
-
# consumer's root having been found at all. This one depends on neither โ exactly the anchor whose
|
|
86
|
-
# absence had `gates.harness.mjs` red on 12.09.
|
|
87
|
-
local sibling="$SELF_DIR/../submit-paper/references/venues"
|
|
88
|
-
if [ -f "$sibling/paper-guards.tex" ]; then
|
|
89
|
-
(cd "$sibling" && pwd)
|
|
90
|
-
return 0
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# 3) the skill directory in the consumer โ for a consumer that mounted the skills differently
|
|
94
|
-
local local_dir="$root/.claude/skills/submit-paper/references/venues"
|
|
95
|
-
if [ -f "$local_dir/paper-guards.tex" ]; then
|
|
96
|
-
printf '%s\n' "$local_dir"
|
|
44
|
+
# 2) the package this script is part of: `skills/render-paper/` โ `presets/tex/`. `cd -P` follows
|
|
45
|
+
# the symlinks a consumer's `.claude/skills/render-paper` is made of, so `../..` is the PACKAGE's
|
|
46
|
+
# root, not the consumer's `.claude/`. Depends neither on the cwd nor on a git tree.
|
|
47
|
+
own="$(cd -P "$SELF_DIR" && pwd)/../../presets/tex"
|
|
48
|
+
if [ -f "$own/paper-guards.tex" ]; then
|
|
49
|
+
(cd "$own" && pwd)
|
|
97
50
|
return 0
|
|
98
51
|
fi
|
|
99
52
|
|
|
@@ -107,8 +60,8 @@ if [ "${1:-}" = "--print-venues" ]; then
|
|
|
107
60
|
printf '%s\n' "$VD"
|
|
108
61
|
exit 0
|
|
109
62
|
fi
|
|
110
|
-
echo "โ paper-guards.tex not found: not under the package name paperlint,
|
|
111
|
-
echo "
|
|
63
|
+
echo "โ paper-guards.tex not found: not under the package name paperlint (paperlint/presets/tex)," >&2
|
|
64
|
+
echo " not in the package this script ships in (../../presets/tex from it)." >&2
|
|
112
65
|
echo " Building the paper without it is not allowed: \\input{paper-guards} will not fail, it will vanish silently," >&2
|
|
113
66
|
echo " and the PDF will be built WITHOUT the check for dangling \\ref and \\cite." >&2
|
|
114
67
|
exit 2
|
|
@@ -135,7 +88,7 @@ if [ "${NO_COMPILE:-0}" != "1" ] && [ -f "$BASE.tex" ]; then
|
|
|
135
88
|
# Two passes: overfull boxes surface on every pass; a second pass settles refs
|
|
136
89
|
# so Reference/Citation-undefined warnings are accurate.
|
|
137
90
|
# ๐ด TEXINPUTS is mandatory, and that was found by a crash on 26.08. Papers pull in their venue's
|
|
138
|
-
# numbers via `\input{<venue>}`, and the file lies in
|
|
91
|
+
# numbers via `\input{<venue>}`, and the file lies in the package's `presets/tex/`.
|
|
139
92
|
# Without that path the build fails with `File \`agenticdev.tex' not found` โ and the `|| true`
|
|
140
93
|
# below swallows it, after which the script reads a log of UNKNOWN origin and reports on it. That
|
|
141
94
|
# is, compiling this paper here silently did not work, and it only became visible once a pass
|
|
@@ -68,34 +68,11 @@ await checkSkill("render-paper");
|
|
|
68
68
|
const run = (args, opts = {}) =>
|
|
69
69
|
spawnSync("bash", [CHECK, ...args], { encoding: "utf8", ...opts });
|
|
70
70
|
|
|
71
|
-
// First half โ on
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
// ๐ด THERE USED TO BE AN UNCONDITIONAL `assert.equal(status, 0)` HERE, AND THE MOVE BROKE IT โ
|
|
75
|
-
// for a real reason, not by accident. It relied on the SURROUNDING tree: while the skill lived
|
|
76
|
-
// at the consumer, the second rung of the ladder won
|
|
77
|
-
// (`.claude/skills/submit-paper/references/venues/`). The package checkout has neither that nor
|
|
78
|
-
// the first rung โ `venues/` arrives together with `submit-paper`, which hasn't moved yet. So
|
|
79
|
-
// the assertion wasn't checking resolution, it was checking for the presence of an unrelated
|
|
80
|
-
// directory nearby.
|
|
81
|
-
//
|
|
82
|
-
// The form now is: resolution must succeed IF AND ONLY IF at least one candidate exists on
|
|
83
|
-
// disk. This is still a real assertion โ it fails if a candidate exists and the script didn't
|
|
84
|
-
// find it โ but it stops requiring the existence of something this repository doesn't have yet.
|
|
85
|
-
// The absence of both candidates gets PRINTED, not swallowed: "the check found nothing to
|
|
86
|
-
// check" and "the check passed" have to look different.
|
|
71
|
+
// First half โ on this tree, resolution must succeed IF AND ONLY IF a candidate exists on disk:
|
|
72
|
+
// the package's own `presets/tex/`. The absence of it is PRINTED, not swallowed: "the check found
|
|
73
|
+
// nothing to check" and "the check passed" have to look different.
|
|
87
74
|
const candidates = [
|
|
88
|
-
|
|
89
|
-
join(HERE, "..", "..", "venues", "paper-guards.tex"),
|
|
90
|
-
// rung 2 โ the skill directory at the consumer
|
|
91
|
-
join(
|
|
92
|
-
HERE,
|
|
93
|
-
"..",
|
|
94
|
-
"submit-paper",
|
|
95
|
-
"references",
|
|
96
|
-
"venues",
|
|
97
|
-
"paper-guards.tex",
|
|
98
|
-
),
|
|
75
|
+
join(HERE, "..", "..", "presets", "tex", "paper-guards.tex"),
|
|
99
76
|
].filter((c) => existsSync(c));
|
|
100
77
|
|
|
101
78
|
const ok = run(["--print-venues"]);
|
|
@@ -108,9 +85,8 @@ await checkSkill("render-paper");
|
|
|
108
85
|
`silent success this whole block was written to catch.`,
|
|
109
86
|
);
|
|
110
87
|
console.log(
|
|
111
|
-
` --print-venues: NOT VERIFIED on the live tree โ paper-guards.tex is absent from
|
|
112
|
-
`
|
|
113
|
-
`\`submit-paper\`; until then only the fixtures below hold this half.`,
|
|
88
|
+
` --print-venues: NOT VERIFIED on the live tree โ paper-guards.tex is absent from the ` +
|
|
89
|
+
`package's presets/tex/; only the fixtures below hold this half.`,
|
|
114
90
|
);
|
|
115
91
|
} else {
|
|
116
92
|
assert.equal(
|
|
@@ -159,18 +135,9 @@ await checkSkill("render-paper");
|
|
|
159
135
|
// When the file is NOWHERE, the script must exit with code 2 and say why. A silent success here
|
|
160
136
|
// is exactly the defect the whole ladder was written for.
|
|
161
137
|
//
|
|
162
|
-
// ๐ด RUN AGAINST A COPY OF THE SCRIPT
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
// the root), and an empty directory found nothing at either. Now the script has a rung anchored
|
|
166
|
-
// to ITS OWN directory (`$SELF_DIR/../submit-paper/references/venues`) โ added for
|
|
167
|
-
// cwd-independence โ so as long as the script sits inside the package, venues next to it exist
|
|
168
|
-
// ALWAYS, and "nowhere" can no longer be reached through the environment. The only honest way to
|
|
169
|
-
// demonstrate that state is to move the script itself out of the package. The property being
|
|
170
|
-
// checked is otherwise identical, word for word: nothing resolved โ exit 2 + the name of the
|
|
171
|
-
// missing file. โ ๏ธ What this form no longer checks: that an empty consumer root won't make the
|
|
172
|
-
// script lie โ and it shouldn't, because such a root is now legitimately shadowed by the copy in
|
|
173
|
-
// the package.
|
|
138
|
+
// ๐ด RUN AGAINST A COPY OF THE SCRIPT. Inside the package its second rung (the package it ships
|
|
139
|
+
// in) always holds the file, so "nowhere" is reachable only by moving the script out of the
|
|
140
|
+
// package: nothing resolved โ exit 2 + the name of the missing file.
|
|
174
141
|
const empty = realpathSync(mkdtempSync(join(tmpdir(), "venues-none-")));
|
|
175
142
|
const lonely = join(empty, "check-render.sh");
|
|
176
143
|
copyFileSync(CHECK, lonely);
|
|
@@ -190,30 +157,21 @@ await checkSkill("render-paper");
|
|
|
190
157
|
"the failure message must name the missing file",
|
|
191
158
|
);
|
|
192
159
|
|
|
193
|
-
// Third half โ the ORDER of the rungs.
|
|
194
|
-
//
|
|
195
|
-
//
|
|
160
|
+
// Third half โ the ORDER of the rungs. The package the consumer installed, found by its name,
|
|
161
|
+
// must win over the copy this script ships in; otherwise a consumer silently builds with a stale
|
|
162
|
+
// copy. Plant a package by name beside the real script and see which one is chosen.
|
|
196
163
|
const both = realpathSync(mkdtempSync(join(tmpdir(), "venues-both-")));
|
|
197
|
-
const pkgVenues = join(both, "node_modules", "paperlint", "
|
|
198
|
-
|
|
199
|
-
both,
|
|
200
|
-
".claude",
|
|
201
|
-
"skills",
|
|
202
|
-
"submit-paper",
|
|
203
|
-
"references",
|
|
204
|
-
"venues",
|
|
205
|
-
);
|
|
206
|
-
for (const d of [pkgVenues, skillVenues]) mkdirSync(d, { recursive: true });
|
|
164
|
+
const pkgVenues = join(both, "node_modules", "paperlint", "presets", "tex");
|
|
165
|
+
mkdirSync(pkgVenues, { recursive: true });
|
|
207
166
|
writeFileSync(
|
|
208
167
|
join(both, "node_modules", "paperlint", "package.json"),
|
|
209
168
|
JSON.stringify({
|
|
210
169
|
name: "paperlint",
|
|
211
170
|
version: "0.0.0",
|
|
212
|
-
exports: { "
|
|
171
|
+
exports: { "./*": "./*" },
|
|
213
172
|
}),
|
|
214
173
|
);
|
|
215
174
|
writeFileSync(join(pkgVenues, "paper-guards.tex"), "% from package\n");
|
|
216
|
-
writeFileSync(join(skillVenues, "paper-guards.tex"), "% from skill dir\n");
|
|
217
175
|
const race = run(["--print-venues"], {
|
|
218
176
|
cwd: both,
|
|
219
177
|
env: { ...process.env, CLAUDE_PROJECT_DIR: both },
|
|
@@ -226,7 +184,7 @@ await checkSkill("render-paper");
|
|
|
226
184
|
assert.equal(
|
|
227
185
|
race.stdout.trim(),
|
|
228
186
|
pkgVenues,
|
|
229
|
-
"with both candidates present, the
|
|
187
|
+
"with both candidates present, the INSTALLED package wins, not the copy the script ships in",
|
|
230
188
|
);
|
|
231
189
|
}
|
|
232
190
|
|
|
@@ -276,7 +234,7 @@ await checkSkill("render-paper");
|
|
|
276
234
|
);
|
|
277
235
|
assert.match(
|
|
278
236
|
build,
|
|
279
|
-
/require\.resolve\("paperlint\/
|
|
237
|
+
/require\.resolve\("paperlint\/presets\/tex\/paper-guards\.tex"\)/,
|
|
280
238
|
`${where}: the ladder's first rung (the package) must remain`,
|
|
281
239
|
);
|
|
282
240
|
assert.match(
|