paperlint 2.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 (762) hide show
  1. package/.github/dependabot.yml +72 -0
  2. package/.github/workflows/ci.yml +297 -0
  3. package/.github/workflows/dependabot-automerge.yml +70 -0
  4. package/.github/workflows/pr-title.yml +59 -0
  5. package/.github/workflows/release.yml +54 -0
  6. package/CLAUDE.md +598 -0
  7. package/CONTRIBUTING.md +159 -0
  8. package/LICENSE +21 -0
  9. package/README.md +240 -0
  10. package/action.harness.mjs +287 -0
  11. package/action.mutations.mjs +162 -0
  12. package/action.yml +138 -0
  13. package/bin/rpp.mjs +43 -0
  14. package/dist/action-ref.d.ts +12 -0
  15. package/dist/action-ref.d.ts.map +1 -0
  16. package/dist/action-ref.js +16 -0
  17. package/dist/action-ref.js.map +1 -0
  18. package/dist/adapters/banal/failure.d.ts +73 -0
  19. package/dist/adapters/banal/failure.d.ts.map +1 -0
  20. package/dist/adapters/banal/failure.js +58 -0
  21. package/dist/adapters/banal/failure.js.map +1 -0
  22. package/dist/adapters/banal/index.d.ts +17 -0
  23. package/dist/adapters/banal/index.d.ts.map +1 -0
  24. package/dist/adapters/banal/index.js +56 -0
  25. package/dist/adapters/banal/index.js.map +1 -0
  26. package/dist/adapters/banal/install.d.ts +26 -0
  27. package/dist/adapters/banal/install.d.ts.map +1 -0
  28. package/dist/adapters/banal/install.js +15 -0
  29. package/dist/adapters/banal/install.js.map +1 -0
  30. package/dist/adapters/banal/invocation.d.ts +48 -0
  31. package/dist/adapters/banal/invocation.d.ts.map +1 -0
  32. package/dist/adapters/banal/invocation.js +43 -0
  33. package/dist/adapters/banal/invocation.js.map +1 -0
  34. package/dist/adapters/banal/locate.d.ts +50 -0
  35. package/dist/adapters/banal/locate.d.ts.map +1 -0
  36. package/dist/adapters/banal/locate.js +34 -0
  37. package/dist/adapters/banal/locate.js.map +1 -0
  38. package/dist/adapters/banal/output.d.ts +27 -0
  39. package/dist/adapters/banal/output.d.ts.map +1 -0
  40. package/dist/adapters/banal/output.js +112 -0
  41. package/dist/adapters/banal/output.js.map +1 -0
  42. package/dist/adapters/banal/pin.d.ts +19 -0
  43. package/dist/adapters/banal/pin.d.ts.map +1 -0
  44. package/dist/adapters/banal/pin.js +15 -0
  45. package/dist/adapters/banal/pin.js.map +1 -0
  46. package/dist/adapters/banal/probe.d.ts +12 -0
  47. package/dist/adapters/banal/probe.d.ts.map +1 -0
  48. package/dist/adapters/banal/probe.js +27 -0
  49. package/dist/adapters/banal/probe.js.map +1 -0
  50. package/dist/adapters/banal/run.d.ts +89 -0
  51. package/dist/adapters/banal/run.d.ts.map +1 -0
  52. package/dist/adapters/banal/run.js +104 -0
  53. package/dist/adapters/banal/run.js.map +1 -0
  54. package/dist/adapters/banal/settings.d.ts +18 -0
  55. package/dist/adapters/banal/settings.d.ts.map +1 -0
  56. package/dist/adapters/banal/settings.js +29 -0
  57. package/dist/adapters/banal/settings.js.map +1 -0
  58. package/dist/adapters/banal/xml.d.ts +48 -0
  59. package/dist/adapters/banal/xml.d.ts.map +1 -0
  60. package/dist/adapters/banal/xml.js +67 -0
  61. package/dist/adapters/banal/xml.js.map +1 -0
  62. package/dist/adapters/curl/download.io.d.ts +14 -0
  63. package/dist/adapters/curl/download.io.d.ts.map +1 -0
  64. package/dist/adapters/curl/download.io.js +69 -0
  65. package/dist/adapters/curl/download.io.js.map +1 -0
  66. package/dist/adapters/curl/index.d.ts +6 -0
  67. package/dist/adapters/curl/index.d.ts.map +1 -0
  68. package/dist/adapters/curl/index.js +6 -0
  69. package/dist/adapters/curl/index.js.map +1 -0
  70. package/dist/adapters/memory/index.d.ts +43 -0
  71. package/dist/adapters/memory/index.d.ts.map +1 -0
  72. package/dist/adapters/memory/index.js +79 -0
  73. package/dist/adapters/memory/index.js.map +1 -0
  74. package/dist/adapters/node/files.io.d.ts +3 -0
  75. package/dist/adapters/node/files.io.d.ts.map +1 -0
  76. package/dist/adapters/node/files.io.js +31 -0
  77. package/dist/adapters/node/files.io.js.map +1 -0
  78. package/dist/adapters/node/host.io.d.ts +3 -0
  79. package/dist/adapters/node/host.io.d.ts.map +1 -0
  80. package/dist/adapters/node/host.io.js +14 -0
  81. package/dist/adapters/node/host.io.js.map +1 -0
  82. package/dist/adapters/node/index.d.ts +25 -0
  83. package/dist/adapters/node/index.d.ts.map +1 -0
  84. package/dist/adapters/node/index.js +14 -0
  85. package/dist/adapters/node/index.js.map +1 -0
  86. package/dist/adapters/node/process.io.d.ts +14 -0
  87. package/dist/adapters/node/process.io.d.ts.map +1 -0
  88. package/dist/adapters/node/process.io.js +41 -0
  89. package/dist/adapters/node/process.io.js.map +1 -0
  90. package/dist/adapters/node/workspace.io.d.ts +4 -0
  91. package/dist/adapters/node/workspace.io.d.ts.map +1 -0
  92. package/dist/adapters/node/workspace.io.js +33 -0
  93. package/dist/adapters/node/workspace.io.js.map +1 -0
  94. package/dist/adapters/pdfjs/fill.d.ts +42 -0
  95. package/dist/adapters/pdfjs/fill.d.ts.map +1 -0
  96. package/dist/adapters/pdfjs/fill.js +91 -0
  97. package/dist/adapters/pdfjs/fill.js.map +1 -0
  98. package/dist/build-engine.d.ts +48 -0
  99. package/dist/build-engine.d.ts.map +1 -0
  100. package/dist/build-engine.js +148 -0
  101. package/dist/build-engine.js.map +1 -0
  102. package/dist/build.d.ts +163 -0
  103. package/dist/build.d.ts.map +1 -0
  104. package/dist/build.js +575 -0
  105. package/dist/build.js.map +1 -0
  106. package/dist/cli.d.ts +151 -0
  107. package/dist/cli.d.ts.map +1 -0
  108. package/dist/cli.js +951 -0
  109. package/dist/cli.js.map +1 -0
  110. package/dist/doctor.d.ts +42 -0
  111. package/dist/doctor.d.ts.map +1 -0
  112. package/dist/doctor.js +280 -0
  113. package/dist/doctor.js.map +1 -0
  114. package/dist/domain/geometry.d.ts +71 -0
  115. package/dist/domain/geometry.d.ts.map +1 -0
  116. package/dist/domain/geometry.js +35 -0
  117. package/dist/domain/geometry.js.map +1 -0
  118. package/dist/domain/host.d.ts +16 -0
  119. package/dist/domain/host.d.ts.map +1 -0
  120. package/dist/domain/host.js +8 -0
  121. package/dist/domain/host.js.map +1 -0
  122. package/dist/domain/page-layout.d.ts +34 -0
  123. package/dist/domain/page-layout.d.ts.map +1 -0
  124. package/dist/domain/page-layout.js +8 -0
  125. package/dist/domain/page-layout.js.map +1 -0
  126. package/dist/domain/paths.d.ts +5 -0
  127. package/dist/domain/paths.d.ts.map +1 -0
  128. package/dist/domain/paths.js +2 -0
  129. package/dist/domain/paths.js.map +1 -0
  130. package/dist/domain/result.d.ts +23 -0
  131. package/dist/domain/result.d.ts.map +1 -0
  132. package/dist/domain/result.js +10 -0
  133. package/dist/domain/result.js.map +1 -0
  134. package/dist/domain/sha256.d.ts +7 -0
  135. package/dist/domain/sha256.d.ts.map +1 -0
  136. package/dist/domain/sha256.js +14 -0
  137. package/dist/domain/sha256.js.map +1 -0
  138. package/dist/domain/text.d.ts +6 -0
  139. package/dist/domain/text.d.ts.map +1 -0
  140. package/dist/domain/text.js +7 -0
  141. package/dist/domain/text.js.map +1 -0
  142. package/dist/engine.d.ts +93 -0
  143. package/dist/engine.d.ts.map +1 -0
  144. package/dist/engine.js +119 -0
  145. package/dist/engine.js.map +1 -0
  146. package/dist/exit-code.d.ts +22 -0
  147. package/dist/exit-code.d.ts.map +1 -0
  148. package/dist/exit-code.js +10 -0
  149. package/dist/exit-code.js.map +1 -0
  150. package/dist/facts-file.d.ts +96 -0
  151. package/dist/facts-file.d.ts.map +1 -0
  152. package/dist/facts-file.js +134 -0
  153. package/dist/facts-file.js.map +1 -0
  154. package/dist/hooks-settings.d.ts +141 -0
  155. package/dist/hooks-settings.d.ts.map +1 -0
  156. package/dist/hooks-settings.js +306 -0
  157. package/dist/hooks-settings.js.map +1 -0
  158. package/dist/init.d.ts +201 -0
  159. package/dist/init.d.ts.map +1 -0
  160. package/dist/init.js +579 -0
  161. package/dist/init.js.map +1 -0
  162. package/dist/latex-log.d.ts +80 -0
  163. package/dist/latex-log.d.ts.map +1 -0
  164. package/dist/latex-log.js +187 -0
  165. package/dist/latex-log.js.map +1 -0
  166. package/dist/latex-loop.d.ts +129 -0
  167. package/dist/latex-loop.d.ts.map +1 -0
  168. package/dist/latex-loop.js +113 -0
  169. package/dist/latex-loop.js.map +1 -0
  170. package/dist/link-skills.d.ts +51 -0
  171. package/dist/link-skills.d.ts.map +1 -0
  172. package/dist/link-skills.js +199 -0
  173. package/dist/link-skills.js.map +1 -0
  174. package/dist/new-paper.d.ts +48 -0
  175. package/dist/new-paper.d.ts.map +1 -0
  176. package/dist/new-paper.js +110 -0
  177. package/dist/new-paper.js.map +1 -0
  178. package/dist/pdf-facts.d.ts +44 -0
  179. package/dist/pdf-facts.d.ts.map +1 -0
  180. package/dist/pdf-facts.js +239 -0
  181. package/dist/pdf-facts.js.map +1 -0
  182. package/dist/pdf-geometry.d.ts +170 -0
  183. package/dist/pdf-geometry.d.ts.map +1 -0
  184. package/dist/pdf-geometry.js +158 -0
  185. package/dist/pdf-geometry.js.map +1 -0
  186. package/dist/ports/download.d.ts +9 -0
  187. package/dist/ports/download.d.ts.map +1 -0
  188. package/dist/ports/download.js +2 -0
  189. package/dist/ports/download.js.map +1 -0
  190. package/dist/ports/files.d.ts +11 -0
  191. package/dist/ports/files.d.ts.map +1 -0
  192. package/dist/ports/files.js +2 -0
  193. package/dist/ports/files.js.map +1 -0
  194. package/dist/ports/measure-geometry.d.ts +8 -0
  195. package/dist/ports/measure-geometry.d.ts.map +1 -0
  196. package/dist/ports/measure-geometry.js +2 -0
  197. package/dist/ports/measure-geometry.js.map +1 -0
  198. package/dist/ports/process.d.ts +45 -0
  199. package/dist/ports/process.d.ts.map +1 -0
  200. package/dist/ports/process.js +2 -0
  201. package/dist/ports/process.js.map +1 -0
  202. package/dist/ports/tool-installer.d.ts +29 -0
  203. package/dist/ports/tool-installer.d.ts.map +1 -0
  204. package/dist/ports/tool-installer.js +2 -0
  205. package/dist/ports/tool-installer.js.map +1 -0
  206. package/dist/ports/workspace.d.ts +18 -0
  207. package/dist/ports/workspace.d.ts.map +1 -0
  208. package/dist/ports/workspace.js +2 -0
  209. package/dist/ports/workspace.js.map +1 -0
  210. package/dist/rules-config.d.ts +34 -0
  211. package/dist/rules-config.d.ts.map +1 -0
  212. package/dist/rules-config.js +132 -0
  213. package/dist/rules-config.js.map +1 -0
  214. package/dist/structure.d.ts +34 -0
  215. package/dist/structure.d.ts.map +1 -0
  216. package/dist/structure.js +149 -0
  217. package/dist/structure.js.map +1 -0
  218. package/dist/tex-requirements.d.ts +43 -0
  219. package/dist/tex-requirements.d.ts.map +1 -0
  220. package/dist/tex-requirements.js +127 -0
  221. package/dist/tex-requirements.js.map +1 -0
  222. package/dist/toolchain.d.ts +159 -0
  223. package/dist/toolchain.d.ts.map +1 -0
  224. package/dist/toolchain.js +542 -0
  225. package/dist/toolchain.js.map +1 -0
  226. package/dist/types.d.ts +110 -0
  227. package/dist/types.d.ts.map +1 -0
  228. package/dist/types.js +2 -0
  229. package/dist/types.js.map +1 -0
  230. package/docs/configuration.md +235 -0
  231. package/docs/e2e.md +152 -0
  232. package/docs/incidents.md +59 -0
  233. package/docs/install.md +170 -0
  234. package/docs/optional-rules.md +107 -0
  235. package/docs/package-shape-options.md +262 -0
  236. package/docs/prior-art/README.md +76 -0
  237. package/docs/prior-art/blocking-vs-advisory.md +83 -0
  238. package/docs/prior-art/content-delivery.md +124 -0
  239. package/docs/prior-art/multi-mode-tools.md +106 -0
  240. package/docs/prior-art/nondeterministic-checks.md +99 -0
  241. package/docs/prior-art/package-location.md +422 -0
  242. package/docs/prior-art/paper-folder-scaffolding.md +538 -0
  243. package/docs/prior-art/readme-structure.md +69 -0
  244. package/docs/prior-art/repro/README.md +92 -0
  245. package/docs/prior-art/repro/claim1-allowedtools.mjs +66 -0
  246. package/docs/prior-art/repro/claim1-at2.mjs +40 -0
  247. package/docs/prior-art/repro/claim1-crosschannel.mjs +54 -0
  248. package/docs/prior-art/repro/claim1-frontmatter.mjs +76 -0
  249. package/docs/prior-art/repro/claim1-hook-payload-reporter.mjs +10 -0
  250. package/docs/prior-art/repro/claim1-plugin-frontmatter.mjs +27 -0
  251. package/docs/prior-art/repro/claim1-plugin-skill.mjs +52 -0
  252. package/docs/prior-art/repro/claim1-project-skill.mjs +81 -0
  253. package/docs/prior-art/repro/claim2-marketplace-flat-asclaimed.json +1 -0
  254. package/docs/prior-art/repro/claim2-marketplace-negative-control.json +1 -0
  255. package/docs/prior-art/repro/claim2-marketplace-nested-exact.json +9 -0
  256. package/docs/prior-art/repro/claim2-marketplace-nested-noversion.json +9 -0
  257. package/docs/prior-art/repro/claim2-marketplace-nested-range.json +1 -0
  258. package/docs/prior-art/repro/claim3-imports.mjs +50 -0
  259. package/docs/prior-art/repro/claim4-find-package-json.mjs +8 -0
  260. package/docs/prior-art/repro/claim4-package-dir.mjs +39 -0
  261. package/docs/prior-art/repro/claim4-parent-arg.mjs +17 -0
  262. package/docs/prior-art/repro/claim4-resolve-apis.mjs +21 -0
  263. package/docs/prior-art/repro/claim4-setup-consumers.mjs +45 -0
  264. package/docs/prior-art/repro/claim4-yarn-pnp.mjs +70 -0
  265. package/docs/prior-art/repro/claim5-bin-launch.mjs +39 -0
  266. package/docs/prior-art/repro/claim5-exports-mutation.mjs +57 -0
  267. package/docs/prior-art/repro/claim5-resolved-location-and-bin.mjs +33 -0
  268. package/docs/prior-art/repro/claim6-candidate-ambiguity.mjs +17 -0
  269. package/docs/prior-art/repro/claim6-doc-path-candidates.mjs +27 -0
  270. package/docs/prior-art/test-tooling.md +131 -0
  271. package/docs/rules.md +58 -0
  272. package/docs/texlive-install-decision.md +230 -0
  273. package/docs/toolchain.md +152 -0
  274. package/eslint-rules/doc-fields.harness.mjs +336 -0
  275. package/eslint-rules/doc-fields.mjs +186 -0
  276. package/eslint-rules/doc-fields.mutations.mjs +96 -0
  277. package/eslint-rules/install-path-literals.harness.mjs +121 -0
  278. package/eslint-rules/install-path-literals.mjs +108 -0
  279. package/eslint-rules/install-path-literals.mutations.mjs +62 -0
  280. package/eslint-rules/latex-language.harness.mjs +599 -0
  281. package/eslint-rules/latex-language.mjs +591 -0
  282. package/eslint-rules/latex-language.mutations.mjs +196 -0
  283. package/eslint-rules/paper-research-question.harness.mjs +146 -0
  284. package/eslint-rules/paper-research-question.mjs +180 -0
  285. package/eslint-rules/paper-research-question.mutations.mjs +127 -0
  286. package/eslint-rules/paper-stages.harness.mjs +356 -0
  287. package/eslint-rules/paper-stages.mjs +455 -0
  288. package/eslint-rules/paper-stages.mutations.mjs +157 -0
  289. package/eslint-rules/paper-typography.harness.mjs +291 -0
  290. package/eslint-rules/paper-typography.mjs +313 -0
  291. package/eslint-rules/paper-typography.mutations.mjs +131 -0
  292. package/eslint-rules/papers.harness.mjs +259 -0
  293. package/eslint-rules/papers.mjs +166 -0
  294. package/eslint-rules/papers.mutations.mjs +186 -0
  295. package/eslint-rules/pdf-last-page-balance.harness.mjs +206 -0
  296. package/eslint-rules/pdf-last-page-balance.mjs +208 -0
  297. package/eslint-rules/review-findings-cause.harness.mjs +228 -0
  298. package/eslint-rules/review-findings-cause.mjs +135 -0
  299. package/eslint-rules/review-findings-cause.mutations.mjs +72 -0
  300. package/eslint-rules/temp-root-realpath.harness.mjs +176 -0
  301. package/eslint-rules/temp-root-realpath.mjs +129 -0
  302. package/eslint-rules/temp-root-realpath.mutations.mjs +99 -0
  303. package/eslint-rules/tex-build.harness.mjs +753 -0
  304. package/eslint-rules/tex-build.mjs +322 -0
  305. package/eslint-rules/tex-build.mutations.mjs +258 -0
  306. package/eslint.config.mjs +521 -0
  307. package/fixtures/build-e2e/acmart/PIPELINE-STATUS.md +3 -0
  308. package/fixtures/build-e2e/acmart/paper.tex +11 -0
  309. package/fixtures/build-e2e/acmart/venue.json +1 -0
  310. package/fixtures/build-e2e/broken/PIPELINE-STATUS.md +3 -0
  311. package/fixtures/build-e2e/broken/paper.tex +7 -0
  312. package/fixtures/build-e2e/cite/PIPELINE-STATUS.md +3 -0
  313. package/fixtures/build-e2e/cite/build.sh +5 -0
  314. package/fixtures/build-e2e/cite/paper.tex +10 -0
  315. package/fixtures/build-e2e/cite/refs.bib +9 -0
  316. package/fixtures/build-e2e/empty/PIPELINE-STATUS.md +3 -0
  317. package/fixtures/build-e2e/empty/paper.tex +6 -0
  318. package/fixtures/build-e2e/fallback/PIPELINE-STATUS.md +3 -0
  319. package/fixtures/build-e2e/fallback/paper.tex +11 -0
  320. package/fixtures/build-e2e/guards/PIPELINE-STATUS.md +3 -0
  321. package/fixtures/build-e2e/guards/paper.tex +10 -0
  322. package/fixtures/build-e2e/no-source/PIPELINE-STATUS.md +3 -0
  323. package/fixtures/build-e2e/unbalanced/PIPELINE-STATUS.md +3 -0
  324. package/fixtures/build-e2e/unbalanced/paper.tex +28 -0
  325. package/fixtures/build-e2e/unbalanced/refs.bib +269 -0
  326. package/fixtures/install-path-literals/clean.fixture.mjs +3 -0
  327. package/fixtures/install-path-literals/clean.md +15 -0
  328. package/fixtures/install-path-literals/defect.fixture.mjs +3 -0
  329. package/fixtures/install-path-literals/defect.md +14 -0
  330. package/fixtures/latex-language/clean.tex +50 -0
  331. package/fixtures/latex-language/defect.tex +52 -0
  332. package/fixtures/paper-research-question/comment-only/PIPELINE-STATUS.md +9 -0
  333. package/fixtures/paper-research-question/comment-only/paper.tex +7 -0
  334. package/fixtures/paper-research-question/declared-not-in-paper/PIPELINE-STATUS.md +10 -0
  335. package/fixtures/paper-research-question/declared-not-in-paper/paper.tex +6 -0
  336. package/fixtures/paper-research-question/draft/PIPELINE-STATUS.md +6 -0
  337. package/fixtures/paper-research-question/draft/paper.tex +2 -0
  338. package/fixtures/paper-research-question/markdown-no-rq/PIPELINE-STATUS.md +9 -0
  339. package/fixtures/paper-research-question/markdown-no-rq/paper.md +4 -0
  340. package/fixtures/paper-research-question/shipped-no-rq/PIPELINE-STATUS.md +12 -0
  341. package/fixtures/paper-research-question/shipped-no-rq/paper.tex +3 -0
  342. package/fixtures/paper-research-question/shipped-with-rq/PIPELINE-STATUS.md +10 -0
  343. package/fixtures/paper-research-question/shipped-with-rq/paper.tex +2 -0
  344. package/fixtures/paper-stages/authors-ran/PIPELINE-STATUS.md +16 -0
  345. package/fixtures/paper-stages/marker-in-prose/PIPELINE-STATUS.md +17 -0
  346. package/fixtures/paper-stages/nofile/PIPELINE-STATUS.md +8 -0
  347. package/fixtures/paper-stages/noheader/PIPELINE-STATUS.md +1 -0
  348. package/fixtures/paper-stages/noheader/versions/2026-07-22-submitted.pdf +0 -0
  349. package/fixtures/paper-stages/nothing/PIPELINE-STATUS.md +3 -0
  350. package/fixtures/paper-stages/ok/PIPELINE-STATUS.md +9 -0
  351. package/fixtures/paper-stages/ok/versions/2026-07-22-submitted.pdf +0 -0
  352. package/fixtures/paper-stages/stale/PIPELINE-STATUS.md +1 -0
  353. package/fixtures/paper-stages/stale/versions/2026-07-22-submitted.STALE-WRONG-FILE.pdf +0 -0
  354. package/fixtures/paper-stages/twice/PIPELINE-STATUS.md +14 -0
  355. package/fixtures/paper-stages/twice/versions/2026-08-06-submitted.pdf +0 -0
  356. package/fixtures/paper-stages/twice/versions/2026-10-24-submitted.pdf +0 -0
  357. package/fixtures/paper-stages/undeclared/PIPELINE-STATUS.md +8 -0
  358. package/fixtures/paper-stages/undeclared/versions/2026-07-22-submitted.pdf +0 -0
  359. package/fixtures/paper-stages/undeclared/versions/2026-08-29-camera-ready.pdf +0 -0
  360. package/fixtures/paper-stages/wrongsize/PIPELINE-STATUS.md +8 -0
  361. package/fixtures/paper-stages/wrongsize/versions/2026-07-22-submitted.pdf +0 -0
  362. package/fixtures/paper-typography/clean-paper/paper.tex +29 -0
  363. package/fixtures/paper-typography/messy-paper/paper.tex +27 -0
  364. package/fixtures/pdf-facts/README.md +22 -0
  365. package/fixtures/pdf-facts/corrupt-font.pdf +0 -0
  366. package/fixtures/pdf-facts/encrypted.pdf +0 -0
  367. package/fixtures/pdf-facts/hidden-text.pdf +0 -0
  368. package/fixtures/pdf-facts/hidden-text.tex +28 -0
  369. package/fixtures/pdf-facts/t3-all.pdf +0 -0
  370. package/fixtures/pdf-facts/t3-all.tex +8 -0
  371. package/fixtures/pdf-facts/t3-mixed.pdf +0 -0
  372. package/fixtures/pdf-facts/t3-mixed.tex +9 -0
  373. package/fixtures/pdf-facts/ttf.pdf +2240 -1
  374. package/fixtures/pdf-facts/ttf.tex +6 -0
  375. package/fixtures/real-markdown-paper/baseline.json +24 -0
  376. package/fixtures/real-markdown-paper/baseline.mjs +48 -0
  377. package/fixtures/render-paper/build-clean.sh +25 -0
  378. package/fixtures/render-paper/build-defect.sh +15 -0
  379. package/fixtures/review-findings-cause/clean.md +17 -0
  380. package/fixtures/review-findings-cause/defect.md +14 -0
  381. package/fixtures/review-findings-cause/old-debt.md +14 -0
  382. package/fixtures/review-findings-cause/quiet-in-fence.md +16 -0
  383. package/fixtures/tex-build/clean.tex +21 -0
  384. package/fixtures/tex-build/defect.tex +24 -0
  385. package/fixtures/tex-build/frontmatter-clean.tex +25 -0
  386. package/fixtures/tex-build/frontmatter-defect.tex +23 -0
  387. package/fixtures/toolchain-mirror/catalog.txt +5 -0
  388. package/fixtures/toolchain-mirror/install-tl +27 -0
  389. package/fixtures/toolchain-mirror/release-texlive.txt +3 -0
  390. package/fixtures/toolchain-mirror/release-year +1 -0
  391. package/fixtures/toolchain-mirror/stub-kpsewhich +8 -0
  392. package/fixtures/toolchain-mirror/stub-pdflatex +3 -0
  393. package/fixtures/toolchain-mirror/stub-tlmgr +44 -0
  394. package/hooks/hooks.harness.mjs +713 -0
  395. package/hooks/hooks.mutations.mjs +337 -0
  396. package/hooks/paper-edit-guard.hook.d.mts +13 -0
  397. package/hooks/paper-edit-guard.hook.mjs +457 -0
  398. package/hooks/paper-skills-nudge.hook.mjs +136 -0
  399. package/hooks/paper-status-gates.hook.mjs +156 -0
  400. package/hooks/paper-status-gates.sh +91 -0
  401. package/lib/agent-cli-version.harness.mjs +165 -0
  402. package/lib/agent-cli-version.mjs +106 -0
  403. package/lib/agent-cli-version.mutations.mjs +109 -0
  404. package/lib/markdown.mjs +386 -0
  405. package/lib/mutation-driver.harness.mjs +227 -0
  406. package/lib/mutation-driver.mjs +397 -0
  407. package/lib/mutation-driver.mutations.mjs +68 -0
  408. package/lib/paper-config.d.mts +34 -0
  409. package/lib/paper-config.harness.mjs +286 -0
  410. package/lib/paper-config.mjs +142 -0
  411. package/lib/paper-config.mutations.mjs +143 -0
  412. package/lib/skill-checks.mjs +701 -0
  413. package/lib/skill-corpus.mjs +403 -0
  414. package/lib/skill-eval-fixture.mjs +63 -0
  415. package/lib/skill-eval-kit.mjs +257 -0
  416. package/lib/skill-trigger-cases.harness.mjs +170 -0
  417. package/lib/skill-trigger-cases.mjs +446 -0
  418. package/lib/skill-trigger-cases.mutations.mjs +65 -0
  419. package/lib/trigger-ledger.mjs +215 -0
  420. package/package.json +97 -0
  421. package/plugin/.claude-plugin/plugin.json +8 -0
  422. package/plugin/hooks/hooks.json +30 -0
  423. package/scripts/check.harness.mjs +177 -0
  424. package/scripts/check.mjs +239 -0
  425. package/scripts/check.mutations.mjs +110 -0
  426. package/scripts/eslint-report-guard.mjs +82 -0
  427. package/scripts/exclusive.mjs +138 -0
  428. package/scripts/harness-api.frozen.json +76 -0
  429. package/scripts/harness-api.test.ts +175 -0
  430. package/scripts/layer-legacy-frozen.d.mts +28 -0
  431. package/scripts/layer-legacy-frozen.mjs +152 -0
  432. package/scripts/layer-legacy-frozen.test.ts +115 -0
  433. package/scripts/layer-legacy.frozen.json +50 -0
  434. package/scripts/mutation-batteries-frozen.harness.mjs +204 -0
  435. package/scripts/mutation-batteries-frozen.mjs +238 -0
  436. package/scripts/mutation-batteries.frozen.json +117 -0
  437. package/scripts/release-config.test.ts +90 -0
  438. package/scripts/rules-are-content-only.harness.mjs +113 -0
  439. package/scripts/rules-are-content-only.mjs +138 -0
  440. package/scripts/rules-are-content-only.mutations.mjs +81 -0
  441. package/scripts/rules-see-files.harness.mjs +115 -0
  442. package/scripts/rules-see-files.mjs +99 -0
  443. package/scripts/rules-see-files.mutations.mjs +131 -0
  444. package/scripts/run-mutations.mjs +100 -0
  445. package/scripts/semantic-release-plugins.d.ts +16 -0
  446. package/skills/README.md +15 -0
  447. package/skills/analyze-sibling-paper/SKILL.md +170 -0
  448. package/skills/analyze-sibling-paper/SKILL.md.spec.ts +186 -0
  449. package/skills/analyze-sibling-paper/analyze-sibling-paper.eval.mjs +19 -0
  450. package/skills/analyze-sibling-paper/analyze-sibling-paper.harness.mjs +23 -0
  451. package/skills/argument-arc/SKILL.md +177 -0
  452. package/skills/argument-arc/SKILL.md.spec.ts +192 -0
  453. package/skills/argument-arc/argument-arc.eval.mjs +19 -0
  454. package/skills/argument-arc/argument-arc.harness.mjs +23 -0
  455. package/skills/build-benchmark/SKILL.md +213 -0
  456. package/skills/build-benchmark/SKILL.md.spec.ts +220 -0
  457. package/skills/build-benchmark/build-benchmark.eval.mjs +19 -0
  458. package/skills/build-benchmark/build-benchmark.harness.mjs +23 -0
  459. package/skills/build-benchmark/references/adversarial-cold-repro.md +68 -0
  460. package/skills/camera-ready/SKILL.md +148 -0
  461. package/skills/camera-ready/SKILL.md.spec.ts +164 -0
  462. package/skills/camera-ready/camera-ready.eval.mjs +19 -0
  463. package/skills/camera-ready/camera-ready.harness.mjs +23 -0
  464. package/skills/cold-read-diff/SKILL.md +160 -0
  465. package/skills/cold-read-diff/SKILL.md.spec.ts +166 -0
  466. package/skills/cold-read-diff/cold-read-diff.eval.mjs +19 -0
  467. package/skills/cold-read-diff/cold-read-diff.harness.mjs +23 -0
  468. package/skills/draft-paper/SKILL.md +152 -0
  469. package/skills/draft-paper/SKILL.md.spec.ts +169 -0
  470. package/skills/draft-paper/draft-paper.eval.mjs +19 -0
  471. package/skills/draft-paper/draft-paper.harness.mjs +23 -0
  472. package/skills/extend-paper/SKILL.md +99 -0
  473. package/skills/extend-paper/SKILL.md.spec.ts +116 -0
  474. package/skills/extend-paper/extend-paper.eval.mjs +19 -0
  475. package/skills/extend-paper/extend-paper.harness.mjs +23 -0
  476. package/skills/find-venue/SKILL.md +128 -0
  477. package/skills/find-venue/SKILL.md.spec.ts +145 -0
  478. package/skills/find-venue/find-venue.eval.mjs +19 -0
  479. package/skills/find-venue/find-venue.harness.mjs +23 -0
  480. package/skills/grade-paper-writing/SKILL.md +436 -0
  481. package/skills/grade-paper-writing/SKILL.md.spec.ts +453 -0
  482. package/skills/grade-paper-writing/fixtures/control_gopen.txt +1 -0
  483. package/skills/grade-paper-writing/fixtures/control_human_paper.txt +1 -0
  484. package/skills/grade-paper-writing/fixtures/rewrite.txt +1 -0
  485. package/skills/grade-paper-writing/fixtures/specimen.txt +1 -0
  486. package/skills/grade-paper-writing/fixtures/structure-checks.md +22 -0
  487. package/skills/grade-paper-writing/grade-paper-writing.eval.mjs +19 -0
  488. package/skills/grade-paper-writing/grade-paper-writing.harness.mjs +23 -0
  489. package/skills/grade-paper-writing/prose-lint.mjs +713 -0
  490. package/skills/harden-paper/SKILL.md +318 -0
  491. package/skills/harden-paper/SKILL.md.spec.ts +336 -0
  492. package/skills/harden-paper/check-numbers.sh +33 -0
  493. package/skills/harden-paper/check-release-claims.sh +35 -0
  494. package/skills/harden-paper/fixtures/uncited-assertions-sample.md +43 -0
  495. package/skills/harden-paper/fixtures/uncited-assertions-sample.tex +77 -0
  496. package/skills/harden-paper/harden-paper.eval.mjs +19 -0
  497. package/skills/harden-paper/harden-paper.harness.mjs +23 -0
  498. package/skills/map-prior-work/SKILL.md +211 -0
  499. package/skills/map-prior-work/SKILL.md.spec.ts +227 -0
  500. package/skills/map-prior-work/map-prior-work.eval.mjs +19 -0
  501. package/skills/map-prior-work/map-prior-work.harness.mjs +23 -0
  502. package/skills/osf-artifact-upload/SKILL.md +52 -0
  503. package/skills/osf-artifact-upload/SKILL.md.spec.ts +59 -0
  504. package/skills/osf-artifact-upload/osf-artifact-upload.eval.mjs +22 -0
  505. package/skills/osf-artifact-upload/osf-artifact-upload.harness.mjs +103 -0
  506. package/skills/paper-adversarial-review/SKILL.md +126 -0
  507. package/skills/paper-adversarial-review/SKILL.md.spec.ts +142 -0
  508. package/skills/paper-adversarial-review/paper-adversarial-review.eval.mjs +19 -0
  509. package/skills/paper-adversarial-review/paper-adversarial-review.harness.mjs +23 -0
  510. package/skills/paper-pipeline/PIPELINE-MAP.md +371 -0
  511. package/skills/paper-pipeline/SKILL.md +499 -0
  512. package/skills/paper-pipeline/SKILL.md.spec.ts +517 -0
  513. package/skills/paper-pipeline/description-language.eval.mjs +347 -0
  514. package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +891 -0
  515. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1254 -0
  516. package/skills/paper-pipeline/paper-pipeline.eval.mjs +22 -0
  517. package/skills/paper-pipeline/paper-pipeline.harness.mjs +143 -0
  518. package/skills/paper-pipeline/pipeline-firing.baseline.json +270 -0
  519. package/skills/paper-pipeline/pipeline-firing.eval.mjs +664 -0
  520. package/skills/paper-pipeline/pipeline-language.eval.mjs +672 -0
  521. package/skills/paper-pipeline/references/acceptance-gate.md +329 -0
  522. package/skills/paper-pipeline/references/acl-venue-rules.md +142 -0
  523. package/skills/paper-pipeline/references/anonymization.md +68 -0
  524. package/skills/paper-pipeline/references/artifact-checklist.md +93 -0
  525. package/skills/paper-pipeline/references/body-vs-appendix.md +97 -0
  526. package/skills/paper-pipeline/references/credit-criteria.md +69 -0
  527. package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/README.md +35 -0
  528. package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/run_retext.mjs +24 -0
  529. package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/sentences.txt +11 -0
  530. package/skills/paper-pipeline/references/occupancy-2026-08-06-probe/test_sentences.py +25 -0
  531. package/skills/paper-pipeline/references/occupancy-2026-08-06-prose-checkers.md +538 -0
  532. package/skills/paper-pipeline/references/occupancy-2026-08-06-reproducible-tooling.md +431 -0
  533. package/skills/paper-pipeline/references/occupancy-2026-08-06-staleness-and-orchestration.md +592 -0
  534. package/skills/paper-pipeline/references/pipeline-status-template.md +162 -0
  535. package/skills/paper-pipeline/references/review-ratchet.md +36 -0
  536. package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +585 -0
  537. package/skills/paper-pipeline/references/writing-craft.md +448 -0
  538. package/skills/paper-pipeline/repro/2026-08-07-description-language-control.log +63 -0
  539. package/skills/paper-pipeline/repro/2026-08-07-fork-check.log +52 -0
  540. package/skills/paper-pipeline/repro/2026-08-07-fork-check2.log +33 -0
  541. package/skills/paper-pipeline/repro/2026-08-07-language-eval-pilot.log +33 -0
  542. package/skills/paper-pipeline/repro/2026-08-07-language-eval-raw.log +166 -0
  543. package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-oracle.json +338 -0
  544. package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-oracle.log +118 -0
  545. package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-raw.log +245 -0
  546. package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary.json +776 -0
  547. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-A6-oracle.log +53 -0
  548. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-A6-raw.log +89 -0
  549. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-oracle.json +450 -0
  550. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-oracle.log +136 -0
  551. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-raw.log +242 -0
  552. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-setupdiff.log +59 -0
  553. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation.json +1032 -0
  554. package/skills/paper-pipeline/repro/2026-08-08-parent-replication-gpw.json +139 -0
  555. package/skills/paper-pipeline/repro/2026-08-08-parent-replication-gpw.log +98 -0
  556. package/skills/paper-pipeline/repro/2026-08-08-parent-replication.mjs +92 -0
  557. package/skills/paper-pipeline/repro/README.md +129 -0
  558. package/skills/paper-pipeline/repro/analyze-language-eval.py +116 -0
  559. package/skills/paper-pipeline/scripts/README.md +344 -0
  560. package/skills/paper-pipeline/scripts/announce.mjs +67 -0
  561. package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +496 -0
  562. package/skills/paper-pipeline/scripts/artifact-coverage.mjs +397 -0
  563. package/skills/paper-pipeline/scripts/artifact-coverage.mutations.mjs +218 -0
  564. package/skills/paper-pipeline/scripts/check-provenance.mjs +184 -0
  565. package/skills/paper-pipeline/scripts/consumer.d.mts +32 -0
  566. package/skills/paper-pipeline/scripts/consumer.harness.mjs +562 -0
  567. package/skills/paper-pipeline/scripts/consumer.mjs +535 -0
  568. package/skills/paper-pipeline/scripts/consumer.mutations.mjs +190 -0
  569. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +457 -0
  570. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +656 -0
  571. package/skills/paper-pipeline/scripts/extract-ref-facts.mutations.mjs +54 -0
  572. package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +51 -0
  573. package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +52 -0
  574. package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +6 -0
  575. package/skills/paper-pipeline/scripts/fixtures/real-bib/refs.bib +153 -0
  576. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +466 -0
  577. package/skills/paper-pipeline/scripts/generated-code.mjs +338 -0
  578. package/skills/paper-pipeline/scripts/generated-code.mutations.mjs +254 -0
  579. package/skills/paper-pipeline/scripts/ledger.mjs +623 -0
  580. package/skills/paper-pipeline/scripts/ledger.selftest.mjs +286 -0
  581. package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +389 -0
  582. package/skills/paper-pipeline/scripts/pipeline-check.mjs +737 -0
  583. package/skills/paper-pipeline/scripts/pipeline-check.mutations.mjs +54 -0
  584. package/skills/paper-pipeline/scripts/pipeline-edges.mjs +169 -0
  585. package/skills/paper-pipeline/scripts/population-map.harness.mjs +178 -0
  586. package/skills/paper-pipeline/scripts/population-map.mjs +181 -0
  587. package/skills/paper-pipeline/scripts/population-map.mutations.mjs +65 -0
  588. package/skills/paper-pipeline/scripts/population-map.selftest.mjs +122 -0
  589. package/skills/paper-pipeline/scripts/provenance.harness.mjs +240 -0
  590. package/skills/paper-pipeline/scripts/provenance.mutations.mjs +59 -0
  591. package/skills/paper-pipeline/scripts/round-diff.harness.mjs +881 -0
  592. package/skills/paper-pipeline/scripts/round-diff.mjs +576 -0
  593. package/skills/paper-pipeline/scripts/round-diff.mutations.mjs +276 -0
  594. package/skills/paper-pipeline/scripts/run-mechanical.mjs +633 -0
  595. package/skills/paper-pipeline/scripts/status.mjs +295 -0
  596. package/skills/paper-status/SKILL.md +183 -0
  597. package/skills/paper-status/SKILL.md.spec.ts +190 -0
  598. package/skills/paper-status/paper-status.eval.mjs +22 -0
  599. package/skills/paper-status/paper-status.harness.mjs +25 -0
  600. package/skills/pc-panel-review/SKILL.md +263 -0
  601. package/skills/pc-panel-review/SKILL.md.spec.ts +280 -0
  602. package/skills/pc-panel-review/pc-panel-review.eval.mjs +19 -0
  603. package/skills/pc-panel-review/pc-panel-review.harness.mjs +23 -0
  604. package/skills/plan-paper-timeline/SKILL.md +182 -0
  605. package/skills/plan-paper-timeline/SKILL.md.spec.ts +200 -0
  606. package/skills/plan-paper-timeline/fixtures/fake-google-calendar.mjs +239 -0
  607. package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +431 -0
  608. package/skills/plan-paper-timeline/plan-paper-timeline.effects.mutations.mjs +65 -0
  609. package/skills/plan-paper-timeline/plan-paper-timeline.eval.mjs +19 -0
  610. package/skills/plan-paper-timeline/plan-paper-timeline.harness.mjs +23 -0
  611. package/skills/render-paper/SKILL.md +159 -0
  612. package/skills/render-paper/SKILL.md.spec.ts +166 -0
  613. package/skills/render-paper/check-render.sh +419 -0
  614. package/skills/render-paper/checkers-requirements.txt +55 -0
  615. package/skills/render-paper/ensure-checkers.sh +69 -0
  616. package/skills/render-paper/extract-pdf-facts.harness.mjs +166 -0
  617. package/skills/render-paper/extract-pdf-facts.mjs +144 -0
  618. package/skills/render-paper/render-paper.eval.mjs +19 -0
  619. package/skills/render-paper/render-paper.harness.mjs +339 -0
  620. package/skills/research-ideate/SKILL.md +136 -0
  621. package/skills/research-ideate/SKILL.md.spec.ts +152 -0
  622. package/skills/research-ideate/research-ideate.eval.mjs +19 -0
  623. package/skills/research-ideate/research-ideate.harness.mjs +23 -0
  624. package/skills/skill-contract.mutations.mjs +179 -0
  625. package/skills/study-accepted-papers/SKILL.md +206 -0
  626. package/skills/study-accepted-papers/SKILL.md.spec.ts +223 -0
  627. package/skills/study-accepted-papers/study-accepted-papers.eval.mjs +19 -0
  628. package/skills/study-accepted-papers/study-accepted-papers.harness.mjs +23 -0
  629. package/skills/submit-paper/SKILL.md +182 -0
  630. package/skills/submit-paper/SKILL.md.spec.ts +199 -0
  631. package/skills/submit-paper/check-deanon.sh +149 -0
  632. package/skills/submit-paper/references/publishers/acm.md +92 -0
  633. package/skills/submit-paper/references/venues/agenticdev.jsonc +108 -0
  634. package/skills/submit-paper/references/venues/agenticdev.md +139 -0
  635. package/skills/submit-paper/references/venues/agenticdev.tex +19 -0
  636. package/skills/submit-paper/references/venues/aisec.jsonc +101 -0
  637. package/skills/submit-paper/references/venues/aisec.md +105 -0
  638. package/skills/submit-paper/references/venues/paper-guards.tex +41 -0
  639. package/skills/submit-paper/references/venues/realm.jsonc +81 -0
  640. package/skills/submit-paper/references/venues/realm.md +155 -0
  641. package/skills/submit-paper/references/venues/tex-base.jsonc +50 -0
  642. package/skills/submit-paper/references/venues/venue-profile.schema.json +74 -0
  643. package/skills/submit-paper/submit-paper.eval.mjs +19 -0
  644. package/skills/submit-paper/submit-paper.harness.mjs +23 -0
  645. package/skills/sweep-design-space/SKILL.md +269 -0
  646. package/skills/sweep-design-space/SKILL.md.spec.ts +285 -0
  647. package/skills/sweep-design-space/sweep-design-space.eval.mjs +19 -0
  648. package/skills/sweep-design-space/sweep-design-space.harness.mjs +23 -0
  649. package/skills/tighten-paper/SKILL.md +368 -0
  650. package/skills/tighten-paper/SKILL.md.spec.ts +384 -0
  651. package/skills/tighten-paper/structure.mjs +371 -0
  652. package/skills/tighten-paper/tighten-paper.eval.mjs +19 -0
  653. package/skills/tighten-paper/tighten-paper.harness.mjs +23 -0
  654. package/skills/verify-citations/SKILL.md +328 -0
  655. package/skills/verify-citations/SKILL.md.spec.ts +345 -0
  656. package/skills/verify-citations/scripts/bib-authors.mjs +479 -0
  657. package/skills/verify-citations/scripts/bib-authors.test.mjs +175 -0
  658. package/skills/verify-citations/scripts/verify-cites.mjs +1108 -0
  659. package/skills/verify-citations/scripts/verify-cites.test.mjs +735 -0
  660. package/skills/verify-citations/verify-citations.eval.mjs +19 -0
  661. package/skills/verify-citations/verify-citations.harness.mjs +23 -0
  662. package/src/CLAUDE.md +51 -0
  663. package/src/action-ref.test.ts +26 -0
  664. package/src/action-ref.ts +15 -0
  665. package/src/adapters/banal/failure.test.ts +63 -0
  666. package/src/adapters/banal/failure.ts +118 -0
  667. package/src/adapters/banal/index.test.ts +119 -0
  668. package/src/adapters/banal/index.ts +100 -0
  669. package/src/adapters/banal/install.test.ts +20 -0
  670. package/src/adapters/banal/install.ts +41 -0
  671. package/src/adapters/banal/invocation.test.ts +74 -0
  672. package/src/adapters/banal/invocation.ts +95 -0
  673. package/src/adapters/banal/locate.test.ts +52 -0
  674. package/src/adapters/banal/locate.ts +84 -0
  675. package/src/adapters/banal/output.test.ts +140 -0
  676. package/src/adapters/banal/output.ts +141 -0
  677. package/src/adapters/banal/pin.ts +30 -0
  678. package/src/adapters/banal/probe.ts +35 -0
  679. package/src/adapters/banal/run.test.ts +191 -0
  680. package/src/adapters/banal/run.ts +244 -0
  681. package/src/adapters/banal/settings.test.ts +31 -0
  682. package/src/adapters/banal/settings.ts +55 -0
  683. package/src/adapters/banal/xml.test.ts +111 -0
  684. package/src/adapters/banal/xml.ts +112 -0
  685. package/src/adapters/curl/download.io.ts +73 -0
  686. package/src/adapters/curl/download.test.ts +55 -0
  687. package/src/adapters/curl/index.ts +5 -0
  688. package/src/adapters/memory/index.ts +131 -0
  689. package/src/adapters/node/files.io.ts +39 -0
  690. package/src/adapters/node/files.test.ts +28 -0
  691. package/src/adapters/node/host.io.ts +15 -0
  692. package/src/adapters/node/index.ts +36 -0
  693. package/src/adapters/node/process.io.ts +49 -0
  694. package/src/adapters/node/process.test.ts +46 -0
  695. package/src/adapters/node/workspace.io.ts +40 -0
  696. package/src/adapters/node/workspace.test.ts +58 -0
  697. package/src/adapters/pdfjs/fill.test.ts +111 -0
  698. package/src/adapters/pdfjs/fill.ts +141 -0
  699. package/src/build-engine.harness.mjs +314 -0
  700. package/src/build-engine.ts +219 -0
  701. package/src/build.harness.mjs +631 -0
  702. package/src/build.mutations.mjs +195 -0
  703. package/src/build.ts +793 -0
  704. package/src/cli.harness.mjs +2007 -0
  705. package/src/cli.mutations.mjs +448 -0
  706. package/src/cli.ts +1189 -0
  707. package/src/doctor.harness.mjs +396 -0
  708. package/src/doctor.mutations.mjs +175 -0
  709. package/src/doctor.ts +356 -0
  710. package/src/domain/geometry.ts +108 -0
  711. package/src/domain/host.ts +23 -0
  712. package/src/domain/page-layout.ts +32 -0
  713. package/src/domain/paths.ts +5 -0
  714. package/src/domain/result.test.ts +26 -0
  715. package/src/domain/result.ts +29 -0
  716. package/src/domain/sha256.test.ts +12 -0
  717. package/src/domain/sha256.ts +21 -0
  718. package/src/domain/text.ts +11 -0
  719. package/src/engine.harness.mjs +252 -0
  720. package/src/engine.ts +176 -0
  721. package/src/exit-code.test.ts +21 -0
  722. package/src/exit-code.ts +38 -0
  723. package/src/facts-file.test.ts +240 -0
  724. package/src/facts-file.ts +241 -0
  725. package/src/hooks-settings.harness.mjs +386 -0
  726. package/src/hooks-settings.mutations.mjs +116 -0
  727. package/src/hooks-settings.ts +434 -0
  728. package/src/init.ts +900 -0
  729. package/src/latex-log.harness.mjs +226 -0
  730. package/src/latex-log.ts +234 -0
  731. package/src/latex-loop.harness.mjs +449 -0
  732. package/src/latex-loop.ts +211 -0
  733. package/src/link-skills.harness.mjs +273 -0
  734. package/src/link-skills.mutations.mjs +136 -0
  735. package/src/link-skills.ts +258 -0
  736. package/src/new-paper.harness.mjs +216 -0
  737. package/src/new-paper.mutations.mjs +79 -0
  738. package/src/new-paper.ts +158 -0
  739. package/src/pdf-facts.harness.mjs +188 -0
  740. package/src/pdf-facts.ts +327 -0
  741. package/src/pdf-geometry.harness.mjs +254 -0
  742. package/src/pdf-geometry.ts +300 -0
  743. package/src/ports/download.ts +10 -0
  744. package/src/ports/files.ts +11 -0
  745. package/src/ports/measure-geometry.ts +8 -0
  746. package/src/ports/process.ts +46 -0
  747. package/src/ports/tool-installer.ts +33 -0
  748. package/src/ports/workspace.ts +20 -0
  749. package/src/rules-config.harness.mjs +114 -0
  750. package/src/rules-config.ts +178 -0
  751. package/src/structure.harness.mjs +179 -0
  752. package/src/structure.mutations.mjs +83 -0
  753. package/src/structure.ts +166 -0
  754. package/src/tex-requirements.harness.mjs +238 -0
  755. package/src/tex-requirements.ts +181 -0
  756. package/src/toolchain.harness.mjs +651 -0
  757. package/src/toolchain.ts +755 -0
  758. package/src/types.ts +106 -0
  759. package/templates/paper/PIPELINE-STATUS.md +72 -0
  760. package/templates/paper/paper.md +4 -0
  761. package/templates/paper/paper.tex +8 -0
  762. package/tsconfig.json +23 -0
