paperlint 3.1.3 → 3.2.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 (371) hide show
  1. package/.github/workflows/ci.yml +12 -7
  2. package/CLAUDE.md +3 -3
  3. package/CONTRIBUTING.md +34 -5
  4. package/dist/adapters/banal/index.d.ts.map +1 -1
  5. package/dist/adapters/banal/index.js +9 -5
  6. package/dist/adapters/banal/index.js.map +1 -1
  7. package/dist/adapters/banal/invocation.d.ts +1 -1
  8. package/dist/adapters/node/files.io.d.ts.map +1 -1
  9. package/dist/adapters/node/files.io.js +2 -1
  10. package/dist/adapters/node/files.io.js.map +1 -1
  11. package/dist/adapters/node/process.io.d.ts +0 -5
  12. package/dist/adapters/node/process.io.d.ts.map +1 -1
  13. package/dist/adapters/node/process.io.js +4 -3
  14. package/dist/adapters/node/process.io.js.map +1 -1
  15. package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
  16. package/dist/adapters/pdfjs/fill.js +13 -7
  17. package/dist/adapters/pdfjs/fill.js.map +1 -1
  18. package/dist/adapters/references/index.d.ts.map +1 -1
  19. package/dist/adapters/references/index.js +4 -5
  20. package/dist/adapters/references/index.js.map +1 -1
  21. package/dist/adapters/references/pool.d.ts.map +1 -1
  22. package/dist/adapters/references/pool.js +4 -5
  23. package/dist/adapters/references/pool.js.map +1 -1
  24. package/dist/adapters/references/reach.io.d.ts.map +1 -1
  25. package/dist/adapters/references/reach.io.js +2 -1
  26. package/dist/adapters/references/reach.io.js.map +1 -1
  27. package/dist/build-engine.js +2 -2
  28. package/dist/build-engine.js.map +1 -1
  29. package/dist/build.d.ts.map +1 -1
  30. package/dist/build.js +14 -11
  31. package/dist/build.js.map +1 -1
  32. package/dist/cli.d.ts.map +1 -1
  33. package/dist/cli.js +31 -34
  34. package/dist/cli.js.map +1 -1
  35. package/dist/doctor.d.ts.map +1 -1
  36. package/dist/doctor.js +3 -2
  37. package/dist/doctor.js.map +1 -1
  38. package/dist/domain/lookup-cache.d.ts.map +1 -1
  39. package/dist/domain/lookup-cache.js +10 -8
  40. package/dist/domain/lookup-cache.js.map +1 -1
  41. package/dist/domain/text.d.ts +12 -0
  42. package/dist/domain/text.d.ts.map +1 -1
  43. package/dist/domain/text.js +17 -0
  44. package/dist/domain/text.js.map +1 -1
  45. package/dist/engine.d.ts.map +1 -1
  46. package/dist/engine.js +4 -3
  47. package/dist/engine.js.map +1 -1
  48. package/dist/eslint-rules/bib-reachable-entry.d.ts +22 -0
  49. package/dist/eslint-rules/bib-reachable-entry.d.ts.map +1 -0
  50. package/dist/eslint-rules/bib-reachable-entry.js +75 -0
  51. package/dist/eslint-rules/bib-reachable-entry.js.map +1 -0
  52. package/dist/eslint-rules/install-path-literals.d.ts +80 -0
  53. package/dist/eslint-rules/install-path-literals.d.ts.map +1 -0
  54. package/dist/eslint-rules/install-path-literals.js +105 -0
  55. package/dist/eslint-rules/install-path-literals.js.map +1 -0
  56. package/dist/eslint-rules/latex-language.d.ts +136 -0
  57. package/dist/eslint-rules/latex-language.d.ts.map +1 -0
  58. package/dist/eslint-rules/latex-language.js +639 -0
  59. package/dist/eslint-rules/latex-language.js.map +1 -0
  60. package/dist/eslint-rules/paper-research-question.d.ts +31 -0
  61. package/dist/eslint-rules/paper-research-question.d.ts.map +1 -0
  62. package/dist/eslint-rules/paper-research-question.js +188 -0
  63. package/dist/eslint-rules/paper-research-question.js.map +1 -0
  64. package/dist/eslint-rules/paper-stages.d.ts +83 -0
  65. package/dist/eslint-rules/paper-stages.d.ts.map +1 -0
  66. package/dist/eslint-rules/paper-stages.js +358 -0
  67. package/dist/eslint-rules/paper-stages.js.map +1 -0
  68. package/dist/eslint-rules/paper-typography.d.ts +74 -0
  69. package/dist/eslint-rules/paper-typography.d.ts.map +1 -0
  70. package/dist/eslint-rules/paper-typography.js +404 -0
  71. package/dist/eslint-rules/paper-typography.js.map +1 -0
  72. package/dist/eslint-rules/papers.d.ts +42 -0
  73. package/dist/eslint-rules/papers.d.ts.map +1 -0
  74. package/dist/eslint-rules/papers.js +145 -0
  75. package/dist/eslint-rules/papers.js.map +1 -0
  76. package/dist/eslint-rules/pdf-last-page-balance.d.ts +72 -0
  77. package/dist/eslint-rules/pdf-last-page-balance.d.ts.map +1 -0
  78. package/dist/eslint-rules/pdf-last-page-balance.js +237 -0
  79. package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -0
  80. package/dist/eslint-rules/review-frontmatter.d.ts +57 -0
  81. package/dist/eslint-rules/review-frontmatter.d.ts.map +1 -0
  82. package/dist/eslint-rules/review-frontmatter.js +126 -0
  83. package/dist/eslint-rules/review-frontmatter.js.map +1 -0
  84. package/dist/eslint-rules/review-frontmatter.schema.json +36 -0
  85. package/dist/eslint-rules/rule-context.d.ts +55 -0
  86. package/dist/eslint-rules/rule-context.d.ts.map +1 -0
  87. package/dist/eslint-rules/rule-context.js +9 -0
  88. package/dist/eslint-rules/rule-context.js.map +1 -0
  89. package/dist/eslint-rules/sibling-frontmatter.d.ts +25 -0
  90. package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -0
  91. package/dist/eslint-rules/sibling-frontmatter.js +16 -0
  92. package/dist/eslint-rules/sibling-frontmatter.js.map +1 -0
  93. package/dist/eslint-rules/sibling-frontmatter.schema.json +14 -0
  94. package/dist/eslint-rules/temp-root-realpath.d.ts +71 -0
  95. package/dist/eslint-rules/temp-root-realpath.d.ts.map +1 -0
  96. package/dist/eslint-rules/temp-root-realpath.js +139 -0
  97. package/dist/eslint-rules/temp-root-realpath.js.map +1 -0
  98. package/dist/eslint-rules/tex-build.d.ts +35 -0
  99. package/dist/eslint-rules/tex-build.d.ts.map +1 -0
  100. package/dist/eslint-rules/tex-build.js +313 -0
  101. package/dist/eslint-rules/tex-build.js.map +1 -0
  102. package/dist/facts-file.d.ts.map +1 -1
  103. package/dist/facts-file.js +2 -1
  104. package/dist/facts-file.js.map +1 -1
  105. package/dist/hooks-settings.d.ts +1 -1
  106. package/dist/hooks-settings.d.ts.map +1 -1
  107. package/dist/hooks-settings.js +14 -9
  108. package/dist/hooks-settings.js.map +1 -1
  109. package/dist/init.d.ts +5 -5
  110. package/dist/init.d.ts.map +1 -1
  111. package/dist/init.js +15 -7
  112. package/dist/init.js.map +1 -1
  113. package/dist/latex-loop.d.ts +2 -2
  114. package/dist/latex-loop.d.ts.map +1 -1
  115. package/dist/latex-loop.js +2 -2
  116. package/dist/latex-loop.js.map +1 -1
  117. package/dist/lib/agent-cli-version.d.ts +65 -0
  118. package/dist/lib/agent-cli-version.d.ts.map +1 -0
  119. package/dist/lib/agent-cli-version.js +77 -0
  120. package/dist/lib/agent-cli-version.js.map +1 -0
  121. package/dist/lib/check.d.ts +19 -0
  122. package/dist/lib/check.d.ts.map +1 -0
  123. package/dist/lib/check.js +52 -0
  124. package/dist/lib/check.js.map +1 -0
  125. package/dist/lib/markdown.d.ts +180 -0
  126. package/dist/lib/markdown.d.ts.map +1 -0
  127. package/dist/lib/markdown.js +302 -0
  128. package/dist/lib/markdown.js.map +1 -0
  129. package/dist/lib/paper-config.d.ts +84 -0
  130. package/dist/lib/paper-config.d.ts.map +1 -0
  131. package/dist/lib/paper-config.js +142 -0
  132. package/dist/lib/paper-config.js.map +1 -0
  133. package/dist/lib/skill-eval-fixture.d.ts +29 -0
  134. package/dist/lib/skill-eval-fixture.d.ts.map +1 -0
  135. package/dist/lib/skill-eval-fixture.js +62 -0
  136. package/dist/lib/skill-eval-fixture.js.map +1 -0
  137. package/dist/link-skills.d.ts.map +1 -1
  138. package/dist/link-skills.js +5 -4
  139. package/dist/link-skills.js.map +1 -1
  140. package/dist/new-paper.d.ts.map +1 -1
  141. package/dist/new-paper.js +2 -2
  142. package/dist/new-paper.js.map +1 -1
  143. package/dist/paper-settings.d.ts.map +1 -1
  144. package/dist/paper-settings.js +5 -4
  145. package/dist/paper-settings.js.map +1 -1
  146. package/dist/pdf-facts.d.ts.map +1 -1
  147. package/dist/pdf-facts.js +2 -1
  148. package/dist/pdf-facts.js.map +1 -1
  149. package/dist/pdf-geometry.d.ts.map +1 -1
  150. package/dist/pdf-geometry.js +1 -1
  151. package/dist/pdf-geometry.js.map +1 -1
  152. package/dist/presets.d.ts.map +1 -1
  153. package/dist/presets.js +3 -2
  154. package/dist/presets.js.map +1 -1
  155. package/dist/references.d.ts.map +1 -1
  156. package/dist/references.js +11 -6
  157. package/dist/references.js.map +1 -1
  158. package/dist/rules-config.d.ts.map +1 -1
  159. package/dist/rules-config.js +6 -3
  160. package/dist/rules-config.js.map +1 -1
  161. package/dist/structure.js +1 -1
  162. package/dist/structure.js.map +1 -1
  163. package/dist/tex-requirements.d.ts.map +1 -1
  164. package/dist/tex-requirements.js +8 -3
  165. package/dist/tex-requirements.js.map +1 -1
  166. package/dist/toolchain.d.ts.map +1 -1
  167. package/dist/toolchain.js +21 -16
  168. package/dist/toolchain.js.map +1 -1
  169. package/dist/venue-rules.js +1 -1
  170. package/dist/venue-rules.js.map +1 -1
  171. package/docs/e2e.md +7 -7
  172. package/docs/install.md +1 -1
  173. package/docs/prior-art/README.md +1 -1
  174. package/docs/prior-art/package-location.md +5 -5
  175. package/docs/prior-art/repro/README.md +1 -1
  176. package/docs/prior-art/test-tooling.md +2 -2
  177. package/docs/testing.md +11 -8
  178. package/docs/toolchain.md +1 -1
  179. package/eslint-rules/{bib-reachable-entry.mjs → bib-reachable-entry.ts} +4 -3
  180. package/eslint-rules/install-path-literals.harness.mjs +1 -1
  181. package/eslint-rules/{install-path-literals.mjs → install-path-literals.ts} +16 -8
  182. package/eslint-rules/latex-language.harness.mjs +2 -2
  183. package/eslint-rules/latex-language.test.mjs +7 -1
  184. package/eslint-rules/{latex-language.mjs → latex-language.ts} +297 -109
  185. package/eslint-rules/paper-research-question.harness.mjs +3 -3
  186. package/eslint-rules/{paper-research-question.mjs → paper-research-question.ts} +34 -15
  187. package/eslint-rules/paper-stages.harness.mjs +2 -2
  188. package/eslint-rules/paper-stages.test.mjs +8 -2
  189. package/eslint-rules/{paper-stages.mjs → paper-stages.ts} +74 -29
  190. package/eslint-rules/paper-typography.test.mjs +3 -3
  191. package/eslint-rules/{paper-typography.mjs → paper-typography.ts} +132 -54
  192. package/eslint-rules/papers.harness.mjs +2 -2
  193. package/eslint-rules/{papers.mjs → papers.ts} +7 -4
  194. package/eslint-rules/pdf-last-page-balance.harness.mjs +3 -3
  195. package/eslint-rules/{pdf-last-page-balance.mjs → pdf-last-page-balance.ts} +88 -31
  196. package/eslint-rules/review-frontmatter.test.mjs +2 -2
  197. package/eslint-rules/{review-frontmatter.mjs → review-frontmatter.ts} +37 -15
  198. package/eslint-rules/rule-context.ts +62 -0
  199. package/eslint-rules/{sibling-frontmatter.mjs → sibling-frontmatter.ts} +1 -1
  200. package/eslint-rules/temp-root-realpath.harness.mjs +1 -1
  201. package/eslint-rules/{temp-root-realpath.mjs → temp-root-realpath.ts} +19 -6
  202. package/eslint-rules/tex-build.harness.mjs +2 -2
  203. package/eslint-rules/{tex-build.mjs → tex-build.ts} +4 -3
  204. package/eslint.config.mjs +139 -30
  205. package/fixtures/pdf-facts/README.md +2 -2
  206. package/fixtures/real-markdown-paper/{baseline.mjs → baseline.ts} +31 -10
  207. package/hooks/{hooks.harness.mjs → hooks.harness.ts} +51 -34
  208. package/hooks/paper-edit-guard.hook.mjs +1 -1
  209. package/hooks/{paper-edit-guard.test.mjs → paper-edit-guard.test.ts} +3 -7
  210. package/hooks/paper-skills-nudge.hook.mjs +1 -1
  211. package/hooks/{paper-skills-nudge.test.mjs → paper-skills-nudge.test.ts} +2 -6
  212. package/hooks/{paper-status-gates.test.mjs → paper-status-gates.test.ts} +2 -6
  213. package/lib/agent-cli-version.harness.mjs +1 -1
  214. package/lib/{agent-cli-version.mjs → agent-cli-version.ts} +32 -18
  215. package/lib/check.test.ts +14 -9
  216. package/lib/{check.mjs → check.ts} +22 -9
  217. package/lib/markdown.test.mjs +7 -7
  218. package/lib/{markdown.mjs → markdown.ts} +68 -29
  219. package/lib/paper-config.harness.mjs +8 -8
  220. package/lib/{paper-config.mjs → paper-config.ts} +19 -14
  221. package/lib/skill-checks.mjs +1 -1
  222. package/lib/skill-checks.test.mjs +1 -1
  223. package/lib/skill-corpus.mjs +1 -1
  224. package/lib/skill-eval-kit.mjs +1 -1
  225. package/package.json +42 -10
  226. package/scripts/{check.harness.mjs → check.harness.ts} +111 -10
  227. package/scripts/{check.test.mjs → check.test.ts} +13 -10
  228. package/scripts/{check.mjs → check.ts} +116 -42
  229. package/scripts/coverage-config.test.ts +80 -37
  230. package/scripts/eslint-report-guard.test.mjs +1 -1
  231. package/scripts/harness-api.frozen.json +14 -15
  232. package/scripts/harness-api.test.ts +8 -5
  233. package/scripts/layer-legacy-frozen.test.ts +17 -13
  234. package/scripts/{layer-legacy-frozen.mjs → layer-legacy-frozen.ts} +128 -39
  235. package/scripts/release-config.test.ts +12 -4
  236. package/scripts/rules-see-files.test.mjs +1 -1
  237. package/scripts/test.test.ts +78 -0
  238. package/scripts/test.ts +87 -0
  239. package/skills/grade-paper-writing/prose-lint.mjs +1 -1
  240. package/skills/grade-paper-writing/{prose-lint.test.mjs → prose-lint.test.ts} +2 -2
  241. package/skills/paper-pipeline/description-language.eval.mjs +1 -1
  242. package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +1 -1
  243. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1 -1
  244. package/skills/paper-pipeline/pipeline-firing.eval.mjs +1 -1
  245. package/skills/paper-pipeline/pipeline-language.eval.mjs +1 -1
  246. package/skills/paper-pipeline/scripts/README.md +1 -1
  247. package/skills/paper-pipeline/scripts/announce.test.mjs +1 -1
  248. package/skills/paper-pipeline/scripts/artifact-coverage.mjs +1 -1
  249. package/skills/paper-pipeline/scripts/{artifact-coverage.test.mjs → artifact-coverage.test.ts} +2 -2
  250. package/skills/paper-pipeline/scripts/consumer.mjs +1 -5
  251. package/skills/paper-pipeline/scripts/consumer.test.mjs +1 -1
  252. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +1 -1
  253. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +1 -4
  254. package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +1 -1
  255. package/skills/paper-pipeline/scripts/fixtures/{scorecard.mjs → scorecard.ts} +36 -7
  256. package/skills/paper-pipeline/scripts/{generated-code.test.mjs → generated-code.test.ts} +3 -3
  257. package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +1 -1
  258. package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +2 -2
  259. package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +2 -2
  260. package/skills/paper-pipeline/scripts/pipeline-check.mjs +1 -4
  261. package/skills/paper-pipeline/scripts/population-map.mjs +1 -4
  262. package/skills/paper-pipeline/scripts/population-map.test.mjs +1 -1
  263. package/skills/paper-pipeline/scripts/{round-diff.harness.mjs → round-diff.harness.ts} +45 -18
  264. package/skills/paper-pipeline/scripts/round-diff.mjs +1 -1
  265. package/skills/paper-pipeline/scripts/round-diff.test.mjs +1 -1
  266. package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +1 -1
  267. package/skills/paper-pipeline/scripts/status.test.mjs +1 -1
  268. package/skills/plan-paper-timeline/fixtures/{fake-google-calendar.mjs → fake-google-calendar.ts} +101 -70
  269. package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +3 -3
  270. package/skills/render-paper/{extract-pdf-facts.harness.mjs → extract-pdf-facts.harness.ts} +34 -9
  271. package/skills/render-paper/render-paper.harness.mjs +2 -2
  272. package/skills/tighten-paper/structure.mjs +1 -1
  273. package/skills/tighten-paper/{structure.test.mjs → structure.test.ts} +4 -3
  274. package/skills/verify-citations/scripts/{bib-authors.cli.test.mjs → bib-authors.cli.test.ts} +14 -4
  275. package/skills/verify-citations/scripts/bib-authors.d.mts +63 -0
  276. package/skills/verify-citations/scripts/bib-authors.mjs +1 -4
  277. package/skills/verify-citations/scripts/{verify-cites.cli.test.mjs → verify-cites.cli.test.ts} +32 -9
  278. package/skills/verify-citations/scripts/verify-cites.d.mts +58 -0
  279. package/src/CLAUDE.md +1 -1
  280. package/src/adapters/banal/index.test.ts +3 -6
  281. package/src/adapters/banal/index.ts +7 -4
  282. package/src/adapters/banal/invocation.test.ts +3 -1
  283. package/src/adapters/banal/invocation.ts +1 -1
  284. package/src/adapters/banal/output.test.ts +1 -1
  285. package/src/adapters/banal/run.test.ts +3 -3
  286. package/src/adapters/banal/xml.test.ts +1 -1
  287. package/src/adapters/curl/download.test.ts +4 -2
  288. package/src/adapters/node/files.io.ts +2 -2
  289. package/src/adapters/node/files.test.ts +3 -1
  290. package/src/adapters/node/process.io.ts +4 -3
  291. package/src/adapters/node/process.test.ts +1 -1
  292. package/src/adapters/node/workspace.test.ts +3 -1
  293. package/src/adapters/pdfjs/fill.test.ts +2 -2
  294. package/src/adapters/pdfjs/fill.ts +14 -7
  295. package/src/adapters/references/index.test.ts +31 -38
  296. package/src/adapters/references/index.ts +26 -58
  297. package/src/adapters/references/pool.ts +3 -5
  298. package/src/adapters/references/reach.io.ts +2 -1
  299. package/src/build-engine.harness.mjs +1 -1
  300. package/src/build-engine.test.ts +2 -2
  301. package/src/build-engine.ts +2 -2
  302. package/src/build.harness.mjs +2 -2
  303. package/src/build.test.ts +15 -14
  304. package/src/build.ts +28 -19
  305. package/src/cli.harness.mjs +6 -6
  306. package/src/cli.test.ts +13 -6
  307. package/src/cli.ts +39 -37
  308. package/src/doctor.harness.mjs +3 -3
  309. package/src/doctor.ts +3 -2
  310. package/src/domain/lookup-cache.ts +21 -11
  311. package/src/domain/result.test.ts +2 -2
  312. package/src/domain/text.test.ts +32 -0
  313. package/src/domain/text.ts +23 -0
  314. package/src/engine.harness.mjs +2 -2
  315. package/src/engine.ts +4 -3
  316. package/src/facts-file.test.ts +9 -7
  317. package/src/facts-file.ts +2 -1
  318. package/src/{hooks-settings.harness.mjs → hooks-settings.harness.ts} +39 -20
  319. package/src/hooks-settings.ts +20 -9
  320. package/src/init.test.ts +12 -9
  321. package/src/init.ts +22 -12
  322. package/src/{latex-log.harness.mjs → latex-log.harness.ts} +14 -14
  323. package/src/{latex-loop.harness.mjs → latex-loop.harness.ts} +64 -36
  324. package/src/latex-loop.ts +3 -3
  325. package/src/{link-skills.harness.mjs → link-skills.harness.ts} +19 -19
  326. package/src/link-skills.test.ts +3 -3
  327. package/src/link-skills.ts +5 -4
  328. package/src/lint-fix.test.ts +4 -6
  329. package/src/linted-set.test.ts +2 -2
  330. package/src/new-paper.harness.mjs +2 -2
  331. package/src/new-paper.test.ts +8 -10
  332. package/src/new-paper.ts +2 -2
  333. package/src/paper-files.test.ts +3 -5
  334. package/src/paper-settings-commands.test.ts +5 -4
  335. package/src/paper-settings.test.ts +5 -5
  336. package/src/paper-settings.ts +8 -9
  337. package/src/{pdf-facts.harness.mjs → pdf-facts.harness.ts} +9 -8
  338. package/src/pdf-facts.test.ts +10 -11
  339. package/src/pdf-facts.ts +2 -1
  340. package/src/{pdf-geometry.harness.mjs → pdf-geometry.harness.ts} +19 -12
  341. package/src/pdf-geometry.ts +3 -1
  342. package/src/presets.ts +3 -2
  343. package/src/references.test.ts +51 -43
  344. package/src/references.ts +14 -7
  345. package/src/{rules-config.harness.mjs → rules-config.harness.ts} +7 -13
  346. package/src/rules-config.ts +7 -4
  347. package/src/rules-off.test.ts +6 -4
  348. package/src/{structure.harness.mjs → structure.harness.ts} +26 -15
  349. package/src/structure.ts +1 -1
  350. package/src/{tex-requirements.harness.mjs → tex-requirements.harness.ts} +50 -22
  351. package/src/tex-requirements.ts +8 -5
  352. package/src/toolchain.harness.mjs +2 -2
  353. package/src/toolchain.test.ts +1 -1
  354. package/src/toolchain.ts +31 -17
  355. package/src/venue-rules.test.ts +62 -64
  356. package/src/venue-rules.ts +1 -1
  357. package/tsconfig.json +6 -3
  358. package/tsconfig.pkg.json +10 -0
  359. package/lib/check.d.mts +0 -17
  360. package/lib/paper-config.d.mts +0 -31
  361. package/scripts/layer-legacy-frozen.d.mts +0 -36
  362. package/scripts/rules-are-content-only.harness.mjs +0 -105
  363. package/scripts/rules-are-content-only.mjs +0 -148
  364. package/scripts/rules-are-content-only.test.mjs +0 -61
  365. package/scripts/test.mjs +0 -44
  366. package/scripts/test.test.mjs +0 -52
  367. /package/bin/{paperlint.test.mjs → paperlint.test.ts} +0 -0
  368. /package/lib/{skill-eval-fixture.mjs → skill-eval-fixture.ts} +0 -0
  369. /package/skills/grade-paper-writing/__snapshots__/{prose-lint.test.mjs.snap → prose-lint.test.ts.snap} +0 -0
  370. /package/skills/osf-artifact-upload/{osf-artifact-upload.harness.mjs → osf-artifact-upload.harness.ts} +0 -0
  371. /package/skills/tighten-paper/__snapshots__/{structure.test.mjs.snap → structure.test.ts.snap} +0 -0
