paperlint 3.2.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/.github/workflows/ci.yml +16 -23
  2. package/CLAUDE.md +33 -13
  3. package/CONTRIBUTING.md +23 -7
  4. package/README.md +11 -8
  5. package/dist/adapters/banal/failure.d.ts +1 -7
  6. package/dist/adapters/banal/failure.d.ts.map +1 -1
  7. package/dist/adapters/banal/failure.js +5 -7
  8. package/dist/adapters/banal/failure.js.map +1 -1
  9. package/dist/adapters/banal/index.d.ts.map +1 -1
  10. package/dist/adapters/banal/index.js +8 -11
  11. package/dist/adapters/banal/index.js.map +1 -1
  12. package/dist/adapters/banal/install.d.ts.map +1 -1
  13. package/dist/adapters/banal/install.js +4 -3
  14. package/dist/adapters/banal/install.js.map +1 -1
  15. package/dist/adapters/banal/invocation.d.ts +10 -5
  16. package/dist/adapters/banal/invocation.d.ts.map +1 -1
  17. package/dist/adapters/banal/invocation.js +13 -1
  18. package/dist/adapters/banal/invocation.js.map +1 -1
  19. package/dist/adapters/banal/locate.d.ts +12 -9
  20. package/dist/adapters/banal/locate.d.ts.map +1 -1
  21. package/dist/adapters/banal/locate.js +19 -12
  22. package/dist/adapters/banal/locate.js.map +1 -1
  23. package/dist/adapters/banal/run.d.ts +10 -1
  24. package/dist/adapters/banal/run.d.ts.map +1 -1
  25. package/dist/adapters/banal/run.js +8 -4
  26. package/dist/adapters/banal/run.js.map +1 -1
  27. package/dist/adapters/banal/settings.d.ts +1 -1
  28. package/dist/adapters/banal/settings.d.ts.map +1 -1
  29. package/dist/adapters/banal/settings.js +2 -1
  30. package/dist/adapters/banal/settings.js.map +1 -1
  31. package/dist/adapters/latex/document-class.d.ts +22 -0
  32. package/dist/adapters/latex/document-class.d.ts.map +1 -0
  33. package/dist/adapters/latex/document-class.js +102 -0
  34. package/dist/adapters/latex/document-class.js.map +1 -0
  35. package/dist/adapters/latex/hidden.d.ts +16 -0
  36. package/dist/adapters/latex/hidden.d.ts.map +1 -0
  37. package/dist/adapters/latex/hidden.js +49 -0
  38. package/dist/adapters/latex/hidden.js.map +1 -0
  39. package/dist/adapters/latex/index.d.ts +29 -0
  40. package/dist/adapters/latex/index.d.ts.map +1 -0
  41. package/dist/adapters/latex/index.js +18 -0
  42. package/dist/adapters/latex/index.js.map +1 -0
  43. package/dist/adapters/latex/nodes.d.ts +54 -0
  44. package/dist/adapters/latex/nodes.d.ts.map +1 -0
  45. package/dist/adapters/latex/nodes.js +93 -0
  46. package/dist/adapters/latex/nodes.js.map +1 -0
  47. package/dist/adapters/latex/outline.d.ts +10 -0
  48. package/dist/adapters/latex/outline.d.ts.map +1 -0
  49. package/dist/adapters/latex/outline.js +39 -0
  50. package/dist/adapters/latex/outline.js.map +1 -0
  51. package/dist/adapters/latex/parse.d.ts +42 -0
  52. package/dist/adapters/latex/parse.d.ts.map +1 -0
  53. package/dist/adapters/latex/parse.js +94 -0
  54. package/dist/adapters/latex/parse.js.map +1 -0
  55. package/dist/adapters/latex/rendered.d.ts +10 -0
  56. package/dist/adapters/latex/rendered.d.ts.map +1 -0
  57. package/dist/adapters/latex/rendered.js +39 -0
  58. package/dist/adapters/latex/rendered.js.map +1 -0
  59. package/dist/adapters/memory/index.d.ts.map +1 -1
  60. package/dist/adapters/memory/index.js +8 -2
  61. package/dist/adapters/memory/index.js.map +1 -1
  62. package/dist/adapters/node/process.io.d.ts +6 -3
  63. package/dist/adapters/node/process.io.d.ts.map +1 -1
  64. package/dist/adapters/node/process.io.js.map +1 -1
  65. package/dist/adapters/node/workspace.io.d.ts.map +1 -1
  66. package/dist/adapters/node/workspace.io.js +4 -2
  67. package/dist/adapters/node/workspace.io.js.map +1 -1
  68. package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
  69. package/dist/adapters/pdfjs/fill.js +12 -12
  70. package/dist/adapters/pdfjs/fill.js.map +1 -1
  71. package/dist/adapters/references/index.d.ts.map +1 -1
  72. package/dist/adapters/references/index.js +4 -2
  73. package/dist/adapters/references/index.js.map +1 -1
  74. package/dist/build-engine.d.ts +1 -1
  75. package/dist/build-engine.d.ts.map +1 -1
  76. package/dist/build-engine.js +8 -1
  77. package/dist/build-engine.js.map +1 -1
  78. package/dist/build.d.ts +2 -3
  79. package/dist/build.d.ts.map +1 -1
  80. package/dist/build.js +9 -10
  81. package/dist/build.js.map +1 -1
  82. package/dist/caller-path.d.ts +3 -0
  83. package/dist/caller-path.d.ts.map +1 -0
  84. package/dist/caller-path.js +13 -0
  85. package/dist/caller-path.js.map +1 -0
  86. package/dist/cli.d.ts +10 -17
  87. package/dist/cli.d.ts.map +1 -1
  88. package/dist/cli.js +91 -17
  89. package/dist/cli.js.map +1 -1
  90. package/dist/doctor.d.ts +12 -3
  91. package/dist/doctor.d.ts.map +1 -1
  92. package/dist/doctor.js +2 -1
  93. package/dist/doctor.js.map +1 -1
  94. package/dist/domain/paths.d.ts +8 -2
  95. package/dist/domain/paths.d.ts.map +1 -1
  96. package/dist/domain/paths.js +12 -1
  97. package/dist/domain/paths.js.map +1 -1
  98. package/dist/domain/ready.d.ts +24 -0
  99. package/dist/domain/ready.d.ts.map +1 -0
  100. package/dist/domain/ready.js +11 -0
  101. package/dist/domain/ready.js.map +1 -0
  102. package/dist/domain/record.d.ts +8 -0
  103. package/dist/domain/record.d.ts.map +1 -0
  104. package/dist/domain/record.js +8 -0
  105. package/dist/domain/record.js.map +1 -0
  106. package/dist/domain/sha256.d.ts.map +1 -1
  107. package/dist/domain/sha256.js +4 -2
  108. package/dist/domain/sha256.js.map +1 -1
  109. package/dist/domain/tex-document.d.ts +84 -0
  110. package/dist/domain/tex-document.d.ts.map +1 -0
  111. package/dist/domain/tex-document.js +43 -0
  112. package/dist/domain/tex-document.js.map +1 -0
  113. package/dist/engine.d.ts +23 -22
  114. package/dist/engine.d.ts.map +1 -1
  115. package/dist/engine.js.map +1 -1
  116. package/dist/eslint-rules/bib-reachable-entry.d.ts +1 -1
  117. package/dist/eslint-rules/bib-reachable-entry.js.map +1 -1
  118. package/dist/eslint-rules/install-path-literals.d.ts +2 -2
  119. package/dist/eslint-rules/install-path-literals.js.map +1 -1
  120. package/dist/eslint-rules/paper-research-question.d.ts +1 -1
  121. package/dist/eslint-rules/paper-research-question.js.map +1 -1
  122. package/dist/eslint-rules/paper-stages.d.ts +2 -2
  123. package/dist/eslint-rules/paper-stages.js.map +1 -1
  124. package/dist/eslint-rules/paper-typography.d.ts +6 -6
  125. package/dist/eslint-rules/paper-typography.js.map +1 -1
  126. package/dist/eslint-rules/pdf-last-page-balance.d.ts +1 -1
  127. package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -1
  128. package/dist/eslint-rules/review-frontmatter.d.ts +2 -2
  129. package/dist/eslint-rules/review-frontmatter.js.map +1 -1
  130. package/dist/eslint-rules/sibling-frontmatter.d.ts +1 -1
  131. package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -1
  132. package/dist/eslint-rules/temp-root-realpath.d.ts +1 -1
  133. package/dist/eslint-rules/temp-root-realpath.js.map +1 -1
  134. package/dist/eslint-rules/tex-build.d.ts +2 -2
  135. package/dist/eslint-rules/tex-build.js.map +1 -1
  136. package/dist/facts-file.d.ts.map +1 -1
  137. package/dist/facts-file.js +31 -28
  138. package/dist/facts-file.js.map +1 -1
  139. package/dist/hooks-settings.d.ts.map +1 -1
  140. package/dist/hooks-settings.js +17 -2
  141. package/dist/hooks-settings.js.map +1 -1
  142. package/dist/init.d.ts +3 -4
  143. package/dist/init.d.ts.map +1 -1
  144. package/dist/init.js +18 -8
  145. package/dist/init.js.map +1 -1
  146. package/dist/lib/paper-config.d.ts.map +1 -1
  147. package/dist/lib/paper-config.js +1 -5
  148. package/dist/lib/paper-config.js.map +1 -1
  149. package/dist/new-paper.d.ts +5 -0
  150. package/dist/new-paper.d.ts.map +1 -1
  151. package/dist/new-paper.js +8 -1
  152. package/dist/new-paper.js.map +1 -1
  153. package/dist/package-dirs.d.ts +5 -0
  154. package/dist/package-dirs.d.ts.map +1 -0
  155. package/dist/package-dirs.js +14 -0
  156. package/dist/package-dirs.js.map +1 -0
  157. package/dist/paper-files.d.ts +4 -4
  158. package/dist/paper-files.d.ts.map +1 -1
  159. package/dist/paper-files.js +6 -6
  160. package/dist/paper-files.js.map +1 -1
  161. package/dist/paper-settings.js +3 -3
  162. package/dist/paper-settings.js.map +1 -1
  163. package/dist/pdf-facts.d.ts +51 -1
  164. package/dist/pdf-facts.d.ts.map +1 -1
  165. package/dist/pdf-facts.js +23 -15
  166. package/dist/pdf-facts.js.map +1 -1
  167. package/dist/pdf-geometry.d.ts.map +1 -1
  168. package/dist/pdf-geometry.js +2 -3
  169. package/dist/pdf-geometry.js.map +1 -1
  170. package/dist/ports/latex.d.ts +24 -0
  171. package/dist/ports/latex.d.ts.map +1 -0
  172. package/dist/ports/latex.js +2 -0
  173. package/dist/ports/latex.js.map +1 -0
  174. package/dist/ports/tool-installer.d.ts +2 -14
  175. package/dist/ports/tool-installer.d.ts.map +1 -1
  176. package/dist/presets.d.ts +15 -2
  177. package/dist/presets.d.ts.map +1 -1
  178. package/dist/presets.js +35 -10
  179. package/dist/presets.js.map +1 -1
  180. package/dist/references.d.ts.map +1 -1
  181. package/dist/references.js +4 -4
  182. package/dist/references.js.map +1 -1
  183. package/dist/rules-config.d.ts +26 -1
  184. package/dist/rules-config.d.ts.map +1 -1
  185. package/dist/rules-config.js +9 -9
  186. package/dist/rules-config.js.map +1 -1
  187. package/dist/tex-requirements.d.ts +15 -0
  188. package/dist/tex-requirements.d.ts.map +1 -1
  189. package/dist/tex-requirements.js +28 -10
  190. package/dist/tex-requirements.js.map +1 -1
  191. package/dist/tex-venue-rules.d.ts +83 -0
  192. package/dist/tex-venue-rules.d.ts.map +1 -0
  193. package/dist/tex-venue-rules.js +254 -0
  194. package/dist/tex-venue-rules.js.map +1 -0
  195. package/dist/types.d.ts +5 -3
  196. package/dist/types.d.ts.map +1 -1
  197. package/dist/venue-rules.d.ts +1 -1
  198. package/dist/venue-rules.d.ts.map +1 -1
  199. package/dist/venue-rules.js +20 -7
  200. package/dist/venue-rules.js.map +1 -1
  201. package/docs/configuration.md +5 -4
  202. package/docs/e2e.md +69 -40
  203. package/docs/install.md +1 -1
  204. package/docs/prior-art/README.md +1 -1
  205. package/docs/prior-art/package-location.md +5 -5
  206. package/docs/prior-art/repro/README.md +1 -1
  207. package/docs/prior-art/test-tooling.md +21 -10
  208. package/docs/rules/tex/required-section.md +73 -0
  209. package/docs/rules/tex/template.md +62 -0
  210. package/docs/rules/tex/venue-leftover.md +71 -0
  211. package/docs/rules.md +70 -48
  212. package/docs/testing.md +17 -4
  213. package/docs/texlive-install-decision.md +1 -1
  214. package/docs/toolchain.md +2 -2
  215. package/eslint-rules/bib-reachable-entry.ts +1 -1
  216. package/eslint-rules/install-path-literals.ts +2 -2
  217. package/eslint-rules/paper-research-question.ts +1 -1
  218. package/eslint-rules/paper-stages.ts +2 -2
  219. package/eslint-rules/paper-typography.ts +2 -2
  220. package/eslint-rules/pdf-last-page-balance.ts +1 -1
  221. package/eslint-rules/review-frontmatter.ts +1 -1
  222. package/eslint-rules/temp-root-realpath.ts +1 -1
  223. package/eslint-rules/tex-build.ts +2 -2
  224. package/eslint.config.mjs +162 -15
  225. package/fixtures/build-e2e/acmart/expect.json +26 -0
  226. package/fixtures/build-e2e/aidc/PIPELINE-STATUS.md +3 -0
  227. package/fixtures/build-e2e/aidc/expect.json +14 -0
  228. package/fixtures/build-e2e/aidc/paper.tex +46 -0
  229. package/fixtures/build-e2e/aidc/paperlint.json +1 -0
  230. package/fixtures/build-e2e/broken/expect.json +11 -0
  231. package/fixtures/build-e2e/cite/expect.json +27 -0
  232. package/fixtures/build-e2e/empty/expect.json +12 -0
  233. package/fixtures/build-e2e/fallback/expect.json +53 -0
  234. package/fixtures/build-e2e/guards/expect.json +6 -0
  235. package/fixtures/build-e2e/no-source/expect.json +10 -0
  236. package/fixtures/build-e2e/unbalanced/expect.json +60 -0
  237. package/fixtures/install-path-literals/clean.fixture.mjs +1 -1
  238. package/fixtures/install-path-literals/clean.md +2 -2
  239. package/fixtures/install-path-literals/defect.fixture.mjs +1 -1
  240. package/fixtures/install-path-literals/defect.md +2 -2
  241. package/fixtures/pdf-facts/README.md +1 -1
  242. package/fixtures/real-markdown-paper/baseline.ts +1 -1
  243. package/fixtures/render-paper/build-clean.sh +3 -5
  244. package/hooks/paper-status-gates.sh +9 -19
  245. package/lib/paper-config.harness.mjs +1 -1
  246. package/lib/paper-config.ts +1 -5
  247. package/lib/skill-checks.mjs +24 -381
  248. package/lib/skill-checks.test.mjs +63 -115
  249. package/lib/skill-corpus.mjs +10 -251
  250. package/lib/skill-corpus.test.mjs +2 -13
  251. package/lib/skill-trigger-cases.mjs +1 -1
  252. package/package.json +13 -2
  253. package/{skills/submit-paper/references/venues → presets}/acm-sigconf.jsonc +4 -1
  254. package/{skills/submit-paper/references/venues → presets}/agenticdev.jsonc +4 -0
  255. package/presets/aidc.jsonc +73 -0
  256. package/{skills/submit-paper/references/venues → presets}/aisec.jsonc +4 -0
  257. package/presets/ieee-conference.jsonc +66 -0
  258. package/{skills/submit-paper/references/venues → presets}/realm.jsonc +8 -1
  259. package/{skills/submit-paper/references/venues → presets/tex}/paper-guards.tex +1 -1
  260. package/{skills/submit-paper/references/venues → presets}/venue-profile.schema.json +30 -2
  261. package/scripts/check.harness.ts +64 -10
  262. package/scripts/check.test.ts +60 -13
  263. package/scripts/check.ts +83 -30
  264. package/scripts/coverage-config.test.ts +0 -1
  265. package/scripts/harness-api.frozen.json +0 -1
  266. package/scripts/test.test.ts +1 -1
  267. package/scripts/test.ts +1 -1
  268. package/skills/analyze-sibling-paper/SKILL.md +1 -39
  269. package/skills/analyze-sibling-paper/SKILL.md.spec.ts +0 -38
  270. package/skills/argument-arc/SKILL.md +2 -36
  271. package/skills/argument-arc/SKILL.md.spec.ts +1 -43
  272. package/skills/build-benchmark/SKILL.md +1 -41
  273. package/skills/build-benchmark/SKILL.md.spec.ts +0 -40
  274. package/skills/camera-ready/SKILL.md +1 -34
  275. package/skills/camera-ready/SKILL.md.spec.ts +0 -33
  276. package/skills/cold-read-diff/SKILL.md +1 -35
  277. package/skills/cold-read-diff/SKILL.md.spec.ts +0 -34
  278. package/skills/draft-paper/SKILL.md +2 -41
  279. package/skills/draft-paper/SKILL.md.spec.ts +1 -50
  280. package/skills/extend-paper/SKILL.md +2 -33
  281. package/skills/extend-paper/SKILL.md.spec.ts +1 -42
  282. package/skills/find-venue/SKILL.md +2 -38
  283. package/skills/find-venue/SKILL.md.spec.ts +1 -47
  284. package/skills/grade-paper-writing/SKILL.md +3 -38
  285. package/skills/grade-paper-writing/SKILL.md.spec.ts +2 -47
  286. package/skills/grade-paper-writing/prose-lint.mjs +2 -3
  287. package/skills/grade-paper-writing/prose-lint.test.ts +1 -1
  288. package/skills/harden-paper/SKILL.md +1 -39
  289. package/skills/harden-paper/SKILL.md.spec.ts +0 -38
  290. package/skills/map-prior-work/SKILL.md +1 -35
  291. package/skills/map-prior-work/SKILL.md.spec.ts +0 -34
  292. package/skills/osf-artifact-upload/osf-artifact-upload.harness.ts +3 -4
  293. package/skills/paper-adversarial-review/SKILL.md +2 -35
  294. package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -43
  295. package/skills/paper-pipeline/PIPELINE-MAP.md +2 -2
  296. package/skills/paper-pipeline/SKILL.md +3 -29
  297. package/skills/paper-pipeline/SKILL.md.spec.ts +2 -28
  298. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1 -1
  299. package/skills/paper-pipeline/paper-pipeline.harness.mjs +25 -40
  300. package/skills/paper-pipeline/references/acceptance-gate.md +1 -6
  301. package/skills/paper-pipeline/references/pipeline-status-template.md +8 -35
  302. package/skills/paper-pipeline/scripts/README.md +30 -225
  303. package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +4 -8
  304. package/skills/paper-pipeline/scripts/consumer.d.mts +0 -2
  305. package/skills/paper-pipeline/scripts/consumer.harness.mjs +6 -104
  306. package/skills/paper-pipeline/scripts/consumer.mjs +24 -119
  307. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +2 -3
  308. package/skills/paper-pipeline/scripts/population-map.harness.mjs +3 -3
  309. package/skills/paper-status/SKILL.md +2 -42
  310. package/skills/paper-status/SKILL.md.spec.ts +1 -41
  311. package/skills/pc-panel-review/SKILL.md +2 -46
  312. package/skills/pc-panel-review/SKILL.md.spec.ts +1 -45
  313. package/skills/plan-paper-timeline/SKILL.md +2 -36
  314. package/skills/plan-paper-timeline/SKILL.md.spec.ts +0 -36
  315. package/skills/render-paper/SKILL.md +2 -38
  316. package/skills/render-paper/SKILL.md.spec.ts +1 -37
  317. package/skills/render-paper/check-render.sh +16 -63
  318. package/skills/render-paper/render-paper.harness.mjs +17 -59
  319. package/skills/research-ideate/SKILL.md +2 -39
  320. package/skills/research-ideate/SKILL.md.spec.ts +1 -47
  321. package/skills/study-accepted-papers/SKILL.md +1 -34
  322. package/skills/study-accepted-papers/SKILL.md.spec.ts +0 -33
  323. package/skills/submit-paper/SKILL.md +1 -33
  324. package/skills/submit-paper/SKILL.md.spec.ts +0 -32
  325. package/skills/sweep-design-space/SKILL.md +1 -38
  326. package/skills/sweep-design-space/SKILL.md.spec.ts +0 -37
  327. package/skills/tighten-paper/SKILL.md +2 -39
  328. package/skills/tighten-paper/SKILL.md.spec.ts +1 -47
  329. package/skills/tighten-paper/structure.mjs +4 -11
  330. package/skills/verify-citations/SKILL.md +2 -38
  331. package/skills/verify-citations/SKILL.md.spec.ts +1 -37
  332. package/src/adapters/banal/failure.ts +9 -10
  333. package/src/adapters/banal/index.test.ts +3 -3
  334. package/src/adapters/banal/index.ts +8 -10
  335. package/src/adapters/banal/install.ts +9 -4
  336. package/src/adapters/banal/invocation.test.ts +20 -8
  337. package/src/adapters/banal/invocation.ts +24 -9
  338. package/src/adapters/banal/locate.test.ts +2 -2
  339. package/src/adapters/banal/locate.ts +27 -21
  340. package/src/adapters/banal/output.test.ts +1 -1
  341. package/src/adapters/banal/run.test.ts +3 -3
  342. package/src/adapters/banal/run.ts +16 -10
  343. package/src/adapters/banal/settings.ts +2 -2
  344. package/src/adapters/banal/xml.test.ts +1 -1
  345. package/src/adapters/curl/download.test.ts +4 -4
  346. package/src/adapters/latex/document-class.ts +147 -0
  347. package/src/adapters/latex/hidden.ts +70 -0
  348. package/src/adapters/latex/index.test.ts +361 -0
  349. package/src/adapters/latex/index.ts +55 -0
  350. package/src/adapters/latex/nodes.ts +141 -0
  351. package/src/adapters/latex/outline.ts +64 -0
  352. package/src/adapters/latex/parse.ts +136 -0
  353. package/src/adapters/latex/rendered.ts +59 -0
  354. package/src/adapters/memory/index.ts +4 -3
  355. package/src/adapters/node/files.test.ts +5 -3
  356. package/src/adapters/node/process.io.ts +9 -2
  357. package/src/adapters/node/process.test.ts +4 -4
  358. package/src/adapters/node/workspace.io.ts +9 -4
  359. package/src/adapters/pdfjs/fill.test.ts +1 -1
  360. package/src/adapters/pdfjs/fill.ts +18 -10
  361. package/src/adapters/references/index.ts +7 -2
  362. package/src/build-engine.test.ts +11 -6
  363. package/src/build-engine.ts +10 -5
  364. package/src/build.harness.mjs +5 -7
  365. package/src/build.test.ts +10 -11
  366. package/src/build.ts +12 -13
  367. package/src/caller-path.ts +13 -0
  368. package/src/cli.harness.mjs +1 -3
  369. package/src/cli.test.ts +21 -16
  370. package/src/cli.ts +115 -33
  371. package/src/doctor.test.ts +1 -1
  372. package/src/doctor.ts +14 -5
  373. package/src/domain/paths.test.ts +15 -0
  374. package/src/domain/paths.ts +20 -1
  375. package/src/domain/ready.ts +31 -0
  376. package/src/domain/record.test.ts +20 -0
  377. package/src/domain/record.ts +12 -0
  378. package/src/domain/sha256.ts +5 -3
  379. package/src/domain/tex-document.test.ts +80 -0
  380. package/src/domain/tex-document.ts +110 -0
  381. package/src/engine.harness.mjs +1 -1
  382. package/src/engine.ts +30 -2
  383. package/src/facts-file.test.ts +4 -7
  384. package/src/facts-file.ts +45 -30
  385. package/src/hooks-settings.harness.ts +17 -0
  386. package/src/hooks-settings.ts +28 -4
  387. package/src/init.test.ts +25 -5
  388. package/src/init.ts +26 -12
  389. package/src/latex-loop.harness.ts +1 -1
  390. package/src/new-paper.harness.mjs +7 -23
  391. package/src/new-paper.test.ts +28 -3
  392. package/src/new-paper.ts +15 -3
  393. package/src/package-dirs.ts +17 -0
  394. package/src/paper-files.test.ts +22 -19
  395. package/src/paper-files.ts +16 -27
  396. package/src/paper-settings-commands.test.ts +6 -1
  397. package/src/paper-settings.test.ts +2 -2
  398. package/src/paper-settings.ts +5 -5
  399. package/src/pdf-facts.test.ts +16 -5
  400. package/src/pdf-facts.ts +79 -22
  401. package/src/pdf-geometry.ts +5 -3
  402. package/src/ports/latex.ts +29 -0
  403. package/src/ports/tool-installer.ts +2 -17
  404. package/src/presets.test.ts +65 -4
  405. package/src/presets.ts +65 -28
  406. package/src/references.test.ts +25 -19
  407. package/src/references.ts +4 -5
  408. package/src/rule-cases.test.ts +474 -0
  409. package/src/rule-docs.test.ts +159 -0
  410. package/src/rules-config.ts +40 -11
  411. package/src/tex-requirements.harness.ts +13 -23
  412. package/src/tex-requirements.test.ts +21 -0
  413. package/src/tex-requirements.ts +64 -14
  414. package/src/tex-venue-rules.test.ts +659 -0
  415. package/src/tex-venue-rules.ts +429 -0
  416. package/src/toolchain.harness.mjs +1 -1
  417. package/src/toolchain.test.ts +9 -5
  418. package/src/toolchain.ts +2 -2
  419. package/src/types.ts +5 -3
  420. package/src/venue-rules.test.ts +104 -8
  421. package/src/venue-rules.ts +22 -12
  422. package/templates/paper/paper.tex +2 -1
  423. package/skills/paper-pipeline/scripts/announce.mjs +0 -67
  424. package/skills/paper-pipeline/scripts/announce.test.mjs +0 -102
  425. package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +0 -51
  426. package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +0 -52
  427. package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +0 -6
  428. package/skills/paper-pipeline/scripts/fixtures/scorecard.ts +0 -100
  429. package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +0 -302
  430. package/skills/paper-pipeline/scripts/ledger.mjs +0 -623
  431. package/skills/paper-pipeline/scripts/ledger.test.mjs +0 -254
  432. package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +0 -474
  433. package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +0 -328
  434. package/skills/paper-pipeline/scripts/pipeline-check.mjs +0 -750
  435. package/skills/paper-pipeline/scripts/pipeline-edges.mjs +0 -169
  436. package/skills/paper-pipeline/scripts/pipeline-edges.test.mjs +0 -73
  437. package/skills/paper-pipeline/scripts/run-mechanical.mjs +0 -648
  438. package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +0 -468
  439. package/skills/paper-pipeline/scripts/status.mjs +0 -295
  440. package/skills/paper-pipeline/scripts/status.test.mjs +0 -232
  441. /package/{skills/submit-paper/references/venues → presets/tex}/agenticdev.tex +0 -0
  442. /package/{skills/submit-paper/references/venues → presets}/tex-base.jsonc +0 -0
