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
@@ -14,17 +14,6 @@ export default experimental_skill({
14
14
  body: `
15
15
  # render-paper — .tex → PDF → readable page PNGs
16
16
 
17
- ## Run me
18
-
19
- 🔴 FIRST, before any other step:
20
-
21
- \`\`\`
22
- node .claude/skills/paper-pipeline/scripts/announce.mjs render-paper <paper-dir>
23
- \`\`\`
24
-
25
- An advisory pass cannot be observed failing — silence is both its error state and its normal
26
- state — so starting is an event, and events get written down.
27
-
28
17
  Turns a LaTeX source into (a) a compiled PDF and (b) per-page PNG images crisp enough to read
29
18
  the font on a phone. Encodes the exact toolchain and the failures already debugged, so it works
30
19
  first try.
@@ -136,31 +125,6 @@ python3 -c "import fitz; d=fitz.open('paper.pdf'); \\
136
125
  - Send the PNGs with \`SendUserFile\` (\`display: render\`) so the user can read on phone; caption what
137
126
  changed since the last render. Send the PDF too (\`display: attach\`) if they want the file.
138
127
 
139
- ## Record the verdict
140
-
141
- 🔴 LAST step, once the deliverable exists:
142
-
143
- \`\`\`
144
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> FINDING <count> <report-path>
145
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record render-paper <paper-dir> ABSTAINED <reason> "<one line>"
146
- \`\`\`
147
-
148
- 🔴 **There is no PASS**, not even here, where the temptation is strongest — an exit code of 0 from
149
- \`check-render.sh\` means the parser found no defect in the log, which is not the same as the page
150
- being right, and the delivered-PDF check exists because that difference once put \`7 x 10^13\` on
151
- page one.
152
-
153
- **FINDING** — \`check-render.sh\` exited non-zero; \`<count>\` is Overfull boxes plus undefined
154
- refs/citations and \`<report-path>\` is the log. Always \`--blocking\`: every one of these is a fact
155
- about the artifact, never a matter of taste.
156
- **ABSTAINED** — \`no-witness\`: it compiled and the log parser found nothing. \`input-missing\`: there
157
- is no \`.tex\` to compile. \`crashed\`: no LaTeX toolchain on this machine, which must never be read
158
- as a clean render.
159
-
160
- It runs twenty times a day, so the ledger fills with rows, and that is fine: each row pins a page count
161
- to a specific set of paper bytes, which is exactly what the \`tighten-paper\` structure gate is blocked
162
- on and what a remembered page count keeps getting wrong.
163
-
164
128
  ## Compose with
165
129
  - \`paper-adversarial-review\` / \`pc-panel-review\` (incl. its venue-fit mode) — review the rendered draft.`,
166
130
  });
@@ -24,7 +24,29 @@ import {
24
24
  import { tmpdir } from "node:os";
25
25
  import { dirname, join, resolve } from "node:path";
26
26
  import { fileURLToPath } from "node:url";
27
- import { createChecker } from "../../lib/check.mjs";
27
+ import { z } from "zod";
28
+ import { createChecker } from "../../lib/check.ts";
29
+ import type { ScriptResult } from "../../test/support.ts";
30
+
31
+ /** The facts file, as far as these checks read it. */
32
+ const Facts = z.looseObject({
33
+ schema: z.unknown().optional(),
34
+ pdf: z.unknown().optional(),
35
+ venue: z.unknown().optional(),
36
+ kind: z.unknown().optional(),
37
+ geometry_source: z.unknown().optional(),
38
+ columns: z.unknown().optional(),
39
+ fonts: z.unknown().optional(),
40
+ });
41
+ const Fonts = z.array(
42
+ z.looseObject({
43
+ name: z.unknown().optional(),
44
+ embedded: z.unknown().optional(),
45
+ type: z.unknown().optional(),
46
+ }),
47
+ );
48
+ const readFacts = (file: string) =>
49
+ Facts.parse(JSON.parse(readFileSync(file, "utf8")));
28
50
 
29
51
  const HERE = dirname(fileURLToPath(import.meta.url));
30
52
  const SHIM = join(HERE, "extract-pdf-facts.mjs");
@@ -37,7 +59,7 @@ const root = realpathSync(mkdtempSync(join(tmpdir(), "paperlint-extract-")));
37
59
  * Run the shim from `root`, with no banal anywhere unless `env` names one. `HOME` is the temp root:
38
60
  * without it Node falls back to the account's home, where `paperlint toolchain` may have installed banal.
39
61
  */
40
- const shim = (args, env = {}) =>
62
+ const shim = (args: readonly string[], env: Record<string, string> = {}) =>
41
63
  spawnSync(process.execPath, [SHIM, ...args], {
42
64
  cwd: root,
43
65
  encoding: "utf8",
@@ -58,7 +80,8 @@ const shim = (args, env = {}) =>
58
80
  ...env,
59
81
  },
60
82
  });