@@ -0,0 +1,358 @@
1
+ /**
2
+ * `paper/stages` — the stage a paper has reached is an author's CLAIM, so it is a FIELD, and
3
+ * the bytes on disk are the evidence that claim is checked against.
4
+ *
5
+ * ── WHAT THIS REPLACES, and why the replacement is not cosmetic ─────────────────────────
6
+ * The predecessor kept a vocabulary of stage names in a JS const and applied its regexes to
7
+ * the WHOLE of `PIPELINE-STATUS.md`:
8
+ *
9
+ * { stage: "submitted", declaredBy: /(?<!\bas\s)(?<!\bbe\s)\bsubmitted\b/i }
10
+ *
11
+ * The lookbehinds are not decoration — they were added after the only match in one paper's
12
+ * file turned out to be a reviewer's idiom, "Weak Accept as submitted", which says nothing
13
+ * about submission. The check then demanded a frozen pdf and was RIGHT BY ACCIDENT.
14
+ *
15
+ * 🔴 And it stayed wrong in the other direction, measured 2026-09-16 on the live corpus:
16
+ * `versions/2026-08-29-camera-ready.pdf` had been on disk for 16 days at 616 175 bytes while
17
+ * the `camera-ready` pattern matched ZERO times anywhere in the file. The artefact preceded
18
+ * the declaration, so all three checks gated on that declaration were blind by construction.
19
+ *
20
+ * ── TWO DIRECTIONS, and neither alone is the check ──────────────────────────────────────
21
+ * declared -> bytes a record without its file, or with the wrong size, is a false claim
22
+ * bytes -> declared a frozen version nobody declared is the case above, and it is also
23
+ * what stops the whole rule being switched off by deleting a line
24
+ *
25
+ * Absence of the field is therefore LEGITIMATE — a paper that has shipped nothing owes
26
+ * nothing — without being an escape hatch: the second direction still speaks if bytes exist.
27
+ * That asymmetry is deliberate and is the reason this rule does not copy `doc/fields`, where
28
+ * a missing frontmatter IS the finding.
29
+ *
30
+ * ── WHY A FIELD CANNOT BECOME A TICKED BOX HERE ─────────────────────────────────────────
31
+ * The usual objection to turning a check into a field is that a field gets ticked instead of
32
+ * the work being done. It does not apply, and the reason is the direction of the incentive:
33
+ * a tick normally REMOVES an obligation, while `stages` CREATES them — declare a stage and
34
+ * you owe a pdf of the right size. Nobody writes a line in order to receive findings. The
35
+ * real-world pressure is to UNDER-declare, which is exactly what direction two catches.
36
+ *
37
+ * ── THE FIELD IS THE ONLY MACHINE-READABLE CARRIER ──────────────────────────────────────
38
+ * ⚠️ A paper's status file also carries a `State:` line in its header and one or two
39
+ * scorecard tables. Those are DISPLAY. No consistency check between them is written here on
40
+ * purpose: one paper in the source corpus carries two scorecards in two different column
41
+ * formats, and a rule reconciling them would drown in noise within a day.
42
+ *
43
+ * ── A LIST, NOT A MAP, and that is load-bearing ─────────────────────────────────────────
44
+ * A paper can reach the same stage twice: one in the source corpus was submitted to a venue
45
+ * in August, rejected in September, and is being resubmitted elsewhere in October. A map
46
+ * keyed by stage name holds one. The `versions/<date>-<stage>.pdf` convention already holds
47
+ * many, and the field must not be weaker than the filenames it describes.
48
+ */
49
+ import { existsSync, statSync, readdirSync } from "node:fs";
50
+ import { join, dirname } from "node:path";
51
+ import assert from "node:assert/strict";
52
+ import { load } from "js-yaml";
53
+ import { z } from "zod";
54
+ /** The frontmatter's `stages` field, whatever it holds; anything that is not a mapping has none. */
55
+ const Frontmatter = z.looseObject({ stages: z.unknown().optional() }).catch({});
56
+ const StageList = z.array(z.unknown());
57
+ /** One `stages` entry. A field of the wrong shape is read as it is written, then judged below. */
58
+ const StageRecord = z
59
+ .looseObject({
60
+ stage: z.unknown().optional(),
61
+ date: z.unknown().optional(),
62
+ pdf: z.unknown().optional(),
63
+ bytes: z.unknown().optional(),
64
+ source: z.unknown().optional(),
65
+ sourceBytes: z.unknown().optional(),
66
+ sourceLost: z.unknown().optional(),
67
+ })
68
+ .catch({});
69
+ const REQUIRED = ["date", "pdf", "bytes"];
70
+ const STAGES = ["submitted", "camera-ready", "arxiv"];
71
+ /**
72
+ * A YAML date without quotes parses to a `Date`, not a string — js-yaml honours YAML 1.1
73
+ * timestamps. Comparing `Date === "2026-08-29"` is silently false, so every date is
74
+ * normalised before it is compared with one taken from a filename.
75
+ */
76
+ /**
77
+ * A YAML value as the text a message shows: a scalar as written, nothing as "", and a mapping or
78
+ * list as its JSON (as a number is) — `String()` would print `[object Object]` for a mapping.
79
+ */
80
+ const scalarText = (v) => typeof v === "string" ? v : v === undefined ? "" : JSON.stringify(v);
81
+ function isoDate(v) {
82
+ if (v instanceof Date)
83
+ return v.toISOString().slice(0, 10);
84
+ if (typeof v === "string")
85
+ return /^\d{4}-\d{2}-\d{2}/.exec(v)?.[0] ?? "";
86
+ return "";
87
+ }
88
+ /** Frozen versions on disk, as `{name, date, stage}`. */
89
+ function frozenPdfs(versionsDir) {
90
+ let names;
91
+ try {
92
+ names = readdirSync(versionsDir);
93
+ }
94
+ catch {
95
+ return [];
96
+ }
97
+ const out = [];
98
+ for (const name of names) {
99
+ if (!name.endsWith(".pdf"))
100
+ continue;
101
+ // ⚠️ A name carrying `STALE` is a version WITHDRAWN on purpose — one such file records
102
+ // that the wrong pdf sat in the folder for a month. Demanding a declaration for it would
103
+ // turn a deliberate record of a mistake into a finding.
104
+ if (name.includes("STALE"))
105
+ continue;
106
+ const m = /^(\d{4}-\d{2}-\d{2})-(.+)\.pdf$/.exec(name);
107
+ if (!m)
108
+ continue;
109
+ const [, date = "", stage = ""] = m;
110
+ if (!STAGES.includes(stage))
111
+ continue;
112
+ out.push({ name, date, stage });
113
+ }
114
+ return out;
115
+ }
116
+ export default {
117
+ rules: {
118
+ stages: {
119
+ meta: {
120
+ type: "problem",
121
+ docs: {
122
+ description: "a paper's stage is declared as a FIELD, and every declaration is checked against the bytes on disk in both directions",
123
+ },
124
+ schema: [],
125
+ messages: {
126
+ badYaml: "the frontmatter does not parse as YAML: {{reason}}",
127
+ notAList: "`stages` must be a LIST of entries, not {{got}} — a paper can reach the same stage twice",
128
+ badStage: "unknown stage «{{stage}}» — the vocabulary is: {{known}}",
129
+ missingKey: "the «{{stage}}» entry has no `{{key}}` field",
130
+ badDate: "the date «{{date}}» in the «{{stage}}» entry is not YYYY-MM-DD",
131
+ declaredNoFile: "stage «{{stage}}» ({{date}}) is declared, but `{{pdf}}` is not on disk",
132
+ bytesDiffer: "«{{stage}}» ({{date}}): {{want}} bytes declared, {{got}} on disk — this is NOT that file",
133
+ fileNotDeclared: "`versions/{{file}}` is frozen, but no «{{stage}}» stage on {{date}} is declared in `stages` — the artefact ran ahead of the declaration",
134
+ },
135
+ },
136
+ create(context) {
137
+ const dir = dirname(context.filename);
138
+ let declared = null; // null = there was no frontmatter at all
139
+ return {
140
+ yaml(node) {
141
+ let data;
142
+ try {
143
+ data = load(node.value ?? "");
144
+ }
145
+ catch (e) {
146
+ // js-yaml throws its own `YAMLException`, an `Error`, and nothing else.
147
+ assert.ok(e instanceof Error);
148
+ context.report({
149
+ node,
150
+ messageId: "badYaml",
151
+ data: { reason: e.message },
152
+ });
153
+ return;
154
+ }
155
+ const { stages: raw } = Frontmatter.parse(data);
156
+ if (raw === undefined)
157
+ return;
158
+ const list = StageList.safeParse(raw);
159
+ if (!list.success) {
160
+ context.report({
161
+ node,
162
+ messageId: "notAList",
163
+ data: { got: raw === null ? "empty" : typeof raw },
164
+ });
165
+ return;
166
+ }
167
+ declared = [];
168
+ for (const entry of list.data) {
169
+ const rec = StageRecord.parse(entry);
170
+ const stage = scalarText(rec.stage);
171
+ if (!STAGES.includes(stage)) {
172
+ context.report({
173
+ node,
174
+ messageId: "badStage",
175
+ data: { stage, known: STAGES.join(" · ") },
176
+ });
177
+ continue;
178
+ }
179
+ let complete = true;
180
+ for (const key of REQUIRED) {
181
+ if (rec[key] === undefined) {
182
+ context.report({
183
+ node,
184
+ messageId: "missingKey",
185
+ data: { stage, key },
186
+ });
187
+ complete = false;
188
+ }
189
+ }
190
+ if (!complete)
191
+ continue;
192
+ const date = isoDate(rec.date);
193
+ if (date === "") {
194
+ context.report({
195
+ node,
196
+ messageId: "badDate",
197
+ data: { stage, date: String(rec.date) },
198
+ });
199
+ continue;
200
+ }
201
+ declared.push({
202
+ stage,
203
+ date,
204
+ pdf: String(rec.pdf),
205
+ bytes: Number(rec.bytes),
206
+ });
207
+ // ── direction one: a claim owes its bytes ────────────────────────────────
208
+ const abs = join(dir, String(rec.pdf));
209
+ if (!existsSync(abs)) {
210
+ context.report({
211
+ node,
212
+ messageId: "declaredNoFile",
213
+ data: { stage, date, pdf: String(rec.pdf) },
214
+ });
215
+ continue;
216
+ }
217
+ const got = statSync(abs).size;
218
+ if (got !== Number(rec.bytes)) {
219
+ context.report({
220
+ node,
221
+ messageId: "bytesDiffer",
222
+ data: {
223
+ stage,
224
+ date,
225
+ want: String(rec.bytes),
226
+ got: String(got),
227
+ },
228
+ });
229
+ }
230
+ }
231
+ },
232
+ // ── direction two: bytes owe their declaration ────────────────────────────────
233
+ // 🔴 On `root:exit` rather than inside `yaml`, because the case worth catching is
234
+ // precisely the one with NO frontmatter at all — where the `yaml` visitor never runs.
235
+ "root:exit"(node) {
236
+ const records = declared ?? [];
237
+ for (const f of frozenPdfs(join(dir, "versions"))) {
238
+ if (records.some((r) => r.stage === f.stage && r.date === f.date))
239
+ continue;
240
+ context.report({
241
+ node,
242
+ messageId: "fileNotDeclared",
243
+ data: { file: f.name, stage: f.stage, date: f.date },
244
+ });
245
+ }
246
+ },
247
+ };
248
+ },
249
+ },
250
+ /**
251
+ * `paper/source` — a declared stage must have its SOURCE frozen on disk, beside the pdf,
252
+ * and the bytes must match. Not a commit reference. Not a hash of one.
253
+ *
254
+ * ── WHY NOT A COMMIT, measured 2026-09-16 and it is not a close call ──────────────────
255
+ * The predecessor recorded provenance as `commit <sha>` in prose and checked that the sha
256
+ * RESOLVED. Its stated premise was "git holds those bytes immutably, materialising a copy
257
+ * duplicates a guarantee we already have". That premise is false wherever branches are
258
+ * SQUASH-merged: the squash destroys the branch commits, and the next `git gc` removes
259
+ * the objects.
260
+ *
261
+ * 🔴 Measured on the live corpus, inside ninety minutes of ONE session: two recorded shas
262
+ * resolved, then stopped resolving after a routine `gc` following a branch reset. Of the
263
+ * four declared stages in that corpus, THREE had lost their source entirely — including
264
+ * papers already submitted to a venue, which is exactly the case the check existed for
265
+ * (a reviewer cites a line number and there is no layout left to resolve it against).
266
+ *
267
+ * So a sha is not a pointer to bytes; it is a pointer to a pointer, and the outer one
268
+ * evaporates. Checking it verifies that the REFERENCE is alive, which is a different
269
+ * claim from the one anybody wants.
270
+ *
271
+ * ── COST, because "duplicating" was the objection ─────────────────────────────────────
272
+ * A paper source is 57-68 KB of LaTeX beside a pdf of 305-382 KB that is already
273
+ * committed. Freezing it adds under a fifth to what the folder holds anyway, and turns a
274
+ * claim about the world into bytes this rule can actually compare.
275
+ *
276
+ * ── SEVERITY: nudge, and the reason CHANGED ──────────────────────────────────────────
277
+ * Still `warn` at the consumer, but no longer because "only the author knows". Now it is
278
+ * because a stage frozen BEFORE this convention existed cannot be fixed at all — those
279
+ * bytes are gone. Failing a build over unrecoverable history is a gate nobody can clear.
280
+ */
281
+ source: {
282
+ meta: {
283
+ type: "problem",
284
+ docs: {
285
+ description: "a declared stage freezes its source beside the pdf and is checked by bytes — not by a commit reference",
286
+ },
287
+ schema: [],
288
+ messages: {
289
+ noSource: "stage «{{stage}}» ({{date}}) carries no frozen source. A commit reference will not do: squash and gc destroy it — three of four sources were lost that way in this corpus",
290
+ sourceMissing: "«{{stage}}» ({{date}}): source `{{src}}` is declared, but the file is not on disk",
291
+ sourceBytes: "«{{stage}}» ({{date}}): the source is declared as {{want}} bytes, {{got}} on disk — this is NOT that file",
292
+ lostAcknowledged: "stage «{{stage}}» ({{date}}): the source is declared LOST. There is nothing left to match a build against a reviewer's line — if a copy turns up, put it in versions/ and clear the flag",
293
+ },
294
+ },
295
+ create(context) {
296
+ const dir = dirname(context.filename);
297
+ return {
298
+ yaml(node) {
299
+ let data;
300
+ try {
301
+ data = load(node.value ?? "");
302
+ }
303
+ catch {
304
+ return; // `paper/stages` has already reported the unreadable YAML
305
+ }
306
+ const list = StageList.safeParse(Frontmatter.parse(data).stages);
307
+ if (!list.success)
308
+ return;
309
+ for (const entry of list.data) {
310
+ const rec = StageRecord.parse(entry);
311
+ const stage = scalarText(rec.stage);
312
+ if (!STAGES.includes(stage))
313
+ continue;
314
+ const date = isoDate(rec.date);
315
+ // Acknowledging the loss is a RECORD, not an exemption: the rule keeps speaking,
316
+ // because the state stays defective, just unfixable today.
317
+ if (rec.sourceLost === true) {
318
+ context.report({
319
+ node,
320
+ messageId: "lostAcknowledged",
321
+ data: { stage, date },
322
+ });
323
+ continue;
324
+ }
325
+ const src = scalarText(rec.source);
326
+ if (src === "") {
327
+ context.report({
328
+ node,
329
+ messageId: "noSource",
330
+ data: { stage, date },
331
+ });
332
+ continue;
333
+ }
334
+ const abs = join(dir, src);
335
+ if (!existsSync(abs)) {
336
+ context.report({
337
+ node,
338
+ messageId: "sourceMissing",
339
+ data: { stage, date, src },
340
+ });
341
+ continue;
342
+ }
343
+ const got = statSync(abs).size;
344
+ const want = Number(rec.sourceBytes);
345
+ if (Number.isFinite(want) && got !== want)
346
+ context.report({
347
+ node,
348
+ messageId: "sourceBytes",
349
+ data: { stage, date, want: String(want), got: String(got) },
350
+ });
351
+ }
352
+ },
353
+ };
354
+ },
355
+ },
356
+ },
357
+ };
358
+ //# sourceMappingURL=paper-stages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-stages.js","sourceRoot":"","sources":["../../eslint-rules/paper-stages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { TexRoot } from "./latex-language.ts";
2
+ import type { RuleContext } from "./rule-context.ts";
3
+ /** Where a `.bib` embedded in a `filecontents` environment sits in the file. */
4
+ export interface BibRange {
5
+ readonly start: number;
6
+ readonly end: number;
7
+ readonly bodyStart: number;
8
+ readonly body: string;
9
+ }
10
+ /** A run of visible text, and for each of its characters the offset it came from (or null). */
11
+ interface Run {
12
+ text: string;
13
+ offs: (number | null)[];
14
+ }
15
+ /** The inline bibliography — a `filecontents` block writing a `.bib` — with its offsets. */
16
+ export declare function bibRange(text: string): BibRange | null;
17
+ /**
18
+ * The visible runs of a LaTeX source. `parse` is unified-latex's parser; a test hands in a tree
19
+ * with the fields the walk tolerates being absent.
20
+ */
21
+ export declare function texVisibleRuns(raw: string, { parse, }?: {
22
+ parse?: (s: string) => TexRoot;
23
+ }): Run[];
24
+ declare const _default: {
25
+ rules: {
26
+ "section-word": {
27
+ meta: {
28
+ hasSuggestions?: boolean;
29
+ type: string;
30
+ fixable: string;
31
+ docs: {
32
+ description: string;
33
+ };
34
+ schema: never[];
35
+ messages: Readonly<Record<string, string>>;
36
+ };
37
+ create: (context: RuleContext) => {
38
+ "root:exit": () => void;
39
+ };
40
+ };
41
+ "leading-zero": {
42
+ meta: {
43
+ hasSuggestions?: boolean;
44
+ type: string;
45
+ fixable: string;
46
+ docs: {
47
+ description: string;
48
+ };
49
+ schema: never[];
50
+ messages: Readonly<Record<string, string>>;
51
+ };
52
+ create: (context: RuleContext) => {
53
+ "root:exit": () => void;
54
+ };
55
+ };
56
+ "figure-ref-style": {
57
+ meta: {
58
+ hasSuggestions?: boolean;
59
+ type: string;
60
+ fixable: string;
61
+ docs: {
62
+ description: string;
63
+ };
64
+ schema: never[];
65
+ messages: Readonly<Record<string, string>>;
66
+ };
67
+ create: (context: RuleContext) => {
68
+ "root:exit": () => void;
69
+ };
70
+ };
71
+ };
72
+ };
73
+ export default _default;
74
+ //# sourceMappingURL=paper-typography.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-typography.d.ts","sourceRoot":"","sources":["../../eslint-rules/paper-typography.ts"],"names":[],"mappings":"AAgEA,OAAO,KAAK,EAAmB,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,gFAAgF;AAChF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAKD,+FAA+F;AAC/F,UAAU,GAAG;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CACzB;AAED,4FAA4F;AAC5F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAWtD;AA4JD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,EACE,KAAoD,GACrD,GAAE;IAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CAAO,GACzC,GAAG,EAAE,CAQP;;;;;iCAgMmC,OAAO;;;;;;;;;8BAUvB,WAAW;;;;;;iCAVK,OAAO;;;;;;;;;8BAUvB,WAAW;;;;;;iCAVK,OAAO;;;;;;;;;8BAUvB,WAAW;;;;;;AAO/B,wBA6BE"}