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
@@ -0,0 +1,78 @@
1
+ /**
2
+ * `npm test`'s runner: both suites run whatever the first returned, each failure is named, and
3
+ * the harness arguments reach the harness runner only.
4
+ */
5
+ import assert from "node:assert/strict";
6
+ import { test } from "vitest";
7
+ import { runSuites, SUITES, type Spawn } from "./test.ts";
8
+
9
+ /** A spawn that records every call and exits with `status[file]` (`null` for a signal). */
10
+ const fake = (status: Record<string, number | null>) => {
11
+ const calls: string[][] = [];
12
+ const spawn: Spawn = (file, args) => {
13
+ calls.push([file, ...args]);
14
+ return { status: status[file] ?? null };
15
+ };
16
+ return { calls, spawn };
17
+ };
18
+
19
+ test("a failing vitest does not skip the harnesses, and is named as the failure", () => {
20
+ const { calls, spawn } = fake({ vitest: 1, vigiles: 0 });
21
+ const said: string[] = [];
22
+ assert.equal(
23
+ runSuites(["--no-skip"], { spawn, err: (s) => said.push(s) }),
24
+ 1,
25
+ );
26
+ assert.deepEqual(calls, [
27
+ ["vitest", "run"],
28
+ ["vigiles", "test", "--min=1", "--no-skip"],
29
+ ]);
30
+ assert.deepEqual(said, [
31
+ "✗ vitest failed (exit 1) — its own report is above",
32
+ ]);
33
+ });
34
+
35
+ test("both passing is 0 and silent; a harness killed by a signal is exit 1, named", () => {
36
+ const ok = fake({ vitest: 0, vigiles: 0 });
37
+ assert.equal(runSuites([], { spawn: ok.spawn, err: assert.fail }), 0);
38
+ const killed = fake({ vitest: 0, vigiles: null });
39
+ const said: string[] = [];
40
+ assert.equal(
41
+ runSuites([], { spawn: killed.spawn, err: (s) => said.push(s) }),
42
+ 1,
43
+ );
44
+ assert.deepEqual(said, [
45
+ "✗ harnesses failed (exit 1) — its own report is above",
46
+ ]);
47
+ assert.deepEqual(
48
+ SUITES.map((s) => s.name),
49
+ ["vitest", "harnesses"],
50
+ );
51
+ });
52
+
53
+ test("every suite runs the SOURCES: the paperlint-source condition is in NODE_OPTIONS, the caller's kept", () => {
54
+ const seen: (string | undefined)[] = [];
55
+ const spawn: Spawn = (_file, _args, options) => {
56
+ seen.push(options.env.NODE_OPTIONS);
57
+ return { status: 0 };
58
+ };
59
+ assert.equal(
60
+ runSuites([], {
61
+ spawn,
62
+ err: assert.fail,
63
+ env: { NODE_OPTIONS: "--import=./x.ts" },
64
+ }),
65
+ 0,
66
+ );
67
+ assert.deepEqual(seen, [
68
+ "--conditions=paperlint-source --import=./x.ts",
69
+ "--conditions=paperlint-source --import=./x.ts",
70
+ ]);
71
+ // Without a caller's NODE_OPTIONS there is no stray trailing space.
72
+ seen.length = 0;
73
+ runSuites([], { spawn, err: assert.fail, env: {} });
74
+ assert.deepEqual(seen, [
75
+ "--conditions=paperlint-source",
76
+ "--conditions=paperlint-source",
77
+ ]);
78
+ });
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `npm test`: the unit tests (vitest), then the harnesses (`vigiles test`). BOTH always run.
3
+ *
4
+ * Until #52 this was `vitest run && vigiles test --min=1`. Under `npm run coverage` a single
5
+ * failing vitest test then skipped every harness, and what the run printed last was c8's summary:
6
+ * lines, branches and functions each some six points below the floor. The one failing test sat
7
+ * above that, looking like a consequence rather than the cause. Running both suites keeps the
8
+ * coverage report whole, so a failing test is reported as itself and the coverage figures still
9
+ * mean what they say.
10
+ *
11
+ * Arguments are the harness runner's (`npm test -- --no-skip`), as they were before.
12
+ *
13
+ * Both suites run the SOURCES: every child gets `--conditions=paperlint-source`, so `#lib/*` and
14
+ * `#eslint-rules/*` resolve to `.ts`, not to `dist/`. This runner is the one owner of that
15
+ * setting. When only `npm run coverage` passed it, a plain `npm test` loaded the rules twice —
16
+ * `dist/` through `eslint.config.mjs`, `.ts` through the harness — and a harness comparing the two
17
+ * failed on macOS CI, the one job that runs `npm test` bare.
18
+ */
19
+ import { spawnSync } from "node:child_process";
20
+ import { isMain } from "../skills/paper-pipeline/scripts/consumer.mjs";
21
+
22
+ /** The two suites, in order: what a failure is named as, and the command. */
23
+ export interface Suite {
24
+ readonly name: string;
25
+ /** The program, then its arguments. */
26
+ readonly command: readonly [string, ...string[]];
27
+ }
28
+
29
+ /** What `runSuites` needs from a finished process: its exit status, `null` when a signal ended it. */
30
+ export type Spawn = (
31
+ file: string,
32
+ args: readonly string[],
33
+ options: { stdio: "inherit"; env: NodeJS.ProcessEnv },
34
+ ) => { readonly status: number | null };
35
+
36
+ /** The condition that points package `imports` at the TypeScript sources instead of `dist/`. */
37
+ const SOURCE_CONDITION = "--conditions=paperlint-source";
38
+
39
+ /** `env` with the source condition first in NODE_OPTIONS, whatever the caller already had kept. */
40
+ export function withSources(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
41
+ const own = env.NODE_OPTIONS?.trim();
42
+ return {
43
+ ...env,
44
+ NODE_OPTIONS: own ? `${SOURCE_CONDITION} ${own}` : SOURCE_CONDITION,
45
+ };
46
+ }
47
+
48
+ export const SUITES: readonly Suite[] = [
49
+ { name: "vitest", command: ["vitest", "run"] },
50
+ { name: "harnesses", command: ["vigiles", "test", "--min=1"] },
51
+ ];
52
+
53
+ /**
54
+ * Run every suite, whatever the one before it returned, and name the ones that failed.
55
+ * @returns 0 when every suite passed; otherwise the first failing suite's exit code (1 for a signal).
56
+ */
57
+ export function runSuites(
58
+ args: readonly string[],
59
+ {
60
+ spawn = spawnSync,
61
+ err = console.error,
62
+ suites = SUITES,
63
+ env = process.env,
64
+ }: {
65
+ spawn?: Spawn;
66
+ err?: (line: string) => void;
67
+ suites?: readonly Suite[];
68
+ env?: NodeJS.ProcessEnv;
69
+ } = {},
70
+ ): number {
71
+ const failed = suites.flatMap(({ name, command }) => {
72
+ const [file, ...rest] = command;
73
+ const r = spawn(file, [...rest, ...(name === "harnesses" ? args : [])], {
74
+ stdio: "inherit",
75
+ env: withSources(env),
76
+ });
77
+ return r.status === 0 ? [] : [{ name, code: r.status ?? 1 }];
78
+ });
79
+ for (const f of failed)
80
+ err(
81
+ `✗ ${f.name} failed (exit ${String(f.code)}) — its own report is above`,
82
+ );
83
+ const [first] = failed;
84
+ return first === undefined ? 0 : first.code;
85
+ }
86
+
87
+ if (isMain(import.meta.url)) process.exit(runSuites(process.argv.slice(2)));
@@ -5,24 +5,10 @@ context: fork
5
5
  allowed-tools: [WebSearch, WebFetch, Read, Write, Grep, Glob, Bash, Agent]
