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,448 @@
1
+ # Writing-craft reference — how well-written papers actually read
2
+
3
+ Grounding for `grade-paper-writing`, `draft-paper`, and `harden-paper`. Distilled from the canonical
4
+ craft sources + an honest dissection of exemplar papers (writing craft only, not scientific impact).
5
+ The point: grade a draft's _prose and structure_ against how the best-written papers do it, not against
6
+ taste. Especially for the failure mode "a wall of text and jargon that doesn't drive home how crazy the
7
+ situation is."
8
+
9
+ ## The three moves that make a human care (the core finding)
10
+
11
+ The most-cited papers are NOT uniformly the best-written — _Attention Is All You Need_ is famous-but-terse
12
+ and wins only because its audience already cared. The papers that actually **make a reader care** —
13
+ _Reflections on Trusting Trust_, indirect-prompt-injection (Greshake), training-data-extraction (Carlini)
14
+ — all share three moves. This trio is the direct cure for "wall of text":
15
+
16
+ 1. **Open on a problem/assumption the reader already holds** (not background, not a topic tour).
17
+ 2. **Break it with the single most visceral concrete instance** (not an aggregate statistic).
18
+ 3. **Land one repeatable sentence** the reader will quote to a colleague.
19
+
20
+ ## Canonical craft rules
21
+
22
+ ### Simon Peyton Jones — _How to Write a Great Research Paper_
23
+
24
+ - **One key idea.** The reader should be able to state it in a sentence. Don't dilute with five half-ideas.
25
+ - **Tell a story — the intro arc:** _problem → it's an interesting problem → it's an unsolved problem →
26
+ here is my idea → my idea works._ This is the canonical intro skeleton.
27
+ - **Intro ≈ one page**, doing two things fast: (1) the problem via a concrete example in ~sentence 1;
28
+ (2) contributions as a **bulleted list with forward references** ("we do X (§3)").
29
+ - **Contributions are "molecules, not atoms"** — refutable, specific claims, not vague ("we studied X").
30
+ - **Do NOT write "the rest of this paper is organized as follows."** The forward-referenced bullets do it better.
31
+ - **Related work goes at the END**, not after the intro — early, it's a wall before the reader knows why to care, and reads as defensive.
32
+ - **The reader is the only person who matters.** Convey the idea; don't recite what you did.
33
+ Sources: simon.peytonjones.org/great-research-paper · microsoft.com/en-us/research/academic-program/write-great-research-paper
34
+
35
+ ### Larry McEnerney — _The Craft of Writing Effectively_
36
+
37
+ - **Writing creates VALUE for a community of readers — it is not a record of your thinking.** The job is to
38
+ change what the reader believes about the world, not to explain what you did.
39
+ - **Clear ≠ good.** "Clear and useless = useless." Value first; clarity only matters in service of value.
40
+ - **The reader is expensive to move** — busy, skeptical experts. Every sentence must earn the next.
41
+ - **The "so what / who cares" test** — before a claim earns space, it must resolve an instability _this
42
+ community_ cares about.
43
+ - **Frame around a problem/instability, not a foundation.** Reject the martini-glass (broad→narrow→broad)
44
+ and the topic-then-background opening; open by exposing a problem the reader already feels, and create tension.
45
+ - **Use the community's code-words** deliberately (for security-measurement: "threat model," "attack
46
+ surface," "false-negative," "real-world," "at scale") — they signal "this is for you."
47
+ Sources: robincussol.com/the-craft-of-writing-effectively-summary · singjupost.com transcript
48
+
49
+ ### Gopen & Swan — _The Science of Scientific Writing_ (sentence mechanics)
50
+
51
+ - "The meaning of prose is not what the writer intends, but what readers interpret." Put info where readers expect it.
52
+ - **Topic position (sentence start) = old/linking info + context. Stress position (sentence end) = the new
53
+ payload you want emphasized.** Put the important word last.
54
+ - **Keep subject and verb close.** Long clauses jammed between them make readers hold their breath.
55
+ - One sentence = one point. Don't put two new ideas in two stress positions.
56
+ Source: usenix.org/sites/default/files/gopen_and_swan_science_of_scientific_writing.pdf
57
+
58
+ ### Strong-abstract structure (Zobel / 4-sentence)
59
+
60
+ Operational template to check an abstract against: **Context (1 sentence) → Gap/problem (1) → Approach (1)
61
+ → Result with ONE memorable number/instance (1) → Meaning/so-what (1).** A stat-wall abstract fails this
62
+ because it stacks numbers with no gap and no "so what." (The tight "4-sentence abstract" is commonly
63
+ attributed to Kent Beck — treat as widely-cited, not primary-verified.)
64
+
65
+ ## Exemplar lessons (writing craft only; grades = craft judgment, 1–5)
66
+
67
+ - **Attention Is All You Need** — Title 5, Abstract 4, Prose **2**. Imitate: six-word thesis-title, one
68
+ killer figure, one memorable number (28.4 BLEU). **Do NOT imitate** the dense, contribution-less prose —
69
+ it works only because the audience already cared. This IS the "wall of jargon" trap.
70
+ - **Reflections on Trusting Trust** — Prose **5**, the gold model. Plain words, one idea built step by step,
71
+ opens on a question the reader already feels ("to what extent should one trust…"), lands one unforgettable
72
+ moral ("You can't trust code that you did not totally create yourself"). The antidote.
73
+ - **Not What You've Signed Up For** (indirect prompt injection, AISec) — the **security-audience** model.
74
+ Abstract pivots on a rhetorical question — _"But, what if it is not the user prompting?"_ — that makes a
75
+ human sit up harder than any statistic. Surface the assumption everyone holds, then break it.
76
+ - **Extracting Training Data from LLMs** (Carlini) — the **measurement-paper** model. Every abstraction is
77
+ cashed out in a visceral concrete example ("128-bit UUID… appearing in just one document"). The fix for
78
+ "doesn't drive home how crazy it is" is the concrete instance, NOT more numbers.
79
+ - **MapReduce** — "Simplified" in the title = the reader's _benefit_ as the promise; clean topic sentences;
80
+ motivating example before mechanism.
81
+
82
+ ## The gradeable rubric — 9 dimensions, score 1–5 (anchors), most-severe first
83
+
84
+ For the "wall of jargon" failure mode, **weight #5 Prose, #6 Jargon, #7 Landing-the-point ×2.** Score each,
85
+ name the offending sentence/section, write the fix.
86
+
87
+ 1. **Title — value + memorability.** 1 = generic topic label, forgettable. 5 = states the finding or the
88
+ reader's benefit and is quotable; repeatable after one read.
89
+ 2. **Abstract — context→gap→approach→result→meaning, with ONE number.** 1 = stat-wall/method-dump, no gap,
90
+ no "so what." 5 = five moves in ≤5 sentences, one memorable result, a line the reader remembers.
91
+ 3. **Intro architecture — problem/why-care/contribution/evidence, fast.** 1 = background/lit-tour, point
92
+ arrives on page 2–3. 5 = SPJ arc in the first half-page + a bulleted, forward-referenced contributions list.
93
+ 4. **Structure & signposting (incl. visual density).** 1 = arbitrary order, paragraphs open mid-thought,
94
+ boilerplate roadmap, OR a wall — one giant unbroken paragraph the reader's eye slides off. 5 = each
95
+ section one job, every paragraph's first sentence is its claim, forward refs not a roadmap, AND no wall:
96
+ long related-work / discussion blocks are broken into scannable chunks with bold/italic run-in sub-heads
97
+ (see the wall-of-text check below).
98
+ 5. **Prose clarity (Gopen/Swan).** 1 = long two-idea sentences, subject/verb far apart, payload buried,
99
+ passive. 5 = one idea/sentence, subject next to verb, payload in the stress position, active by default.
100
+ 6. **Jargon discipline (graded for the NON-ACADEMIC target reader, not for you the expert).** 1 = undefined
101
+ acronyms/in-group terms stacked to sound rigorous, OR standard field-jargon (`Bonferroni`, `construct
102
+ validity`, `null`, `coarse`, coined handles) used with no plain-words gloss — the LLM-grader trap: you know
103
+ them so you don't stall, but the reader does. 5 = every term earns its place and is glossed in plain language
104
+ at first use; analogy before term; a strong engineer who is not a researcher never hits a wall. **Hard-capped
105
+ by stall density (see the stall pass): > 1 stall/page ⇒ ≤ 2 here.**
106
+ 7. **Landing-the-point / reader value (graded on BOTH the intro AND the conclusion).** 1 = abstractions all
107
+ the way down; reader finishes thinking "so what?" 5 = exposes an assumption, breaks it with the most
108
+ visceral concrete instance, quantifies stakes, and **the abstract and the conclusion each leave a
109
+ memorable, extractable line** (the quotable test). A strong intro with a weak, summary-only conclusion
110
+ scores LOW here — the conclusion is a graded surface, not an afterthought (see the conclusion & quotability
111
+ check below). **Boring is a defect here, not neutral:** a technically-correct paper the target reader
112
+ skims out of duty — flat, no line worth quoting, no moment that makes them sit up — scores ≤ 2, however
113
+ sound. "Correct but I was bored to death" is a failing Landing grade.
114
+ 8. **Figure/table economy.** 1 = many dense tables, no single figure that carries the thesis, captions not
115
+ self-contained. 5 = one "money figure" a skim-reader understands alone; self-contained captions; tables show the one comparison that matters.
116
+ 9. **Honesty without hedge-stacking.** 1 = overclaims OR drowns in hedges + defensive early related-work
117
+ wall. 5 = explicit "what we do NOT claim," one clean threats-to-validity move, related work at the end as context.
118
+
119
+ ## Scoring calibration — how to avoid an inflated grade (read before scoring)
120
+
121
+ A writing grade is worthless if it's inflated, and the default failure mode is a single grader — _especially
122
+ one that just wrote, rewrote, or verified the paper_ — scoring on optimism and anchoring on "it got better."
123
+
124
+ **⚠️ The blind panel does NOT fix the expertise blind spot.** LLM graders share a vocabulary: all three know
125
+ `Bonferroni`, `construct validity`, `null`, `coarse` — so a blind 3-grader panel can _converge_ on 44/60 and
126
+ all be wrong the same way (this happened; the human target reader then found the paper unreadable). The panel
127
+ fixes _optimism/anchoring_, not _"the graders are experts and the reader isn't."_ Defenses: (1) every grader
128
+ runs the stall pass with expertise DEMOTED to the target reader (above); (2) **if the human target reader
129
+ stalls where the panel didn't, the human wins — they ARE the reader the grade is for.** A panel consensus that
130
+ contradicts the actual reader's "I was bored / lost" is a mis-grade, not a tie.
131
+
132
+ Two disciplines are mandatory:
133
+
134
+ **1. Absolute scale, not relative.** Grade against the whole field, NEVER against the previous draft.
135
+
136
+ - **5** = the best-written papers in existence (Trusting-Trust tier: a non-expert reads it willingly, one
137
+ unforgettable line). Vanishingly rare — almost no real paper earns a 5 on most dimensions.
138
+ - **4** = clearly above average, a pleasure to read.
139
+ - **3** = competent and publishable but a slog in places — **the DEFAULT for a solid accepted paper.**
140
+ - **2** = a real weakness a reviewer gripes about. **1** = bad.
141
+ Most dimensions of most accepted papers are **2–3**. A row of 4s and 5s means you are being lenient —
142
+ recheck. "It improved from the last draft" is not evidence of a 4; grade only what is on the page today.
143
+
144
+ **2. One grade is not trustworthy — run a blind panel when the number matters.** Spawn **≥3 independent
145
+ graders**, each blind to (a) any prior score, (b) each other, and (c) the "we improved X" framing — give
146
+ them only the current page and the field's best as the yardstick. **Report the distribution (per-dimension
147
+ and overall min / median / max), not a point estimate.** Treat a lone high score as suspect until a blind
148
+ panel confirms it; if graders disagree by >1 on a dimension, that dimension is genuinely ambiguous — say so.
149
+ (This is the writing-axis analogue of `pc-panel-review`'s N-independent-reviewers design.)
150
+
151
+ ## The cold-read stall pass (the "wait, what does that even mean?" axis)
152
+
153
+ The rubric's Prose, Jargon, and Figure dimensions are scored holistically — but the most _actionable_ signal
154
+ is localized: the exact spots where a reader who did NOT write the paper stops and thinks "what does that even
155
+ mean?" Those stalls are what make a paper _feel_ like a wall, and **authors are blind to them because they
156
+ already know what everything means.** This is the pass most worth delegating to a cold grader (a fresh
157
+ subagent with no context on the work), because the author literally cannot run it honestly on themselves.
158
+
159
+ **Run it as a PERSONA subagent, not as yourself "demoting expertise."** This is the fix for why the pass
160
+ under-fires: telling a frontier model to "imagine you don't know the terms" is an abstract instruction it glides
161
+ past — it still knows everything, so it glances over the jargon a real reader would trip on. A subagent
162
+ _committed to a specific persona_ flags authentically, because it is answering AS someone who genuinely lacks the
163
+ vocabulary. Spawn a fresh subagent with a prompt like:
164
+
165
+ > You are Sam, a senior software engineer — 10 years building production web backends, sharp, but you have NEVER
166
+ > read an academic paper in this subfield and you do NOT know its vocabulary. Read this start to finish, linearly.
167
+ > EVERY time you hit a word, symbol, table cell, or sentence you would not use in a normal code review — STOP and
168
+ > write down the exact trigger (quote it) and what you'd need to get it. Do not be polite, do not push through, do
169
+ > not assume "it'll be explained later." If you'd mutter "what the fuck does that mean," that is a stall — log it.
170
+ > Output the stall inventory only.
171
+
172
+ Match the persona to the paper's ACTUAL target reader, and keep it inside the venue's field but OUTSIDE academia
173
+ (a security paper → a security-adjacent engineer who still doesn't know stats/measurement jargon), so it keeps
174
+ bucket-1 field terms and trips on buckets 2–3. Optionally also run it on a **deliberately weaker model**, which
175
+ lacks the vocabulary for real (not by role-play) and stalls even more like a human. The persona's inventory feeds
176
+ straight into the fix pass.
177
+
178
+ **Run the persona PER SECTION for a dense or long (>~6pp) paper — never one whole-paper pass.** A single pass over
179
+ a full paper skims the middle: this session a whole-paper sweep scored 44/60 and missed the walls that per-section
180
+ persona reads (intro, method, results) each caught immediately. Chunk it to 2–3pp / one section per subagent, so
181
+ the reader's attention doesn't degrade across the length.
182
+
183
+ **This persona-proxy technique generalizes.** Any skill that needs the LLM to stand in for a _limited_ human —
184
+ a naive first-time-user docs walkthrough, a "can a newcomer follow this setup," a non-native-speaker read, a
185
+ "would a busy exec get the point in 10s" test — hits the same wall: the model's omniscience makes it a bad proxy.
186
+ The fix is always the same: **give it a committed persona (and/or a weaker model), don't ask it to "imagine" the
187
+ limitation.** When adding a skill that simulates a human constraint, reach for a persona subagent by default.
188
+
189
+ **Read as the paper's ACTUAL target reader — a strong practitioner/engineer who is NOT an academic in this
190
+ subfield — NOT as "a smart non-author."** This is the fix for the failure that let a jargon-dense paper score
191
+ "above average": _you, the LLM grader, know what `Bonferroni`, `construct validity`, `coarse`, `null`, `TOST`,
192
+ `ablation`, `orthogonal` mean — the target reader does not._ An LLM's default failure is never stalling because
193
+ it knows every term. **Deliberately demote your own expertise** and flag every term, notation, or construction
194
+ the target reader wouldn't get in ~5 seconds. If a strong engineer who is not a researcher would type "fuck
195
+ does that even mean" — it is a stall, no matter how standard the term is in the field. That "fuck does that mean"
196
+ reflex is the FLAG pass (catch broadly); the **Register calibration** below is the TRIAGE (keep field-native terms,
197
+ gloss/cut methodology shorthand, rename coinages) — run both, in that order.
198
+
199
+ ### Register calibration — which terms to KEEP vs kill (the hard balance)
200
+
201
+ "Flag every term the reader wouldn't get in 5 seconds" is too blunt on its own: applied literally it strips the
202
+ **field-native vocabulary that makes a paper read as competent to its reviewers**, and glossing those reads as
203
+ naïve. The reader is a strong engineer _in the paper's own field_ — **not a layperson and not a cross-field
204
+ methodologist.** Sort every candidate term into three buckets:
205
+
206
+ 1. **KEEP — field-native terms a reviewer at THIS venue uses without thinking.** Glossing them wastes words and
207
+ signals you don't know the field. _Security venue:_ `exfiltrate`, `PreToolUse`, `AST`, `false positive`,
208
+ `supply-chain`. _Benchmark venue:_ `held-out`, `baseline`, `ablation`. Test: **would a reviewer at
209
+ this venue type this word in their own review?** If yes, keep it (gloss at most once if borderline, then move on).
210
+ **Bucket-1 is NARROW — be strict, when in doubt it's bucket 2.** The failure mode (real: `fnmatch` slipped through
211
+ this list as a "keep" and the author stalled on it) is calling a **library/function/POSIX name** field-native
212
+ because it's _plausibly_ known. Test harder: not "might a reviewer know it?" but "would they type it _unglossed_
213
+ in prose?" A libc function (`fnmatch`), a specific syscall, a niche flag — usually **NO**; it's artifact/detail,
214
+ so gloss-or-cut (often just cut the name: "matches the glob" beats "an `fnmatch` bound"). **The AUTHOR's stall is
215
+ authoritative:** if the author — a strong engineer — stalls on a term, it is NOT bucket-1, no matter how
216
+ field-native it looks to you. Your "a reviewer probably knows it" does not override a real reader's "wtf is that."
217
+ 2. **GLOSS-ONCE-OR-CUT — methodology / stats / philosophy-of-measurement shorthand foreign to the paper's field.**
218
+ The LLM grader waves these through because _it_ knows them, but they aren't native to the venue's reviewers as
219
+ prose: `construct validity`, `existence result`, `declared scope`, `orthogonal`, `null` (=no effect), `TOST`,
220
+ `coarse`, `net-cancel`, `re-derivation`, `modal` (=most common), `Bonferroni`. Gloss in plain words at first
221
+ use, or cut.
222
+ 3. **RENAME — labels the authors COINED that brand instead of describe** (sound like marketing, mean nothing to the
223
+ reader): `robust coverage` → _coverage under evasion_; `honest residue` → _what still gets through_; a "corner"
224
+ / "split" / "axis" used before it's shown. Test: **did we invent this label, and does it describe the thing or
225
+ just brand it?** If it brands, make it say the thing.
226
+
227
+ **The failure is the reader STALLING or getting BORED — not fancy words per se.** A paragraph with zero jargon can
228
+ still be a wall: a **comma-list of mechanism steps where a story belongs** (the reader can't find the point through
229
+ the enumeration — e.g. a guard described as "resolves quoting, reduces the interpreter to its basename, strips a
230
+ backslash head, canonicalizes flag aliases, expands \$HOME…" instead of "it strips the disguises so every spelling
231
+ of `rm -rf` collapses to one"), a triple-nested-em-dash sentence you parse twice, or a dutiful flat paragraph.
232
+ **Fix by leading with the plain story in 1–2 sentences, THEN the precise mechanism/term — never the reverse.**
233
+ (the author's rule: don't open on the spec sheet.) When unsure which bucket a term is in, ask: _would a reviewer at THIS
234
+ venue use it, or is it imported from stats/philosophy/our own coinage?_
235
+
236
+ **De-jargon is RE-VOICING the sentence, not swapping the word.** Replacing a coined term with a plainer noun inside
237
+ an otherwise stiff academic sentence leaves the sentence academic — the reader still stalls on the _register_, not
238
+ just the word (GateBench 2026-07-25: a term-level de-jargon pass cleared the flagged words but the author still hit
239
+ sections "way too academicy for 0 reason"). The fix: rewrite the whole SENTENCE the way you'd say it to a colleague
240
+ at a whiteboard — subject–verb–object, active voice, one clause, contractions fine, no nominalizations ("performs
241
+ an evaluation of" → "checks"). **Read each rewritten sentence ALOUD: if you'd never say it that way to a person,
242
+ it's still academic.** E.g. "We therefore position the guard as a defense against trigger~A and a measurement
243
+ instrument, not an injection defense" → "So the guard is there to catch accidents and to measure the problem — it
244
+ is not built to stop an attacker." A word-swap that leaves the academic sentence shape is a HALF-fix; the
245
+ deliverable is plain-spoken sentences, and a de-jargon/tighten pass is not done until the prose reads spoken.
246
+
247
+ **Step 0 — mechanical pre-scan (BEFORE reading, so the pass can't rubber-stamp).** Run the coined-compound
248
+ grep from the avoid-list against the source and add EVERY hit to the stall inventory as a candidate; grep the
249
+ named avoid-list terms too. This is the FLOOR the repeated 44/60 mis-grades kept falling through — a persona
250
+ that "reads and feels" keeps waving these past because the model knows them. The persona's real job is to ADD
251
+ what a regex can't see (walls, boredom, read-twice sentences, a coinage used before it's defined), not to
252
+ re-discover terms a grep already finds. **A hyphenated coinage or a listed avoid-term that survives to the
253
+ final draft unglossed is a FAIL of this pass, full stop — not a "minor" left for later.**
254
+
255
+ **Run it as a linear cold read**, start to finish. Every time that reader would stop, log a stall. Trigger on:
256
+
257
+ - **Gloss-or-die: any academic/technical term used without a plain-words gloss at first use.** These are the
258
+ ones LLM graders wave through because they know them — flag every one: `Bonferroni`, `construct validity`,
259
+ `null` (meaning "no effect"), `ablation`, `TOST`, `coarse`, `orthogonal`, `monotone`, `a priori`,
260
+ `first-class` (as jargon), an unexpanded acronym (`MCP`, `CI` on first use), or a **coined handle used before
261
+ it's defined** ("the corner", "the split", "output-share bound", "the input-dominance fact our audit
262
+ presupposes"). Rule: **gloss in plain words at first use, or cut.** A coined handle is fine _once glossed_.
263
+ - a **bare number with no source on the page** — "where did 31.7% come from?", a naked p-value;
264
+ - **"what am I looking at?"** — a table cell needing a dagger legend, a figure whose caption isn't self-contained;
265
+ - a **sentence you had to read twice** to parse (usually an em-dash-nested composite);
266
+ - **boredom** — a paragraph the reader skims because it's dutiful and flat. Boring is a defect, not a neutral.
267
+
268
+ **No paragraph is exempt — and Related-Work / "grounding" citation clusters are the WORST jargon nests.**
269
+ A sentence like "grounded in construct-validity and benchmarking-pitfall work [4,10,20]" stacks field terms
270
+ to sound rigorous and is exactly where a de-jargon pass tends to skip (it "looks like citations"). Sweep it
271
+ like everything else: gloss or kill each term. **A term glossed once and then reused unglossed pages later is
272
+ still a stall on reuse** — the reader can't hold a definition from three pages ago; prefer the plain wording
273
+ every time over relying on an earlier gloss (`construct validity` recurring = fix it everywhere, not once).
274
+
275
+ **Each stall:** location → the exact trigger (quote it) → the reader's question → the one-line fix
276
+ (gloss / define / cut / move / add a source). The **stall inventory is the deliverable** — hand it straight to
277
+ a fix pass.
278
+
279
+ **Stall density HARD-CAPS the score (mechanical, not "considered").** A paper the target reader stalls on every
280
+ paragraph is NOT "above average," however correct or clean-sentenced. Apply as a ceiling:
281
+
282
+ - **> 1 stall/page → Jargon (#6) ≤ 2.**
283
+ - **> 2 stalls/page → Jargon ≤ 2, Prose (#5) ≤ 2, and Landing (#7) ≤ 3.**
284
+ - **A row of 4s on a paper with > 2 stalls/page is a MIS-GRADE — you read as an expert, not the target
285
+ reader. Re-run the pass demoting your expertise.** Report stalls/page next to the scorecard; if it exceeds
286
+ these thresholds and the dimension scores don't reflect the cap, the grade is wrong.
287
+
288
+ **Why this pass UNDER-FIRES in practice — and how to make it bite.** Cautionary case (2026-07 AISec paper): the
289
+ blind panel scored it 44/60 and called the remaining walls "minor," yet the author — a real non-expert reading
290
+ linearly — hit ~15 WTF stalls it had waved through (`exfiltrate`-adjacent terms, `robust coverage`, `honest
291
+ residue`, `held-out`, a spec-sheet mechanism paragraph, `construct validity`, `existence result`). **Root cause:
292
+ a frontier LLM cannot authentically stall — it knows every term, so "did _I_ stop and go 'what's that'?"
293
+ systematically under-counts. "Demote your expertise" only half-works.** Remedies:
294
+
295
+ - **Count stalls MECHANICALLY, not by felt confusion.** Auto-stall regardless of whether you understand it:
296
+ (1) any bucket-2 methodology term unglossed at first use; (2) any bucket-3 coined label — a metric or heading
297
+ name the authors invented (`robust coverage`, `honest residue`); (3) any **comma-list of ≥3 mechanism steps**
298
+ standing in for a story; (4) any run-in heading that's cute rather than descriptive. These fire by
299
+ pattern-match, so the count no longer depends on the grader's knowledge.
300
+ - **Walls and spec-sheets HARD-FAIL — never "minor."** "Minor walls left" is the signature of a mis-grade: a
301
+ wall's fix is cheap and mandatory, so an un-fixed wall caps Prose/Landing — it does not get a pass because the
302
+ sentences around it are clean.
303
+ - **The LLM pass is a PROXY that under-fires by design; the ground truth is a human linear read.** Budget for one
304
+ (the author, or a deliberately WEAKER model that actually lacks the vocabulary and so stalls like a human). When
305
+ a human read surfaces stalls the LLM missed, that is a **skill miss, not just a paper bug** — feed the specific
306
+ terms back into the Register-calibration buckets so the next paper never ships them.
307
+
308
+ ## The claim-preservation diff (`claims`) — mandatory after EVERY rewrite
309
+
310
+ **Owner of the `claims` scorecard row.** A rewrite/de-jargon/readability pass is NOT done until an
311
+ adversarial claim-preservation diff clears it. Rewording is a claim-integrity RISK, not a cosmetic
312
+ edit: it silently drops hedges, flips "no _detectable_ change" into proven-zero, restates a bounded
313
+ result as an absolute, and re-breaks numbers. A real Fable diff-check caught three that readability
314
+ passes _introduced_ — a heading ("Deny-globs that never match") contradicting its own body ("rarely
315
+ match, median 1/10"); "both estimates point to no saving **at all**" (proven-zero overclaim); and
316
+ "with correctness **held fixed**" (overstating a gate the paper itself calls shallow).
317
+
318
+ **The check:** after ANY rewrite pass, run an adversarial diff (Fable or equivalent) over the
319
+ before/after that verifies — **no number moved, no hedge dropped, no claim strengthened, no new
320
+ absolute, no self-contradiction with unchanged text.** Pair every readability/fix pass with this
321
+ check; the pass isn't complete without it, and the `claims` row in `PIPELINE-STATUS.md` records the run.
322
+ `grade-paper-writing` runs it after applying its sentence fixes; `harden-paper` gates on it
323
+ (claims-honest gate).
324
+
325
+ ## The wall-of-text check (visual density — distinct from stall density)
326
+
327
+ Stall density is about COMPREHENSION (unglossed terms, sourceless numbers). This is about the EYE: a
328
+ paragraph so long and unbroken the reader slides off it before reading a word. The classic offender is a
329
+ Related-work or Discussion section dumped as one 30+-line block covering a dozen works. Rules:
330
+
331
+ - **A paragraph running >~15 source lines / ~150 words, or covering >3 distinct sub-points, is a wall —
332
+ break it.** Split into 2–4 chunks, each led by a **bold or italic run-in sub-head** that names its theme
333
+ (`\textbf{Denylist fragility.}`, `\emph{Syntax vs.\ intent.}`), exactly as the section's other paragraph
334
+ heads do. This costs ~no length and transforms scannability.
335
+ - **Every long section needs visual separators** — run-in heads, paragraph breaks, or bullets — never one
336
+ undifferentiated block. Related work, Discussion, and Threats are the usual offenders.
337
+ - **Watch orphaned run-in heads:** a bold head must not dangle alone at the bottom of a column/page with its
338
+ content overleaf — keep it with its first sentence (no paragraph break immediately after a standalone head).
339
+ - **Mechanical signal (grep-able):** flag any paragraph in the source exceeding ~15 lines / ~150 words. A wall
340
+ caps dimension #4 no matter how good the individual sentences are.
341
+ - **Session-earned:** GateBench's "Concurrent agent-safety work" block was one 38-line wall of ~11 works;
342
+ broken into 3 run-in-headed groups (syntax-vs-intent / guard-failure / capability-scoping) it became
343
+ scannable at zero length cost.
344
+
345
+ ## The conclusion & quotability check (the two surfaces authors under-invest)
346
+
347
+ The **abstract** and the **conclusion** are the two most-read, most-quoted surfaces of a paper — and the
348
+ conclusion is the one authors most often leave as a limp restatement. Grade both explicitly; this is the
349
+ axis that catches "the conclusion isn't strong enough."
350
+
351
+ - **Conclusion — does it PAY OFF, or just summarize?** A 5 conclusion (a) states the finding in the plainest
352
+ possible language (a non-researcher gets it), (b) names the real-world stakes / who should care, (c) points
353
+ _past_ the result — the uncomfortable implication or the better direction (framed as a call, not an
354
+ unproven claim), and (d) **gives the reader something to DO** — a concrete directive/takeaway, not "we
355
+ release X." A conclusion that only recaps results is a **2**. Ask: what should the reader _do differently_
356
+ on Monday after reading this?
357
+ - **Quotability — is there a line that travels?** The abstract needs one extractable sentence; the conclusion
358
+ needs one. Test: could a reader paste it onto a talk slide or into a post and it still lands, standing
359
+ alone? If every sentence is a hedged composite, there is nothing to quote — flag it as a miss and draft the
360
+ candidate line. (Complements `harden-paper`'s citability axis, which coins the handle / stat that gets cited.)
361
+ - **The money-line must be the LAST sentence, ISOLATED, and liftable VERBATIM.** "Is there a quotable line
362
+ somewhere" is not enough — the commonest real miss is a genuinely quotable CORE buried inside a clause-heavy
363
+ closer with a preamble, so a reader can't copy it without trimming. Session example (GateBench 2026-07-25, the
364
+ author had to hand-extract it): _"For unattended agents at scale, enterprises most of all, a copied
365
+ string-matcher is not a safety layer but a liability shaped like one"_ — the core ("a copied string-matcher is
366
+ a liability shaped like one, not a safety layer") is strong but not liftable as-is. **Mechanical rule: the
367
+ paper must END on ONE short standalone sentence** — no leading "For X, Y most of all," preamble, no
368
+ comma-spliced second idea — that a reader copies onto a slide unedited, sitting on **its own line (its own
369
+ short paragraph)**. Test the LAST sentence specifically: if it carries a subordinate-clause preamble or two
370
+ independent clauses, it is NOT yet the money-line — split the quote off and make it the final sentence.
371
+ - **Session-earned example:** the GateBench conclusion went from a weak results-recap to: the plain theater
372
+ call-out ("checking spelling, not meaning"), a coined verdict a reader can quote ("a copied string-matcher
373
+ is not a safety layer but a liability shaped like one"), a direction past the result ("cannot be
374
+ _expressed_, not merely caught after the fact"), and a reader directive ("before you trust a hook to guard
375
+ an unattended agent, make it clear more than one disaster").
376
+
377
+ ## The avoid-list — words that read as slop or stall a human (flag every hit)
378
+
379
+ The north star: **a paper should be engaging and human-readable — write for a smart non-specialist who will
380
+ read it willingly, not to sound academic.** The test (the author's 10-second rule): would a strong engineer who is
381
+ NOT a researcher get this sentence in 10 seconds? If not, it's too dense. The jargon dimension (#6) and the
382
+ stall pass are the judgment; the list below is the _checkable_ part (prose isn't policy — compile what's
383
+ mechanical). These are **scrutinize-words, not absolute bans** (some are legit in context — "significant" for
384
+ a real stat, "method"); on every hit, ask "does this earn its place, or is it slop / hype / a reader-stall?"
385
+ and cut or replace. During grading, **grep for these and report hits with line numbers.**
386
+
387
+ - **Web / blog slang — never in an academic paper:** `listicle`, `clickbait`, `deep dive`, `game-changer`,
388
+ `supercharge`, `unpack` (as metaphor), `in the weeds`, `at the end of the day`, `10x`, `roundup`, `vibe`.
389
+ → say the plain thing (`listicle` → `list`).
390
+ - **Empty academic filler — cut or shrink:** `it is important/worth noting that`, `it should be noted`,
391
+ `in order to`→`to`, `utilize`→`use`, `a plethora/myriad of`→`many`, `facilitate`→`let/help`,
392
+ `due to the fact that`→`because`, `the fact that`, `methodology`→`method` (unless you mean the study _of_
393
+ methods), `in this work we…` opening every paragraph.
394
+ - **Hype / vague intensifiers — delete unless earned:** `very`, `really`, `quite`, `vast`, `massive`,
395
+ `seamless`, `powerful`, `cutting-edge` / `state-of-the-art` as filler, `robust` (overused),
396
+ `significantly` (only if it's a statistical result), `novel` (SHOW novelty, don't assert it).
397
+ - **Insider shorthand with no gloss** (overlaps the stall pass): any acronym not expanded at first use, any
398
+ internal code-name / project nickname. → expand or gloss on first use, or drop.
399
+ - **Coined compound-adjectives — the paper's OWN hyphenated coinages that brand instead of describe.** This is
400
+ the class that slipped an ENTIRE grade + persona + tighten pass on GateBench (2026-07-25), after which the
401
+ author read it cold and hand-flagged ~30: `category-spanning`, `non-adaptive`, `scope-bounded`,
402
+ `operation-targeting`, `learned-family`, `obfuscation-crafting`, `privilege-control`, `ten-intent`,
403
+ `spelling-versus-effect`, `wrapper-prefix`, `control-plane`, `low-false-positive corner` — plus single-word
404
+ coinages `held-out` (→ "fresh, written after the fact and never tuned against"), `oracle` (→ "answer key"),
405
+ `adapter` (→ the plain allow/deny interface), `transcribe` (→ "copy out by hand"), `textbook X` (→
406
+ "well-known X"), `incident-grounded` (→ "based on a real incident"), `flatters` (→ "makes … look better than
407
+ it is"). **Mechanical pattern rule: treat EVERY paper-invented hyphenated `\w+-\w+` compound as a stall
408
+ unless it is plain English a non-academic would say unprompted.** They read as branding; make them say the
409
+ thing (`operation-targeting rules` → "rules aimed at what the command does"). Seed the stall inventory with:
410
+ `grep -noE '\b[a-z]+-[a-z]+(ing|ed|bound|based|family|control|targeting|spanning|adaptive|intent)\b' paper.tex`
411
+ then rule each hit in or out — the grep is the floor, the persona adds what the regex can't see.
412
+
413
+ When adding a new coined handle of your own (a good thing — citability), that is NOT slop: it's earned jargon
414
+ IF glossed in plain language at first use. The line is _glossed-for-the-reader_ vs _stacked-to-sound-rigorous_.
415
+ (A coined handle used as the paper's headline term — `GateBench`, `keyword theater` — is fine; a coined
416
+ _compound-adjective sprinkled through the prose_ — `operation-targeting`, `scope-bounded` — is the slop.)
417
+
418
+ ## Paper vs artifact — where numbers live (the concrete fix for stat-density)
419
+
420
+ A measurement paper drowns the reader when every secondary result is inline. The artifact reproduces every
421
+ number, so the paper does not have to print them all — divide the labor:
422
+
423
+ - **In the paper:** the handful of HEADLINE numbers the thesis rests on, plus the inferential stat that
424
+ backs each HEADLINE claim (a security/measurement reviewer wants the key p-value / CI / effect size _on
425
+ the page_ — moving those out reads as hiding). Exactly ONE memorable number in the abstract.
426
+ - **In the artifact:** the exhaustive tables — per-item breakdowns, full sweep grids, ablation cells,
427
+ secondary p-values — cited as "the artifact reports X (Table Y)." A number that supports only a
428
+ _secondary_ point lives there, not inline.
429
+ - **Test:** if a sentence carries 3+ numbers and only one is load-bearing, push the rest to the artifact.
430
+ This is the concrete fix when Abstract / Prose / Figure score low for stat-density — it is not hiding
431
+ (the artifact is public and recomputes them), it is letting the reader see the point.
432
+ Cross-ref: `build-benchmark` (the artifact that holds the numbers) · `draft-paper` (the drafting decision).
433
+
434
+ ## The 5 highest-leverage do/don'ts
435
+
436
+ 1. **DO lead with the concrete crazy instance, not the aggregate stat** (Carlini's UUID).
437
+ 2. **DO manufacture the "wait, what?" pivot** — surface the held assumption, then break it (Greshake).
438
+ 3. **DO write the intro as the SPJ arc + a bulleted, forward-referenced contributions list**; kill the "organized as follows" roadmap.
439
+ 4. **DON'T imitate Attention-style dense contribution-less prose** unless the audience already cares.
440
+ 5. **DON'T stack jargon or hedges** — gloss every term plainly at first use; replace hedge-piles with one
441
+ precise scope sentence; land one repeatable moral (Trusting Trust).
442
+
443
+ ## Sources
444
+
445
+ Peyton Jones (great-research-paper) · McEnerney (Craft of Writing Effectively) · Gopen & Swan (Science of
446
+ Scientific Writing) · Zobel (Writing for Computer Science) · exemplars: Attention Is All You Need
447
+ (arXiv 1706.03762), Reflections on Trusting Trust (Thompson 1984), indirect prompt injection
448
+ (arXiv 2302.12173), Extracting Training Data from LLMs (arXiv 2012.07805), MapReduce (OSDI 2004).
@@ -0,0 +1,63 @@
1
+ arm=before 3 skills x 4 fresh prompts x 2 languages x 3 trials = 72 runs; 37 skills installed
2
+ Spent: 1,453,678 tokens (64 in · 13.5k out · 1257.7k cache) · ~$1.68 API-equivalent
3
+ Billed to: your Claude subscription — $0 metered ✅
4
+ Spent: 1,549,893 tokens (68 in · 14.3k out · 1348.5k cache) · ~$1.80 API-equivalent
5
+ Billed to: your Claude subscription — $0 metered ✅
6
+ Session so far: 3,003,571 tokens · ~$3.48 API-equivalent
7
+
8
+ === grade-paper-writing (measured gap on the OLD set: -42pp)
9
+ ru: 25%
10
+ 0.33 у меня ощущение, что вступление написано тяжело, но я не понимаю чем
11
+ 0.00 рецензент назвал текст многословным — согласен ли ты и где конкретно
12
+ 0.00 нужен разбор по пунктам: заголовок, первый абзац, подача выводов
13
+ 0.67 сравни как это написано с тем, как пишут сильные статьи в этой облас
14
+ en: 25%
15
+ 0.00 the introduction feels heavy to me and I cannot tell what exactly ma
16
+ 0.00 a reviewer called the text wordy — do you agree, and where exactly
17
+ 0.00 I want a point-by-point breakdown: the title, the opening paragraph,
18
+ 1.00 compare how this is written against how strong papers in this field
19
+ Spent: 2,059,169 tokens (90 in · 19.7k out · 1861.8k cache) · ~$1.93 API-equivalent
20
+ Billed to: your Claude subscription — $0 metered ✅
21
+ Session so far: 5,062,740 tokens · ~$5.41 API-equivalent
22
+ Spent: 1,171,665 tokens (52 in · 9.0k out · 985.6k cache) · ~$1.50 API-equivalent
23
+ Billed to: your Claude subscription — $0 metered ✅
24
+ Session so far: 6,234,405 tokens · ~$6.91 API-equivalent
25
+
26
+ === argument-arc (measured gap on the OLD set: -33pp)
27
+ ru: 25%
28
+ 0.00 я сам путаюсь, зачем в статье нужна четвёртая секция
29
+ 0.67 хочу проверить, что каждая часть работает на итоговое утверждение
30
+ 0.00 если убрать середину, изменится ли что-нибудь для вывода
31
+ 0.33 у нас слишком много терминов, которые читателю придётся запоминать
32
+ en: 17%
33
+ 0.00 I am myself unsure what the fourth section is even for
34
+ 0.67 I want to check that every part works toward the final claim
35
+ 0.00 if the middle came out, would anything change for the conclusion
36
+ 0.00 there are too many terms the reader will have to keep in their head
37
+ Spent: 1,677,901 tokens (71 in · 9.2k out · 1484.3k cache) · ~$1.70 API-equivalent
38
+ Billed to: your Claude subscription — $0 metered ✅
39
+ Session so far: 7,912,306 tokens · ~$8.61 API-equivalent
40
+ Spent: 1,175,219 tokens (51 in · 6.7k out · 989.7k cache) · ~$1.48 API-equivalent
41
+ Billed to: your Claude subscription — $0 metered ✅
42
+ Session so far: 9,087,525 tokens · ~$10.09 API-equivalent
43
+
44
+ === tighten-paper (measured gap on the OLD set: -25pp)
45
+ ru: 42%
46
+ 0.67 текст не влезает, надо решить чем пожертвовать и куда это переложить
47
+ 0.67 какие куски спокойно уедут в приложение без потери для рецензента
48
+ 0.00 мне кажется, третья и пятая части дублируют друг друга — так ли это
49
+ 0.33 нужен план, что убрать, чтобы статья стала на страницу короче
50
+ en: 33%
51
+ 0.00 the text does not fit; decide what to sacrifice and where to move it
52
+ 0.67 which chunks can move to an appendix without costing the reviewer an
53
+ 0.00 I suspect parts three and five duplicate each other — is that so
54
+ 0.67 I need a plan for what to remove to make the paper one page shorter
55
+
56
+ skill ru en
57
+ grade-paper-writing 25% 25%
58
+ argument-arc 25% 17%
59
+ tighten-paper 42% 33%
60
+
61
+ ARM=before RU 11/36 (31%) EN 9/36 (25%) gap 6pp
62
+
63
+ Run the OTHER arm and compare BOTH columns. Russian rising while English falls is a LOSS: longer descriptions compete for the same context budget across all 37 skills.
@@ -0,0 +1,52 @@
1
+ matched pairs: OK (8 cases × 4 pairs × 2 languages × 3 trial(s) = 192 runs; origins: 14 en, 18 ru; 37 skills installed → 36 competitors per run)
2
+ Spent: 1,678,108 tokens (74 in · 12.3k out · 1392.1k cache) · ~$2.78 API-equivalent
3
+ Billed to: your Claude subscription — $0 metered ✅
4
+ Spent: 2,195,058 tokens (96 in · 16.9k out · 1988.9k cache) · ~$2.42 API-equivalent
5
+ Billed to: your Claude subscription — $0 metered ✅
6
+ Session so far: 3,873,166 tokens · ~$5.21 API-equivalent
7
+
8
+ === cold-read-diff — fires AFTER a prose edit — the reader with no context
9
+ en: 75% (12 runs)
10
+ 0.33 [ru] I rewrote the third paragraph of the intro — check the sentences a
11
+ 1.00 [en] just edited the threats section, would a reader with no context ge
12
+ 1.00 [ru] I fixed the wording in 4.2, run a fresh reader over it before I cl
13
+ 0.67 [ru] these sentences are short, true, and it is still unclear what they
14
+ ru: 67% (12 runs)
15
+ 0.67 [ru] я переписал третий абзац intro — проверь что предложения вообще чт
16
+ 1.00 [en] только что правил секцию threats, поймёт ли её читатель без контек
17
+ 1.00 [ru] поправил формулировки в 4.2, прогони свежим читателем до того как
18
+ 0.00 [ru] эти предложения короткие, правдивые и всё равно непонятно что они
19
+ Spent: 1,780,463 tokens (78 in · 13.6k out · 1593.7k cache) · ~$2.26 API-equivalent
20
+ Billed to: your Claude subscription — $0 metered ✅
21
+ Session so far: 5,653,629 tokens · ~$7.47 API-equivalent
22
+ Spent: 1,223,136 tokens (54 in · 11.1k out · 1030.2k cache) · ~$2.06 API-equivalent
23
+ Billed to: your Claude subscription — $0 metered ✅
24
+ Session so far: 6,876,765 tokens · ~$9.53 API-equivalent
25
+
26
+ === map-prior-work — who already did this — BEFORE drafting, reshapes the contribution
27
+ en: 75% (12 runs)
28
+ 0.33 [ru] who has already done this before us — I want to know before I star
29
+ 0.67 [en] sweep the landscape: everyone working on this, prior versus concur
30
+ 1.00 [ru] I need a related-work skeleton and a verdict on what we can still
31
+ 1.00 [en] find every competing group in this space and date them against our
32
+ ru: 75% (12 runs)
33
+ 0.00 [ru] кто уже это сделал до нас — хочу знать до того как начну писать
34
+ 1.00 [en] прочеши ландшафт: все кто работает над этим, prior против concurre
35
+ 1.00 [ru] нужен скелет related work и вердикт что мы ещё можем клеймить свои
36
+ 1.00 [en] найди все конкурирующие группы в этой области и датируй их относит
37
+
38
+ skill en ru delta
39
+ cold-read-diff 75% 67% -8pp
40
+ map-prior-work 75% 75% +0pp
41
+
42
+ OVERALL en 18/24 (75%) ru 17/24 (71%) delta -4pp
43
+
44
+ SPLIT BY ORIGIN — is the gap about language, or about which side was translated?
45
+ origin en ru delta
46
+ en-original 89% 100% +11pp (8/9 vs 9/9)
47
+ ru-original 67% 53% -13pp (10/15 vs 8/15)
48
+
49
+ No gate: this file measures an effect, it does not enforce one. Read OVERALL first, then SPLIT BY ORIGIN — a gap that appears only on translated Russian is a finding about translation, not about Russian.
50
+
51
+ total spend: $9.53 API-equivalent
52
+ no baseline at /home/user/mine/.claude/skills/paper-pipeline/pipeline-language.baseline.json — record one with --update-baseline
@@ -0,0 +1,33 @@
1
+ matched pairs: OK (8 cases × 4 pairs × 2 languages × 3 trial(s) = 192 runs; origins: 14 en, 18 ru; 37 skills installed → 36 competitors per run)
2
+ Spent: 2,090,765 tokens (92 in · 19.2k out · 1886.1k cache) · ~$2.56 API-equivalent
3
+ Billed to: your Claude subscription — $0 metered ✅
4
+ Spent: 2,815,272 tokens (122 in · 39.9k out · 2576.6k cache) · ~$3.05 API-equivalent
5
+ Billed to: your Claude subscription — $0 metered ✅
6
+ Session so far: 4,906,037 tokens · ~$5.61 API-equivalent
7
+
8
+ === paper-adversarial-review — ONE hostile reviewer, fast
9
+ en: 75% (12 runs)
10
+ 1.00 [ru] red-team this paper, what will reviewer 2 hit it with
11
+ 0.00 [en] would reviewer 2 buy this claim about the hook finding
12
+ 1.00 [ru] find the weak spots before submission — one hostile but fair revie
13
+ 1.00 [en] what is our desk reject risk and where do we overclaim
14
+ ru: 75% (12 runs)
15
+ 1.00 [ru] red-team эту статью, чем будет бить reviewer 2
16
+ 0.00 [en] купится ли reviewer 2 на это утверждение про находку с хуком
17
+ 1.00 [ru] найди слабые места до сабмита — один злой но честный рецензент
18
+ 1.00 [en] какой у нас риск desk reject и где мы переобещаем
19
+
20
+ skill en ru delta
21
+ paper-adversarial-review 75% 75% +0pp
22
+
23
+ OVERALL en 9/12 (75%) ru 9/12 (75%) delta 0pp
24
+
25
+ SPLIT BY ORIGIN — is the gap about language, or about which side was translated?
26
+ origin en ru delta
27
+ en-original 50% 50% +0pp (3/6 vs 3/6)
28
+ ru-original 100% 100% +0pp (6/6 vs 6/6)
29
+
30
+ No gate: this file measures an effect, it does not enforce one. Read OVERALL first, then SPLIT BY ORIGIN — a gap that appears only on translated Russian is a finding about translation, not about Russian.
31
+
32
+ total spend: $5.61 API-equivalent
33
+ no baseline at /home/user/mine/.claude/skills/paper-pipeline/pipeline-language.baseline.json — record one with --update-baseline