@@ -1,169 +0,0 @@
1
- /**
2
- * pipeline-edges — the ONE declaration of which scorecard row feeds which gate.
3
- *
4
- * WHY THIS FILE EXISTS. The dependencies between pipeline skills are already enforced: every paper's
5
- * `PIPELINE-STATUS.md` has a `Requires` column in its `### GATES` table, and `pipeline-check.mjs`
6
- * reads it and reports `gate-missing-input` / `gate-stale-input` / `unknown-input`. The machinery is
7
- * right. What was hand-copied is the DECLARATION — each new paper retypes the cells, so a paper can
8
- * drop an edge and the checker will then cheerfully confirm a gate that never had its input. That is
9
- * not a hypothetical: on 2026-08-08 the live `<paper-a>` scorecard had `structure` requiring
10
- * only `render`, while `argument-arc/SKILL.md` says in its own words that it runs *before*
11
- * `tighten-paper`.
12
- *
13
- * WHY ONE TABLE HERE AND NOT A `requires:` FIELD IN EACH SKILL'S FRONTMATTER. The join key is the
14
- * SCORECARD ROW ID (`structure`, `writing`, `panel`, …) — that is what the status files and the
15
- * checker already speak — and a row id is not a property of a skill:
16
- * - one skill owns two rows: `plan-paper-timeline` owns `access` and `schedule`; `map-prior-work`
17
- * owns `priorwork` (SETUP sweep) and `priordelta` (CONTINUOUS delta); `argument-arc` owns `frame`
18
- * (frame) and `arc` (arc). Frontmatter keyed by skill cannot say which of its rows an edge lands on.
19
- * - one row has no skill at all: `claims` is "Fable diff", a protocol in `references/writing-craft.md`.
20
- * Frontmatter would therefore need a second table mapping skills to rows, i.e. this table plus a
21
- * layer. So: one table, keyed the way the rest of the system is keyed.
22
- *
23
- * 🔴 WHY THE IDS ARE WORDS AND NOT TWO LETTERS (renamed 2026-08-09). The join key used to be a
24
- * two-letter code (`St`, `Wc`, `Pn`, …). That space was exhausted and had already collided: in
25
- * `<paper-a>/PIPELINE-STATUS.md`, `Cr` was BOTH `cold-read-diff` (in the 06.08 gate log)
26
- * and `Camera-ready` (in `### AFTER`) — one join key, two rows, and the checker merges rows by id.
27
- * A second collision was live and silent: the row id `Id` (research-ideate) is exactly the table's
28
- * own header word, so `parseStatus` dropped that row on every paper as if it were a header. Both are
29
- * unrepresentable once the ids are words: `coldread` ≠ `cameraready`, and `idea` ≠ `id`.
30
- *
31
- * SCOPE, deliberately narrow. Only rows in the `### GATES` section appear here, because `Requires` is
32
- * a GATES column — SETUP/LOOP/CONTINUOUS rows have nowhere to declare an input, so an edge into them
33
- * is unexpressible and listing it would just be prose. The real ones found in the audit are recorded
34
- * in `UNEXPRESSED` below rather than dropped.
35
- *
36
- * ADMISSION RULE (why an edge is here and not in `NOT_EDGES`): the owning skill states a REQUIREMENT
37
- * ("required input", "blocked on", "STOP and run those first", "mandatory") or an ORDERING ("run it
38
- * before X", "run X first") in normative prose — a `Run me` / axis / when-to-run section. An entry in
39
- * a `## Compose with` list is a suggestion and does NOT qualify, even when it contains the word
40
- * "first". Every edge carries the sentence that admitted it, so the judgement stays auditable.
41
- *
42
- * This is a table and a loop on purpose. There is no graph engine here, and there should not be one:
43
- * a dozen edges do not need transitive closure, cycle detection or topological sorting, and building
44
- * those is how a table nobody can read stops being maintained.
45
- */
46
-
47
- /** row id → { skill (for the message), requires: { input row id → the sentence that admitted it } } */
48
- export const CANONICAL_INPUTS = {
49
- structure: {
50
- skill: "tighten-paper",
51
- requires: {
52
- render:
53
- 'render-paper/SKILL.md: "that page count is the hard input the `tighten-paper` structure gate is blocked on"',
54
- arc: 'argument-arc/SKILL.md: "Run it *before* them" (them = tighten-paper, grade-paper-writing) — "cutting words inside a broken arc is how a session burns a day"',
55
- },
56
- },
57
- writing: {
58
- skill: "grade-paper-writing",
59
- requires: {
60
- draft:
61
- "the template's own cell: the writing grade reads the current draft",
62
- arc: 'argument-arc/SKILL.md: "Before `tighten-paper` / `grade-paper-writing` / `pc-panel-review` on any draft whose thesis has changed since those gates last ran"',
63
- structure:
64
- 'tighten-paper/SKILL.md: "Run it BEFORE those on a bloated draft — no point polishing sentences in a section that should be cut"; harden-paper/SKILL.md: "Order matters: STRUCTURE before SENTENCES. Run axis 0 FIRST."',
65
- },
66
- },
67
- panel: {
68
- skill: "pc-panel-review",
69
- requires: {
70
- structure:
71
- 'pc-panel-review/SKILL.md: "there must exist for THIS draft … the **structural verdict** from `tighten-paper` … If either doesn\'t exist yet, STOP and run those skills first."',
72
- writing:
73
- 'pc-panel-review/SKILL.md: "there must exist for THIS draft: (a) the **persona stall inventory** from `grade-paper-writing`"',
74
- },
75
- },
76
- claims: {
77
- skill: "Fable diff",
78
- requires: {
79
- draft:
80
- "the template's own cell: the diff is against the pre-pass draft baseline",
81
- writing:
82
- 'grade-paper-writing/SKILL.md: "**After applying sentence fixes, run the `claims` claim-preservation diff** … This step is mandatory after EVERY rewrite, not optional."',
83
- },
84
- },
85
- harden: {
86
- skill: "harden-paper",
87
- requires: {
88
- panel:
89
- 'harden-paper/SKILL.md axis 1: "run `paper-adversarial-review` (quick) and, as the final decision gate, `pc-panel-review`"',
90
- structure:
91
- 'harden-paper/SKILL.md axis 0: "**Structure / editorial (run FIRST)** — run **`tighten-paper`**"; paper-pipeline/SKILL.md: "Its structure and writing axes are the **re-run/confirm** pass, not the first invocation."',
92
- writing:
93
- 'harden-paper/SKILL.md axis 8: "run **`grade-paper-writing`** … Without it this axis silently does not run"',
94
- cites:
95
- 'harden-paper/SKILL.md axis 4: "**Citations** — run `verify-citations`" under "## The axes (run all; each is a gate)"',
96
- priordelta:
97
- 'map-prior-work/SKILL.md, the `priordelta` row: "**Whenever the contribution\'s framing moves**, and again before `harden-paper`."',
98
- },
99
- },
100
- submit: {
101
- skill: "submit-paper",
102
- requires: {
103
- harden:
104
- 'submit-paper/SKILL.md: "Harden first: `pc-panel-review` (incl. its venue-fit mode), `paper-adversarial-review`, `render-paper`."',
105
- access:
106
- 'paper-pipeline/SKILL.md GATES table, Submit: "🔴 **The `access` row green.**"',
107
- },
108
- },
109
- };
110
-
111
- /**
112
- * Orderings that are REAL but have nowhere to be declared: they end in a SETUP or LOOP row, and only
113
- * GATES rows carry a `Requires` cell. Kept here so the audit is complete and so nobody re-derives
114
- * them and then invents a column for them.
115
- */
116
- export const UNEXPRESSED = [
117
- [
118
- "schedule ← venue",
119
- 'plan-paper-timeline/SKILL.md: "`find-venue` — the source of the four CFP dates this skill consumes; run it first."',
120
- ],
121
- [
122
- "access ← venue",
123
- "same sentence: the portal and its form are venue facts, so the venue is picked first.",
124
- ],
125
- [
126
- "draft ← study",
127
- 'draft-paper/SKILL.md: "**FINDING** — it declined to draft because a required input was missing: no numbers from `build-benchmark`"',
128
- ],
129
- [
130
- "priorwork ← idea",
131
- 'map-prior-work/SKILL.md, the `priorwork` row: "SETUP, right after `research-ideate` says go"',
132
- ],
133
- ];
134
-
135
- /**
136
- * Claims read during the audit and JUDGED TOO WEAK to be an edge, with the sentence that made the
137
- * call hesitate. Recorded because "we looked and decided no" and "we never looked" are
138
- * indistinguishable afterwards, and the first is only worth anything if it is written down.
139
- */
140
- export const NOT_EDGES = [
141
- [
142
- "panel ← arc",
143
- 'argument-arc/SKILL.md: "Before `tighten-paper` / `grade-paper-writing` / `pc-panel-review` **on any draft whose thesis has changed since those gates last ran**." — conditional, and panel already requires structure and writing, which both require arc, so declaring it adds no enforcement.',
144
- ],
145
- [
146
- "writing ← render",
147
- 'grade-paper-writing/SKILL.md: "`render-paper` — build the PDF/PNGs first so you grade what the reviewer will actually see." — it is an entry in the `## Compose with` list and about fidelity of grading, not a block. `tighten-paper` states its render dependency in normative prose; this one does not.',
148
- ],
149
- [
150
- "harden ← siblings",
151
- 'harden-paper/SKILL.md axis 3: "For every genuine sibling found, run **`analyze-sibling-paper`**" — conditional on a sibling existing, and `siblings` is itself a trigger row that is n/a on a paper with no close neighbour.',
152
- ],
153
- [
154
- "harden ← venuebar",
155
- 'study-accepted-papers/SKILL.md: "`harden-paper` — the multi-axis pre-submit gate; this skill **feeds it** the venue-specific axis" — a compose-with, and harden\'s own axis list never calls it.',
156
- ],
157
- [
158
- "harden ← siblings (via analyze-sibling-paper)",
159
- 'analyze-sibling-paper/SKILL.md: "Compose with … harden-paper (its nearest-neighbor-scoop axis calls this)" — a compose-with sentence in a description, mirrored by the conditional above.',
160
- ],
161
- [
162
- "structure ← draft",
163
- 'tighten-paper/SKILL.md description: "The developmental / editorial pass on a **DRAFTED** paper" — states a precondition on the object, not on a scorecard row, and no sentence orders it against `draft`.',
164
- ],
165
- [
166
- "writing ← panel / claims ← panel / harden ← claims (the chain read off the GATES table order)",
167
- 'paper-pipeline/SKILL.md: "Ordered, and the order is real: every one refuses to run without the output of the one before it." — the same table\'s own `Requires (hard)` column contradicts it (Writing craft requires "The current draft", not the structure verdict). Rhetoric about the table, not a declaration; the column is the declaration.',
168
- ],
169
- ];
@@ -1,73 +0,0 @@
1
- /**
2
- * pipeline-edges.mjs admits each edge on a SENTENCE from a skill's own SKILL.md, quoted in the
3
- * table so the judgement stays auditable. A quote is only evidence while the skill still says it,
4
- * so every quote is looked up in the SKILL.md it names. A skill reworded since — or a quote that
5
- * was never verbatim — fails here, naming the edge.
6
- *
7
- * Matching tolerates what quoting legitimately changes: runs of whitespace, `**` emphasis, and an
8
- * elision `…`, which splits a quote into fragments that must each appear. The values are prose,
9
- * so reading them with a pattern is reading prose, not parsing a format.
10
- */
11
- import assert from "node:assert/strict";
12
- import { existsSync, readFileSync } from "node:fs";
13
- import { dirname, join } from "node:path";
14
- import { fileURLToPath } from "node:url";
15
- import { test } from "vitest";
16
- import { CANONICAL_INPUTS, NOT_EDGES, UNEXPRESSED } from "./pipeline-edges.mjs";
17
-
18
- const SKILLS = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
19
- const norm = (s) => s.replace(/\*\*/g, "").replace(/\s+/g, " ");
20
-
21
- /** [edge, skill, quote] for every `<skill>/SKILL.md…: "<quote>"` in the three tables. */
22
- function quotes() {
23
- const cells = [
24
- ...Object.entries(CANONICAL_INPUTS).flatMap(([row, { requires }]) =>
25
- Object.entries(requires).map(([input, why]) => [
26
- `${row} ← ${input}`,
27
- why,
28
- ]),
29
- ),
30
- ...UNEXPRESSED,
31
- ...NOT_EDGES,
32
- ];
33
- return cells.flatMap(([edge, why]) =>
34
- quotesIn(why).map(([skill, quote]) => [edge, skill, quote]),
35
- );
36
- }
37
-
38
- /** [skill, quote] for every `<skill>/SKILL.md…: "<quote>"` in one cell. */
39
- function quotesIn(why) {
40
- return [...why.matchAll(/([a-z-]+)\/SKILL\.md[^"]*"((?:[^"\\]|\\.)*)"/g)].map(
41
- (m) => [m[1], m[2]],
42
- );
43
- }
44
-
45
- // Guards: the pattern below is not vacuous — a cell that names a SKILL.md yields its quote.
46
- test("every cell that names a SKILL.md yields a quote to check", () => {
47
- const cells = [
48
- ...Object.values(CANONICAL_INPUTS).flatMap((v) =>
49
- Object.values(v.requires),
50
- ),
51
- ...UNEXPRESSED.map(([, why]) => why),
52
- ...NOT_EDGES.map(([, why]) => why),
53
- ];
54
- const unparsed = cells.filter(
55
- (why) => why.includes("/SKILL.md") && quotesIn(why).length === 0,
56
- );
57
- assert.deepEqual(unparsed, []);
58
- });
59
-
60
- test("every quoted sentence is still in the SKILL.md it is attributed to", () => {
61
- const stale = quotes().flatMap(([edge, skill, quote]) => {
62
- const file = join(SKILLS, skill, "SKILL.md");
63
- if (!existsSync(file))
64
- return [{ edge, skill, missing: "the skill itself" }];
65
- const text = norm(readFileSync(file, "utf8"));
66
- return norm(quote)
67
- .split("…")
68
- .map((f) => f.trim())
69
- .filter((f) => f.length > 0 && !text.includes(f))
70
- .map((missing) => ({ edge, skill, missing }));
71
- });
72
- assert.deepEqual(stale, []);
73
- });