6
6
  ---
7
7
 
8
- <!-- vigiles:sha256:f528cbe9e892d6d0 compiled from skills/analyze-sibling-paper/SKILL.md.spec.ts -->
8
+ <!-- vigiles:sha256:238796152df07749 compiled from skills/analyze-sibling-paper/SKILL.md.spec.ts -->
9
9
 
10
10
  # analyze-sibling-paper — settle "isn't this just X?" before a reviewer does
11
11
 
12
- ## Run me
13
-
14
- 🔴 FIRST, before any other step:
15
-
16
- ```
17
- node .claude/skills/paper-pipeline/scripts/announce.mjs analyze-sibling-paper <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
- The `<paper-dir>` argument is **your** paper, not the sibling — the row belongs to the paper being
24
- defended. The sibling is named by `<report-path>` when the verdict is recorded.
25
-
26
12
  When a paper close to yours surfaces, the wrong move is to cite it from its abstract and move on — that
27
13
  leaves a scoop risk you can't see and a reviewer can. This skill reads the *actual* competitor, judges
28
14
  whether your contribution genuinely differs, and produces a saved analysis with concrete action points
@@ -114,30 +100,6 @@ and the action points (with the exact clause text to add/replace). Per the save-
114
100
  analysis that lives only in a chat is lost the moment the session ends — and it's exactly what you'll need
115
101
  again at rebuttal. **A close sibling with no file in `<paper-dir>/siblings/` is an unfinished analysis.**
116
102
 
117
- ## Record the verdict
118
-
119
- 🔴 LAST step, once the deliverable exists:
120
-
121
- ```
122
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record analyze-sibling-paper <paper-dir> FINDING <count> <report-path>
123
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record analyze-sibling-paper <paper-dir> ABSTAINED <reason> "<one line>"
124
- ```
125
-
126
- **FINDING** — `<count>` is the number of action points the card produced (positioning clauses plus
127
- *MUST CITE* entries), `<report-path>` is the saved card, which names the sibling. Add `--blocking`
128
- for a genuine scoop, which the skill already treats as an escalation rather than a clause.
129
- **ABSTAINED** — `no-witness`: the sibling was read in full and the delta needs no text to change.
130
- `blocked`: the sibling's full text could not be obtained, so only its abstract was seen — which is
131
- explicitly not an analysis and must never be recorded as one.
132
-
133
- 🔴 **There is no PASS.** "The delta is real" read identically whether the sibling had been read
134
- whole or skimmed, and this skill's own first rule is that an abstract-only delta is not a verdict.
135
- `no-witness` and `blocked` now say which happened.
136
-
137
- One row per sibling analysed, filed under its own `--check=<sibling-slug>`; several finding rows
138
- against one paper is the normal shape here, not a check that keeps failing. Before 2026-08-10 they
139
- would have overwritten one another.
140
-
141
103
  ## Rules
142
104
  - **Read the paper, not the abstract.** An abstract-only "delta" is not a verdict — and the card must
143
105
  say so: `read: abstract` in its frontmatter, and which parts in its `**Read:**` line.
@@ -24,20 +24,6 @@ export default experimental_skill({
24
24
  body: `