@@ -0,0 +1,169 @@
1
+ // Compiled to SKILL.md by `vigiles compile`. Edit THIS file, never the markdown.
2
+ //
3
+ // Adopted 2026-08-17 (batch 3). Body carried over VERBATIM so the compiled diff shows
4
+ // only what the compiler adds. No `disallowedTools` fence yet — the field landed on
5
+ // `SkillSpec` in vigiles branch `claude/skill-disallowed-tools` and is not in a release
6
+ // this repo installs, so writing one here would not compile.
7
+ import { experimental_skill } from "vigiles/spec";
8
+
9
+ export default experimental_skill({
10
+ name: "draft-paper",
11
+ description:
12
+ 'Use when the numbers exist and it\'s time to WRITE the paper — "draft the paper", "turn these findings into a submission", "write the abstract/intro/threats". Gives the section skeleton of a measurement/benchmark paper plus what gets it accepted AND cited — precise claim-sizing (including an explicit "what we do NOT claim"), a construct-validity frame, an honest threats-to-validity section that turns limitations in your favor, and one memorable stat that travels. Encodes the two theses that carried real measurement papers ("measuring the wrong number", "safety theater"). NOT for grading finished prose (grade-paper-writing) or structural editing (tighten-paper) — this is the generative counterpart. Compose with build-benchmark (numbers), grade-paper-writing (prose QA), render-paper, verify-citations, then the review skills.',
13
+ tools: [
14
+ "Read",
15
+ "Write",
16
+ "Edit",
17
+ "Grep",
18
+ "Glob",
19
+ "Agent",
20
+ "Skill",
21
+ "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
+ "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
+ ],
24
+ body: `
25
+ # draft-paper — prose that survives review and gets cited
26
+
27
+ ## Run me
28
+
29
+ 🔴 FIRST, before any other step:
30
+
31
+ \`\`\`
32
+ node .claude/skills/paper-pipeline/scripts/announce.mjs draft-paper <paper-dir>
33
+ \`\`\`
34
+
35
+ An advisory pass cannot be observed failing — silence is both its error state and its normal
36
+ state — so starting is an event, and events get written down.
37
+
38
+ A measurement paper lives or dies on two things reviewers actually reward: a **reusable method/norm**
39
+ they can apply to the next system, and **claim-sizing so precise it can't be attacked**. Numbers alone
40
+ are a blog post. This skill turns \`build-benchmark\`'s output into that kind of draft.
41
+
42
+ The bar is not "is the result true" — it's "will a stranger cite this in two years." That happens when
43
+ you gave them a *way to measure something* or a *bound they can quote*, not a verdict on one tool.
44
+
45
+ ## Section skeleton (measurement/benchmark paper)
46
+ Write in this order; it's also roughly the read order a reviewer skims.
47
+
48
+ 🔴 **Decide body vs appendix as you write, not when the page limit forces it** —
49
+ \`paper-pipeline/references/body-vs-appendix.md\`. A page limit with no rule behind it evicts whatever
50
+ was written last, which is reliably the honest qualification nobody had room for. The rule in one
51
+ line: the body carries everything a reviewer's decision depends on, and **a bound that narrows a
52
+ number in the body stays in the body**.
53
+
54
+ 1. **Abstract** — the ONE contribution, sized. Problem → the method/insight → the single headline
55
+ number → what it means. Tight (see "Scope the abstract" below).
56
+ 2. **Introduction + contributions** — the gap (what everyone measures / assumes today and why it's
57
+ wrong or unmeasured), then a bulleted **contributions** list. Each contribution is a *thing you
58
+ built or established* (a method, a benchmark, a bound, a norm), not "we ran experiments."
59
+ 3. **Background + threat model** (security) / **Setup** (non-security) — define terms, the system under
60
+ study, and — for security — the explicit threat model (attacker goals/capabilities/knowledge). A
61
+ fuzzy threat model is the fastest reject at a security venue.
62
+ 4. **Method** — the reusable core. How the measurement/benchmark is *constructed* so someone else can
63
+ run it on a different target. This is the part that gets cited; give it the most care.
64
+ 5. **Results** — the numbers from \`build-benchmark\`, each tied to a claim. Report ranges/CIs, not
65
+ rounded maxes. One figure or table carries the paper — make it legible standalone.
66
+ 6. **Threats to validity** — construct / internal / external, honestly (see below). This section is a
67
+ trust signal, not a confession.
68
+ 7. **Related work** — position against the *nearest* neighbor explicitly ("X measures A; we measure B
69
+ because A is the wrong number"). Credit generously; that's where the framing lands.
70
+ 8. **Ethics** (security papers) — responsible disclosure, who could be harmed, punching-down check.
71
+ Point to \`paper-pipeline/references/anonymization.md\` before naming any real system/maintainer.
72
+ 9. **Conclusion** — restate the method and the one insight; no new claims.
73
+ 10. **Availability** — the anonymized artifact link (see \`submit-paper\`). Reviewers reward a runnable
74
+ artifact more than another paragraph.
75
+
76
+ ## What makes it ACCEPTED and CITED
77
+ - **A reusable method/norm over a one-off result.** "Tool Y scores 40%" dies; "here's how to measure
78
+ Z, and by it Y scores 40%" survives, because the method outlives Y. Frame every result as an instance
79
+ of a general procedure.
80
+ - **A crisp, generalizable bound or insight** the reader can quote without your paper open — one
81
+ sentence they'll paraphrase back to you in review. That sentence is the abstract's spine.
82
+ - **Precise claim-sizing.** Say exactly how big the claim is and no bigger. Include an explicit
83
+ **"What we do NOT claim"** paragraph — it pre-empts Reviewer 2's whole attack surface and reads as
84
+ rigor, not weakness. (Both real papers have one; it's the highest-leverage paragraph in the draft.)
85
+ - **A construct-validity frame.** State plainly what quantity you're measuring and why it's the *right*
86
+ quantity — "measuring the wrong number" only works if you've defined the right one. Make the mapping
87
+ from concept → metric explicit; that's what separates a benchmark from a leaderboard.
88
+ - **An honest threats section that turns limitations in your favor.** Every limitation you name first,
89
+ bounded, is one a reviewer can't wield against you. "N is small, so we claim a lower bound not a
90
+ point estimate" converts a weakness into a scoped claim. Don't hide; scope.
91
+ - **One memorable stat or figure that travels.** Pick the single number/image that survives out of
92
+ context (a tweet, a related-work sentence in someone else's paper). Everything else supports it.
93
+ - **Credit-the-humans tone.** Dunk on the *claim or the metric*, never the authors. "The field measures
94
+ X; X is the wrong number" — not "prior work is naive." Punching down reads as insecurity and invites
95
+ a hostile review; generous framing invites a citation.
96
+
97
+ ## Scope the abstract tightly
98
+ The abstract sells ONE contribution and ONE headline number. Do **not** cram every hedged sub-result —
99
+ each extra qualified number dilutes the one that matters and invites nitpicks before the reviewer
100
+ reaches the method. Hedge in Results/Threats, not the abstract. If you can't say the contribution in one
101
+ sentence, you haven't found it yet — go back to the method. Structure it against the five-move template
102
+ (context → gap → approach → one number → so-what) in \`../paper-pipeline/references/writing-craft.md\`, which
103
+ also holds the craft rules and the writing rubric \`grade-paper-writing\` grades against — write toward the
104
+ grade.
105
+
106
+ ## Run the prose through the PAPER suite's QA (do not skip — and do not use the blog skills)
107
+ Before any review pass, run the draft through the paper-side prose QA — it catches what a self-read won't:
108
+ - **\`grade-paper-writing\`** — the 9-dim rubric + the PERSONA cold-read stall pass (a committed
109
+ non-academic persona, per-section — the localized "wait, what does that even mean?" axis authors are
110
+ blind to). Its avoid-list grep also strips the AI-writing tropes (hedge-stacking, "it's worth
111
+ noting", limp connectives, fake balance) that make a draft read unserious to a human PC.
112
+ - **\`../paper-pipeline/references/writing-craft.md\`** — write toward the rubric; its
113
+ register-calibration buckets decide which jargon to keep / gloss / rename for the venue's actual reader.
114
+
115
+ **Boundary:** the site repo's \`writing-quality\` + \`audience-test\` skills are for **blog posts only**.
116
+ For papers they duplicate — and are superseded by — \`grade-paper-writing\` + writing-craft's persona
117
+ pass (the blog skills lack the persona fix, so they under-fire on paper prose). Never route paper
118
+ prose QA to them.
119
+
120
+ ## Record the verdict
121
+
122
+ 🔴 LAST step, once the deliverable exists:
123
+
124
+ \`\`\`
125
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> FINDING <count> <report-path>
126
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record draft-paper <paper-dir> ABSTAINED <reason> "<one line>"
127
+ \`\`\`
128
+
129
+ This skill generates rather than judges, so what it records is about the run, not about the paper.
130
+
131
+ **FINDING** — it declined to draft because a required input was missing: no numbers from
132
+ \`build-benchmark\`, or an empty \`frame\` paragraph from \`argument-arc\`. \`--blocking\`, always, because
133
+ drafting past it produces prose about numbers that do not exist.
134
+ **ABSTAINED** — \`no-witness\`: sections were written and the generator has nothing to report about
135
+ the paper. Put the drafted sections in the note; they are the deliverable, not evidence of a defect.
136
+
137
+ 🔴 **Design smell, stated plainly: this gate will almost always record an abstention**, and
138
+ \`status.mjs\` will flag it as one that has never returned a finding. Leave the flag standing — it is
139
+ telling the truth. A generator is not a gate, and the only honest negative it can produce is the
140
+ refusal above. If a run ever ends with prose written from numbers that do not exist, that is a
141
+ \`FINDING --blocking\` and must be recorded as one rather than quietly upgraded.
142
+
143
+ 🔴 Deleting \`PASS\` did not fix this skill and was never going to: the old vocabulary let it write
144
+ down "I produced sections" as though that were an answer about the manuscript, and the new one
145
+ simply refuses to. The generator is still not a gate. \`draft-paper/population-map\` — a real check —
146
+ is the row that can say no about this skill's output.
147
+
148
+ ## Compose with
149
+ - **\`build-benchmark\`** — its numbers/CIs are the Results section's raw material; never hand-type a
150
+ number that isn't in its output (that's how paper↔artifact mismatches get born).
151
+ - **\`grade-paper-writing\`** (+ \`../paper-pipeline/references/writing-craft.md\`) — the paper-side prose
152
+ QA, above. (Site-repo \`writing-quality\` / \`audience-test\` = blog posts only.)
153
+ - **\`render-paper\`** — compile + eyeball pages 1–2 once prose is in.
154
+ - **\`verify-citations\`** — every cite in Related Work must exist AND say what you claim.
155
+ - Then the review loop: **\`paper-adversarial-review\`** → **\`pc-panel-review\`** (venue-fit mode for a
156
+ quick fit score, then the full panel as the gate).
157
+
158
+ ## Provenance (two real papers)
159
+ - **AgenticDev 2026 @ ASE — "Measuring the Wrong Number."** The thesis IS the construct-validity frame:
160
+ the field optimizes a metric that isn't the thing anyone cares about. The method (how to measure the
161
+ *right* number) is the contribution; the tool verdict is just the demonstration. Its "what we do NOT
162
+ claim" paragraph and lower-bound-not-point-estimate threats framing are what moved it through review.
163
+ - **AISec 2026 @ ACM CCS — "Safety Theater."** A security-venue measurement paper: a defense that
164
+ *looks* like safety without measurably being it. Needs the explicit threat model + ethics/disclosure
165
+ sections above, and dunks on the *defense pattern*, never the maintainers who shipped it — the
166
+ credit-the-humans rule is load-bearing at a top-tier security venue where a hostile framing draws a
167
+ hostile review. Both papers win on precise claim-sizing and an honest threats section, not on the
168
+ size of the effect.`,
169
+ });
@@ -0,0 +1,19 @@
1
+ /**
2
+ * draft-paper — the PAID tier: does this skill's description actually fire?
3
+ *
4
+ * COLOCATED ON PURPOSE (vigiles decides coverage by placement as of 2026-08-11).
5
+ * The prompts live in `.claude/lib/skill-trigger-cases.mjs` so all 21 cases
6
+ * are reviewed as one table where collisions between siblings are visible;
7
+ * copying them here would recreate the drift that rule exists to prevent.
8
+ *
9
+ * Measures recall (fires on its own territory) AND precision (stays quiet on a
10
+ * colliding sibling's territory), against the REAL `.claude` harness so the skill
11
+ * competes with every other installed description — an isolated run overstates
12
+ * recall and understates false positives.
13
+ *
14
+ * Costs money; not CI.
15
+ * node .claude/skills/draft-paper/draft-paper.eval.mjs [trials]
16
+ */
17
+ import { runSkillTriggerEval } from "../../lib/skill-eval-kit.mjs";
18
+
19
+ await runSkillTriggerEval("draft-paper");
@@ -0,0 +1,23 @@
1
+ /**
2
+ * draft-paper — the free, deterministic tier. No model, no network.
3
+ *
4
+ * COLOCATED ON PURPOSE. vigiles decides coverage by PLACEMENT as of 2026-08-11:
5
+ * a test that merely names a surface no longer counts, because that tier was
6
+ * crediting surfaces nothing touched. So each skill needs a file inside its own
7
+ * directory — this one.
8
+ *
9
+ * The assertions live in `.claude/lib/skill-checks.mjs` and are CALLED here with
10
+ * this skill's name. They are not copied: 22 copies of the same checks is the drift that
11
+ * module exists to avoid. (Until 2026-08-11 this was an env-var side channel into a
12
+ * 614-line file named after no surface; it is a function call now.)
13
+ *
14
+ * What this proves: this skill's frontmatter parses as strict YAML, its declared
15
+ * tool contract is sane, its pipeline wiring points at scripts that exist, and it
16
+ * announces/records under ITS OWN identity rather than a sibling's.
17
+ *
18
+ * What it does NOT prove: that the skill fires, or that its guidance produces a
19
+ * good result. Those need a real model — see `draft-paper.eval.mjs`.
20
+ */
21
+ import { checkSkill } from "../../lib/skill-checks.mjs";
22
+
23
+ await checkSkill("draft-paper");
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: extend-paper
3
+ description: Turn an accepted workshop / short paper into a second, stronger publication at a higher-prestige indexed venue — the "body of work" a strong dossier needs, not a one-hit paper. Covers the ≥30% new-material rule, the never-dual-submit rule, what genuinely counts as new content, and picking + timelining the upgrade venue. Use after a paper is accepted and you want the follow-on publication. Compose with find-venue, plan-paper-timeline, camera-ready, research-ideate.
4
+ allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Skill, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
5
+ ---
6
+
7
+ <!-- vigiles:sha256:436bb3586d84a654 compiled from skills/extend-paper/SKILL.md.spec.ts -->
8
+
9
+ # extend-paper — workshop/short paper → a second, stronger publication
10
+
11
+ ## Run me
12
+
13
+ 🔴 FIRST, before any other step:
14
+
15
+ ```
16
+ node .claude/skills/paper-pipeline/scripts/announce.mjs extend-paper <paper-dir>
17
+ ```
18
+
19
+ An advisory pass cannot be observed failing — silence is both its error state and its normal
20
+ state — so starting is an event, and events get written down.
21
+
22
+ One accepted paper is a data point; two related papers climbing in prestige is a **trajectory**, and
23
+ "sustained acclaim" is what a body-of-work review actually rewards. Workshop→conference and
24
+ conference→journal extensions are a standard, expected move — venues invite them. The catch: an
25
+ extension is *new work that subsumes the old*, not the same paper resubmitted. This skill is how to do
26
+ it legitimately.
27
+
28
+ ## The two hard rules
29
+ - **≥30% new material.** Most venues (and ACM/IEEE self-plagiarism policy) require an extension to add
30
+ substantial new content — the common bar is roughly a third genuinely new. Not reformatting, not more
31
+ words: new experiments, new analysis, new data. Cite the original workshop paper explicitly and state
32
+ in the intro what's new ("this paper extends our workshop paper [X] with …").
33
+ - **Never dual-submit.** One venue at a time, full stop. The workshop paper is done and indexed; the
34
+ extension goes to exactly one new venue and waits for its decision before going anywhere else.
35
+ Simultaneous submission of the same/overlapping work is an ethics violation that can get both papers
36
+ retracted — a dossier-killer.
37
+
38
+ ## What actually counts as new material
39
+ Pick the axis where the workshop paper was thin and build it out for real:
40
+ - **More coverage** — more tools / venues / models / languages measured (a 3-tool study → 12 tools).
41
+ - **A deeper analysis axis** — add a dimension the short paper only gestured at (cost *and* latency,
42
+ a failure taxonomy, an ablation over the method's knobs).
43
+ - **A field study or user study** — take the lab measurement into a real deployment / real developers.
44
+ - **The residual-bug fix built out** — the "future work" / limitation you named in Threats to Validity
45
+ becomes a full contribution (you designed the fix; now implement + evaluate it).
46
+ - **A stronger artifact** — a benchmark others can run and cite, not just a repro of your own numbers.
47
+
48
+ If you can't honestly point to which ≥30% is new, it's not an extension yet — go back to
49
+ `research-ideate` and find the new contribution first.
50
+
51
+ ## Pick the upgrade venue
52
+ Run **find-venue** — the target is a higher-prestige *indexed* home than the workshop, matched to the
53
+ paper type:
54
+ - A **measurement / evaluation** paper → **MSR** (Mining Software Repositories) or **NeurIPS
55
+ Datasets & Benchmarks** — venues that reward reusable measurement contributions.
56
+ - A **benchmark / security** paper → a full security conference (the tier above the workshop it started
57
+ at), where the artifact is the headline.
58
+ - Prefer venues that **explicitly invite journal/conference extensions** (many workshops, AgenticDev
59
+ included, say so in their CFP) — the extension path is sanctioned there.
60
+ Verify the target's CFP the same way `find-venue` does: fetch it, confirm it accepts extensions of prior
61
+ short papers, and check its self-plagiarism / overlap policy.
62
+
63
+ ## Timeline it (and space it out)
64
+ Run **plan-paper-timeline** against the upgrade venue's deadline, then deliberately **space the
65
+ submissions**. A burst of papers clustered right before an external filing deadline reads as
66
+ manufactured, not sustained — a documented reason for refusal, not a stylistic worry. Aim the extension to land a few months after the first paper's
67
+ acceptance so the record shows steady output over time, one ORCID tying every version together.
68
+
69
+ ## Record the verdict
70
+
71
+ 🔴 LAST step, once the deliverable exists:
72
+
73
+ ```
74
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> FINDING <count> <report-path>
75
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> ABSTAINED <reason> "<one line>"
76
+ ```
77
+
78
+ **FINDING** — `<count>` open items before the extension is legitimate; `<report-path>` is the plan.
79
+ Add `--blocking` when the ≥30% cannot honestly be pointed at, which sends the work back to
80
+ `research-ideate`.
81
+ **ABSTAINED** — `no-witness`: a legitimate extension is scoped — ≥30% genuinely new material, one
82
+ named venue, no dual submission — and nothing is open. `blocked`: there is no accepted base paper
83
+ to extend.
84
+
85
+ 🔴 **There is no PASS**, and here that matters more than anywhere: the tempting move at this moment
86
+ is to resubmit the same paper with a new title, and a stored "legitimate" would have been exactly
87
+ the paperwork for it. The blocking finding is what the pipeline is watching for; nothing else is.
88
+
89
+ ## Compose with
90
+ - **find-venue** — choose the higher-prestige indexed target and confirm it welcomes extensions.
91
+ - **plan-paper-timeline** — schedule the new experiments + write-up against the target deadline.
92
+ - **research-ideate** — if the ≥30% new contribution isn't obvious yet, find it here first.
93
+ - **camera-ready** — the accepted, de-anonymized, DOI'd base version you're extending from.
94
+
95
+ ## Provenance
96
+ The AgenticDev 2026 "Measuring the Wrong Number" workshop paper's **planned** extension to **MSR 2027**
97
+ (deadline ~Oct 23, 2026) or **NeurIPS 2027 Evaluations & Datasets** (~May 2027) — a second, stronger,
98
+ higher-prestige indexed publication that turns one accepted paper into a body of work. AgenticDev's CFP
99
+ explicitly invites journal extensions; the same ORCID links the workshop paper and its extension.
@@ -0,0 +1,116 @@
1
+ // Compiled to SKILL.md by `vigiles compile`. Edit THIS file, never the markdown.
2
+ //
3
+ // Adopted 2026-08-17 (batch 3). Body carried over VERBATIM so the compiled diff shows
4
+ // only what the compiler adds. No `disallowedTools` fence yet — the field landed on
5
+ // `SkillSpec` in vigiles branch `claude/skill-disallowed-tools` and is not in a release
6
+ // this repo installs, so writing one here would not compile.
7
+ import { experimental_skill } from "vigiles/spec";
8
+
9
+ export default experimental_skill({
10
+ name: "extend-paper",
11
+ description:
12
+ 'Turn an accepted workshop / short paper into a second, stronger publication at a higher-prestige indexed venue — the "body of work" a strong dossier needs, not a one-hit paper. Covers the ≥30% new-material rule, the never-dual-submit rule, what genuinely counts as new content, and picking + timelining the upgrade venue. Use after a paper is accepted and you want the follow-on publication. Compose with find-venue, plan-paper-timeline, camera-ready, research-ideate.',
13
+ tools: [
14
+ "Read",
15
+ "Write",
16
+ "Grep",
17
+ "Glob",
18
+ "WebSearch",
19
+ "WebFetch",
20
+ "Skill",
21
+ "Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*)",
22
+ "Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)",
23
+ ],
24
+ body: `
25
+ # extend-paper — workshop/short paper → a second, stronger publication
26
+
27
+ ## Run me
28
+
29
+ 🔴 FIRST, before any other step:
30
+
31
+ \`\`\`
32
+ node .claude/skills/paper-pipeline/scripts/announce.mjs extend-paper <paper-dir>
33
+ \`\`\`
34
+
35
+ An advisory pass cannot be observed failing — silence is both its error state and its normal
36
+ state — so starting is an event, and events get written down.
37
+
38
+ One accepted paper is a data point; two related papers climbing in prestige is a **trajectory**, and
39
+ "sustained acclaim" is what a body-of-work review actually rewards. Workshop→conference and
40
+ conference→journal extensions are a standard, expected move — venues invite them. The catch: an
41
+ extension is *new work that subsumes the old*, not the same paper resubmitted. This skill is how to do
42
+ it legitimately.
43
+
44
+ ## The two hard rules
45
+ - **≥30% new material.** Most venues (and ACM/IEEE self-plagiarism policy) require an extension to add
46
+ substantial new content — the common bar is roughly a third genuinely new. Not reformatting, not more
47
+ words: new experiments, new analysis, new data. Cite the original workshop paper explicitly and state
48
+ in the intro what's new ("this paper extends our workshop paper [X] with …").
49
+ - **Never dual-submit.** One venue at a time, full stop. The workshop paper is done and indexed; the
50
+ extension goes to exactly one new venue and waits for its decision before going anywhere else.
51
+ Simultaneous submission of the same/overlapping work is an ethics violation that can get both papers
52
+ retracted — a dossier-killer.
53
+
54
+ ## What actually counts as new material
55
+ Pick the axis where the workshop paper was thin and build it out for real:
56
+ - **More coverage** — more tools / venues / models / languages measured (a 3-tool study → 12 tools).
57
+ - **A deeper analysis axis** — add a dimension the short paper only gestured at (cost *and* latency,
58
+ a failure taxonomy, an ablation over the method's knobs).
59
+ - **A field study or user study** — take the lab measurement into a real deployment / real developers.
60
+ - **The residual-bug fix built out** — the "future work" / limitation you named in Threats to Validity
61
+ becomes a full contribution (you designed the fix; now implement + evaluate it).
62
+ - **A stronger artifact** — a benchmark others can run and cite, not just a repro of your own numbers.
63
+
64
+ If you can't honestly point to which ≥30% is new, it's not an extension yet — go back to
65
+ \`research-ideate\` and find the new contribution first.
66
+
67
+ ## Pick the upgrade venue
68
+ Run **find-venue** — the target is a higher-prestige *indexed* home than the workshop, matched to the
69
+ paper type:
70
+ - A **measurement / evaluation** paper → **MSR** (Mining Software Repositories) or **NeurIPS
71
+ Datasets & Benchmarks** — venues that reward reusable measurement contributions.
72
+ - A **benchmark / security** paper → a full security conference (the tier above the workshop it started
73
+ at), where the artifact is the headline.
74
+ - Prefer venues that **explicitly invite journal/conference extensions** (many workshops, AgenticDev
75
+ included, say so in their CFP) — the extension path is sanctioned there.
76
+ Verify the target's CFP the same way \`find-venue\` does: fetch it, confirm it accepts extensions of prior
77
+ short papers, and check its self-plagiarism / overlap policy.
78
+
79
+ ## Timeline it (and space it out)
80
+ Run **plan-paper-timeline** against the upgrade venue's deadline, then deliberately **space the
81
+ submissions**. A burst of papers clustered right before an external filing deadline reads as
82
+ manufactured, not sustained — a documented reason for refusal, not a stylistic worry. Aim the extension to land a few months after the first paper's
83
+ acceptance so the record shows steady output over time, one ORCID tying every version together.
84
+
85
+ ## Record the verdict
86
+
87
+ 🔴 LAST step, once the deliverable exists:
88
+
89
+ \`\`\`
90
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> FINDING <count> <report-path>
91
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record extend-paper <paper-dir> ABSTAINED <reason> "<one line>"
92
+ \`\`\`
93
+
94
+ **FINDING** — \`<count>\` open items before the extension is legitimate; \`<report-path>\` is the plan.
95
+ Add \`--blocking\` when the ≥30% cannot honestly be pointed at, which sends the work back to
96
+ \`research-ideate\`.
97
+ **ABSTAINED** — \`no-witness\`: a legitimate extension is scoped — ≥30% genuinely new material, one
98
+ named venue, no dual submission — and nothing is open. \`blocked\`: there is no accepted base paper
99
+ to extend.
100
+
101
+ 🔴 **There is no PASS**, and here that matters more than anywhere: the tempting move at this moment
102
+ is to resubmit the same paper with a new title, and a stored "legitimate" would have been exactly
103
+ the paperwork for it. The blocking finding is what the pipeline is watching for; nothing else is.
104
+
105
+ ## Compose with
106
+ - **find-venue** — choose the higher-prestige indexed target and confirm it welcomes extensions.
107
+ - **plan-paper-timeline** — schedule the new experiments + write-up against the target deadline.
108
+ - **research-ideate** — if the ≥30% new contribution isn't obvious yet, find it here first.
109
+ - **camera-ready** — the accepted, de-anonymized, DOI'd base version you're extending from.
110
+
111
+ ## Provenance
112
+ The AgenticDev 2026 "Measuring the Wrong Number" workshop paper's **planned** extension to **MSR 2027**
113
+ (deadline ~Oct 23, 2026) or **NeurIPS 2027 Evaluations & Datasets** (~May 2027) — a second, stronger,
114
+ higher-prestige indexed publication that turns one accepted paper into a body of work. AgenticDev's CFP
115
+ explicitly invites journal extensions; the same ORCID links the workshop paper and its extension.`,
116
+ });
@@ -0,0 +1,19 @@
1
+ /**
2
+ * extend-paper — the PAID tier: does this skill's description actually fire?
3
+ *
4
+ * COLOCATED ON PURPOSE (vigiles decides coverage by placement as of 2026-08-11).
5
+ * The prompts live in `.claude/lib/skill-trigger-cases.mjs` so all 21 cases
6
+ * are reviewed as one table where collisions between siblings are visible;
7
+ * copying them here would recreate the drift that rule exists to prevent.
8
+ *
9
+ * Measures recall (fires on its own territory) AND precision (stays quiet on a
10
+ * colliding sibling's territory), against the REAL `.claude` harness so the skill
11
+ * competes with every other installed description — an isolated run overstates
12
+ * recall and understates false positives.
13
+ *
14
+ * Costs money; not CI.
15
+ * node .claude/skills/extend-paper/extend-paper.eval.mjs [trials]
16
+ */
17
+ import { runSkillTriggerEval } from "../../lib/skill-eval-kit.mjs";
18
+
19
+ await runSkillTriggerEval("extend-paper");
@@ -0,0 +1,23 @@
1
+ /**
2
+ * extend-paper — the free, deterministic tier. No model, no network.
3
+ *
4
+ * COLOCATED ON PURPOSE. vigiles decides coverage by PLACEMENT as of 2026-08-11:
5
+ * a test that merely names a surface no longer counts, because that tier was
6
+ * crediting surfaces nothing touched. So each skill needs a file inside its own
7
+ * directory — this one.
8
+ *
9
+ * The assertions live in `.claude/lib/skill-checks.mjs` and are CALLED here with
10
+ * this skill's name. They are not copied: 22 copies of the same checks is the drift that
11
+ * module exists to avoid. (Until 2026-08-11 this was an env-var side channel into a
12
+ * 614-line file named after no surface; it is a function call now.)
13
+ *
14
+ * What this proves: this skill's frontmatter parses as strict YAML, its declared
15
+ * tool contract is sane, its pipeline wiring points at scripts that exist, and it
16
+ * announces/records under ITS OWN identity rather than a sibling's.
17
+ *
18
+ * What it does NOT prove: that the skill fires, or that its guidance produces a
19
+ * good result. Those need a real model — see `extend-paper.eval.mjs`.
20
+ */
21
+ import { checkSkill } from "../../lib/skill-checks.mjs";
22
+
23
+ await checkSkill("extend-paper");
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: find-venue
3
+ description: "Discover and rank real venues for a given paper, scored by authorship credit not just prestige. Fetch candidate CFPs (WebSearch/WebFetch), capture deadline / page limit / paper-type fit / indexing (ACM DL / IEEE Xplore / archival vs non-archival) / double-blind / remote-attendance / selectivity, then rank by credit-weight (peer-reviewed + indexed + parent-venue prestige) × topic fit × accept-probability × deadline feasibility × remote-friendliness. Emit a comparison table and a keep/switch recommendation. Encodes: workshop newness does NOT hurt authorship; non-archival workshops rank LOW; the prestige move is to EXTEND the accepted paper later, not hold out. Compose with research-ideate (upstream), plan-paper-timeline, the submit-paper venue data cards (submit-paper/references/venues/<venue>.md), and extend-paper."
4
+ allowed-tools: [Read, Write, Grep, Glob, WebSearch, WebFetch, Agent, Bash(node .claude/skills/paper-pipeline/scripts/announce.mjs:*), Bash(node .claude/skills/paper-pipeline/scripts/ledger.mjs:*)]
5
+ ---
6
+
7
+ <!-- vigiles:sha256:d1efcdc10319e6a3 compiled from skills/find-venue/SKILL.md.spec.ts -->
8
+
9
+ # find-venue — rank real venues by what earns the credit, then keep or switch
10
+
11
+ ## Run me
12
+
13
+ 🔴 FIRST, before any other step:
14
+
15
+ ```
16
+ node .claude/skills/paper-pipeline/scripts/announce.mjs find-venue <dir>
17
+ ```
18
+
19
+ An advisory pass cannot be observed failing — silence is both its error state and its normal
20
+ state — so starting is an event, and events get written down.
21
+
22
+ The `<dir>` argument is **optional in spirit**: this skill can run before a paper directory exists, so
23
+ pass whichever directory the work lives in, or `.`. The ledger row is written either way, and a plain
24
+ dot is more honest than an invented path.
25
+
26
+ Takes a paper (or the candidate venue *types* from `research-ideate`) and finds the best real place to
27
+ submit it. "Best" here means **best for the publication record**, which is not the same as most prestigious —
28
+ an indexed workshop you can actually hit beats a top conference whose deadline already closed. This
29
+ skill produces a ranked table and a keep/switch call; it does NOT do the submission mechanics (that's
30
+ `submit-paper` + the venue card).
31
+
32
+ Grounding: the authorship criterion — why archival + indexed is the whole game.
33
+
34
+ ## Gather candidates (fetch, don't guess)
35
+
36
+ `WebSearch` / `WebFetch` the open CFPs for the paper's topic + the current cycle. For EACH candidate
37
+ capture, from the actual CFP page:
38
+ - **Deadline** (in AoE; convert to your local time for feasibility).
39
+ - **Page limit** and required format (ACM sigconf / IEEE / other) — a full-paper limit vs a
40
+ short/WIP/workshop limit changes what you must produce.
41
+ - **Paper-type fit** — does the CFP call for measurement/benchmark/short/WIP/full papers of this shape?
42
+ - **Indexing** — the single most load-bearing field. Does acceptance land in **ACM DL / IEEE Xplore /
43
+ archival proceedings** (counts for authorship) or is it **non-archival** (talk-only, no indexed
44
+ proceedings — does NOT count)?
45
+ - **Double-blind?** — determines anonymization work (see `anonymization.md`).
46
+ - **Remote attendance** — can the author present/attend without international travel?
47
+ - **Selectivity / prestige** — the parent venue's tier (workshop @ CCS/ASE/FSE inherits weight).
48
+
49
+ ## Rank
50
+
51
+ Score each candidate by:
52
+
53
+ ```
54
+ rank = credit-weight × topic-fit × accept-probability × deadline-feasibility × remote-friendliness
55
+ ```
56
+
57
+ - **credit-weight** = (peer-reviewed? — required) × (indexed/archival? — required) × parent-venue
58
+ prestige (a bonus, not a gate). **Non-archival ⇒ credit-weight ≈ 0** — it earns no authorship credit,
59
+ so it sinks to the bottom no matter how nice the CFP reads.
60
+ - **topic-fit** — how squarely the paper matches the CFP scope (a stretch fit raises reject risk).
61
+ - **accept-probability** — realistic odds given the paper's maturity and the venue's bar.
62
+ - **deadline-feasibility** — can the paper (and artifact) be ready by the deadline? A great venue you
63
+ miss is a zero.
64
+ - **remote-friendliness** — remote-OK is a real weight here, not a footnote.
65
+
66
+ ### Facts to encode while ranking
67
+ - **Workshop newness does NOT hurt the authorship criterion.** A brand-new workshop's indexed
68
+ proceedings count the same; venue prestige only matters at final merits, never for authorship. Do not
69
+ down-rank a venue just for being new.
70
+ - **Non-archival workshops rank LOW for authorship** — no indexed proceedings, no credit. A great talk
71
+ slot with no DOI is worth little to the dossier.
72
+ - **Prestige is a later move, not a hold-out.** Do NOT sit on a finished paper waiting for a fancier
73
+ venue. Ship to the best-fit archival venue open now, then **EXTEND** the accepted paper (≥30% new) to
74
+ a higher-prestige venue as a *second, stronger* publication — see `extend-paper`. Two indexed papers
75
+ (workshop → conference) beat one that missed its window.
76
+
77
+ ## Output
78
+
79
+ 1. **Comparison table** — one row per candidate: venue, parent, deadline (AoE + local), page limit,
80
+ type fit, **indexed? (Y/N + where)**, double-blind, remote, selectivity, computed rank.
81
+ 2. **Keep/switch recommendation** — the top-ranked venue with the one-line reason, and (if the paper
82
+ already has a target) an explicit **keep** or **switch** verdict against it. Note the intended
83
+ `extend-paper` upgrade target for later.
84
+
85
+ ## Record the verdict
86
+
87
+ 🔴 LAST step, once the deliverable exists:
88
+
89
+ ```
90
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> FINDING <count> <report-path>
91
+ node .claude/skills/paper-pipeline/scripts/ledger.mjs record find-venue <dir> ABSTAINED <reason> "<one line>"
92
+ ```
93
+
94
+ 🔴 **There is no PASS.** A shortlist is a set of findings about the world, not a certificate that
95
+ the venue question is settled.
96
+
97
+ **FINDING** — the sweep produced a ranked shortlist with an explicit keep/switch call; `<count>` is
98
+ the number of candidates ranked and `<report-path>` the comparison table. Add `--blocking` when
99
+ nothing open clears the peer-reviewed + indexed gate — a real answer, and not an empty run.
100
+ **ABSTAINED** — `no-witness`: CFPs were read and no candidate could be ranked either way.
101
+ `input-missing`: there is no paper description to match venues against.
102
+
103
+ Record the whole table's path, not just the winner. The next sweep starts from the candidates that were
104
+ dropped and why, and a verdict with no table behind it cannot be re-checked when a deadline moves.
105
+
106
+ ## Rules
107
+ - Fetch every CFP fact from the real page; never invent a deadline, page limit, or indexing status.
108
+ - Indexed + peer-reviewed is a gate, not a tiebreaker — a non-archival venue cannot win on charm.
109
+ - Don't hold a finished paper hostage to prestige; ship archival now, extend later.
110
+ - A missed deadline is a zero — weight feasibility honestly against the paper's real readiness.
111
+ - Convert deadlines to your local time so `plan-paper-timeline` can schedule against them.
112
+
113
+ ## Compose with
114
+ - `research-ideate` (upstream) — consumes its candidate venue *types* and sharpest framing.
115
+ - `plan-paper-timeline` — feed it the chosen deadline to back-plan the work.
116
+ - `submit-paper` venue data cards (`submit-paper/references/venues/<venue>.md`, e.g. `agenticdev.md`,
117
+ `aisec.md`) — the winner gets a venue-specific data card with its HotCRP quirks; save a new one per
118
+ venue as plain data, not a new skill.
119
+ - `extend-paper` — the prestige-upgrade target this skill names but defers.
120
+
121
+ ## Provenance
122
+ The **AgenticDev 2026 @ ASE** venue decision was made by a **9-agent analysis** that checked every open
123
+ venue against this exact rubric. It **kept AgenticDev** — nothing open beat it on fit × archival ×
124
+ timeline: NeurIPS Eval had already **closed**, and FSE/MSR each needed a **full paper** (wrong type /
125
+ too much scope for the deadline). The prestige upgrade was deliberately deferred to an **extension to
126
+ MSR/NeurIPS 2027**, not a switch — proving the rule: ship the best-fit archival venue open now, extend
127
+ later. **AISec 2026 @ ACM CCS** confirmed the archival-weight logic at a top-tier security bar. Both
128
+ papers are indexed proceedings; neither was down-ranked for the workshop's newness.