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.
Files changed (527) hide show
  1. package/.github/workflows/ci.yml +12 -7
  2. package/CLAUDE.md +5 -5
  3. package/CONTRIBUTING.md +34 -5
  4. package/dist/adapters/banal/failure.d.ts +1 -7
  5. package/dist/adapters/banal/failure.d.ts.map +1 -1
  6. package/dist/adapters/banal/failure.js +5 -7
  7. package/dist/adapters/banal/failure.js.map +1 -1
  8. package/dist/adapters/banal/index.d.ts.map +1 -1
  9. package/dist/adapters/banal/index.js +4 -3
  10. package/dist/adapters/banal/index.js.map +1 -1
  11. package/dist/adapters/banal/install.d.ts.map +1 -1
  12. package/dist/adapters/banal/install.js +4 -3
  13. package/dist/adapters/banal/install.js.map +1 -1
  14. package/dist/adapters/banal/invocation.d.ts +10 -5
  15. package/dist/adapters/banal/invocation.d.ts.map +1 -1
  16. package/dist/adapters/banal/invocation.js +13 -1
  17. package/dist/adapters/banal/invocation.js.map +1 -1
  18. package/dist/adapters/banal/locate.d.ts +12 -9
  19. package/dist/adapters/banal/locate.d.ts.map +1 -1
  20. package/dist/adapters/banal/locate.js +19 -12
  21. package/dist/adapters/banal/locate.js.map +1 -1
  22. package/dist/adapters/banal/run.d.ts +10 -1
  23. package/dist/adapters/banal/run.d.ts.map +1 -1
  24. package/dist/adapters/banal/run.js +8 -4
  25. package/dist/adapters/banal/run.js.map +1 -1
  26. package/dist/adapters/banal/settings.d.ts +1 -1
  27. package/dist/adapters/banal/settings.d.ts.map +1 -1
  28. package/dist/adapters/banal/settings.js +2 -1
  29. package/dist/adapters/banal/settings.js.map +1 -1
  30. package/dist/adapters/memory/index.d.ts.map +1 -1
  31. package/dist/adapters/memory/index.js +8 -2
  32. package/dist/adapters/memory/index.js.map +1 -1
  33. package/dist/adapters/node/files.io.d.ts.map +1 -1
  34. package/dist/adapters/node/files.io.js +2 -1
  35. package/dist/adapters/node/files.io.js.map +1 -1
  36. package/dist/adapters/node/process.io.d.ts +5 -7
  37. package/dist/adapters/node/process.io.d.ts.map +1 -1
  38. package/dist/adapters/node/process.io.js +4 -3
  39. package/dist/adapters/node/process.io.js.map +1 -1
  40. package/dist/adapters/node/workspace.io.d.ts.map +1 -1
  41. package/dist/adapters/node/workspace.io.js +4 -2
  42. package/dist/adapters/node/workspace.io.js.map +1 -1
  43. package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
  44. package/dist/adapters/pdfjs/fill.js +13 -7
  45. package/dist/adapters/pdfjs/fill.js.map +1 -1
  46. package/dist/adapters/references/index.d.ts.map +1 -1
  47. package/dist/adapters/references/index.js +8 -7
  48. package/dist/adapters/references/index.js.map +1 -1
  49. package/dist/adapters/references/pool.d.ts.map +1 -1
  50. package/dist/adapters/references/pool.js +4 -5
  51. package/dist/adapters/references/pool.js.map +1 -1
  52. package/dist/adapters/references/reach.io.d.ts.map +1 -1
  53. package/dist/adapters/references/reach.io.js +2 -1
  54. package/dist/adapters/references/reach.io.js.map +1 -1
  55. package/dist/build-engine.d.ts +1 -1
  56. package/dist/build-engine.d.ts.map +1 -1
  57. package/dist/build-engine.js +10 -3
  58. package/dist/build-engine.js.map +1 -1
  59. package/dist/build.d.ts +2 -3
  60. package/dist/build.d.ts.map +1 -1
  61. package/dist/build.js +19 -17
  62. package/dist/build.js.map +1 -1
  63. package/dist/caller-path.d.ts +3 -0
  64. package/dist/caller-path.d.ts.map +1 -0
  65. package/dist/caller-path.js +13 -0
  66. package/dist/caller-path.js.map +1 -0
  67. package/dist/cli.d.ts +10 -17
  68. package/dist/cli.d.ts.map +1 -1
  69. package/dist/cli.js +93 -46
  70. package/dist/cli.js.map +1 -1
  71. package/dist/doctor.d.ts +12 -3
  72. package/dist/doctor.d.ts.map +1 -1
  73. package/dist/doctor.js +5 -3
  74. package/dist/doctor.js.map +1 -1
  75. package/dist/domain/lookup-cache.d.ts.map +1 -1
  76. package/dist/domain/lookup-cache.js +10 -8
  77. package/dist/domain/lookup-cache.js.map +1 -1
  78. package/dist/domain/paths.d.ts +8 -2
  79. package/dist/domain/paths.d.ts.map +1 -1
  80. package/dist/domain/paths.js +12 -1
  81. package/dist/domain/paths.js.map +1 -1
  82. package/dist/domain/ready.d.ts +24 -0
  83. package/dist/domain/ready.d.ts.map +1 -0
  84. package/dist/domain/ready.js +11 -0
  85. package/dist/domain/ready.js.map +1 -0
  86. package/dist/domain/record.d.ts +8 -0
  87. package/dist/domain/record.d.ts.map +1 -0
  88. package/dist/domain/record.js +8 -0
  89. package/dist/domain/record.js.map +1 -0
  90. package/dist/domain/sha256.d.ts.map +1 -1
  91. package/dist/domain/sha256.js +4 -2
  92. package/dist/domain/sha256.js.map +1 -1
  93. package/dist/domain/text.d.ts +12 -0
  94. package/dist/domain/text.d.ts.map +1 -1
  95. package/dist/domain/text.js +17 -0
  96. package/dist/domain/text.js.map +1 -1
  97. package/dist/engine.d.ts +23 -22
  98. package/dist/engine.d.ts.map +1 -1
  99. package/dist/engine.js +4 -3
  100. package/dist/engine.js.map +1 -1
  101. package/dist/eslint-rules/bib-reachable-entry.d.ts +22 -0
  102. package/dist/eslint-rules/bib-reachable-entry.d.ts.map +1 -0
  103. package/dist/eslint-rules/bib-reachable-entry.js +75 -0
  104. package/dist/eslint-rules/bib-reachable-entry.js.map +1 -0
  105. package/dist/eslint-rules/install-path-literals.d.ts +80 -0
  106. package/dist/eslint-rules/install-path-literals.d.ts.map +1 -0
  107. package/dist/eslint-rules/install-path-literals.js +105 -0
  108. package/dist/eslint-rules/install-path-literals.js.map +1 -0
  109. package/dist/eslint-rules/latex-language.d.ts +136 -0
  110. package/dist/eslint-rules/latex-language.d.ts.map +1 -0
  111. package/dist/eslint-rules/latex-language.js +639 -0
  112. package/dist/eslint-rules/latex-language.js.map +1 -0
  113. package/dist/eslint-rules/paper-research-question.d.ts +31 -0
  114. package/dist/eslint-rules/paper-research-question.d.ts.map +1 -0
  115. package/dist/eslint-rules/paper-research-question.js +188 -0
  116. package/dist/eslint-rules/paper-research-question.js.map +1 -0
  117. package/dist/eslint-rules/paper-stages.d.ts +83 -0
  118. package/dist/eslint-rules/paper-stages.d.ts.map +1 -0
  119. package/dist/eslint-rules/paper-stages.js +358 -0
  120. package/dist/eslint-rules/paper-stages.js.map +1 -0
  121. package/dist/eslint-rules/paper-typography.d.ts +74 -0
  122. package/dist/eslint-rules/paper-typography.d.ts.map +1 -0
  123. package/dist/eslint-rules/paper-typography.js +404 -0
  124. package/dist/eslint-rules/paper-typography.js.map +1 -0
  125. package/dist/eslint-rules/papers.d.ts +42 -0
  126. package/dist/eslint-rules/papers.d.ts.map +1 -0
  127. package/dist/eslint-rules/papers.js +145 -0
  128. package/dist/eslint-rules/papers.js.map +1 -0
  129. package/dist/eslint-rules/pdf-last-page-balance.d.ts +72 -0
  130. package/dist/eslint-rules/pdf-last-page-balance.d.ts.map +1 -0
  131. package/dist/eslint-rules/pdf-last-page-balance.js +237 -0
  132. package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -0
  133. package/dist/eslint-rules/review-frontmatter.d.ts +57 -0
  134. package/dist/eslint-rules/review-frontmatter.d.ts.map +1 -0
  135. package/dist/eslint-rules/review-frontmatter.js +126 -0
  136. package/dist/eslint-rules/review-frontmatter.js.map +1 -0
  137. package/dist/eslint-rules/review-frontmatter.schema.json +36 -0
  138. package/dist/eslint-rules/rule-context.d.ts +55 -0
  139. package/dist/eslint-rules/rule-context.d.ts.map +1 -0
  140. package/dist/eslint-rules/rule-context.js +9 -0
  141. package/dist/eslint-rules/rule-context.js.map +1 -0
  142. package/dist/eslint-rules/sibling-frontmatter.d.ts +25 -0
  143. package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -0
  144. package/dist/eslint-rules/sibling-frontmatter.js +16 -0
  145. package/dist/eslint-rules/sibling-frontmatter.js.map +1 -0
  146. package/dist/eslint-rules/sibling-frontmatter.schema.json +14 -0
  147. package/dist/eslint-rules/temp-root-realpath.d.ts +71 -0
  148. package/dist/eslint-rules/temp-root-realpath.d.ts.map +1 -0
  149. package/dist/eslint-rules/temp-root-realpath.js +139 -0
  150. package/dist/eslint-rules/temp-root-realpath.js.map +1 -0
  151. package/dist/eslint-rules/tex-build.d.ts +35 -0
  152. package/dist/eslint-rules/tex-build.d.ts.map +1 -0
  153. package/dist/eslint-rules/tex-build.js +313 -0
  154. package/dist/eslint-rules/tex-build.js.map +1 -0
  155. package/dist/facts-file.d.ts.map +1 -1
  156. package/dist/facts-file.js +31 -27
  157. package/dist/facts-file.js.map +1 -1
  158. package/dist/hooks-settings.d.ts +1 -1
  159. package/dist/hooks-settings.d.ts.map +1 -1
  160. package/dist/hooks-settings.js +31 -11
  161. package/dist/hooks-settings.js.map +1 -1
  162. package/dist/init.d.ts +8 -9
  163. package/dist/init.d.ts.map +1 -1
  164. package/dist/init.js +33 -15
  165. package/dist/init.js.map +1 -1
  166. package/dist/latex-loop.d.ts +2 -2
  167. package/dist/latex-loop.d.ts.map +1 -1
  168. package/dist/latex-loop.js +2 -2
  169. package/dist/latex-loop.js.map +1 -1
  170. package/dist/lib/agent-cli-version.d.ts +65 -0
  171. package/dist/lib/agent-cli-version.d.ts.map +1 -0
  172. package/dist/lib/agent-cli-version.js +77 -0
  173. package/dist/lib/agent-cli-version.js.map +1 -0
  174. package/dist/lib/check.d.ts +19 -0
  175. package/dist/lib/check.d.ts.map +1 -0
  176. package/dist/lib/check.js +52 -0
  177. package/dist/lib/check.js.map +1 -0
  178. package/dist/lib/markdown.d.ts +180 -0
  179. package/dist/lib/markdown.d.ts.map +1 -0
  180. package/dist/lib/markdown.js +302 -0
  181. package/dist/lib/markdown.js.map +1 -0
  182. package/dist/lib/paper-config.d.ts +84 -0
  183. package/dist/lib/paper-config.d.ts.map +1 -0
  184. package/dist/lib/paper-config.js +138 -0
  185. package/dist/lib/paper-config.js.map +1 -0
  186. package/dist/lib/skill-eval-fixture.d.ts +29 -0
  187. package/dist/lib/skill-eval-fixture.d.ts.map +1 -0
  188. package/dist/lib/skill-eval-fixture.js +62 -0
  189. package/dist/lib/skill-eval-fixture.js.map +1 -0
  190. package/dist/link-skills.d.ts.map +1 -1
  191. package/dist/link-skills.js +5 -4
  192. package/dist/link-skills.js.map +1 -1
  193. package/dist/new-paper.d.ts.map +1 -1
  194. package/dist/new-paper.js +7 -3
  195. package/dist/new-paper.js.map +1 -1
  196. package/dist/paper-files.d.ts +4 -4
  197. package/dist/paper-files.d.ts.map +1 -1
  198. package/dist/paper-files.js +6 -6
  199. package/dist/paper-files.js.map +1 -1
  200. package/dist/paper-settings.d.ts.map +1 -1
  201. package/dist/paper-settings.js +8 -7
  202. package/dist/paper-settings.js.map +1 -1
  203. package/dist/pdf-facts.d.ts +51 -1
  204. package/dist/pdf-facts.d.ts.map +1 -1
  205. package/dist/pdf-facts.js +25 -16
  206. package/dist/pdf-facts.js.map +1 -1
  207. package/dist/pdf-geometry.d.ts.map +1 -1
  208. package/dist/pdf-geometry.js +3 -4
  209. package/dist/pdf-geometry.js.map +1 -1
  210. package/dist/ports/tool-installer.d.ts +2 -14
  211. package/dist/ports/tool-installer.d.ts.map +1 -1
  212. package/dist/presets.d.ts.map +1 -1
  213. package/dist/presets.js +19 -6
  214. package/dist/presets.js.map +1 -1
  215. package/dist/references.d.ts.map +1 -1
  216. package/dist/references.js +15 -10
  217. package/dist/references.js.map +1 -1
  218. package/dist/rules-config.d.ts +26 -1
  219. package/dist/rules-config.d.ts.map +1 -1
  220. package/dist/rules-config.js +15 -12
  221. package/dist/rules-config.js.map +1 -1
  222. package/dist/structure.js +1 -1
  223. package/dist/structure.js.map +1 -1
  224. package/dist/tex-requirements.d.ts +4 -0
  225. package/dist/tex-requirements.d.ts.map +1 -1
  226. package/dist/tex-requirements.js +22 -5
  227. package/dist/tex-requirements.js.map +1 -1
  228. package/dist/toolchain.d.ts.map +1 -1
  229. package/dist/toolchain.js +21 -16
  230. package/dist/toolchain.js.map +1 -1
  231. package/dist/types.d.ts +5 -3
  232. package/dist/types.d.ts.map +1 -1
  233. package/dist/venue-rules.d.ts.map +1 -1
  234. package/dist/venue-rules.js +21 -8
  235. package/dist/venue-rules.js.map +1 -1
  236. package/docs/configuration.md +2 -2
  237. package/docs/e2e.md +7 -7
  238. package/docs/install.md +1 -1
  239. package/docs/prior-art/README.md +1 -1
  240. package/docs/prior-art/package-location.md +5 -5
  241. package/docs/prior-art/repro/README.md +1 -1
  242. package/docs/prior-art/test-tooling.md +2 -2
  243. package/docs/testing.md +11 -8
  244. package/docs/toolchain.md +1 -1
  245. package/eslint-rules/{bib-reachable-entry.mjs → bib-reachable-entry.ts} +5 -4
  246. package/eslint-rules/install-path-literals.harness.mjs +1 -1
  247. package/eslint-rules/{install-path-literals.mjs → install-path-literals.ts} +18 -10
  248. package/eslint-rules/latex-language.harness.mjs +2 -2
  249. package/eslint-rules/latex-language.test.mjs +7 -1
  250. package/eslint-rules/{latex-language.mjs → latex-language.ts} +297 -109
  251. package/eslint-rules/paper-research-question.harness.mjs +3 -3
  252. package/eslint-rules/{paper-research-question.mjs → paper-research-question.ts} +35 -16
  253. package/eslint-rules/paper-stages.harness.mjs +2 -2
  254. package/eslint-rules/paper-stages.test.mjs +8 -2
  255. package/eslint-rules/{paper-stages.mjs → paper-stages.ts} +76 -31
  256. package/eslint-rules/paper-typography.test.mjs +3 -3
  257. package/eslint-rules/{paper-typography.mjs → paper-typography.ts} +134 -56
  258. package/eslint-rules/papers.harness.mjs +2 -2
  259. package/eslint-rules/{papers.mjs → papers.ts} +7 -4
  260. package/eslint-rules/pdf-last-page-balance.harness.mjs +3 -3
  261. package/eslint-rules/{pdf-last-page-balance.mjs → pdf-last-page-balance.ts} +89 -32
  262. package/eslint-rules/review-frontmatter.test.mjs +2 -2
  263. package/eslint-rules/{review-frontmatter.mjs → review-frontmatter.ts} +38 -16
  264. package/eslint-rules/rule-context.ts +62 -0
  265. package/eslint-rules/{sibling-frontmatter.mjs → sibling-frontmatter.ts} +1 -1
  266. package/eslint-rules/temp-root-realpath.harness.mjs +1 -1
  267. package/eslint-rules/{temp-root-realpath.mjs → temp-root-realpath.ts} +20 -7
  268. package/eslint-rules/tex-build.harness.mjs +2 -2
  269. package/eslint-rules/{tex-build.mjs → tex-build.ts} +6 -5
  270. package/eslint.config.mjs +146 -30
  271. package/fixtures/install-path-literals/clean.fixture.mjs +1 -1
  272. package/fixtures/install-path-literals/clean.md +2 -2
  273. package/fixtures/install-path-literals/defect.fixture.mjs +1 -1
  274. package/fixtures/install-path-literals/defect.md +2 -2
  275. package/fixtures/pdf-facts/README.md +2 -2
  276. package/fixtures/real-markdown-paper/{baseline.mjs → baseline.ts} +31 -10
  277. package/hooks/{hooks.harness.mjs → hooks.harness.ts} +51 -34
  278. package/hooks/paper-edit-guard.hook.mjs +1 -1
  279. package/hooks/{paper-edit-guard.test.mjs → paper-edit-guard.test.ts} +3 -7
  280. package/hooks/paper-skills-nudge.hook.mjs +1 -1
  281. package/hooks/{paper-skills-nudge.test.mjs → paper-skills-nudge.test.ts} +2 -6
  282. package/hooks/paper-status-gates.sh +9 -19
  283. package/hooks/{paper-status-gates.test.mjs → paper-status-gates.test.ts} +2 -6
  284. package/lib/agent-cli-version.harness.mjs +1 -1
  285. package/lib/{agent-cli-version.mjs → agent-cli-version.ts} +32 -18
  286. package/lib/check.test.ts +14 -9
  287. package/lib/{check.mjs → check.ts} +22 -9
  288. package/lib/markdown.test.mjs +7 -7
  289. package/lib/{markdown.mjs → markdown.ts} +68 -29
  290. package/lib/paper-config.harness.mjs +9 -9
  291. package/lib/{paper-config.mjs → paper-config.ts} +20 -19
  292. package/lib/skill-checks.mjs +24 -381
  293. package/lib/skill-checks.test.mjs +64 -116
  294. package/lib/skill-corpus.mjs +10 -251
  295. package/lib/skill-corpus.test.mjs +2 -13
  296. package/lib/skill-eval-kit.mjs +1 -1
  297. package/lib/skill-trigger-cases.mjs +1 -1
  298. package/package.json +42 -10
  299. package/scripts/{check.harness.mjs → check.harness.ts} +111 -10
  300. package/scripts/{check.test.mjs → check.test.ts} +13 -10
  301. package/scripts/{check.mjs → check.ts} +116 -42
  302. package/scripts/coverage-config.test.ts +80 -38
  303. package/scripts/eslint-report-guard.test.mjs +1 -1
  304. package/scripts/harness-api.frozen.json +14 -16
  305. package/scripts/harness-api.test.ts +8 -5
  306. package/scripts/layer-legacy-frozen.test.ts +17 -13
  307. package/scripts/{layer-legacy-frozen.mjs → layer-legacy-frozen.ts} +128 -39
  308. package/scripts/release-config.test.ts +12 -4
  309. package/scripts/rules-see-files.test.mjs +1 -1
  310. package/scripts/test.test.ts +78 -0
  311. package/scripts/test.ts +87 -0
  312. package/skills/analyze-sibling-paper/SKILL.md +1 -39
  313. package/skills/analyze-sibling-paper/SKILL.md.spec.ts +0 -38
  314. package/skills/argument-arc/SKILL.md +2 -36
  315. package/skills/argument-arc/SKILL.md.spec.ts +1 -43
  316. package/skills/build-benchmark/SKILL.md +1 -41
  317. package/skills/build-benchmark/SKILL.md.spec.ts +0 -40
  318. package/skills/camera-ready/SKILL.md +1 -34
  319. package/skills/camera-ready/SKILL.md.spec.ts +0 -33
  320. package/skills/cold-read-diff/SKILL.md +1 -35
  321. package/skills/cold-read-diff/SKILL.md.spec.ts +0 -34
  322. package/skills/draft-paper/SKILL.md +2 -41
  323. package/skills/draft-paper/SKILL.md.spec.ts +1 -50
  324. package/skills/extend-paper/SKILL.md +2 -33
  325. package/skills/extend-paper/SKILL.md.spec.ts +1 -42
  326. package/skills/find-venue/SKILL.md +2 -38
  327. package/skills/find-venue/SKILL.md.spec.ts +1 -47
  328. package/skills/grade-paper-writing/SKILL.md +3 -38
  329. package/skills/grade-paper-writing/SKILL.md.spec.ts +2 -47
  330. package/skills/grade-paper-writing/prose-lint.mjs +3 -4
  331. package/skills/grade-paper-writing/{prose-lint.test.mjs → prose-lint.test.ts} +3 -3
  332. package/skills/harden-paper/SKILL.md +1 -39
  333. package/skills/harden-paper/SKILL.md.spec.ts +0 -38
  334. package/skills/map-prior-work/SKILL.md +1 -35
  335. package/skills/map-prior-work/SKILL.md.spec.ts +0 -34
  336. package/skills/osf-artifact-upload/{osf-artifact-upload.harness.mjs → osf-artifact-upload.harness.ts} +3 -4
  337. package/skills/paper-adversarial-review/SKILL.md +2 -35
  338. package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -43
  339. package/skills/paper-pipeline/SKILL.md +2 -28
  340. package/skills/paper-pipeline/SKILL.md.spec.ts +1 -27
  341. package/skills/paper-pipeline/description-language.eval.mjs +1 -1
  342. package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +1 -1
  343. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +2 -2
  344. package/skills/paper-pipeline/paper-pipeline.harness.mjs +25 -40
  345. package/skills/paper-pipeline/pipeline-firing.eval.mjs +1 -1
  346. package/skills/paper-pipeline/pipeline-language.eval.mjs +1 -1
  347. package/skills/paper-pipeline/references/acceptance-gate.md +1 -6
  348. package/skills/paper-pipeline/references/pipeline-status-template.md +8 -35
  349. package/skills/paper-pipeline/scripts/README.md +30 -225
  350. package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +4 -8
  351. package/skills/paper-pipeline/scripts/artifact-coverage.mjs +1 -1
  352. package/skills/paper-pipeline/scripts/{artifact-coverage.test.mjs → artifact-coverage.test.ts} +2 -2
  353. package/skills/paper-pipeline/scripts/consumer.harness.mjs +6 -104
  354. package/skills/paper-pipeline/scripts/consumer.mjs +24 -109
  355. package/skills/paper-pipeline/scripts/consumer.test.mjs +1 -1
  356. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +1 -1
  357. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +1 -4
  358. package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +1 -1
  359. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +2 -3
  360. package/skills/paper-pipeline/scripts/{generated-code.test.mjs → generated-code.test.ts} +3 -3
  361. package/skills/paper-pipeline/scripts/population-map.harness.mjs +3 -3
  362. package/skills/paper-pipeline/scripts/population-map.mjs +1 -4
  363. package/skills/paper-pipeline/scripts/population-map.test.mjs +1 -1
  364. package/skills/paper-pipeline/scripts/{round-diff.harness.mjs → round-diff.harness.ts} +45 -18
  365. package/skills/paper-pipeline/scripts/round-diff.mjs +1 -1
  366. package/skills/paper-pipeline/scripts/round-diff.test.mjs +1 -1
  367. package/skills/paper-status/SKILL.md +2 -42
  368. package/skills/paper-status/SKILL.md.spec.ts +1 -41
  369. package/skills/pc-panel-review/SKILL.md +2 -46
  370. package/skills/pc-panel-review/SKILL.md.spec.ts +1 -45
  371. package/skills/plan-paper-timeline/SKILL.md +2 -36
  372. package/skills/plan-paper-timeline/SKILL.md.spec.ts +0 -36
  373. package/skills/plan-paper-timeline/fixtures/{fake-google-calendar.mjs → fake-google-calendar.ts} +101 -70
  374. package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +3 -3
  375. package/skills/render-paper/SKILL.md +1 -37
  376. package/skills/render-paper/SKILL.md.spec.ts +0 -36
  377. package/skills/render-paper/{extract-pdf-facts.harness.mjs → extract-pdf-facts.harness.ts} +34 -9
  378. package/skills/render-paper/render-paper.harness.mjs +2 -2
  379. package/skills/research-ideate/SKILL.md +2 -39
  380. package/skills/research-ideate/SKILL.md.spec.ts +1 -47
  381. package/skills/study-accepted-papers/SKILL.md +1 -34
  382. package/skills/study-accepted-papers/SKILL.md.spec.ts +0 -33
  383. package/skills/submit-paper/SKILL.md +1 -33
  384. package/skills/submit-paper/SKILL.md.spec.ts +0 -32
  385. package/skills/sweep-design-space/SKILL.md +1 -38
  386. package/skills/sweep-design-space/SKILL.md.spec.ts +0 -37
  387. package/skills/tighten-paper/SKILL.md +2 -39
  388. package/skills/tighten-paper/SKILL.md.spec.ts +1 -47
  389. package/skills/tighten-paper/structure.mjs +5 -12
  390. package/skills/tighten-paper/{structure.test.mjs → structure.test.ts} +4 -3
  391. package/skills/verify-citations/SKILL.md +2 -38
  392. package/skills/verify-citations/SKILL.md.spec.ts +1 -37
  393. package/skills/verify-citations/scripts/{bib-authors.cli.test.mjs → bib-authors.cli.test.ts} +14 -4
  394. package/skills/verify-citations/scripts/bib-authors.d.mts +63 -0
  395. package/skills/verify-citations/scripts/bib-authors.mjs +1 -4
  396. package/skills/verify-citations/scripts/{verify-cites.cli.test.mjs → verify-cites.cli.test.ts} +32 -9
  397. package/skills/verify-citations/scripts/verify-cites.d.mts +58 -0
  398. package/src/CLAUDE.md +1 -1
  399. package/src/adapters/banal/failure.ts +9 -10
  400. package/src/adapters/banal/index.test.ts +5 -8
  401. package/src/adapters/banal/index.ts +8 -7
  402. package/src/adapters/banal/install.ts +9 -4
  403. package/src/adapters/banal/invocation.test.ts +23 -9
  404. package/src/adapters/banal/invocation.ts +24 -9
  405. package/src/adapters/banal/locate.test.ts +2 -2
  406. package/src/adapters/banal/locate.ts +27 -21
  407. package/src/adapters/banal/output.test.ts +1 -1
  408. package/src/adapters/banal/run.test.ts +5 -5
  409. package/src/adapters/banal/run.ts +16 -10
  410. package/src/adapters/banal/settings.ts +2 -2
  411. package/src/adapters/banal/xml.test.ts +1 -1
  412. package/src/adapters/curl/download.test.ts +8 -6
  413. package/src/adapters/memory/index.ts +4 -3
  414. package/src/adapters/node/files.io.ts +2 -2
  415. package/src/adapters/node/files.test.ts +8 -4
  416. package/src/adapters/node/process.io.ts +13 -5
  417. package/src/adapters/node/process.test.ts +5 -5
  418. package/src/adapters/node/workspace.io.ts +9 -4
  419. package/src/adapters/node/workspace.test.ts +3 -1
  420. package/src/adapters/pdfjs/fill.test.ts +2 -2
  421. package/src/adapters/pdfjs/fill.ts +14 -7
  422. package/src/adapters/references/index.test.ts +31 -38
  423. package/src/adapters/references/index.ts +33 -60
  424. package/src/adapters/references/pool.ts +3 -5
  425. package/src/adapters/references/reach.io.ts +2 -1
  426. package/src/build-engine.harness.mjs +1 -1
  427. package/src/build-engine.test.ts +13 -8
  428. package/src/build-engine.ts +12 -7
  429. package/src/build.harness.mjs +2 -2
  430. package/src/build.test.ts +24 -24
  431. package/src/build.ts +34 -26
  432. package/src/caller-path.ts +13 -0
  433. package/src/cli.harness.mjs +6 -8
  434. package/src/cli.test.ts +31 -13
  435. package/src/cli.ts +117 -58
  436. package/src/doctor.harness.mjs +3 -3
  437. package/src/doctor.test.ts +1 -1
  438. package/src/doctor.ts +17 -7
  439. package/src/domain/lookup-cache.ts +21 -11
  440. package/src/domain/paths.test.ts +15 -0
  441. package/src/domain/paths.ts +20 -1
  442. package/src/domain/ready.ts +31 -0
  443. package/src/domain/record.test.ts +20 -0
  444. package/src/domain/record.ts +12 -0
  445. package/src/domain/result.test.ts +2 -2
  446. package/src/domain/sha256.ts +5 -3
  447. package/src/domain/text.test.ts +32 -0
  448. package/src/domain/text.ts +23 -0
  449. package/src/engine.harness.mjs +2 -2
  450. package/src/engine.ts +34 -5
  451. package/src/facts-file.test.ts +9 -7
  452. package/src/facts-file.ts +45 -29
  453. package/src/{hooks-settings.harness.mjs → hooks-settings.harness.ts} +56 -20
  454. package/src/hooks-settings.ts +48 -13
  455. package/src/init.test.ts +37 -14
  456. package/src/init.ts +48 -24
  457. package/src/{latex-log.harness.mjs → latex-log.harness.ts} +14 -14
  458. package/src/{latex-loop.harness.mjs → latex-loop.harness.ts} +64 -36
  459. package/src/latex-loop.ts +3 -3
  460. package/src/{link-skills.harness.mjs → link-skills.harness.ts} +19 -19
  461. package/src/link-skills.test.ts +3 -3
  462. package/src/link-skills.ts +5 -4
  463. package/src/lint-fix.test.ts +4 -6
  464. package/src/linted-set.test.ts +2 -2
  465. package/src/new-paper.harness.mjs +9 -25
  466. package/src/new-paper.test.ts +8 -10
  467. package/src/new-paper.ts +9 -5
  468. package/src/paper-files.test.ts +25 -24
  469. package/src/paper-files.ts +16 -27
  470. package/src/paper-settings-commands.test.ts +5 -4
  471. package/src/paper-settings.test.ts +7 -7
  472. package/src/paper-settings.ts +13 -14
  473. package/src/{pdf-facts.harness.mjs → pdf-facts.harness.ts} +9 -8
  474. package/src/pdf-facts.test.ts +25 -15
  475. package/src/pdf-facts.ts +81 -23
  476. package/src/{pdf-geometry.harness.mjs → pdf-geometry.harness.ts} +19 -12
  477. package/src/pdf-geometry.ts +8 -4
  478. package/src/ports/tool-installer.ts +2 -17
  479. package/src/presets.ts +31 -16
  480. package/src/references.test.ts +76 -62
  481. package/src/references.ts +18 -12
  482. package/src/{rules-config.harness.mjs → rules-config.harness.ts} +7 -13
  483. package/src/rules-config.ts +46 -14
  484. package/src/rules-off.test.ts +6 -4
  485. package/src/{structure.harness.mjs → structure.harness.ts} +26 -15
  486. package/src/structure.ts +1 -1
  487. package/src/{tex-requirements.harness.mjs → tex-requirements.harness.ts} +50 -22
  488. package/src/tex-requirements.test.ts +21 -0
  489. package/src/tex-requirements.ts +37 -11
  490. package/src/toolchain.harness.mjs +2 -2
  491. package/src/toolchain.test.ts +10 -6
  492. package/src/toolchain.ts +31 -17
  493. package/src/types.ts +5 -3
  494. package/src/venue-rules.test.ts +70 -68
  495. package/src/venue-rules.ts +22 -12
  496. package/tsconfig.json +6 -3
  497. package/tsconfig.pkg.json +10 -0
  498. package/lib/check.d.mts +0 -17
  499. package/lib/paper-config.d.mts +0 -31
  500. package/scripts/layer-legacy-frozen.d.mts +0 -36
  501. package/scripts/rules-are-content-only.harness.mjs +0 -105
  502. package/scripts/rules-are-content-only.mjs +0 -148
  503. package/scripts/rules-are-content-only.test.mjs +0 -61
  504. package/scripts/test.mjs +0 -44
  505. package/scripts/test.test.mjs +0 -52
  506. package/skills/paper-pipeline/scripts/announce.mjs +0 -67
  507. package/skills/paper-pipeline/scripts/announce.test.mjs +0 -102
  508. package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +0 -51
  509. package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +0 -52
  510. package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +0 -6
  511. package/skills/paper-pipeline/scripts/fixtures/scorecard.mjs +0 -71
  512. package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +0 -302
  513. package/skills/paper-pipeline/scripts/ledger.mjs +0 -623
  514. package/skills/paper-pipeline/scripts/ledger.test.mjs +0 -254
  515. package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +0 -474
  516. package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +0 -328
  517. package/skills/paper-pipeline/scripts/pipeline-check.mjs +0 -753
  518. package/skills/paper-pipeline/scripts/pipeline-edges.mjs +0 -169
  519. package/skills/paper-pipeline/scripts/pipeline-edges.test.mjs +0 -73
  520. package/skills/paper-pipeline/scripts/run-mechanical.mjs +0 -648
  521. package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +0 -468
  522. package/skills/paper-pipeline/scripts/status.mjs +0 -295
  523. package/skills/paper-pipeline/scripts/status.test.mjs +0 -232
  524. /package/bin/{paperlint.test.mjs → paperlint.test.ts} +0 -0
  525. /package/lib/{skill-eval-fixture.mjs → skill-eval-fixture.ts} +0 -0
  526. /package/skills/grade-paper-writing/__snapshots__/{prose-lint.test.mjs.snap → prose-lint.test.ts.snap} +0 -0
  527. /package/skills/tighten-paper/__snapshots__/{structure.test.mjs.snap → structure.test.ts.snap} +0 -0