25
25
  # analyze-sibling-paper — settle "isn't this just X?" before a reviewer does
26
26
 
27
- ## Run me
28
-
29
- 🔴 FIRST, before any other step:
30
-
31
- \`\`\`
32
- node .claude/skills/paper-pipeline/scripts/announce.mjs analyze-sibling-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
- The \`<paper-dir>\` argument is **your** paper, not the sibling — the row belongs to the paper being
39
- defended. The sibling is named by \`<report-path>\` when the verdict is recorded.
40
-
41
27
  When a paper close to yours surfaces, the wrong move is to cite it from its abstract and move on — that
42
28
  leaves a scoop risk you can't see and a reviewer can. This skill reads the *actual* competitor, judges
43
29
  whether your contribution genuinely differs, and produces a saved analysis with concrete action points
@@ -129,30 +115,6 @@ and the action points (with the exact clause text to add/replace). Per the save-
129
115
  analysis that lives only in a chat is lost the moment the session ends — and it's exactly what you'll need
130
116
  again at rebuttal. **A close sibling with no file in \`<paper-dir>/siblings/\` is an unfinished analysis.**
131
117
 
132
- ## Record the verdict
133
-
134
- 🔴 LAST step, once the deliverable exists:
135
-
136
- \`\`\`
137
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record analyze-sibling-paper <paper-dir> FINDING <count> <report-path>
138
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record analyze-sibling-paper <paper-dir> ABSTAINED <reason> "<one line>"
139
- \`\`\`
140
-
141
- **FINDING** — \`<count>\` is the number of action points the card produced (positioning clauses plus
142
- *MUST CITE* entries), \`<report-path>\` is the saved card, which names the sibling. Add \`--blocking\`
143
- for a genuine scoop, which the skill already treats as an escalation rather than a clause.
144
- **ABSTAINED** — \`no-witness\`: the sibling was read in full and the delta needs no text to change.
145
- \`blocked\`: the sibling's full text could not be obtained, so only its abstract was seen — which is
146
- explicitly not an analysis and must never be recorded as one.
147
-
148
- 🔴 **There is no PASS.** "The delta is real" read identically whether the sibling had been read
149
- whole or skimmed, and this skill's own first rule is that an abstract-only delta is not a verdict.
150
- \`no-witness\` and \`blocked\` now say which happened.
151
-
152
- One row per sibling analysed, filed under its own \`--check=<sibling-slug>\`; several finding rows
153
- against one paper is the normal shape here, not a check that keeps failing. Before 2026-08-10 they
154
- would have overwritten one another.
155
-
156
118
  ## Rules
157
119
  - **Read the paper, not the abstract.** An abstract-only "delta" is not a verdict — and the card must
158
120
  say so: \`read: abstract\` in its frontmatter, and which parts in its \`**Read:**\` line.
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: argument-arc
3
3
  description: Build or repair the paper's argument architecture — the one-sentence-per-section outline, the bottom-up inevitability pass, and the name/number budget. Run it when the reader says the paper throws ideas at them, when a structural objection repeats, or before any large rewrite. Not a prose or length skill.
4
- allowed-tools: [Read, Write, Grep, Glob, 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, Agent]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:05a1eaa79bb596d5 compiled from skills/argument-arc/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:66be3161e5bde916 compiled from skills/argument-arc/SKILL.md.spec.ts -->
8
8
 
9
9
  # argument-arc — does the paper carry the reader to one conclusion
10
10
 
@@ -14,17 +14,6 @@ allowed-tools: [Read, Write, Grep, Glob, Agent, Bash(node .claude/skills/paper-p
14
14
  > whether the argument exists. Run it *before* them — cutting words inside a broken arc is how a
15
15
  > session burns a day and ships the same paper.
16
16
 
17
- ## Run me
18
-
19
- 🔴 FIRST, before any other step:
20
-
21
- ```
22
- node .claude/skills/paper-pipeline/scripts/announce.mjs argument-arc <paper-dir>
23
- ```
24
-
25
- An advisory pass cannot be observed failing — silence is both its error state and its normal
26
- state — so starting is an event, and events get written down.
27
-
28
17
  The failure it exists to catch has a signature: every paragraph is defensible, every number is real,
29
18
  and the reader still finishes the section unable to say what it was for. That is not a prose problem
30
19
  and no amount of rewriting sentences fixes it.
@@ -48,7 +37,6 @@ came out — which is how a run gets thrown away. That is not hypothetical: it w
48
37
  data is collected costs the data. Costs a paragraph; saves a study.**
49
38
 
50
39
  `build-benchmark` reads this paragraph before designing, and refuses to proceed if `frame` is empty.
51
- `pipeline-check.mjs` reports a study that ran with no stated claim.
52
40
 
53
41
  *Added 2026-08-03 alongside the replacement of the numbered stage list — this skill previously existed
54
42
  only as a repair, which meant nobody stated the claim while stating it was still cheap.*
@@ -125,28 +113,6 @@ most needs help. This skill does:
125
113
  the calendar against it is a category error.
126
114
  - **Rebuild produces a new outline through steps 1–4 above, and it too gets shown before editing.**
127
115
 
128
- ## Record the verdict
129
-
130
- 🔴 LAST step, once the deliverable exists:
131
-
132
- ```
133
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record argument-arc <paper-dir> FINDING <count> <report-path>
134
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record argument-arc <paper-dir> ABSTAINED <reason> "<one line>"
135
- ```
136
-
137
- 🔴 **There is no PASS.** "The arc carries the reader" is not a value this pass can write down; it is
138
- what a reader may conclude from the absence of findings, and the concluding is theirs.
139
-
140
- **FINDING** — the arc is broken; `<count>` is the number of sections the new outline moves, merges
141
- or deletes, and `<report-path>` is that outline. Add `--blocking` when there is no conclusion
142
- sentence to build an arc from: that refusal is a finding about the draft, not an aborted run, and
143
- `<report-path>` is the one-line statement of what is missing.
144
- **ABSTAINED** — `no-witness`: the outline was read end to end and nothing moved. `blocked`: there
145
- was no outline to read at all.
146
-
147
- An `ABSTAINED no-witness` on a draft the author has twice called a pile is a missed finding, and
148
- `status.mjs` will start asking about a check that has only ever abstained.
149
-
150
116
  ## Rules
151
117
 
152
118
  - **The arc is judged on the outline, never on the draft.** If you find yourself rereading paragraphs
@@ -10,15 +10,7 @@ export default experimental_skill({
10
10
  name: "argument-arc",
11
11
  description:
12
12
  "Build or repair the paper's argument architecture — the one-sentence-per-section outline, the bottom-up inevitability pass, and the name/number budget. Run it when the reader says the paper throws ideas at them, when a structural objection repeats, or before any large rewrite. Not a prose or length skill.",
13
- tools: [
14
- "Read",
15
- "Write",
16
- "Grep",
17
- "Glob",
18
- "Agent",
19
- "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
20
- "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
21
- ],
13
+ tools: ["Read", "Write", "Grep", "Glob", "Agent"],
22
14
  body: `
