paperlint 3.1.3 → 4.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/workflows/ci.yml +12 -7
- package/CLAUDE.md +5 -5
- package/CONTRIBUTING.md +34 -5
- 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 +4 -3
- 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/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/files.io.d.ts.map +1 -1
- package/dist/adapters/node/files.io.js +2 -1
- package/dist/adapters/node/files.io.js.map +1 -1
- package/dist/adapters/node/process.io.d.ts +5 -7
- package/dist/adapters/node/process.io.d.ts.map +1 -1
- package/dist/adapters/node/process.io.js +4 -3
- 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 +13 -7
- 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 +8 -7
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/adapters/references/pool.d.ts.map +1 -1
- package/dist/adapters/references/pool.js +4 -5
- package/dist/adapters/references/pool.js.map +1 -1
- package/dist/adapters/references/reach.io.d.ts.map +1 -1
- package/dist/adapters/references/reach.io.js +2 -1
- package/dist/adapters/references/reach.io.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 +10 -3
- 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 +19 -17
- 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 +93 -46
- 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 +5 -3
- package/dist/doctor.js.map +1 -1
- package/dist/domain/lookup-cache.d.ts.map +1 -1
- package/dist/domain/lookup-cache.js +10 -8
- package/dist/domain/lookup-cache.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/text.d.ts +12 -0
- package/dist/domain/text.d.ts.map +1 -1
- package/dist/domain/text.js +17 -0
- package/dist/domain/text.js.map +1 -1
- package/dist/engine.d.ts +23 -22
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +4 -3
- package/dist/engine.js.map +1 -1
- package/dist/eslint-rules/bib-reachable-entry.d.ts +22 -0
- package/dist/eslint-rules/bib-reachable-entry.d.ts.map +1 -0
- package/dist/eslint-rules/bib-reachable-entry.js +75 -0
- package/dist/eslint-rules/bib-reachable-entry.js.map +1 -0
- package/dist/eslint-rules/install-path-literals.d.ts +80 -0
- package/dist/eslint-rules/install-path-literals.d.ts.map +1 -0
- package/dist/eslint-rules/install-path-literals.js +105 -0
- package/dist/eslint-rules/install-path-literals.js.map +1 -0
- package/dist/eslint-rules/latex-language.d.ts +136 -0
- package/dist/eslint-rules/latex-language.d.ts.map +1 -0
- package/dist/eslint-rules/latex-language.js +639 -0
- package/dist/eslint-rules/latex-language.js.map +1 -0
- package/dist/eslint-rules/paper-research-question.d.ts +31 -0
- package/dist/eslint-rules/paper-research-question.d.ts.map +1 -0
- package/dist/eslint-rules/paper-research-question.js +188 -0
- package/dist/eslint-rules/paper-research-question.js.map +1 -0
- package/dist/eslint-rules/paper-stages.d.ts +83 -0
- package/dist/eslint-rules/paper-stages.d.ts.map +1 -0
- package/dist/eslint-rules/paper-stages.js +358 -0
- package/dist/eslint-rules/paper-stages.js.map +1 -0
- package/dist/eslint-rules/paper-typography.d.ts +74 -0
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -0
- package/dist/eslint-rules/paper-typography.js +404 -0
- package/dist/eslint-rules/paper-typography.js.map +1 -0
- package/dist/eslint-rules/papers.d.ts +42 -0
- package/dist/eslint-rules/papers.d.ts.map +1 -0
- package/dist/eslint-rules/papers.js +145 -0
- package/dist/eslint-rules/papers.js.map +1 -0
- package/dist/eslint-rules/pdf-last-page-balance.d.ts +72 -0
- package/dist/eslint-rules/pdf-last-page-balance.d.ts.map +1 -0
- package/dist/eslint-rules/pdf-last-page-balance.js +237 -0
- package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -0
- package/dist/eslint-rules/review-frontmatter.d.ts +57 -0
- package/dist/eslint-rules/review-frontmatter.d.ts.map +1 -0
- package/dist/eslint-rules/review-frontmatter.js +126 -0
- package/dist/eslint-rules/review-frontmatter.js.map +1 -0
- package/dist/eslint-rules/review-frontmatter.schema.json +36 -0
- package/dist/eslint-rules/rule-context.d.ts +55 -0
- package/dist/eslint-rules/rule-context.d.ts.map +1 -0
- package/dist/eslint-rules/rule-context.js +9 -0
- package/dist/eslint-rules/rule-context.js.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.d.ts +25 -0
- package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.js +16 -0
- package/dist/eslint-rules/sibling-frontmatter.js.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.schema.json +14 -0
- package/dist/eslint-rules/temp-root-realpath.d.ts +71 -0
- package/dist/eslint-rules/temp-root-realpath.d.ts.map +1 -0
- package/dist/eslint-rules/temp-root-realpath.js +139 -0
- package/dist/eslint-rules/temp-root-realpath.js.map +1 -0
- package/dist/eslint-rules/tex-build.d.ts +35 -0
- package/dist/eslint-rules/tex-build.d.ts.map +1 -0
- package/dist/eslint-rules/tex-build.js +313 -0
- package/dist/eslint-rules/tex-build.js.map +1 -0
- package/dist/facts-file.d.ts.map +1 -1
- package/dist/facts-file.js +31 -27
- package/dist/facts-file.js.map +1 -1
- package/dist/hooks-settings.d.ts +1 -1
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +31 -11
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +8 -9
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +33 -15
- package/dist/init.js.map +1 -1
- package/dist/latex-loop.d.ts +2 -2
- package/dist/latex-loop.d.ts.map +1 -1
- package/dist/latex-loop.js +2 -2
- package/dist/latex-loop.js.map +1 -1
- package/dist/lib/agent-cli-version.d.ts +65 -0
- package/dist/lib/agent-cli-version.d.ts.map +1 -0
- package/dist/lib/agent-cli-version.js +77 -0
- package/dist/lib/agent-cli-version.js.map +1 -0
- package/dist/lib/check.d.ts +19 -0
- package/dist/lib/check.d.ts.map +1 -0
- package/dist/lib/check.js +52 -0
- package/dist/lib/check.js.map +1 -0
- package/dist/lib/markdown.d.ts +180 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +302 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/paper-config.d.ts +84 -0
- package/dist/lib/paper-config.d.ts.map +1 -0
- package/dist/lib/paper-config.js +138 -0
- package/dist/lib/paper-config.js.map +1 -0
- package/dist/lib/skill-eval-fixture.d.ts +29 -0
- package/dist/lib/skill-eval-fixture.d.ts.map +1 -0
- package/dist/lib/skill-eval-fixture.js +62 -0
- package/dist/lib/skill-eval-fixture.js.map +1 -0
- package/dist/link-skills.d.ts.map +1 -1
- package/dist/link-skills.js +5 -4
- package/dist/link-skills.js.map +1 -1
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +7 -3
- package/dist/new-paper.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/paper-settings.js +8 -7
- 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 +25 -16
- package/dist/pdf-facts.js.map +1 -1
- package/dist/pdf-geometry.d.ts.map +1 -1
- package/dist/pdf-geometry.js +3 -4
- package/dist/pdf-geometry.js.map +1 -1
- package/dist/ports/tool-installer.d.ts +2 -14
- package/dist/ports/tool-installer.d.ts.map +1 -1
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +19 -6
- package/dist/presets.js.map +1 -1
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +15 -10
- 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 +15 -12
- package/dist/rules-config.js.map +1 -1
- package/dist/structure.js +1 -1
- package/dist/structure.js.map +1 -1
- package/dist/tex-requirements.d.ts +4 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +22 -5
- package/dist/tex-requirements.js.map +1 -1
- package/dist/toolchain.d.ts.map +1 -1
- package/dist/toolchain.js +21 -16
- package/dist/toolchain.js.map +1 -1
- package/dist/types.d.ts +5 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts.map +1 -1
- package/dist/venue-rules.js +21 -8
- package/dist/venue-rules.js.map +1 -1
- package/docs/configuration.md +2 -2
- package/docs/e2e.md +7 -7
- 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 +2 -2
- package/docs/testing.md +11 -8
- package/docs/toolchain.md +1 -1
- package/eslint-rules/{bib-reachable-entry.mjs → bib-reachable-entry.ts} +5 -4
- package/eslint-rules/install-path-literals.harness.mjs +1 -1
- package/eslint-rules/{install-path-literals.mjs → install-path-literals.ts} +18 -10
- package/eslint-rules/latex-language.harness.mjs +2 -2
- package/eslint-rules/latex-language.test.mjs +7 -1
- package/eslint-rules/{latex-language.mjs → latex-language.ts} +297 -109
- package/eslint-rules/paper-research-question.harness.mjs +3 -3
- package/eslint-rules/{paper-research-question.mjs → paper-research-question.ts} +35 -16
- package/eslint-rules/paper-stages.harness.mjs +2 -2
- package/eslint-rules/paper-stages.test.mjs +8 -2
- package/eslint-rules/{paper-stages.mjs → paper-stages.ts} +76 -31
- package/eslint-rules/paper-typography.test.mjs +3 -3
- package/eslint-rules/{paper-typography.mjs → paper-typography.ts} +134 -56
- package/eslint-rules/papers.harness.mjs +2 -2
- package/eslint-rules/{papers.mjs → papers.ts} +7 -4
- package/eslint-rules/pdf-last-page-balance.harness.mjs +3 -3
- package/eslint-rules/{pdf-last-page-balance.mjs → pdf-last-page-balance.ts} +89 -32
- package/eslint-rules/review-frontmatter.test.mjs +2 -2
- package/eslint-rules/{review-frontmatter.mjs → review-frontmatter.ts} +38 -16
- package/eslint-rules/rule-context.ts +62 -0
- package/eslint-rules/{sibling-frontmatter.mjs → sibling-frontmatter.ts} +1 -1
- package/eslint-rules/temp-root-realpath.harness.mjs +1 -1
- package/eslint-rules/{temp-root-realpath.mjs → temp-root-realpath.ts} +20 -7
- package/eslint-rules/tex-build.harness.mjs +2 -2
- package/eslint-rules/{tex-build.mjs → tex-build.ts} +6 -5
- package/eslint.config.mjs +146 -30
- 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 +2 -2
- package/fixtures/real-markdown-paper/{baseline.mjs → baseline.ts} +31 -10
- package/hooks/{hooks.harness.mjs → hooks.harness.ts} +51 -34
- package/hooks/paper-edit-guard.hook.mjs +1 -1
- package/hooks/{paper-edit-guard.test.mjs → paper-edit-guard.test.ts} +3 -7
- package/hooks/paper-skills-nudge.hook.mjs +1 -1
- package/hooks/{paper-skills-nudge.test.mjs → paper-skills-nudge.test.ts} +2 -6
- package/hooks/paper-status-gates.sh +9 -19
- package/hooks/{paper-status-gates.test.mjs → paper-status-gates.test.ts} +2 -6
- package/lib/agent-cli-version.harness.mjs +1 -1
- package/lib/{agent-cli-version.mjs → agent-cli-version.ts} +32 -18
- package/lib/check.test.ts +14 -9
- package/lib/{check.mjs → check.ts} +22 -9
- package/lib/markdown.test.mjs +7 -7
- package/lib/{markdown.mjs → markdown.ts} +68 -29
- package/lib/paper-config.harness.mjs +9 -9
- package/lib/{paper-config.mjs → paper-config.ts} +20 -19
- package/lib/skill-checks.mjs +24 -381
- package/lib/skill-checks.test.mjs +64 -116
- package/lib/skill-corpus.mjs +10 -251
- package/lib/skill-corpus.test.mjs +2 -13
- package/lib/skill-eval-kit.mjs +1 -1
- package/lib/skill-trigger-cases.mjs +1 -1
- package/package.json +42 -10
- package/scripts/{check.harness.mjs → check.harness.ts} +111 -10
- package/scripts/{check.test.mjs → check.test.ts} +13 -10
- package/scripts/{check.mjs → check.ts} +116 -42
- package/scripts/coverage-config.test.ts +80 -38
- package/scripts/eslint-report-guard.test.mjs +1 -1
- package/scripts/harness-api.frozen.json +14 -16
- package/scripts/harness-api.test.ts +8 -5
- package/scripts/layer-legacy-frozen.test.ts +17 -13
- package/scripts/{layer-legacy-frozen.mjs → layer-legacy-frozen.ts} +128 -39
- package/scripts/release-config.test.ts +12 -4
- package/scripts/rules-see-files.test.mjs +1 -1
- package/scripts/test.test.ts +78 -0
- package/scripts/test.ts +87 -0
- 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 +3 -4
- package/skills/grade-paper-writing/{prose-lint.test.mjs → prose-lint.test.ts} +3 -3
- 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.mjs → 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/SKILL.md +2 -28
- package/skills/paper-pipeline/SKILL.md.spec.ts +1 -27
- package/skills/paper-pipeline/description-language.eval.mjs +1 -1
- package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +1 -1
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +2 -2
- package/skills/paper-pipeline/paper-pipeline.harness.mjs +25 -40
- package/skills/paper-pipeline/pipeline-firing.eval.mjs +1 -1
- package/skills/paper-pipeline/pipeline-language.eval.mjs +1 -1
- 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/artifact-coverage.mjs +1 -1
- package/skills/paper-pipeline/scripts/{artifact-coverage.test.mjs → artifact-coverage.test.ts} +2 -2
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +6 -104
- package/skills/paper-pipeline/scripts/consumer.mjs +24 -109
- package/skills/paper-pipeline/scripts/consumer.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +1 -1
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +1 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +2 -3
- package/skills/paper-pipeline/scripts/{generated-code.test.mjs → generated-code.test.ts} +3 -3
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +3 -3
- package/skills/paper-pipeline/scripts/population-map.mjs +1 -4
- package/skills/paper-pipeline/scripts/population-map.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/{round-diff.harness.mjs → round-diff.harness.ts} +45 -18
- package/skills/paper-pipeline/scripts/round-diff.mjs +1 -1
- package/skills/paper-pipeline/scripts/round-diff.test.mjs +1 -1
- 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/plan-paper-timeline/fixtures/{fake-google-calendar.mjs → fake-google-calendar.ts} +101 -70
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +3 -3
- package/skills/render-paper/SKILL.md +1 -37
- package/skills/render-paper/SKILL.md.spec.ts +0 -36
- package/skills/render-paper/{extract-pdf-facts.harness.mjs → extract-pdf-facts.harness.ts} +34 -9
- package/skills/render-paper/render-paper.harness.mjs +2 -2
- 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 +5 -12
- package/skills/tighten-paper/{structure.test.mjs → structure.test.ts} +4 -3
- package/skills/verify-citations/SKILL.md +2 -38
- package/skills/verify-citations/SKILL.md.spec.ts +1 -37
- package/skills/verify-citations/scripts/{bib-authors.cli.test.mjs → bib-authors.cli.test.ts} +14 -4
- package/skills/verify-citations/scripts/bib-authors.d.mts +63 -0
- package/skills/verify-citations/scripts/bib-authors.mjs +1 -4
- package/skills/verify-citations/scripts/{verify-cites.cli.test.mjs → verify-cites.cli.test.ts} +32 -9
- package/skills/verify-citations/scripts/verify-cites.d.mts +58 -0
- package/src/CLAUDE.md +1 -1
- package/src/adapters/banal/failure.ts +9 -10
- package/src/adapters/banal/index.test.ts +5 -8
- package/src/adapters/banal/index.ts +8 -7
- package/src/adapters/banal/install.ts +9 -4
- package/src/adapters/banal/invocation.test.ts +23 -9
- 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 +5 -5
- 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 +8 -6
- package/src/adapters/memory/index.ts +4 -3
- package/src/adapters/node/files.io.ts +2 -2
- package/src/adapters/node/files.test.ts +8 -4
- package/src/adapters/node/process.io.ts +13 -5
- package/src/adapters/node/process.test.ts +5 -5
- package/src/adapters/node/workspace.io.ts +9 -4
- package/src/adapters/node/workspace.test.ts +3 -1
- package/src/adapters/pdfjs/fill.test.ts +2 -2
- package/src/adapters/pdfjs/fill.ts +14 -7
- package/src/adapters/references/index.test.ts +31 -38
- package/src/adapters/references/index.ts +33 -60
- package/src/adapters/references/pool.ts +3 -5
- package/src/adapters/references/reach.io.ts +2 -1
- package/src/build-engine.harness.mjs +1 -1
- package/src/build-engine.test.ts +13 -8
- package/src/build-engine.ts +12 -7
- package/src/build.harness.mjs +2 -2
- package/src/build.test.ts +24 -24
- package/src/build.ts +34 -26
- package/src/caller-path.ts +13 -0
- package/src/cli.harness.mjs +6 -8
- package/src/cli.test.ts +31 -13
- package/src/cli.ts +117 -58
- package/src/doctor.harness.mjs +3 -3
- package/src/doctor.test.ts +1 -1
- package/src/doctor.ts +17 -7
- package/src/domain/lookup-cache.ts +21 -11
- 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/result.test.ts +2 -2
- package/src/domain/sha256.ts +5 -3
- package/src/domain/text.test.ts +32 -0
- package/src/domain/text.ts +23 -0
- package/src/engine.harness.mjs +2 -2
- package/src/engine.ts +34 -5
- package/src/facts-file.test.ts +9 -7
- package/src/facts-file.ts +45 -29
- package/src/{hooks-settings.harness.mjs → hooks-settings.harness.ts} +56 -20
- package/src/hooks-settings.ts +48 -13
- package/src/init.test.ts +37 -14
- package/src/init.ts +48 -24
- package/src/{latex-log.harness.mjs → latex-log.harness.ts} +14 -14
- package/src/{latex-loop.harness.mjs → latex-loop.harness.ts} +64 -36
- package/src/latex-loop.ts +3 -3
- package/src/{link-skills.harness.mjs → link-skills.harness.ts} +19 -19
- package/src/link-skills.test.ts +3 -3
- package/src/link-skills.ts +5 -4
- package/src/lint-fix.test.ts +4 -6
- package/src/linted-set.test.ts +2 -2
- package/src/new-paper.harness.mjs +9 -25
- package/src/new-paper.test.ts +8 -10
- package/src/new-paper.ts +9 -5
- package/src/paper-files.test.ts +25 -24
- package/src/paper-files.ts +16 -27
- package/src/paper-settings-commands.test.ts +5 -4
- package/src/paper-settings.test.ts +7 -7
- package/src/paper-settings.ts +13 -14
- package/src/{pdf-facts.harness.mjs → pdf-facts.harness.ts} +9 -8
- package/src/pdf-facts.test.ts +25 -15
- package/src/pdf-facts.ts +81 -23
- package/src/{pdf-geometry.harness.mjs → pdf-geometry.harness.ts} +19 -12
- package/src/pdf-geometry.ts +8 -4
- package/src/ports/tool-installer.ts +2 -17
- package/src/presets.ts +31 -16
- package/src/references.test.ts +76 -62
- package/src/references.ts +18 -12
- package/src/{rules-config.harness.mjs → rules-config.harness.ts} +7 -13
- package/src/rules-config.ts +46 -14
- package/src/rules-off.test.ts +6 -4
- package/src/{structure.harness.mjs → structure.harness.ts} +26 -15
- package/src/structure.ts +1 -1
- package/src/{tex-requirements.harness.mjs → tex-requirements.harness.ts} +50 -22
- package/src/tex-requirements.test.ts +21 -0
- package/src/tex-requirements.ts +37 -11
- package/src/toolchain.harness.mjs +2 -2
- package/src/toolchain.test.ts +10 -6
- package/src/toolchain.ts +31 -17
- package/src/types.ts +5 -3
- package/src/venue-rules.test.ts +70 -68
- package/src/venue-rules.ts +22 -12
- package/tsconfig.json +6 -3
- package/tsconfig.pkg.json +10 -0
- package/lib/check.d.mts +0 -17
- package/lib/paper-config.d.mts +0 -31
- package/scripts/layer-legacy-frozen.d.mts +0 -36
- package/scripts/rules-are-content-only.harness.mjs +0 -105
- package/scripts/rules-are-content-only.mjs +0 -148
- package/scripts/rules-are-content-only.test.mjs +0 -61
- package/scripts/test.mjs +0 -44
- package/scripts/test.test.mjs +0 -52
- 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.mjs +0 -71
- 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 -753
- 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/bin/{paperlint.test.mjs → paperlint.test.ts} +0 -0
- /package/lib/{skill-eval-fixture.mjs → skill-eval-fixture.ts} +0 -0
- /package/skills/grade-paper-writing/__snapshots__/{prose-lint.test.mjs.snap → prose-lint.test.ts.snap} +0 -0
- /package/skills/tighten-paper/__snapshots__/{structure.test.mjs.snap → structure.test.ts.snap} +0 -0
|
@@ -14,17 +14,6 @@ export default experimental_skill({
|
|
|
14
14
|
body: `
|
|
15
15
|
# paper-status — state, measured before it is narrated
|
|
16
16
|
|
|
17
|
-
## Run me
|
|
18
|
-
|
|
19
|
-
🔴 FIRST, before any other step:
|
|
20
|
-
|
|
21
|
-
\`\`\`
|
|
22
|
-
node .claude/skills/paper-pipeline/scripts/announce.mjs paper-status <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
|
The author asks "what's the status there?" constantly, and the answer keeps coming from the wrong place: my
|
|
29
18
|
memory of the session, which drifts, or a 200-line scorecard he cannot skim. Both fail the same way —
|
|
30
19
|
**they narrate state instead of measuring it.**
|
|
@@ -55,18 +44,13 @@ So on any turn that touched a paper, the reply ends with **three lines, unprompt
|
|
|
55
44
|
Three failures make this a rule rather than a preference, all in one session:
|
|
56
45
|
- I finished a page-fit cut and stopped, so he asked what the status was;
|
|
57
46
|
- I left artifact hosting on his side of the split for a day and a half while the credential to clear
|
|
58
|
-
it sat in the environment
|
|
47
|
+
it sat in the environment;
|
|
59
48
|
- three consecutive panels returned Weak Accept and the ceiling they named was never the next task,
|
|
60
49
|
because nothing turned "here is the score" into "here is what to do about it".
|
|
61
50
|
|
|
62
51
|
**Never end a paper turn on a completed sub-task alone.** "Fits in 8 pages" is a measurement, not a
|
|
63
52
|
status; the status is what that measurement makes possible next.
|
|
64
53
|
|
|
65
|
-
**Enforcement leg.** \`pipeline-check.mjs\` prints its banner **unconditionally**, including when it has
|
|
66
|
-
zero findings — deadline countdown, verdict row, and \`➡️ NEXT\`. It runs from \`paper-status-gates.sh\`
|
|
67
|
-
on every edit to a paper source, so the state arrives without anyone pulling it. If that banner and
|
|
68
|
-
this section ever disagree, the banner is a measurement and this is prose: believe the banner.
|
|
69
|
-
|
|
70
54
|
## How to run it
|
|
71
55
|
|
|
72
56
|
### 1. Measure (no reading yet)
|
|
@@ -96,8 +80,6 @@ gate's verdict **does not describe the current paper** — say so explicitly, an
|
|
|
96
80
|
An accept-probability from a superseded draft is not evidence about this one; carrying it forward is
|
|
97
81
|
the single most common way a status report lies.
|
|
98
82
|
|
|
99
|
-
If the project ships a checker (\`.claude/skills/paper-pipeline/scripts/pipeline-check.mjs\`), run it.
|
|
100
|
-
|
|
101
83
|
### 3. Read the judgement rows — from BOTH checklists, they answer different questions
|
|
102
84
|
|
|
103
85
|
The project already carries the checklists this skill should report against. Do not invent a new list
|
|
@@ -132,28 +114,6 @@ Short. He is asking because he wants to decide what to do next, not to read a re
|
|
|
132
114
|
5. **What moved since he last asked**, three lines maximum.
|
|
133
115
|
6. **The deadline, in his timezone**, and what is on the critical path to it.
|
|
134
116
|
|
|
135
|
-
## Record the verdict
|
|
136
|
-
|
|
137
|
-
🔴 LAST step, once the deliverable exists:
|
|
138
|
-
|
|
139
|
-
\`\`\`
|
|
140
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record paper-status <paper-dir> FINDING <count> <report-path>
|
|
141
|
-
node .claude/skills/paper-pipeline/scripts/ledger.mjs record paper-status <paper-dir> ABSTAINED <reason> "<one line>"
|
|
142
|
-
\`\`\`
|
|
143
|
-
|
|
144
|
-
This skill reports state and does not judge the paper, so what it records is about the **status run**:
|
|
145
|
-
**FINDING** — \`<count>\` blockers printed, \`<report-path>\` the status output.
|
|
146
|
-
**ABSTAINED** — \`no-witness\`: the status run measured everything it can and printed zero blockers.
|
|
147
|
-
\`crashed\`: the build did not run, so nothing was measured.
|
|
148
|
-
|
|
149
|
-
🔴 \`crashed\` is the one outcome that must never be narrated as a status. This skill exists because
|
|
150
|
-
state was being narrated instead of measured; a status report built on a build that did not happen
|
|
151
|
-
is that same failure with a fresh timestamp on it. Under the old vocabulary this was \`ERROR\`, which
|
|
152
|
-
sat in the same column as a verdict about the paper — it does not any more.
|
|
153
|
-
|
|
154
|
-
🔴 **There is no PASS**, so "zero blockers" cannot be stored. Print it, and let the reader draw the
|
|
155
|
-
conclusion from an empty blocker list they can see.
|
|
156
|
-
|
|
157
117
|
## Rules
|
|
158
118
|
|
|
159
119
|
- **Never report a gate as run because I intended to run it.** Predicting a background agent's result,
|
|
@@ -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
|
package/skills/plan-paper-timeline/fixtures/{fake-google-calendar.mjs → fake-google-calendar.ts}
RENAMED
|
@@ -34,6 +34,20 @@
|
|
|
34
34
|
* Calls are appended as JSONL to $FAKE_MCP_LOG.
|
|
35
35
|
*/
|
|
36
36
|
import { appendFileSync } from "node:fs";
|
|
37
|
+
/** One tool as the real server declares it: which arguments it requires and which it knows. */
|
|
38
|
+
interface ToolSpec {
|
|
39
|
+
readonly description: string;
|
|
40
|
+
readonly required: readonly string[];
|
|
41
|
+
readonly known: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A JSON object. The narrowing is written out rather than done with zod on purpose: zod's import
|
|
46
|
+
* costs ~45 ms at startup, and the effects harness calls a tool as soon as the session opens — with
|
|
47
|
+
* zod loaded the server was measured still connecting on every run, without it ready on every run.
|
|
48
|
+
*/
|
|
49
|
+
type Msg = Readonly<Record<string, unknown>>;
|
|
50
|
+
const isObject = (v: unknown): v is Msg => typeof v === "object" && v !== null;
|
|
37
51
|
|
|
38
52
|
const LOG = process.env.FAKE_MCP_LOG;
|
|
39
53
|
if (!LOG) {
|
|
@@ -44,12 +58,14 @@ if (!LOG) {
|
|
|
44
58
|
);
|
|
45
59
|
process.exit(1);
|
|
46
60
|
}
|
|
61
|
+
/** The log, known to be set from here on. */
|
|
62
|
+
const LOG_FILE: string = LOG;
|
|
47
63
|
|
|
48
64
|
/**
|
|
49
65
|
* Transcribed from the live tool definitions, 2026-08-17. `required` is the field
|
|
50
66
|
* that carries the weight — everything else is here so an unknown key is detectable.
|
|
51
67
|
*/
|
|
52
|
-
const TOOLS = {
|
|
68
|
+
const TOOLS: Readonly<Record<string, ToolSpec>> = {
|
|
53
69
|
create_event: {
|
|
54
70
|
description: "Creates an event on the given calendar.",
|
|
55
71
|
required: ["summary", "startTime", "endTime"],
|
|
@@ -138,7 +154,7 @@ const TOOLS = {
|
|
|
138
154
|
},
|
|
139
155
|
};
|
|
140
156
|
|
|
141
|
-
const schemaOf = (spec) => ({
|
|
157
|
+
const schemaOf = (spec: ToolSpec) => ({
|
|
142
158
|
type: "object",
|
|
143
159
|
properties: Object.fromEntries(spec.known.map((k) => [k, {}])),
|
|
144
160
|
required: spec.required,
|
|
@@ -147,9 +163,12 @@ const schemaOf = (spec) => ({
|
|
|
147
163
|
let created = 0;
|
|
148
164
|
|
|
149
165
|
/** @returns {string|null} the reason this call would be rejected, or null if it is well-formed. */
|
|
150
|
-
function reject(
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
function reject(
|
|
167
|
+
name: unknown,
|
|
168
|
+
args: Readonly<Record<string, unknown>> | null | undefined,
|
|
169
|
+
): string | null {
|
|
170
|
+
const spec = TOOLS[String(name)];
|
|
171
|
+
if (!spec) return `no such tool: ${String(name)}`;
|
|
153
172
|
const a = args ?? {};
|
|
154
173
|
const missing = spec.required.filter(
|
|
155
174
|
(k) => a[k] === undefined || a[k] === "",
|
|
@@ -158,82 +177,94 @@ function reject(name, args) {
|
|
|
158
177
|
return `missing required argument(s): ${missing.join(", ")} — the real Google Calendar API rejects this call`;
|
|
159
178
|
const unknown = Object.keys(a).filter((k) => !spec.known.includes(k));
|
|
160
179
|
if (unknown.length)
|
|
161
|
-
return `unknown argument(s): ${unknown.join(", ")} — not fields of ${name} on the real server`;
|
|
180
|
+
return `unknown argument(s): ${unknown.join(", ")} — not fields of ${String(name)} on the real server`;
|
|
162
181
|
return null;
|
|
163
182
|
}
|
|
164
183
|
|
|
184
|
+
/** A `tools/call`: logged whatever its fate, then answered with an error or a fake event id. */
|
|
185
|
+
function call(msg: Msg): Record<string, unknown> {
|
|
186
|
+
const params = isObject(msg.params) ? msg.params : undefined;
|
|
187
|
+
const name = params?.name;
|
|
188
|
+
const args = isObject(params?.arguments) ? params.arguments : {};
|
|
189
|
+
const why = reject(name, args);
|
|
190
|
+
// Every call is logged, accepted or not. A rejected call that left no trace
|
|
191
|
+
// would be indistinguishable from a call that never happened.
|
|
192
|
+
appendFileSync(
|
|
193
|
+
LOG_FILE,
|
|
194
|
+
JSON.stringify({ name, args, ok: why === null, why }) + "\n",
|
|
195
|
+
);
|
|
196
|
+
if (why)
|
|
197
|
+
return {
|
|
198
|
+
result: {
|
|
199
|
+
isError: true,
|
|
200
|
+
content: [{ type: "text", text: `INVALID CALL: ${why}` }],
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
created += 1;
|
|
204
|
+
return {
|
|
205
|
+
result: {
|
|
206
|
+
content: [
|
|
207
|
+
{
|
|
208
|
+
type: "text",
|
|
209
|
+
text: JSON.stringify({
|
|
210
|
+
id: `evt_fake_${String(created)}`,
|
|
211
|
+
status: "confirmed",
|
|
212
|
+
}),
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** The reply to one message, or `null` for a notification (no id) this server does not handle. */
|
|
220
|
+
function answer(msg: Msg): Record<string, unknown> | null {
|
|
221
|
+
if (msg.method === "initialize")
|
|
222
|
+
return {
|
|
223
|
+
result: {
|
|
224
|
+
protocolVersion: "2024-11-05",
|
|
225
|
+
capabilities: { tools: {} },
|
|
226
|
+
serverInfo: { name: "fake-google-calendar", version: "1.0.0" },
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
if (msg.method === "tools/list")
|
|
230
|
+
return {
|
|
231
|
+
result: {
|
|
232
|
+
tools: Object.entries(TOOLS).map(([name, spec]) => ({
|
|
233
|
+
name,
|
|
234
|
+
description: spec.description,
|
|
235
|
+
inputSchema: schemaOf(spec),
|
|
236
|
+
})),
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
if (msg.method === "tools/call") return call(msg);
|
|
240
|
+
return msg.id !== undefined ? { result: {} } : null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** One line of input, parsed; `null` for a line that is not a JSON-RPC message. */
|
|
244
|
+
function parseLine(line: string): Msg | null {
|
|
245
|
+
let json: unknown;
|
|
246
|
+
try {
|
|
247
|
+
json = JSON.parse(line);
|
|
248
|
+
} catch {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
return isObject(json) ? json : null;
|
|
252
|
+
}
|
|
253
|
+
|
|
165
254
|
let buf = "";
|
|
166
|
-
process.stdin.on("data", (chunk) => {
|
|
167
|
-
buf += chunk;
|
|
255
|
+
process.stdin.on("data", (chunk: Buffer | string) => {
|
|
256
|
+
buf += String(chunk);
|
|
168
257
|
let nl;
|
|
169
258
|
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
170
259
|
const line = buf.slice(0, nl).trim();
|
|
171
260
|
buf = buf.slice(nl + 1);
|
|
172
261
|
if (!line) continue;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
const send = (payload) =>
|
|
262
|
+
const msg = parseLine(line);
|
|
263
|
+
if (msg === null) continue;
|
|
264
|
+
const payload = answer(msg);
|
|
265
|
+
if (payload)
|
|
180
266
|
process.stdout.write(
|
|
181
267
|
JSON.stringify({ jsonrpc: "2.0", id: msg.id, ...payload }) + "\n",
|
|
182
268
|
);
|
|
183
|
-
|
|
184
|
-
if (msg.method === "initialize") {
|
|
185
|
-
send({
|
|
186
|
-
result: {
|
|
187
|
-
protocolVersion: "2024-11-05",
|
|
188
|
-
capabilities: { tools: {} },
|
|
189
|
-
serverInfo: { name: "fake-google-calendar", version: "1.0.0" },
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
} else if (msg.method === "tools/list") {
|
|
193
|
-
send({
|
|
194
|
-
result: {
|
|
195
|
-
tools: Object.entries(TOOLS).map(([name, spec]) => ({
|
|
196
|
-
name,
|
|
197
|
-
description: spec.description,
|
|
198
|
-
inputSchema: schemaOf(spec),
|
|
199
|
-
})),
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
} else if (msg.method === "tools/call") {
|
|
203
|
-
const name = msg.params?.name;
|
|
204
|
-
const args = msg.params?.arguments ?? {};
|
|
205
|
-
const why = reject(name, args);
|
|
206
|
-
// Every call is logged, accepted or not. A rejected call that left no trace
|
|
207
|
-
// would be indistinguishable from a call that never happened.
|
|
208
|
-
appendFileSync(
|
|
209
|
-
LOG,
|
|
210
|
-
JSON.stringify({ name, args, ok: why === null, why }) + "\n",
|
|
211
|
-
);
|
|
212
|
-
if (why) {
|
|
213
|
-
send({
|
|
214
|
-
result: {
|
|
215
|
-
isError: true,
|
|
216
|
-
content: [{ type: "text", text: `INVALID CALL: ${why}` }],
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
} else {
|
|
220
|
-
created += 1;
|
|
221
|
-
send({
|
|
222
|
-
result: {
|
|
223
|
-
content: [
|
|
224
|
-
{
|
|
225
|
-
type: "text",
|
|
226
|
-
text: JSON.stringify({
|
|
227
|
-
id: `evt_fake_${String(created)}`,
|
|
228
|
-
status: "confirmed",
|
|
229
|
-
}),
|
|
230
|
-
},
|
|
231
|
-
],
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
} else if (msg.id !== undefined) {
|
|
236
|
-
send({ result: {} });
|
|
237
|
-
}
|
|
238
269
|
}
|
|
239
270
|
});
|
|
@@ -60,7 +60,7 @@ import { tmpdir } from "node:os";
|
|
|
60
60
|
import { dirname, join, resolve } from "node:path";
|
|
61
61
|
import { fileURLToPath } from "node:url";
|
|
62
62
|
import { runHarnessTest, skip } from "vigiles";
|
|
63
|
-
import { observeAgentCli } from "
|
|
63
|
+
import { observeAgentCli } from "#lib/agent-cli-version";
|
|
64
64
|
import { DEFAULT_TIMEZONE } from "../paper-pipeline/scripts/consumer.mjs";
|
|
65
65
|
|
|
66
66
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
@@ -225,7 +225,7 @@ try {
|
|
|
225
225
|
// Run A above pins that the calendar surface is absent from a headless session, which
|
|
226
226
|
// is true and worth knowing and also means the skill's CENTRAL STEP has never been
|
|
227
227
|
// checked by anything. Run B supplies the surface with a stand-in
|
|
228
|
-
// (`fixtures/fake-google-calendar.
|
|
228
|
+
// (`fixtures/fake-google-calendar.ts`) carrying the REAL API's required-field sets,
|
|
229
229
|
// so the step becomes executable for the first time.
|
|
230
230
|
//
|
|
231
231
|
// ── WHAT IS UNDER TEST, AND WHY IT IS NOT THE MODEL ─────────────────────────────
|
|
@@ -312,7 +312,7 @@ try {
|
|
|
312
312
|
mcpServers: {
|
|
313
313
|
Google_Calendar: {
|
|
314
314
|
command: process.execPath,
|
|
315
|
-
args: [join(HERE, "fixtures", "fake-google-calendar.
|
|
315
|
+
args: [join(HERE, "fixtures", "fake-google-calendar.ts")],
|
|
316
316
|
env: { FAKE_MCP_LOG: callLog },
|
|
317
317
|
},
|
|
318
318
|
},
|
|
@@ -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:a1ec1d392f144c80 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.
|
|
@@ -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.
|