@@ -5,20 +5,11 @@ context: fork
5
5
  allowed-tools: [Bash, Read, Agent]
6
6
  ---
7
7
 
8
- <!-- vigiles:sha256:596fbd7e2eb85252 compiled from skills/cold-read-diff/SKILL.md.spec.ts -->
8
+ <!-- vigiles:sha256:e45391841e689aa9 compiled from skills/cold-read-diff/SKILL.md.spec.ts -->
9
9
 
10
10
  # cold-read-diff — the reader who cannot fake understanding
11
11
 
12
- ## Run me
13
12
 
14
- 🔴 FIRST, before any other step:
15
-
16
- ```
17
- node .claude/skills/paper-pipeline/scripts/announce.mjs cold-read-diff <paper-dir>
18
- ```
19
-
20
- An advisory pass cannot be observed failing — silence is both its error state and its normal
21
- state — so starting is an event, and events get written down.
22
13
 
23
14
  ## The failure this exists for
24
15
 
@@ -120,25 +111,6 @@ findings:
120
111
  ---
121
112
  ```
122
113
 
123
- ## Record the verdict
124
-
125
- 🔴 LAST step, once the deliverable exists:
126
-
127
- ```
128
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> FINDING <count> <report-path>
129
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> ABSTAINED <reason> "<one line>"
130
- ```
131
-
132
- **FINDING** — `<count>` is the number of changed sentences the cold reader could not restate (every
133
- `CANNOT PARSE` counts), `<report-path>` is the `reviews/*cold-read*.md` file.
134
- **ABSTAINED** — `no-witness`: every changed sentence came back restated correctly.
135
- `input-missing`: the diff held no prose to read.
136
-
137
- 🔴 These two are different answers and the difference is the whole reason the vocabulary is closed:
138
- one says a reader read it and found nothing, the other says there was nothing to hand a reader.
139
- Prose collapses them and the old `PASS`/`ABSENT` pair only half-separated them, because `PASS` also
140
- got recorded when nobody had run a reader at all. There is no `PASS` now; the reason is the answer.
141
-
142
114
  ## Rules
143
115
 
144
116
  - 🔴 **No context in the prompt. Ever.** Not the title, not the abstract, not "this is a paper about
@@ -158,12 +130,6 @@ got recorded when nobody had run a reader at all. There is no `PASS` now; the re
158
130
  - **Run it on your own fixes too.** The author is the least qualified judge of whether his repair
159
131
  reads, and that is exactly when he feels most certain.
160
132
 
161
- ## Enforcement
162
-
163
- `pipeline-check.mjs` raises `stale-cold-read` when the newest `reviews/*cold-read*.md` is older than
164
- the paper source, and `no-cold-read` when none exists. The date comparison is the whole mechanism:
165
- a cold read that predates the current text describes prose that no longer exists.
166
-
167
133
  ## Compose with
168
134
 
169
135
  - `grade-paper-writing` — the batch readability gate; this is its continuous counterpart. That one
@@ -14,16 +14,7 @@ export default experimental_skill({
14
14
  body: `
15
15
  # cold-read-diff — the reader who cannot fake understanding
16
16
 
17
- ## Run me
18
17
 
19
- 🔴 FIRST, before any other step:
20
-
21
- \`\`\`
22
- node .claude/skills/paper-pipeline/scripts/announce.mjs cold-read-diff <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
18
 
28
19
  ## The failure this exists for
29
20
 
@@ -125,25 +116,6 @@ findings:
125
116
  ---
126
117
  \`\`\`
127
118
 
128
- ## Record the verdict
129
-
130
- 🔴 LAST step, once the deliverable exists:
131
-
132
- \`\`\`
133
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> FINDING <count> <report-path>
134
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record cold-read-diff <paper-dir> ABSTAINED <reason> "<one line>"
135
- \`\`\`
136
-
137
- **FINDING** — \`<count>\` is the number of changed sentences the cold reader could not restate (every
138
- \`CANNOT PARSE\` counts), \`<report-path>\` is the \`reviews/*cold-read*.md\` file.
139
- **ABSTAINED** — \`no-witness\`: every changed sentence came back restated correctly.
140
- \`input-missing\`: the diff held no prose to read.
141
-
142
- 🔴 These two are different answers and the difference is the whole reason the vocabulary is closed:
143
- one says a reader read it and found nothing, the other says there was nothing to hand a reader.
144
- Prose collapses them and the old \`PASS\`/\`ABSENT\` pair only half-separated them, because \`PASS\` also
145
- got recorded when nobody had run a reader at all. There is no \`PASS\` now; the reason is the answer.
146
-
147
119
  ## Rules
148
120
 
149
121
  - 🔴 **No context in the prompt. Ever.** Not the title, not the abstract, not "this is a paper about
@@ -163,12 +135,6 @@ got recorded when nobody had run a reader at all. There is no \`PASS\` now; the
163
135
  - **Run it on your own fixes too.** The author is the least qualified judge of whether his repair
164
136
  reads, and that is exactly when he feels most certain.
165
137
 
166
- ## Enforcement
167
-
168
- \`pipeline-check.mjs\` raises \`stale-cold-read\` when the newest \`reviews/*cold-read*.md\` is older than
169
- the paper source, and \`no-cold-read\` when none exists. The date comparison is the whole mechanism:
170
- a cold read that predates the current text describes prose that no longer exists.
171
-
172
138
  ## Compose with
173
139
 
174
140
  - \`grade-paper-writing\` — the batch readability gate; this is its continuous counterpart. That one
@@ -1,24 +1,13 @@
1
1
  ---
2
2
  name: draft-paper
3
3
  description: Use when the numbers exist and it's time to WRITE the paper — "draft the paper", "turn these findings into a submission", "write the abstract/intro/threats". Gives the section skeleton of a measurement/benchmark paper plus what gets it accepted AND cited — precise claim-sizing (including an explicit "what we do NOT claim"), a construct-validity frame, an honest threats-to-validity section that turns limitations in your favor, and one memorable stat that travels. Encodes the two theses that carried real measurement papers ("measuring the wrong number", "safety theater"). NOT for grading finished prose (grade-paper-writing) or structural editing (tighten-paper) — this is the generative counterpart. Compose with build-benchmark (numbers), grade-paper-writing (prose QA), render-paper, verify-citations, then the review skills.
4
- allowed-tools: [Read, Write, Edit, Grep, Glob, Agent, Skill, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
4
+ allowed-tools: [Read, Write, Edit, Grep, Glob, Agent, Skill]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:1b6a7bdc0ea402ec compiled from skills/draft-paper/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:46bb85bfaa45e595 compiled from skills/draft-paper/SKILL.md.spec.ts -->
8
8
 
9
9
  # draft-paper — prose that survives review and gets cited
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs draft-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
  A measurement paper lives or dies on two things reviewers actually reward: a **reusable method/norm**
23
12
  they can apply to the next system, and **claim-sizing so precise it can't be attacked**. Numbers alone
24
13
  are a blog post. This skill turns `build-benchmark`'s output into that kind of draft.
@@ -101,34 +90,6 @@ For papers they duplicate — and are superseded by — `grade-paper-writing` +
101
90
  pass (the blog skills lack the persona fix, so they under-fire on paper prose). Never route paper
102
91
  prose QA to them.
103
92
 
104
- ## Record the verdict
105
-
106
- 🔴 LAST step, once the deliverable exists:
107
-
108
- ```
109
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> FINDING <count> <report-path>
110
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> ABSTAINED <reason> "<one line>"
111
- ```
112
-
113
- This skill generates rather than judges, so what it records is about the run, not about the paper.
114
-
115
- **FINDING** — it declined to draft because a required input was missing: no numbers from
116
- `build-benchmark`, or an empty `frame` paragraph from `argument-arc`. `--blocking`, always, because
117
- drafting past it produces prose about numbers that do not exist.
118
- **ABSTAINED** — `no-witness`: sections were written and the generator has nothing to report about
119
- the paper. Put the drafted sections in the note; they are the deliverable, not evidence of a defect.
120
-
121
- 🔴 **Design smell, stated plainly: this gate will almost always record an abstention**, and
122
- `status.mjs` will flag it as one that has never returned a finding. Leave the flag standing — it is
123
- telling the truth. A generator is not a gate, and the only honest negative it can produce is the
124
- refusal above. If a run ever ends with prose written from numbers that do not exist, that is a
125
- `FINDING --blocking` and must be recorded as one rather than quietly upgraded.
126
-
127
- 🔴 Deleting `PASS` did not fix this skill and was never going to: the old vocabulary let it write
128
- down "I produced sections" as though that were an answer about the manuscript, and the new one
129
- simply refuses to. The generator is still not a gate. `draft-paper/population-map` — a real check —
130
- is the row that can say no about this skill's output.
131
-
132
93
  ## Compose with
133
94
  - **`build-benchmark`** — its numbers/CIs are the Results section's raw material; never hand-type a
134
95
  number that isn't in its output (that's how paper↔artifact mismatches get born).
@@ -10,31 +10,10 @@ export default experimental_skill({
10
10
  name: "draft-paper",
11
11
  description:
12
12
  'Use when the numbers exist and it\'s time to WRITE the paper — "draft the paper", "turn these findings into a submission", "write the abstract/intro/threats". Gives the section skeleton of a measurement/benchmark paper plus what gets it accepted AND cited — precise claim-sizing (including an explicit "what we do NOT claim"), a construct-validity frame, an honest threats-to-validity section that turns limitations in your favor, and one memorable stat that travels. Encodes the two theses that carried real measurement papers ("measuring the wrong number", "safety theater"). NOT for grading finished prose (grade-paper-writing) or structural editing (tighten-paper) — this is the generative counterpart. Compose with build-benchmark (numbers), grade-paper-writing (prose QA), render-paper, verify-citations, then the review skills.',
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Edit",
17
- "Grep",
18
- "Glob",
19
- "Agent",
20
- "Skill",
21
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
- ],
13
+ tools: ["Read", "Write", "Edit", "Grep", "Glob", "Agent", "Skill"],
24
14
  body: `
25
15
  # draft-paper — prose that survives review and gets cited
26
16
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs draft-paper <paper-dir>
33
- \`\`\`
34
-
35
- An advisory pass cannot be observed failing — silence is both its error state and its normal
36
- state — so starting is an event, and events get written down.
37
-
38
17
  A measurement paper lives or dies on two things reviewers actually reward: a **reusable method/norm**
39
18
  they can apply to the next system, and **claim-sizing so precise it can't be attacked**. Numbers alone
40
19
  are a blog post. This skill turns \`build-benchmark\`'s output into that kind of draft.
@@ -117,34 +96,6 @@ For papers they duplicate — and are superseded by — \`grade-paper-writing\`
117
96
  pass (the blog skills lack the persona fix, so they under-fire on paper prose). Never route paper
118
97
  prose QA to them.
119
98
 
120
- ## Record the verdict
121
-
122
- 🔴 LAST step, once the deliverable exists:
123
-
124
- \`\`\`
125
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> FINDING <count> <report-path>
126
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> ABSTAINED <reason> "<one line>"
127
- \`\`\`
128
-
129
- This skill generates rather than judges, so what it records is about the run, not about the paper.
130
-
131
- **FINDING** — it declined to draft because a required input was missing: no numbers from
132
- \`build-benchmark\`, or an empty \`frame\` paragraph from \`argument-arc\`. \`--blocking\`, always, because
133
- drafting past it produces prose about numbers that do not exist.
134
- **ABSTAINED** — \`no-witness\`: sections were written and the generator has nothing to report about
135
- the paper. Put the drafted sections in the note; they are the deliverable, not evidence of a defect.
136
-
137
- 🔴 **Design smell, stated plainly: this gate will almost always record an abstention**, and
138
- \`status.mjs\` will flag it as one that has never returned a finding. Leave the flag standing — it is
139
- telling the truth. A generator is not a gate, and the only honest negative it can produce is the
140
- refusal above. If a run ever ends with prose written from numbers that do not exist, that is a
141
- \`FINDING --blocking\` and must be recorded as one rather than quietly upgraded.
142
-
143
- 🔴 Deleting \`PASS\` did not fix this skill and was never going to: the old vocabulary let it write
144
- down "I produced sections" as though that were an answer about the manuscript, and the new one
145
- simply refuses to. The generator is still not a gate. \`draft-paper/population-map\` — a real check —
146
- is the row that can say no about this skill's output.
147
-
148
99
  ## Compose with
149
100
  - **\`build-benchmark\`** — its numbers/CIs are the Results section's raw material; never hand-type a
150
101
  number that isn't in its output (that's how paper↔artifact mismatches get born).
@@ -1,24 +1,13 @@
1
1
  ---
2
2
  name: extend-paper
3
3
  description: Turn an accepted workshop / short paper into a second, stronger publication at a higher-prestige indexed venue — the "body of work" a strong dossier needs, not a one-hit paper. Covers the ≥30% new-material rule, the never-dual-submit rule, what genuinely counts as new content, and picking + timelining the upgrade venue. Use after a paper is accepted and you want the follow-on publication. Compose with find-venue, plan-paper-timeline, camera-ready, research-ideate.
4
- allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Skill, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
4
+ allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Skill]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:436bb3586d84a654 compiled from skills/extend-paper/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:6310b1e7748e10de compiled from skills/extend-paper/SKILL.md.spec.ts -->
8
8
 
9
9
  # extend-paper — workshop/short paper → a second, stronger publication
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs extend-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
  One accepted paper is a data point; two related papers climbing in prestige is a **trajectory**, and
23
12
  "sustained acclaim" is what a body-of-work review actually rewards. Workshop→conference and
24
13
  conference→journal extensions are a standard, expected move — venues invite them. The catch: an
@@ -66,26 +55,6 @@ submissions**. A burst of papers clustered right before an external filing deadl
66
55
  manufactured, not sustained — a documented reason for refusal, not a stylistic worry. Aim the extension to land a few months after the first paper's
67
56
  acceptance so the record shows steady output over time, one ORCID tying every version together.
68
57
 
69
- ## Record the verdict
70
-
71
- 🔴 LAST step, once the deliverable exists:
72
-
73
- ```
74
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> FINDING <count> <report-path>
75
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> ABSTAINED <reason> "<one line>"
76
- ```
77
-
78
- **FINDING** — `<count>` open items before the extension is legitimate; `<report-path>` is the plan.
79
- Add `--blocking` when the ≥30% cannot honestly be pointed at, which sends the work back to
80
- `research-ideate`.
81
- **ABSTAINED** — `no-witness`: a legitimate extension is scoped — ≥30% genuinely new material, one
82
- named venue, no dual submission — and nothing is open. `blocked`: there is no accepted base paper
83
- to extend.
84
-
85
- 🔴 **There is no PASS**, and here that matters more than anywhere: the tempting move at this moment
86
- is to resubmit the same paper with a new title, and a stored "legitimate" would have been exactly
87
- the paperwork for it. The blocking finding is what the pipeline is watching for; nothing else is.
88
-
89
58
  ## Compose with
90
59
  - **find-venue** — choose the higher-prestige indexed target and confirm it welcomes extensions.
91
60
  - **plan-paper-timeline** — schedule the new experiments + write-up against the target deadline.
@@ -10,31 +10,10 @@ export default experimental_skill({
10
10
  name: "extend-paper",
11
11
  description:
12
12
  'Turn an accepted workshop / short paper into a second, stronger publication at a higher-prestige indexed venue — the "body of work" a strong dossier needs, not a one-hit paper. Covers the ≥30% new-material rule, the never-dual-submit rule, what genuinely counts as new content, and picking + timelining the upgrade venue. Use after a paper is accepted and you want the follow-on publication. Compose with find-venue, plan-paper-timeline, camera-ready, research-ideate.',
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Grep",
17
- "Glob",
18
- "WebSearch",
19
- "WebFetch",
20
- "Skill",
21
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
- ],
13
+ tools: ["Read", "Write", "Grep", "Glob", "WebSearch", "WebFetch", "Skill"],
24
14
  body: `
25
15
  # extend-paper — workshop/short paper → a second, stronger publication
26
16
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs extend-paper <paper-dir>
33
- \`\`\`
34
-
35
- An advisory pass cannot be observed failing — silence is both its error state and its normal
36
- state — so starting is an event, and events get written down.
37
-
38
17
  One accepted paper is a data point; two related papers climbing in prestige is a **trajectory**, and
39
18
  "sustained acclaim" is what a body-of-work review actually rewards. Workshop→conference and
40
19
  conference→journal extensions are a standard, expected move — venues invite them. The catch: an
@@ -82,26 +61,6 @@ submissions**. A burst of papers clustered right before an external filing deadl
82
61
  manufactured, not sustained — a documented reason for refusal, not a stylistic worry. Aim the extension to land a few months after the first paper's
83
62
  acceptance so the record shows steady output over time, one ORCID tying every version together.
84
63
 
85
- ## Record the verdict
86
-
87
- 🔴 LAST step, once the deliverable exists:
88
-
89
- \`\`\`
90
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> FINDING <count> <report-path>
91
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> ABSTAINED <reason> "<one line>"
92
- \`\`\`
93
-
94
- **FINDING** — \`<count>\` open items before the extension is legitimate; \`<report-path>\` is the plan.
95
- Add \`--blocking\` when the ≥30% cannot honestly be pointed at, which sends the work back to
96
- \`research-ideate\`.
97
- **ABSTAINED** — \`no-witness\`: a legitimate extension is scoped — ≥30% genuinely new material, one
98
- named venue, no dual submission — and nothing is open. \`blocked\`: there is no accepted base paper
99
- to extend.
100
-
101
- 🔴 **There is no PASS**, and here that matters more than anywhere: the tempting move at this moment
102
- is to resubmit the same paper with a new title, and a stored "legitimate" would have been exactly
103
- the paperwork for it. The blocking finding is what the pipeline is watching for; nothing else is.
104
-
105
64
  ## Compose with
106
65
  - **find-venue** — choose the higher-prestige indexed target and confirm it welcomes extensions.
107
66
  - **plan-paper-timeline** — schedule the new experiments + write-up against the target deadline.
@@ -1,28 +1,13 @@
1
1
  ---
2
2
  name: find-venue
3
3
  description: "Discover and rank real venues for a given paper, scored by authorship credit not just prestige. Fetch candidate CFPs (WebSearch/WebFetch), capture deadline / page limit / paper-type fit / indexing (ACM DL / IEEE Xplore / archival vs non-archival) / double-blind / remote-attendance / selectivity, then rank by credit-weight (peer-reviewed + indexed + parent-venue prestige) × topic fit × accept-probability × deadline feasibility × remote-friendliness. Emit a comparison table and a keep/switch recommendation. Encodes: workshop newness does NOT hurt authorship; non-archival workshops rank LOW; the prestige move is to EXTEND the accepted paper later, not hold out. Compose with research-ideate (upstream), plan-paper-timeline, the submit-paper venue data cards (submit-paper/references/venues/<venue>.md), and extend-paper."
4
- allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Agent, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
4
+ allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Agent]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:5efdcc0e1b178c1a compiled from skills/find-venue/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:bfda3e840d81d95d compiled from skills/find-venue/SKILL.md.spec.ts -->
8
8
 
9
9
  # find-venue — rank real venues by what earns the credit, then keep or switch
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs find-venue <dir>
17
- ```
18
-
19
- An advisory pass cannot be observed failing — silence is both its error state and its normal
20
- state — so starting is an event, and events get written down.
21
-
22
- The `<dir>` argument is **optional in spirit**: this skill can run before a paper directory exists, so
23
- pass whichever directory the work lives in, or `.`. The ledger row is written either way, and a plain
24
- dot is more honest than an invented path.
25
-
26
11
  Takes a paper (or the candidate venue *types* from `research-ideate`) and finds the best real place to
27
12
  submit it. "Best" here means **best for the publication record**, which is not the same as most prestigious —
28
13
  an indexed workshop you can actually hit beats a top conference whose deadline already closed. This
@@ -82,27 +67,6 @@ rank = credit-weight × topic-fit × accept-probability × deadline-feasibility
82
67
  already has a target) an explicit **keep** or **switch** verdict against it. Note the intended
83
68
  `extend-paper` upgrade target for later.
84
69
 
85
- ## Record the verdict
86
-
87
- 🔴 LAST step, once the deliverable exists:
88
-
89
- ```
90
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> FINDING <count> <report-path>
91
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> ABSTAINED <reason> "<one line>"
92
- ```
93
-
94
- 🔴 **There is no PASS.** A shortlist is a set of findings about the world, not a certificate that
95
- the venue question is settled.
96
-
97
- **FINDING** — the sweep produced a ranked shortlist with an explicit keep/switch call; `<count>` is
98
- the number of candidates ranked and `<report-path>` the comparison table. Add `--blocking` when
99
- nothing open clears the peer-reviewed + indexed gate — a real answer, and not an empty run.
100
- **ABSTAINED** — `no-witness`: CFPs were read and no candidate could be ranked either way.
101
- `input-missing`: there is no paper description to match venues against.
102
-
103
- Record the whole table's path, not just the winner. The next sweep starts from the candidates that were
104
- dropped and why, and a verdict with no table behind it cannot be re-checked when a deadline moves.
105
-
106
70
  ## Rules
107
71
  - Fetch every CFP fact from the real page; never invent a deadline, page limit, or indexing status.
108
72
  - Indexed + peer-reviewed is a gate, not a tiebreaker — a non-archival venue cannot win on charm.
@@ -10,35 +10,10 @@ export default experimental_skill({
10
10
  name: "find-venue",
11
11
  description:
12
12
  "Discover and rank real venues for a given paper, scored by authorship credit not just prestige. Fetch candidate CFPs (WebSearch/WebFetch), capture deadline / page limit / paper-type fit / indexing (ACM DL / IEEE Xplore / archival vs non-archival) / double-blind / remote-attendance / selectivity, then rank by credit-weight (peer-reviewed + indexed + parent-venue prestige) × topic fit × accept-probability × deadline feasibility × remote-friendliness. Emit a comparison table and a keep/switch recommendation. Encodes: workshop newness does NOT hurt authorship; non-archival workshops rank LOW; the prestige move is to EXTEND the accepted paper later, not hold out. Compose with research-ideate (upstream), plan-paper-timeline, the submit-paper venue data cards (submit-paper/references/venues/<venue>.md), and extend-paper.",
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Grep",
17
- "Glob",
18
- "WebSearch",
19
- "WebFetch",
20
- "Agent",
21
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
- ],
13
+ tools: ["Read", "Write", "Grep", "Glob", "WebSearch", "WebFetch", "Agent"],
24
14
  body: `
25
15
  # find-venue — rank real venues by what earns the credit, then keep or switch
26
16
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs find-venue <dir>
33
- \`\`\`
34
-
35
- An advisory pass cannot be observed failing — silence is both its error state and its normal
36
- state — so starting is an event, and events get written down.
37
-
38
- The \`<dir>\` argument is **optional in spirit**: this skill can run before a paper directory exists, so
39
- pass whichever directory the work lives in, or \`.\`. The ledger row is written either way, and a plain
40
- dot is more honest than an invented path.
41
-
42
17
  Takes a paper (or the candidate venue *types* from \`research-ideate\`) and finds the best real place to
43
18
  submit it. "Best" here means **best for the publication record**, which is not the same as most prestigious —
44
19
  an indexed workshop you can actually hit beats a top conference whose deadline already closed. This
@@ -98,27 +73,6 @@ rank = credit-weight × topic-fit × accept-probability × deadline-feasibility
98
73
  already has a target) an explicit **keep** or **switch** verdict against it. Note the intended
99
74
  \`extend-paper\` upgrade target for later.
100
75
 
101
- ## Record the verdict
102
-
103
- 🔴 LAST step, once the deliverable exists:
104
-
105
- \`\`\`
106
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> FINDING <count> <report-path>
107
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> ABSTAINED <reason> "<one line>"
108
- \`\`\`
109
-
110
- 🔴 **There is no PASS.** A shortlist is a set of findings about the world, not a certificate that
111
- the venue question is settled.
112
-
113
- **FINDING** — the sweep produced a ranked shortlist with an explicit keep/switch call; \`<count>\` is
114
- the number of candidates ranked and \`<report-path>\` the comparison table. Add \`--blocking\` when
115
- nothing open clears the peer-reviewed + indexed gate — a real answer, and not an empty run.
116
- **ABSTAINED** — \`no-witness\`: CFPs were read and no candidate could be ranked either way.
117
- \`input-missing\`: there is no paper description to match venues against.
118
-
119
- Record the whole table's path, not just the winner. The next sweep starts from the candidates that were
120
- dropped and why, and a verdict with no table behind it cannot be re-checked when a deadline moves.
121
-
122
76
  ## Rules
123
77
  - Fetch every CFP fact from the real page; never invent a deadline, page limit, or indexing status.
124
78
  - Indexed + peer-reviewed is a gate, not a tiebreaker — a non-archival venue cannot win on charm.
@@ -1,24 +1,13 @@
1
1
  ---
2
2
  name: grade-paper-writing
3
3
  description: Use when asking "does this paper read well?" / "is the writing any good?" / "it reads like a wall of text and jargon" / "grade the writing" on a draft. Grades WRITING CRAFT only — nine dimensions 1–5 (Title, Abstract, Intro architecture, Structure, Prose clarity, Jargon discipline, Landing-the-point, Figure economy, Honesty-without-hedge-stacking) against how the best-written papers read (Peyton Jones, McEnerney, Gopen & Swan; exemplars Trusting Trust, Carlini, Greshake), naming the offending sentence and the fix for each. Runs the PERSONA cold-read stall pass (a committed non-academic persona subagent, per-section) whose stall inventory — not the rubric number — is the readability gate other skills consume (pc-panel-review, paper-adversarial-review, harden-paper). Defaults to a blind multi-grader panel; after fixes, mandates the claims-preservation diff (row `claims`). NOT a content/defect review (paper-adversarial-review / pc-panel-review), NOT a structural cut plan (tighten-paper — run that first on a bloated draft), NOT venue-bar content strength (study-accepted-papers). Compose with harden-paper (which calls it), draft-paper (generative counterpart), render-paper.
4
- allowed-tools: [Read, Write, Edit, Grep, Glob, Agent, Skill, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
4
+ allowed-tools: [Read, Write, Edit, Grep, Glob, Agent, Skill]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:c0907d5c98e2c831 compiled from skills/grade-paper-writing/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:c5d998b7471000fc compiled from skills/grade-paper-writing/SKILL.md.spec.ts -->
8
8
 
9
9
  # grade-paper-writing — grade how the paper READS, then fix it sentence by sentence
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs grade-paper-writing <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
  The review skills hunt scientific defects; `study-accepted-papers` checks whether the contribution clears
23
12
  the venue's bar. Neither tells you the paper is a slog to read. This skill does exactly that: it grades
24
13
  the **writing craft** against how the best-written papers actually read, and turns each low score into a
@@ -212,8 +201,7 @@ is what happened.
212
201
  side effect.
213
202
 
214
203
  7. 🔴 **Put `WORST-SECTION: <section>` on the FIRST LINE of the report.** Machine-readable, one
215
- section, lowercase, no decoration. `pipeline-check.mjs` reads the last four reports and raises
216
- `repeat-finding` when the same section is worst twice running. This exists because the abstract
204
+ section, lowercase, no decoration, so the next round can compare it with the last report. This exists because the abstract
217
205
  was named worst **five consecutive times**, was faithfully recorded in the scorecard all five
218
206
  times, and was never once the next task. A review loop that only appends findings converges on a
219
207
  paper whose defects are all thoroughly documented and none of them fixed. **Naming the worst
@@ -274,29 +262,6 @@ findings:
274
262
  ---
275
263
  ```
276
264
 
277
- ## Record the verdict
278
-
279
- 🔴 LAST step, once the deliverable exists:
280
-
281
- ```
282
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record grade-paper-writing <paper-dir> FINDING <count> <report-path>
283
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record grade-paper-writing <paper-dir> ABSTAINED <reason> "<one line>"
284
- ```
285
-
286
- **FINDING** — `<count>` is the number of entries in the PERSONA stall inventory, and `<report-path>`
287
- is that inventory. Add `--blocking` when a dimension scored 1–2, or stall density is over its cap.
288
- **ABSTAINED** — `no-witness`: the inventory came back empty. `blocked`: no persona reader was run,
289
- so there is no inventory — which is not an empty inventory and must never be filed as one.
290
-
291
- 🔴 **There is no PASS**, and the distinction the two abstentions draw is the one that was being
292
- lost: "a reader stalled nowhere" and "nobody read it" produced the same word.
293
-
294
- 🔴 **Record the stall count, never the rubric number.** The inventory is what `pc-panel-review`,
295
- `paper-adversarial-review` and `harden-paper` consume; a 44/60 in the ledger would let a paper whose
296
- readability gate is failing look clean to every skill downstream.
297
-
298
- `prose-lint.mjs` files separately as `grade-paper-writing/prose-lint`. One check, one row.
299
-
300
265
  ## Rules
301
266
  - Grade **writing, not science.** A correct paper can still score a 2 here; say so. Don't drift into
302
267
  content/defect review — that's `paper-adversarial-review` / `pc-panel-review`.
@@ -10,31 +10,10 @@ export default experimental_skill({
10
10
  name: "grade-paper-writing",
11
11
  description:
12
12
  'Use when asking "does this paper read well?" / "is the writing any good?" / "it reads like a wall of text and jargon" / "grade the writing" on a draft. Grades WRITING CRAFT only — nine dimensions 1–5 (Title, Abstract, Intro architecture, Structure, Prose clarity, Jargon discipline, Landing-the-point, Figure economy, Honesty-without-hedge-stacking) against how the best-written papers read (Peyton Jones, McEnerney, Gopen & Swan; exemplars Trusting Trust, Carlini, Greshake), naming the offending sentence and the fix for each. Runs the PERSONA cold-read stall pass (a committed non-academic persona subagent, per-section) whose stall inventory — not the rubric number — is the readability gate other skills consume (pc-panel-review, paper-adversarial-review, harden-paper). Defaults to a blind multi-grader panel; after fixes, mandates the claims-preservation diff (row `claims`). NOT a content/defect review (paper-adversarial-review / pc-panel-review), NOT a structural cut plan (tighten-paper — run that first on a bloated draft), NOT venue-bar content strength (study-accepted-papers). Compose with harden-paper (which calls it), draft-paper (generative counterpart), render-paper.',
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Edit",
17
- "Grep",
18
- "Glob",
19
- "Agent",
20
- "Skill",
21
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
- ],
13
+ tools: ["Read", "Write", "Edit", "Grep", "Glob", "Agent", "Skill"],
24
14
  body: `
25
15
  # grade-paper-writing — grade how the paper READS, then fix it sentence by sentence
26
16
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs grade-paper-writing <paper-dir>
33
- \`\`\`
34
-
35
- An advisory pass cannot be observed failing — silence is both its error state and its normal
36
- state — so starting is an event, and events get written down.
37
-
38
17
  The review skills hunt scientific defects; \`study-accepted-papers\` checks whether the contribution clears
39
18
  the venue's bar. Neither tells you the paper is a slog to read. This skill does exactly that: it grades
40
19
  the **writing craft** against how the best-written papers actually read, and turns each low score into a
@@ -228,8 +207,7 @@ is what happened.
228
207
  side effect.
229
208
 
230
209
  7. 🔴 **Put \`WORST-SECTION: <section>\` on the FIRST LINE of the report.** Machine-readable, one
231
- section, lowercase, no decoration. \`pipeline-check.mjs\` reads the last four reports and raises
232
- \`repeat-finding\` when the same section is worst twice running. This exists because the abstract
210
+ section, lowercase, no decoration, so the next round can compare it with the last report. This exists because the abstract
233
211
  was named worst **five consecutive times**, was faithfully recorded in the scorecard all five
234
212
  times, and was never once the next task. A review loop that only appends findings converges on a
235
213
  paper whose defects are all thoroughly documented and none of them fixed. **Naming the worst
@@ -290,29 +268,6 @@ findings:
290
268
  ---
291
269
  \`\`\`
292
270
 
293
- ## Record the verdict
294
-
295
- 🔴 LAST step, once the deliverable exists:
296
-
297
- \`\`\`
298
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record grade-paper-writing <paper-dir> FINDING <count> <report-path>
299
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record grade-paper-writing <paper-dir> ABSTAINED <reason> "<one line>"
300
- \`\`\`
301
-
302
- **FINDING** — \`<count>\` is the number of entries in the PERSONA stall inventory, and \`<report-path>\`
303
- is that inventory. Add \`--blocking\` when a dimension scored 1–2, or stall density is over its cap.
304
- **ABSTAINED** — \`no-witness\`: the inventory came back empty. \`blocked\`: no persona reader was run,
305
- so there is no inventory — which is not an empty inventory and must never be filed as one.
306
-
307
- 🔴 **There is no PASS**, and the distinction the two abstentions draw is the one that was being
308
- lost: "a reader stalled nowhere" and "nobody read it" produced the same word.
309
-
310
- 🔴 **Record the stall count, never the rubric number.** The inventory is what \`pc-panel-review\`,
311
- \`paper-adversarial-review\` and \`harden-paper\` consume; a 44/60 in the ledger would let a paper whose
312
- readability gate is failing look clean to every skill downstream.
313
-
314
- \`prose-lint.mjs\` files separately as \`grade-paper-writing/prose-lint\`. One check, one row.
315
-
316
271
  ## Rules
317
272
  - Grade **writing, not science.** A correct paper can still score a 2 here; say so. Don't drift into
318
273
  content/defect review — that's \`paper-adversarial-review\` / \`pc-panel-review\`.
@@ -70,7 +70,7 @@ import {
70
70
  stripFences,
71
71
  requireMarkdown,
72
72
  stripFrontmatter,
73
- } from "../../lib/markdown.mjs";
73
+ } from "#lib/markdown";
74
74
 
75
75
  // Markup is parsed with a PARSER (`CLAUDE.md`, 2026-08-11). We fail rather than degrade, even
76
76
  // though this file is advisory: without a parser the paper's body would collapse to empty, and from
@@ -692,9 +692,8 @@ for (const f of args.filter((a) => !a.startsWith("--"))) {
692
692
  // `hedge-density`, `discourse-subject`, `undefined-coinage`.
693
693
  if (lines.length) {
694
694
  flagged += lines.length;
695
- // The header STATES the count. run-mechanical.mjs prefers a stated "— N finding(s)" over
696
- // counting output lines, and without it recorded header + findings + footer: one flagged
697
- // caption became three findings in the ledger.
695
+ // The header STATES the count, so a caller need not count output lines — header and footer
696
+ // are not findings.
698
697
  console.error(
699
698
  `✍️ prose-lint — ${f.split("/").pop()} — ${lines.length} finding(s):`,
700
699
  );