61
- const said = (r) => `${r.stdout}${r.stderr}`;
83
+ const said = (r: Pick<ScriptResult, "stdout" | "stderr">) =>
84
+ `${r.stdout}${r.stderr}`;
62
85
 
63
86
  try {
64
87
  const paper = join(root, "papers", "mixed");
@@ -92,7 +115,9 @@ try {
92
115
  /banal not found/.test(local.stderr),
93
116
  said(local),
94
117
  );
95
- const facts = JSON.parse(readFileSync(factsFile, "utf8"));
118
+ const facts = readFacts(factsFile);
119
+ const fonts = Fonts.safeParse(facts.fonts);
120
+ const fontList = fonts.success ? fonts.data : [];
96
121
  check(
97
122
  "the facts are schema 2, about paper.pdf, for the venue paperlint.json declares",
98
123
  facts.schema === 2 &&
@@ -103,10 +128,10 @@ try {
103
128
  );
104
129
  check(
105
130
  "a text PDF has fonts",
106
- Array.isArray(facts.fonts) && facts.fonts.length === 4,
131
+ fonts.success && fontList.length === 4,
107
132
  JSON.stringify(facts.fonts),
108
133
  );
109
- const times = facts.fonts.find((f) => f.name === "Times-Roman");
134
+ const times = fontList.find((f) => f.name === "Times-Roman");
110
135
  check(
111
136
  "🔴 Times-Roman — pdffonts `Type 1 Custom no no yes` — is embedded: false (the old reader said true)",
112
137
  times?.embedded === false && times.type === "Type 1",
@@ -114,7 +139,7 @@ try {
114
139
  );
115
140
  check(
116
141
  "the Type 3 font keeps poppler's type spelling, which consumers match on",
117
- facts.fonts.some((f) => f.type === "Type 3"),
142
+ fontList.some((f) => f.type === "Type 3"),
118
143
  );
119
144
 
120
145
  const fake = join(root, "banal.pl");
@@ -123,7 +148,7 @@ try {
123
148
  `print '{"papersize":[792,612],"columns":2,"bodyfontsize":9,"pages":[{}]}';\n`,
124
149
  );
125
150
  const withBanal = shim([paper, "--strict"], { BANAL: fake });
126
- const g = JSON.parse(readFileSync(factsFile, "utf8"));
151
+ const g = readFacts(factsFile);
127
152
  check(
128
153
  "--strict with banal ($BANAL): exit 0, and the geometry is banal's",
129
154
  withBanal.status === 0 && g.geometry_source === "banal" && g.columns === 2,
@@ -176,7 +201,7 @@ try {
176
201
  direct.stdout.startsWith(
177
202
  "✅ draft.pdf → papers/loose/_build/paper.facts.json (",
178
203
  ) &&
179
- JSON.parse(readFileSync(looseFacts, "utf8")).venue === null,
204
+ readFacts(looseFacts).venue === null,
180
205
  said(direct),
181
206
  );
182
207
  // The project directory IS the facts file (nonsense, but an environment can say it): the
@@ -34,7 +34,7 @@ import { spawnSync } from "node:child_process";
34
34
  import { fileURLToPath } from "node:url";
35
35
  import { dirname, join } from "node:path";
36
36
  import { checkSkill } from "../../lib/skill-checks.mjs";
37
- import { papersRoot } from "../../eslint-rules/papers.mjs";
37
+ import { papersRoot } from "#eslint-rules/papers";
38
38
  import {
39
39
  consumerRoot,
40
40
  settingsOf,
@@ -44,7 +44,7 @@ await checkSkill("render-paper");
44
44
 
45
45
  // The TeX package pins that stood here (texlive-fonts-extra, texlive-plain-generic in
46
46
  // ensure-toolchain.sh) moved with the list itself: the venue profiles declare the packages, and
47
- // src/tex-requirements.harness.mjs asserts that every acmart venue declares libertine, inconsolata,
47
+ // src/tex-requirements.harness.ts asserts that every acmart venue declares libertine, inconsolata,
48
48
  // newtx, kastrup (binhex.tex) and fancyhdr — each proved by the file whose absence broke a build.
49
49
 
50
50
  // ── TEXINPUTS: WHERE THE SCRIPTS LOOK FOR `paper-guards.tex` ─────────────────
@@ -1,28 +1,13 @@
1
1
  ---
2
2
  name: research-ideate
3
3
  description: "Decide whether a research idea is worth doing at all — before any work goes into it. Use when someone has an idea and asks: is this worth pursuing, should we take it on, is it a paper or just a blog post, is there a quick minimal result that doesn't need a dramatic finding, will it pull us away from our main line of work. Returns a go / no-go verdict with the sharpest framing, the minimal finding and the kinds of venue that would take it. Judges the idea by what counts in a body of work: a peer-reviewed indexed publication, a reusable method or benchmark rather than a one-off \"tool X is bad\", onward citations rather than GitHub stars, and one connected line rather than scattered topics. Stage: conception, before find-venue and before any draft; hands off to find-venue, build-benchmark, draft-paper."
4
- allowed-tools: [Read, Write, 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, Grep, Glob, Agent, Skill]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:f0ccfb74162bca40 compiled from skills/research-ideate/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:03a0131d306d7ab0 compiled from skills/research-ideate/SKILL.md.spec.ts -->
8
8
 
9
9
  # research-ideate — is this idea worth a paper, and does the paper earn authorship credit?
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs research-ideate <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
  Runs BEFORE any effort is spent. An idea can be interesting and still be a bad *publication*
27
12
  investment — the wrong framing produces something un-publishable or un-citable, which counts for
28
13
  nothing toward a body of work. This skill kills those ideas early and reshapes the survivors into the framing
@@ -87,28 +72,6 @@ Emit a compact verdict:
87
72
  e.g. "security-of-AI-coding workshop @ a top-tier security conference," "SE-measurement workshop @
88
73
  ASE/FSE," "eval/benchmark track." Hand these to `find-venue`.
89
74
 
90
- ## Record the verdict
91
-
92
- 🔴 LAST step, once the deliverable exists:
93
-
94
- ```
95
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record research-ideate <dir> FINDING <count> <report-path>
96
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record research-ideate <dir> ABSTAINED <reason> "<one line>"
97
- ```
98
-
99
- 🔴 **There is no PASS**, so there is no way to write down "go" as a value. A clean go is the
100
- absence of findings across the axes, and whoever wants to call it a go says so themselves.
101
-
102
- **FINDING** — go with reshaping, where `<count>` is the number of axes that need it and
103
- `<report-path>` is the output. Add `--blocking` for a no-go: axis (a) is a hard stop, not a weight,
104
- and a no-go is the loudest finding this skill produces.
105
- **ABSTAINED** — `no-witness`: all axes were scored and none needed reshaping. `blocked`: the idea
106
- was too vague to score, which is a different thing from a no-go and must not be recorded as one.
107
-
108
- A recorded no-go is the cheapest artifact in this whole pipeline, and the one most often lost: an idea
109
- killed in conversation comes back three months later wearing a different name, and nothing in the repo
110
- remembers that it was already judged.
111
-
112
75
  ## Rules
113
76
  - Axis (a) is a gate, not a weight — no indexed peer review, no idea. Everything else reshapes.
114
77
  - Never justify an idea by GitHub stars, demo virality, or "it'd be a great blog post." Those don't
@@ -10,34 +10,10 @@ export default experimental_skill({
10
10
  name: "research-ideate",
11
11
  description:
12
12
  'Decide whether a research idea is worth doing at all — before any work goes into it. Use when someone has an idea and asks: is this worth pursuing, should we take it on, is it a paper or just a blog post, is there a quick minimal result that doesn\'t need a dramatic finding, will it pull us away from our main line of work. Returns a go / no-go verdict with the sharpest framing, the minimal finding and the kinds of venue that would take it. Judges the idea by what counts in a body of work: a peer-reviewed indexed publication, a reusable method or benchmark rather than a one-off "tool X is bad", onward citations rather than GitHub stars, and one connected line rather than scattered topics. Stage: conception, before find-venue and before any draft; hands off to find-venue, build-benchmark, draft-paper.',
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Grep",
17
- "Glob",
18
- "Agent",
19
- "Skill",
20
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
21
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
22
- ],
13
+ tools: ["Read", "Write", "Grep", "Glob", "Agent", "Skill"],
23
14
  body: `
24
15
  # research-ideate — is this idea worth a paper, and does the paper earn authorship credit?
25
16
 
26
- ## Run me
27
-
28
- 🔴 FIRST, before any other step:
29
-
30
- \`\`\`
31
- node .claude/skills/paper-pipeline/scripts/announce.mjs research-ideate <dir>
32
- \`\`\`
33
-
34
- An advisory pass cannot be observed failing — silence is both its error state and its normal
35
- state — so starting is an event, and events get written down.
36
-
37
- The \`<dir>\` argument is **optional in spirit**: this skill can run before a paper directory exists, so
38
- pass whichever directory the work lives in, or \`.\`. The ledger row is written either way, and a plain
39
- dot is more honest than an invented path.
40
-
41
17
  Runs BEFORE any effort is spent. An idea can be interesting and still be a bad *publication*
42
18
  investment — the wrong framing produces something un-publishable or un-citable, which counts for
43
19
  nothing toward a body of work. This skill kills those ideas early and reshapes the survivors into the framing
@@ -102,28 +78,6 @@ Emit a compact verdict:
102
78
  e.g. "security-of-AI-coding workshop @ a top-tier security conference," "SE-measurement workshop @
103
79
  ASE/FSE," "eval/benchmark track." Hand these to \`find-venue\`.
104
80
 
105
- ## Record the verdict
106
-
107
- 🔴 LAST step, once the deliverable exists:
108
-
109
- \`\`\`
110
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record research-ideate <dir> FINDING <count> <report-path>
111
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record research-ideate <dir> ABSTAINED <reason> "<one line>"
112
- \`\`\`
113
-
114
- 🔴 **There is no PASS**, so there is no way to write down "go" as a value. A clean go is the
115
- absence of findings across the axes, and whoever wants to call it a go says so themselves.
116
-
117
- **FINDING** — go with reshaping, where \`<count>\` is the number of axes that need it and
118
- \`<report-path>\` is the output. Add \`--blocking\` for a no-go: axis (a) is a hard stop, not a weight,
119
- and a no-go is the loudest finding this skill produces.
120
- **ABSTAINED** — \`no-witness\`: all axes were scored and none needed reshaping. \`blocked\`: the idea
121
- was too vague to score, which is a different thing from a no-go and must not be recorded as one.
122
-
123
- A recorded no-go is the cheapest artifact in this whole pipeline, and the one most often lost: an idea
124
- killed in conversation comes back three months later wearing a different name, and nothing in the repo
125
- remembers that it was already judged.
126
-
127
81
  ## Rules
128
82
  - Axis (a) is a gate, not a weight — no indexed peer review, no idea. Everything else reshapes.
129
83
  - Never justify an idea by GitHub stars, demo virality, or "it'd be a great blog post." Those don't
@@ -5,21 +5,10 @@ context: fork
5
5
  allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch, Agent]
6
6
  ---
7
7
 
8
- <!-- vigiles:sha256:177ca8805990361e compiled from skills/study-accepted-papers/SKILL.md.spec.ts -->
8
+ <!-- vigiles:sha256:e199b342e4e98338 compiled from skills/study-accepted-papers/SKILL.md.spec.ts -->
9
9
 
10
10
  # study-accepted-papers — learn the venue's bar from its own accepted corpus, then lever your draft up
11
11
 
12
- ## Run me
13
-
14
- 🔴 FIRST, before any other step:
15
-
16
- ```
17
- node .claude/skills/paper-pipeline/scripts/announce.mjs study-accepted-papers <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
-
23
12
  Reviewers don't score in a vacuum — they score against the papers that got in last cycle. This skill
24
13
  makes that reference standard explicit: pull the venue's **actually-accepted** papers of your type,
25
14
  extract the concrete properties that separated the strong ones from the weak-accepts, and diff your
@@ -157,28 +146,6 @@ being violated, and the **things previously believed that the corpus disproved**
157
146
  valuable lines in the file, because without them the pipeline re-derives the wrong belief). Keep it
158
147
  short enough that it survives being loaded into every session.
159
148
 
160
- ## Record the verdict
161
-
162
- 🔴 LAST step, once the deliverable exists:
163
-
164
- ```
165
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record study-accepted-papers <paper-dir> FINDING <count> <report-path>
166
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record study-accepted-papers <paper-dir> ABSTAINED <reason> "<one line>"
167
- ```
168
-
169
- **FINDING** — `<count>` is the number of levers, `<report-path>` the ranked CHEAP/EXPENSIVE list.
170
- Add `--blocking` when the draft is missing something the track *requires* (an artifact link, a named
171
- benchmark, a metric definition): a desk-reject, never a weak accept, and worth the loudest thing
172
- this skill can say.
173
- **ABSTAINED** — `no-witness`: the corpus was read and no lever came out of it. `input-missing`: the
174
- venue publishes no accepted papers to mine.
175
-
176
- 🔴 **There is no PASS**, and the reason is visible here. "The draft already sits at the venue's bar"
177
- is only meaningful next to the corpus it was measured against — *33 of 34 accepted papers*, not
178
- *most of them* — and a stored acquittal carried that denominator nowhere. Put the corpus size in the
179
- `ABSTAINED` note and in the report; without it the row is an impression with a machine-readable
180
- label on it.
181
-
182
149
  ## Rules
183
150
  - **Fetch real accepted papers.** Never fabricate a title, author, or "what made it strong". Unverifiable → drop or mark VERIFY.
184
151
  - **A lever-proposed citation is not written into the `.tex`/bib until `verify-citations` confirms it** (real
@@ -25,17 +25,6 @@ export default experimental_skill({
25
25
  body: `
26
26
  # study-accepted-papers — learn the venue's bar from its own accepted corpus, then lever your draft up
27
27
 
28
- ## Run me
29
-
30
- 🔴 FIRST, before any other step:
31
-
32
- \`\`\`
33
- node .claude/skills/paper-pipeline/scripts/announce.mjs study-accepted-papers <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
28
  Reviewers don't score in a vacuum — they score against the papers that got in last cycle. This skill
40
29
  makes that reference standard explicit: pull the venue's **actually-accepted** papers of your type,
41
30
  extract the concrete properties that separated the strong ones from the weak-accepts, and diff your
@@ -173,28 +162,6 @@ being violated, and the **things previously believed that the corpus disproved**
173
162
  valuable lines in the file, because without them the pipeline re-derives the wrong belief). Keep it
174
163
  short enough that it survives being loaded into every session.
175
164
 
176
- ## Record the verdict
177
-
178
- 🔴 LAST step, once the deliverable exists:
179
-
180
- \`\`\`
181
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record study-accepted-papers <paper-dir> FINDING <count> <report-path>
182
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record study-accepted-papers <paper-dir> ABSTAINED <reason> "<one line>"
183
- \`\`\`
184
-
185
- **FINDING** — \`<count>\` is the number of levers, \`<report-path>\` the ranked CHEAP/EXPENSIVE list.
186
- Add \`--blocking\` when the draft is missing something the track *requires* (an artifact link, a named
187
- benchmark, a metric definition): a desk-reject, never a weak accept, and worth the loudest thing
188
- this skill can say.
189
- **ABSTAINED** — \`no-witness\`: the corpus was read and no lever came out of it. \`input-missing\`: the
190
- venue publishes no accepted papers to mine.
191
-
192
- 🔴 **There is no PASS**, and the reason is visible here. "The draft already sits at the venue's bar"
193
- is only meaningful next to the corpus it was measured against — *33 of 34 accepted papers*, not
194
- *most of them* — and a stored acquittal carried that denominator nowhere. Put the corpus size in the
195
- \`ABSTAINED\` note and in the report; without it the row is an impression with a machine-readable
196
- label on it.
197
-
198
165
  ## Rules
199
166
  - **Fetch real accepted papers.** Never fabricate a title, author, or "what made it strong". Unverifiable → drop or mark VERIFY.
200
167
  - **A lever-proposed citation is not written into the \`.tex\`/bib until \`verify-citations\` confirms it** (real
@@ -4,21 +4,10 @@ description: End-to-end playbook for submitting a peer-reviewed paper to a doubl
4
4
  allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch, Skill]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:4a42424fd18098e5 compiled from skills/submit-paper/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:9e57bcb2ba1fb055 compiled from skills/submit-paper/SKILL.md.spec.ts -->
8
8
 
9
9
  # submit-paper — get a reviewed paper from "done" to "ready for review"
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs submit-paper <paper-dir>
17
- ```
18
-
19
- An advisory pass cannot be observed failing — silence is both its error state and its normal
20
- state — so starting is an event, and events get written down.
21
-
22
11
  Assumes the paper is already hardened (run `pc-panel-review` — incl. its venue-fit mode — +
23
12
  `paper-adversarial-review` first). This skill is the submission mechanics — the part that bit us with
24
13
  avoidable friction the first time. Distilled from the AgenticDev 2026 submission.
@@ -155,27 +144,6 @@ the file inside was the wrong build (340 952 B vs the real 352 357 B). It surfac
155
144
  cited `L. 166` and there was nothing to resolve the line against. A folder without a checker is a
156
145
  convention with no reader.
157
146
 
158
- ## 8. Record the verdict
159
-
160
- 🔴 LAST step, once the deliverable exists:
161
-
162
- ```
163
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> FINDING <count> <report-path>
164
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> ABSTAINED <reason> "<one line>"
165
- ```
166
-
167
- **FINDING** — `check-deanon.sh` exited non-zero, `access` is not green, the PDF is over the limit, or
168
- the ready-for-review click never happened; `<count>` is the number of blocking items and
169
- `<report-path>` names them. Always `--blocking` — every item here stops the submission.
170
- **ABSTAINED** — `no-witness`: uploaded **and** marked ready for review, with the venue card or the
171
- submission id in the note. `blocked`: the portal account is not through moderation yet.
172
-
173
- 🔴 **A saved draft must never be recorded as done — and it now cannot be.** A saved-but-not-submitted
174
- paper is the one failure this skill's provenance names by hand, and it was invisible to every other
175
- check in the pipeline. There is no constructor for "submitted"; there is only the absence of blocking
176
- items, plus a submission id in the note that a human can go and look up. The id IS the witness, and
177
- recording `no-witness` without one is the same lie in a new vocabulary.
178
-
179
147
  ## Compose with
180
148
  - Harden first: `pc-panel-review` (incl. its venue-fit mode), `paper-adversarial-review`, `render-paper`.
181
149
  - Publisher mechanics (camera-ready): `references/publishers/<publisher>.md`.
@@ -24,17 +24,6 @@ export default experimental_skill({
24
24
  body: `
25
25
  # submit-paper — get a reviewed paper from "done" to "ready for review"
26
26
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs submit-paper <paper-dir>
33
- \`\`\`
34
-
35
- An advisory pass cannot be observed failing — silence is both its error state and its normal
36
- state — so starting is an event, and events get written down.
37
-
38
27
  Assumes the paper is already hardened (run \`pc-panel-review\` — incl. its venue-fit mode — +
39
28
  \`paper-adversarial-review\` first). This skill is the submission mechanics — the part that bit us with
40
29
  avoidable friction the first time. Distilled from the AgenticDev 2026 submission.
@@ -171,27 +160,6 @@ the file inside was the wrong build (340 952 B vs the real 352 357 B). It surfac
171
160
  cited \`L. 166\` and there was nothing to resolve the line against. A folder without a checker is a
172
161
  convention with no reader.
173
162
 
174
- ## 8. Record the verdict
175
-
176
- 🔴 LAST step, once the deliverable exists:
177
-
178
- \`\`\`
179
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> FINDING <count> <report-path>
180
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record submit-paper <paper-dir> ABSTAINED <reason> "<one line>"
181
- \`\`\`
182
-
183
- **FINDING** — \`check-deanon.sh\` exited non-zero, \`access\` is not green, the PDF is over the limit, or
184
- the ready-for-review click never happened; \`<count>\` is the number of blocking items and
185
- \`<report-path>\` names them. Always \`--blocking\` — every item here stops the submission.
186
- **ABSTAINED** — \`no-witness\`: uploaded **and** marked ready for review, with the venue card or the
187
- submission id in the note. \`blocked\`: the portal account is not through moderation yet.
188
-
189
- 🔴 **A saved draft must never be recorded as done — and it now cannot be.** A saved-but-not-submitted
190
- paper is the one failure this skill's provenance names by hand, and it was invisible to every other
191
- check in the pipeline. There is no constructor for "submitted"; there is only the absence of blocking
192
- items, plus a submission id in the note that a human can go and look up. The id IS the witness, and
193
- recording \`no-witness\` without one is the same lie in a new vocabulary.
194
-
195
163
  ## Compose with
196
164
  - Harden first: \`pc-panel-review\` (incl. its venue-fit mode), \`paper-adversarial-review\`, \`render-paper\`.
197
165
  - Publisher mechanics (camera-ready): \`references/publishers/<publisher>.md\`.
@@ -5,25 +5,10 @@ context: fork
5
5
  allowed-tools: [WebSearch, WebFetch, Read, Write, Grep, Glob, Bash, Agent]
6
6
  ---
7
7
 
8
- <!-- vigiles:sha256:1822c8c01e352f42 compiled from skills/sweep-design-space/SKILL.md.spec.ts -->
8
+ <!-- vigiles:sha256:46cb38ac1731883d compiled from skills/sweep-design-space/SKILL.md.spec.ts -->
9
9
 
10
10
  # sweep-design-space — stop circling, sweep
11
11
 
12
- ## Run me
13
-
14
- 🔴 FIRST, before any other step:
15
-
16
- ```
17
- node .claude/skills/paper-pipeline/scripts/announce.mjs sweep-design-space <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
-
23
- The `<dir>` argument is **optional in spirit**: this skill can run before a paper directory exists, so
24
- pass whichever directory the work lives in, or `.`. The ledger row is written either way, and a plain
25
- dot is more honest than an invented path.
26
-
27
12
  A model asked for "a solution" returns the three designs nearest its training prior, then variations of
28
13
  those, then variations of the variations. The user experiences this as *"you are thinking very narrowly"* —
29
14
  and they are right. The fix is not to think harder in place; it is to **sweep named source domains on
@@ -214,28 +199,6 @@ assurance levels already exist; the question is whether anyone has carried them
214
199
 
215
200
  ---
216
201
 
217
- ## Record the verdict
218
-
219
- 🔴 LAST step, once the deliverable exists:
220
-
221
- ```
222
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record sweep-design-space <dir> FINDING <count> <report-path>
223
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record sweep-design-space <dir> ABSTAINED <reason> "<one line>"
224
- ```
225
-
226
- 🔴 **There is no PASS.** A sweep that turns up survivors has not certified anything; it has found
227
- candidates, and candidates are findings.
228
-
229
- **FINDING** — the sweep produced something to act on; `<count>` is the number of survivors and
230
- `<report-path>` the sweep, including the groups that yielded nothing. Add `--blocking` when the
231
- whole sweep died on the filters — that is the loudest thing this skill can say.
232
- **ABSTAINED** — `no-witness`: the sweep ran and neither found a survivor nor established that none
233
- exists. `blocked`: there was no problem statement to sweep against.
234
-
235
- The skill's own rules already say negative results count. The ledger is how that survives the session:
236
- a recorded finding names the groups that were swept, so the next sweep starts from named constructs
237
- instead of from memory — which is the failure mode this skill exists to break.
238
-
239
202
  ## Rules
240
203
 
241
204
  - **Name the forbidden options in the generation brief.** Without an explicit "do not return these"
@@ -24,21 +24,6 @@ export default experimental_skill({
24
24
  body: `
25
25
  # sweep-design-space — stop circling, sweep
26
26
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs sweep-design-space <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
27
  A model asked for "a solution" returns the three designs nearest its training prior, then variations of
43
28
  those, then variations of the variations. The user experiences this as *"you are thinking very narrowly"* —
44
29
  and they are right. The fix is not to think harder in place; it is to **sweep named source domains on
@@ -229,28 +214,6 @@ assurance levels already exist; the question is whether anyone has carried them
229
214
 
230
215
  ---
231
216
 
232
- ## Record the verdict
233
-
234
- 🔴 LAST step, once the deliverable exists:
235
-
236
- \`\`\`
237
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record sweep-design-space <dir> FINDING <count> <report-path>
238
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record sweep-design-space <dir> ABSTAINED <reason> "<one line>"
239
- \`\`\`
240
-
241
- 🔴 **There is no PASS.** A sweep that turns up survivors has not certified anything; it has found
242
- candidates, and candidates are findings.
243
-
244
- **FINDING** — the sweep produced something to act on; \`<count>\` is the number of survivors and
245
- \`<report-path>\` the sweep, including the groups that yielded nothing. Add \`--blocking\` when the
246
- whole sweep died on the filters — that is the loudest thing this skill can say.
247
- **ABSTAINED** — \`no-witness\`: the sweep ran and neither found a survivor nor established that none
248
- exists. \`blocked\`: there was no problem statement to sweep against.
249
-
250
- The skill's own rules already say negative results count. The ledger is how that survives the session:
251
- a recorded finding names the groups that were swept, so the next sweep starts from named constructs
252
- instead of from memory — which is the failure mode this skill exists to break.
253
-
254
217
  ## Rules
255
218
 
256
219
  - **Name the forbidden options in the generation brief.** Without an explicit "do not return these"