23
15
  # argument-arc — does the paper carry the reader to one conclusion
24
16
 
@@ -28,17 +20,6 @@ export default experimental_skill({
28
20
  > whether the argument exists. Run it *before* them — cutting words inside a broken arc is how a
29
21
  > session burns a day and ships the same paper.
30
22
 
31
- ## Run me
32
-
33
- 🔴 FIRST, before any other step:
34
-
35
- \`\`\`
36
- node .claude/skills/paper-pipeline/scripts/announce.mjs argument-arc <paper-dir>
37
- \`\`\`
38
-
39
- An advisory pass cannot be observed failing — silence is both its error state and its normal
40
- state — so starting is an event, and events get written down.
41
-
42
23
  The failure it exists to catch has a signature: every paragraph is defensible, every number is real,
43
24
  and the reader still finishes the section unable to say what it was for. That is not a prose problem
44
25
  and no amount of rewriting sentences fixes it.
@@ -62,7 +43,6 @@ came out — which is how a run gets thrown away. That is not hypothetical: it w
62
43
  data is collected costs the data. Costs a paragraph; saves a study.**
63
44
 
64
45
  \`build-benchmark\` reads this paragraph before designing, and refuses to proceed if \`frame\` is empty.
65
- \`pipeline-check.mjs\` reports a study that ran with no stated claim.
66
46
 
67
47
  *Added 2026-08-03 alongside the replacement of the numbered stage list — this skill previously existed
68
48
  only as a repair, which meant nobody stated the claim while stating it was still cheap.*
@@ -139,28 +119,6 @@ most needs help. This skill does:
139
119
  the calendar against it is a category error.
140
120
  - **Rebuild produces a new outline through steps 1–4 above, and it too gets shown before editing.**
141
121
 
142
- ## Record the verdict
143
-
144
- 🔴 LAST step, once the deliverable exists:
145
-
146
- \`\`\`
147
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record argument-arc <paper-dir> FINDING <count> <report-path>
148
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record argument-arc <paper-dir> ABSTAINED <reason> "<one line>"
149
- \`\`\`
150
-
151
- 🔴 **There is no PASS.** "The arc carries the reader" is not a value this pass can write down; it is
152
- what a reader may conclude from the absence of findings, and the concluding is theirs.
153
-
154
- **FINDING** — the arc is broken; \`<count>\` is the number of sections the new outline moves, merges
155
- or deletes, and \`<report-path>\` is that outline. Add \`--blocking\` when there is no conclusion
156
- sentence to build an arc from: that refusal is a finding about the draft, not an aborted run, and
157
- \`<report-path>\` is the one-line statement of what is missing.
158
- **ABSTAINED** — \`no-witness\`: the outline was read end to end and nothing moved. \`blocked\`: there
159
- was no outline to read at all.
160
-
161
- An \`ABSTAINED no-witness\` on a draft the author has twice called a pile is a missed finding, and
162
- \`status.mjs\` will start asking about a check that has only ever abstained.
163
-
164
122
  ## Rules
165
123
 
166
124
  - **The arc is judged on the outline, never on the draft.** If you find yourself rereading paragraphs
@@ -5,21 +5,10 @@ context: fork
5
5
  allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, Agent]
6
6
  ---
7
7
 
8
- <!-- vigiles:sha256:067ada6f8aa44d5b compiled from skills/build-benchmark/SKILL.md.spec.ts -->
8
+ <!-- vigiles:sha256:0b91129ca6a6b2a3 compiled from skills/build-benchmark/SKILL.md.spec.ts -->
9
9
 
10
10
  # build-benchmark — the study + the artifact reviewers can run
11
11
 
12
- ## Run me
13
-
14
- 🔴 FIRST, before any other step:
15
-
16
- ```
17
- node .claude/skills/paper-pipeline/scripts/announce.mjs build-benchmark <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
  A measurement paper is only as strong as the artifact a reviewer can `cd` into and re-run. This skill
24
13
  covers both halves: the study design that makes the finding true, and the self-checking artifact that
25
14
  makes it *verifiable*. The contribution is the **method**, not the one tool you happened to test — build
@@ -163,35 +152,6 @@ real-code-through-real-contract execution reveals it.
163
152
  Before submitting, verify the artifact you built with the reviewer-side reproduction protocol:
164
153
  **`references/adversarial-cold-repro.md`** (cold re-run, three-way reconcile, robustness attacks).
165
154
 
166
- ## Record the verdict
167
-
168
- 🔴 LAST step, once the deliverable exists:
169
-
170
- ```
171
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> FINDING <count> <report-path>
172
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> ABSTAINED <reason> "<one line>"
173
- ```
174
-
175
- 🔴 **There is no PASS.** An artifact that recomputes every headline number and exits 0 has produced
176
- no finding; it has not certified the study. Record the absence, do not name it a success.
177
-
178
- **FINDING** — `<count>` numbers did not reproduce, or reproduce only with caveats; `<report-path>`
179
- is the artifact output. Add `--blocking` for the §0 refusal: `frame` is empty, so the study was not
180
- designed.
181
- **ABSTAINED** — `no-witness`: the artifact ran and every number reproduced. `input-missing`: the
182
- raw data is not in the repo. `crashed`: the harness itself died.
183
-
184
- 🔴 That §0 refusal is a **finding, not an aborted run** — it is a fact about the work, so it is a
185
- FINDING and not an abstention. Record it and stop. A study that was never designed leaves exactly
186
- the same silence as one that is still running, and the difference costs a week to rediscover.
187
-
188
- 🔴 **THREE MECHANICAL CHECKS FILE UNDER THIS SKILL** and each has its own ledger row:
189
- `build-benchmark/check-provenance`, `build-benchmark/arm-permutation`,
190
- `build-benchmark/delivered-pdf` (see `.claude/skills/paper-pipeline/scripts/run-mechanical.mjs`). Until 2026-08-10 the
191
- ledger keyed on the SKILL, so a clean run of one erased a finding of another from every derived
192
- view — which is why two of the three sat unwired. This block records the JUDGEMENT pass, under the
193
- bare key `build-benchmark`; never file a mechanical result here.
194
-
195
155
  ## Compose with
196
156
  - **argument-arc (frame mode)** — 🔴 **hard input.** Owns row `frame`, the stated claim. No `frame`, no study.
197
157
  - **research-ideate** (upstream) — supplies the contribution and the pitfall to invert; this skill turns
@@ -15,17 +15,6 @@ export default experimental_skill({
15
15
  body: `
16
16
  # build-benchmark — the study + the artifact reviewers can run
17
17
 
18
- ## Run me
19
-
20
- 🔴 FIRST, before any other step:
21
-
22
- \`\`\`
23
- node .claude/skills/paper-pipeline/scripts/announce.mjs build-benchmark <paper-dir>
24
- \`\`\`
25
-
26
- An advisory pass cannot be observed failing — silence is both its error state and its normal
27
- state — so starting is an event, and events get written down.
28
-
29
18
  A measurement paper is only as strong as the artifact a reviewer can \`cd\` into and re-run. This skill
30
19
  covers both halves: the study design that makes the finding true, and the self-checking artifact that
31
20
  makes it *verifiable*. The contribution is the **method**, not the one tool you happened to test — build
@@ -169,35 +158,6 @@ real-code-through-real-contract execution reveals it.
169
158
  Before submitting, verify the artifact you built with the reviewer-side reproduction protocol:
170
159
  **\`references/adversarial-cold-repro.md\`** (cold re-run, three-way reconcile, robustness attacks).
171
160
 
172
- ## Record the verdict
173
-
174
- 🔴 LAST step, once the deliverable exists:
175
-
176
- \`\`\`
177
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> FINDING <count> <report-path>
178
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record build-benchmark <paper-dir> ABSTAINED <reason> "<one line>"
179
- \`\`\`
180
-
181
- 🔴 **There is no PASS.** An artifact that recomputes every headline number and exits 0 has produced
182
- no finding; it has not certified the study. Record the absence, do not name it a success.
183
-
184
- **FINDING** — \`<count>\` numbers did not reproduce, or reproduce only with caveats; \`<report-path>\`
185
- is the artifact output. Add \`--blocking\` for the §0 refusal: \`frame\` is empty, so the study was not
186
- designed.
187
- **ABSTAINED** — \`no-witness\`: the artifact ran and every number reproduced. \`input-missing\`: the
188
- raw data is not in the repo. \`crashed\`: the harness itself died.
189
-
190
- 🔴 That §0 refusal is a **finding, not an aborted run** — it is a fact about the work, so it is a
191
- FINDING and not an abstention. Record it and stop. A study that was never designed leaves exactly
192
- the same silence as one that is still running, and the difference costs a week to rediscover.
193
-
194
- 🔴 **THREE MECHANICAL CHECKS FILE UNDER THIS SKILL** and each has its own ledger row:
195
- \`build-benchmark/check-provenance\`, \`build-benchmark/arm-permutation\`,
196
- \`build-benchmark/delivered-pdf\` (see \`.claude/skills/paper-pipeline/scripts/run-mechanical.mjs\`). Until 2026-08-10 the
197
- ledger keyed on the SKILL, so a clean run of one erased a finding of another from every derived
198
- view — which is why two of the three sat unwired. This block records the JUDGEMENT pass, under the
199
- bare key \`build-benchmark\`; never file a mechanical result here.
200
-
201
161
  ## Compose with
202
162
  - **argument-arc (frame mode)** — 🔴 **hard input.** Owns row \`frame\`, the stated claim. No \`frame\`, no study.
203
163
  - **research-ideate** (upstream) — supplies the contribution and the pitfall to invert; this skill turns
@@ -4,21 +4,10 @@ description: On acceptance, turn the anonymized-for-review paper into the de-ano
4
4
  allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch]
5
5
  ---
6
6
 
7
- <!-- vigiles:sha256:8fa0190054cc5314 compiled from skills/camera-ready/SKILL.md.spec.ts -->
7
+ <!-- vigiles:sha256:5c85ef4004c31956 compiled from skills/camera-ready/SKILL.md.spec.ts -->
8
8
 
9
9
  # camera-ready — de-anonymize an accepted paper into the final proceedings version
10
10
 
11
- ## Run me
12
-
13
- 🔴 FIRST, before any other step:
14
-
15
- ```
16
- node .claude/skills/paper-pipeline/scripts/announce.mjs camera-ready <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 reviewed PDF was anonymized on purpose. Acceptance flips that: the camera-ready carries your
23
12
  real name, your real repo, and an archival DOI — and it's the version that gets indexed, so it's the
24
13
  actual authorship evidence. This skill is the reverse of the anonymization you did at
@@ -113,28 +102,6 @@ If tight, ACM allows references to spill into the reference-only extra pages.
113
102
  - Record the paper's DOI, the artifact DOI, and the ORCID in the paper's HANDOFF — those three IDs are
114
103
  the authorship evidence and the anchor the extension (`extend-paper`) builds on.
115
104
 
116
- ## 6. Record the verdict
117
-
118
- 🔴 LAST step, once the deliverable exists:
119
-
120
- ```
121
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> FINDING <count> <report-path>
122
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> ABSTAINED <reason> "<one line>"
123
- ```
124
-
125
- **FINDING** — `<count>` residual items still open; `<report-path>` names them. Add `--blocking` for
126
- anything that must not be pushed past: anonymization residue, a dead artifact link, or — on a
127
- security paper — disclosure not yet complete.
128
- **ABSTAINED** — `no-witness`: shipped, de-anonymized, DOI live, page limit re-checked, with the DOI
129
- in the note. `blocked`: the acceptance notice has not arrived, so there is nothing to make ready.
130
-
131
- 🔴 That blocking finding is the only one in this pipeline whose consequence is **irreversible**. The
132
- public de-anonymized repo is Google-findable the moment it is pushed, so record it before, not after.
133
-
134
- 🔴 **There is no PASS**, and on this skill that is not a formality: a stored "shipped" would have
135
- been the one row in the pipeline that could be true of a repo nobody had looked at. The DOI in the
136
- note is the witness. Without it there is nothing to check the row against.
137
-
138
105
  ## Compose with
139
106
  - **submit-paper** (upstream — this reverses what it anonymized).
140
107
  - **paper-pipeline/references/anonymization.md** — the canonical list of anonymization moves; undo each.
@@ -23,17 +23,6 @@ export default experimental_skill({
23
23
  body: `
24
24
  # camera-ready — de-anonymize an accepted paper into the final proceedings version
25
25
 
26
- ## Run me
27
-
28
- 🔴 FIRST, before any other step:
29
-
30
- \`\`\`
31
- node .claude/skills/paper-pipeline/scripts/announce.mjs camera-ready <paper-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
26
  The reviewed PDF was anonymized on purpose. Acceptance flips that: the camera-ready carries your
38
27
  real name, your real repo, and an archival DOI — and it's the version that gets indexed, so it's the
39
28
  actual authorship evidence. This skill is the reverse of the anonymization you did at
@@ -128,28 +117,6 @@ If tight, ACM allows references to spill into the reference-only extra pages.
128
117
  - Record the paper's DOI, the artifact DOI, and the ORCID in the paper's HANDOFF — those three IDs are
129
118
  the authorship evidence and the anchor the extension (\`extend-paper\`) builds on.
130
119
 
131
- ## 6. Record the verdict
132
-
133
- 🔴 LAST step, once the deliverable exists:
134
-
135
- \`\`\`
136
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> FINDING <count> <report-path>
137
- node .claude/skills/paper-pipeline/scripts/ledger.mjs record camera-ready <paper-dir> ABSTAINED <reason> "<one line>"
138
- \`\`\`
139
-
140
- **FINDING** — \`<count>\` residual items still open; \`<report-path>\` names them. Add \`--blocking\` for
141
- anything that must not be pushed past: anonymization residue, a dead artifact link, or — on a
142
- security paper — disclosure not yet complete.
143
- **ABSTAINED** — \`no-witness\`: shipped, de-anonymized, DOI live, page limit re-checked, with the DOI
144
- in the note. \`blocked\`: the acceptance notice has not arrived, so there is nothing to make ready.
145
-
146
- 🔴 That blocking finding is the only one in this pipeline whose consequence is **irreversible**. The
147
- public de-anonymized repo is Google-findable the moment it is pushed, so record it before, not after.
148
-
149
- 🔴 **There is no PASS**, and on this skill that is not a formality: a stored "shipped" would have
150
- been the one row in the pipeline that could be true of a repo nobody had looked at. The DOI in the
151
- note is the witness. Without it there is nothing to check the row against.
152
-
153
120
  ## Compose with
154
121
  - **submit-paper** (upstream — this reverses what it anonymized).
155
122
  - **paper-pipeline/references/anonymization.md** — the canonical list of anonymization moves; undo each.