paperlint 6.3.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/CONTRIBUTING.md +4 -2
  2. package/README.md +20 -13
  3. package/dist/adapters/latex/conditionals.d.ts +21 -0
  4. package/dist/adapters/latex/conditionals.d.ts.map +1 -0
  5. package/dist/adapters/latex/conditionals.js +75 -0
  6. package/dist/adapters/latex/conditionals.js.map +1 -0
  7. package/dist/adapters/latex/headings.d.ts +10 -0
  8. package/dist/adapters/latex/headings.d.ts.map +1 -0
  9. package/dist/adapters/latex/headings.js +129 -0
  10. package/dist/adapters/latex/headings.js.map +1 -0
  11. package/dist/adapters/latex/index.d.ts +1 -0
  12. package/dist/adapters/latex/index.d.ts.map +1 -1
  13. package/dist/adapters/latex/index.js +3 -0
  14. package/dist/adapters/latex/index.js.map +1 -1
  15. package/dist/adapters/latex/parse.d.ts +1 -1
  16. package/dist/adapters/latex/parse.d.ts.map +1 -1
  17. package/dist/adapters/latex/parse.js +3 -2
  18. package/dist/adapters/latex/parse.js.map +1 -1
  19. package/dist/build.d.ts +1 -1
  20. package/dist/build.d.ts.map +1 -1
  21. package/dist/build.js +1 -1
  22. package/dist/build.js.map +1 -1
  23. package/dist/cli.d.ts +1 -1
  24. package/dist/cli.d.ts.map +1 -1
  25. package/dist/cli.js +19 -5
  26. package/dist/cli.js.map +1 -1
  27. package/dist/domain/body-pages.d.ts +29 -0
  28. package/dist/domain/body-pages.d.ts.map +1 -1
  29. package/dist/domain/body-pages.js +25 -0
  30. package/dist/domain/body-pages.js.map +1 -1
  31. package/dist/domain/heading-case.d.ts +100 -0
  32. package/dist/domain/heading-case.d.ts.map +1 -0
  33. package/dist/domain/heading-case.js +365 -0
  34. package/dist/domain/heading-case.js.map +1 -0
  35. package/dist/domain/tex-document.d.ts +32 -0
  36. package/dist/domain/tex-document.d.ts.map +1 -1
  37. package/dist/domain/tex-document.js +11 -0
  38. package/dist/domain/tex-document.js.map +1 -1
  39. package/dist/eslint-rules/latex-language.d.ts.map +1 -1
  40. package/dist/eslint-rules/latex-language.js +16 -3
  41. package/dist/eslint-rules/latex-language.js.map +1 -1
  42. package/dist/facts-file.d.ts +3 -3
  43. package/dist/facts-file.d.ts.map +1 -1
  44. package/dist/facts-file.js +3 -3
  45. package/dist/facts-file.js.map +1 -1
  46. package/dist/folder-venue-rule.js +6 -6
  47. package/dist/folder-venue-rule.js.map +1 -1
  48. package/dist/heading-case.d.ts +48 -0
  49. package/dist/heading-case.d.ts.map +1 -0
  50. package/dist/heading-case.js +191 -0
  51. package/dist/heading-case.js.map +1 -0
  52. package/dist/paper-includes.d.ts +3 -0
  53. package/dist/paper-includes.d.ts.map +1 -1
  54. package/dist/paper-includes.js +17 -2
  55. package/dist/paper-includes.js.map +1 -1
  56. package/dist/ports/latex.d.ts +7 -1
  57. package/dist/ports/latex.d.ts.map +1 -1
  58. package/dist/preset-card-rule.d.ts +100 -0
  59. package/dist/preset-card-rule.d.ts.map +1 -0
  60. package/dist/preset-card-rule.js +221 -0
  61. package/dist/preset-card-rule.js.map +1 -0
  62. package/dist/presets.d.ts +29 -5
  63. package/dist/presets.d.ts.map +1 -1
  64. package/dist/presets.js +104 -68
  65. package/dist/presets.js.map +1 -1
  66. package/dist/submission.d.ts +8 -0
  67. package/dist/submission.d.ts.map +1 -1
  68. package/dist/submission.js +19 -7
  69. package/dist/submission.js.map +1 -1
  70. package/dist/tex-requirements.d.ts +42 -3
  71. package/dist/tex-requirements.d.ts.map +1 -1
  72. package/dist/tex-requirements.js +34 -5
  73. package/dist/tex-requirements.js.map +1 -1
  74. package/dist/tex-venue-rules.d.ts +6 -3
  75. package/dist/tex-venue-rules.d.ts.map +1 -1
  76. package/dist/tex-venue-rules.js +29 -10
  77. package/dist/tex-venue-rules.js.map +1 -1
  78. package/dist/venue-rules.d.ts +2 -1
  79. package/dist/venue-rules.d.ts.map +1 -1
  80. package/dist/venue-rules.js +55 -7
  81. package/dist/venue-rules.js.map +1 -1
  82. package/docs/configuration.md +13 -1
  83. package/docs/e2e.md +14 -12
  84. package/docs/optional-rules.md +4 -3
  85. package/docs/rules/format/page-limit.md +19 -2
  86. package/docs/rules/paper/folder-venue-leftover.md +1 -1
  87. package/docs/rules/talk/profile.md +1 -1
  88. package/docs/rules/tex/heading-case.md +424 -0
  89. package/docs/rules/tex/template.md +25 -5
  90. package/docs/rules/tex/venue-leftover.md +13 -0
  91. package/docs/rules.md +74 -57
  92. package/docs/submission.md +5 -1
  93. package/eslint-rules/latex-language.test.mjs +12 -0
  94. package/eslint-rules/latex-language.ts +17 -4
  95. package/eslint-rules/paper-typography.test.mjs +12 -0
  96. package/eslint.config.mjs +59 -1
  97. package/fixtures/build-e2e/acmart/paper.tex +1 -1
  98. package/fixtures/build-e2e/fallback/expect.json +3 -3
  99. package/fixtures/build-e2e/msr/PIPELINE-STATUS.md +3 -0
  100. package/fixtures/build-e2e/msr/expect.json +18 -0
  101. package/fixtures/build-e2e/msr/paper.tex +49 -0
  102. package/fixtures/build-e2e/msr/paperlint.json +1 -0
  103. package/fixtures/build-e2e/msr-appendix-after/PIPELINE-STATUS.md +3 -0
  104. package/fixtures/build-e2e/msr-appendix-after/expect.json +20 -0
  105. package/fixtures/build-e2e/msr-appendix-after/paper.tex +48 -0
  106. package/fixtures/build-e2e/msr-appendix-after/paperlint.json +1 -0
  107. package/lib/skill-checks.mjs +31 -0
  108. package/package.json +7 -1
  109. package/presets/acm-sigconf.jsonc +5 -0
  110. package/presets/acm-sigconf.md +43 -0
  111. package/presets/agenticdev.jsonc +27 -6
  112. package/presets/agenticdev.md +151 -0
  113. package/presets/aidc.jsonc +6 -0
  114. package/presets/aidc.md +75 -0
  115. package/presets/aisec.jsonc +5 -1
  116. package/presets/aisec.md +117 -0
  117. package/presets/ieee-conference.jsonc +5 -0
  118. package/presets/ieee-conference.md +38 -0
  119. package/presets/msr.jsonc +71 -0
  120. package/presets/msr.md +94 -0
  121. package/presets/realm.jsonc +7 -2
  122. package/presets/realm.md +166 -0
  123. package/presets/tex/agenticdev.tex +1 -1
  124. package/presets/tex-base.jsonc +6 -0
  125. package/presets/tex-base.md +30 -0
  126. package/presets/venue-profile.schema.json +65 -1
  127. package/skills/camera-ready/SKILL.md +8 -1
  128. package/skills/camera-ready/SKILL.md.spec.ts +7 -0
  129. package/skills/find-venue/SKILL.md +6 -5
  130. package/skills/find-venue/SKILL.md.spec.ts +5 -4
  131. package/skills/paper-pipeline/SKILL.md +5 -6
  132. package/skills/paper-pipeline/SKILL.md.spec.ts +4 -5
  133. package/skills/paper-pipeline/references/acl-venue-rules.md +1 -1
  134. package/skills/study-accepted-papers/SKILL.md +3 -3
  135. package/skills/study-accepted-papers/SKILL.md.spec.ts +2 -2
  136. package/skills/submission-portal/SKILL.md +2 -2
  137. package/skills/submission-portal/SKILL.md.spec.ts +1 -1
  138. package/skills/submit-paper/SKILL.md +34 -22
  139. package/skills/submit-paper/SKILL.md.spec.ts +33 -21
  140. package/skills/submit-paper/references/publishers/acm.md +1 -1
  141. package/src/adapters/latex/conditionals.ts +130 -0
  142. package/src/adapters/latex/headings.ts +163 -0
  143. package/src/adapters/latex/index.test.ts +65 -0
  144. package/src/adapters/latex/index.ts +3 -0
  145. package/src/adapters/latex/parse.ts +3 -2
  146. package/src/build.ts +2 -2
  147. package/src/cli.test.ts +50 -7
  148. package/src/cli.ts +28 -6
  149. package/src/domain/body-pages.test.ts +144 -0
  150. package/src/domain/body-pages.ts +61 -1
  151. package/src/domain/heading-case.test.ts +660 -0
  152. package/src/domain/heading-case.ts +538 -0
  153. package/src/domain/tex-document.ts +36 -0
  154. package/src/domain/venue-name.test.ts +13 -7
  155. package/src/facts-file.test.ts +4 -4
  156. package/src/facts-file.ts +6 -6
  157. package/src/folder-venue-rule.test.ts +10 -10
  158. package/src/folder-venue-rule.ts +6 -6
  159. package/src/heading-case.test.ts +500 -0
  160. package/src/heading-case.ts +275 -0
  161. package/src/init.test.ts +1 -1
  162. package/src/new-paper.test.ts +37 -6
  163. package/src/paper-includes.test.ts +26 -0
  164. package/src/paper-includes.ts +20 -2
  165. package/src/paper-settings-commands.test.ts +26 -11
  166. package/src/ports/latex.ts +7 -0
  167. package/src/preset-card-rule.test.ts +267 -0
  168. package/src/preset-card-rule.ts +384 -0
  169. package/src/presets.test.ts +259 -41
  170. package/src/presets.ts +161 -75
  171. package/src/rule-cases.test.ts +136 -50
  172. package/src/submission.test.ts +44 -4
  173. package/src/submission.ts +28 -7
  174. package/src/talk-rules.test.ts +6 -3
  175. package/src/tex-requirements.harness.ts +25 -11
  176. package/src/tex-requirements.test.ts +127 -1
  177. package/src/tex-requirements.ts +91 -12
  178. package/src/tex-venue-rules.test.ts +196 -21
  179. package/src/tex-venue-rules.ts +47 -16
  180. package/src/venue-rules.test.ts +180 -8
  181. package/src/venue-rules.ts +71 -10
  182. package/templates/paper/paper.tex +1 -1
  183. package/skills/submit-paper/references/venues/agenticdev.md +0 -171
  184. package/skills/submit-paper/references/venues/aisec.md +0 -105
  185. package/skills/submit-paper/references/venues/realm.md +0 -155
@@ -0,0 +1,117 @@
1
+ ---
2
+ title: "AISec @ ACM CCS — venue card"
3
+ ---
4
+
5
+ # AISec @ ACM CCS
6
+
7
+ The card of the venue preset `paperlint:aisec` ([`aisec.jsonc`](aisec.jsonc)): what the venue asks
8
+ for, in prose. The numbers a machine checks live in the preset; the section at the end is generated
9
+ from it. The `submit-paper` skill reads this card for the venue's specifics.
10
+
11
+ **Re-verify the call for papers every year** ([aisec.cc](https://aisec.cc/)) — deadline, page limit
12
+ and tracks shift between editions.
13
+
14
+ ## The bar
15
+
16
+ AISec is the long-running AI-security workshop of **ACM CCS**, a top security conference — not a
17
+ first-edition workshop. Mature threat modelling, honest evaluation and sound ethics are expected,
18
+ not rewarded: a security committee rejects on soundness and ethics grounds that a software
19
+ engineering workshop would wave through.
20
+
21
+ ## The venue (2026 edition)
22
+
23
+ - **Venue**: ACM Workshop on Artificial Intelligence and Security (**AISec**), co-located with
24
+ **ACM CCS** (Computer and Communications Security).
25
+ - **Deadline**: 24 July 2026 (check the AoE cutoff on the call each cycle).
26
+ - **Tracks**: full research papers; **benchmark papers** (new evaluation frameworks or datasets
27
+ **with artifact sharing** — a track of its own); position and SoK (systematization of knowledge)
28
+ papers. Pitch to the bar of the chosen track.
29
+ - **Format**: ACM double-column (`sigconf`). Build with `pdflatex; bibtex; pdflatex; pdflatex`; add
30
+ `\microtypesetup{expansion=false}` (the most common acmart crash).
31
+ - **Blind model**: **double-blind** — `\documentclass[sigconf,review,anonymous]{acmart}`, author
32
+ `Anonymous Author(s)`. See `submit-paper` §0/§4.
33
+ - **Archival**: accepted papers go into the CCS workshop proceedings in the ACM Digital Library,
34
+ with a DOI.
35
+ - **No supplementary-material field** on the form: host the artifact externally, anonymized (a
36
+ view-only link), and `\url{}` it in the Availability section. See `submit-paper` §2 and
37
+ `paper-pipeline/references/anonymization.md`.
38
+
39
+ ## Paper kinds and limits
40
+
41
+ Verbatim from the call: «Submitted papers must be at most 10 pages long in double-column ACM
42
+ format---excluding bibliography and well-marked appendices, for which up to two additional pages
43
+ can be used (hence, the paper's overall length must be of 12 pages at most).»
44
+
45
+ The limits are the same for every track; the preset keeps one kind per track so a paper's
46
+ `paperlint.json` says which track it was submitted under.
47
+
48
+ | kind | body pages | pages of bibliography and appendices |
49
+ | ----------- | ---------: | -----------------------------------: |
50
+ | `research` | 10 | 2 |
51
+ | `benchmark` | 10 | 2 |
52
+ | `position` | 10 | 2 |
53
+ | `sok` | 10 | 2 |
54
+
55
+ ⚠️ The venue tolerates a 13th page that holds **only** the generative-AI paragraph («Too many pages:
56
+ the limit is 12 pages, found 13» is then acceptable). `format/page-limit` does not know this
57
+ exception and reports the 13th page; a person clears that case by eye.
58
+
59
+ ## What else the preset encodes
60
+
61
+ - **The ACM template**, through `extends: paperlint:acm-sigconf` — AISec points to the main ACM
62
+ CCS formatting instructions and publishes no numbers of its own ([`acm-sigconf.md`](acm-sigconf.md)).
63
+ - **Names**: `AISec` and `ACM CCS`, what `tex/venue-leftover` looks for in another venue's paper.
64
+ - **No rules of its own**: nothing says who produces the AISec proceedings or whether they require
65
+ a balanced last page. A paper turns `pdf/last-page-balance` on in its own `paperlint.json` if the
66
+ camera-ready instructions ask for it.
67
+
68
+ ## What decides acceptance at a security venue
69
+
70
+ 1. **Threat-model soundness.** Name the attacker and their capabilities (what they observe and
71
+ control, their goal, their budget), and separate accidental failure from an adaptive adversary
72
+ — conflating the two is the classic reject. The threat model goes up front.
73
+ 2. **Ethics and responsible disclosure — a hard reject vector.**
74
+ - Anonymize studied third parties too: aggregate statistics and use anonymized IDs for the
75
+ entities studied, rather than naming maintainers or projects.
76
+ - Disclose findings to affected parties **before** any de-anonymized release; the paper states
77
+ the disclosure timeline and the release gate that holds de-anonymized data back until then.
78
+ - The anonymized artifact must itself be leak-free — the released files, not just the PDF. A
79
+ named entity in the artifact is invisible to a paper-only read.
80
+ 3. **Dual use.** A paper that publishes an evasion or attack technique publishes its fix with it.
81
+ 4. **Generative-AI disclosure.** ACM and CCS require stating how generative AI was used in the
82
+ work (writing, code, experiments).
83
+
84
+ ## Track fit
85
+
86
+ Adversarial ML, ML for security and security for ML, LLM and agent safety and security, evaluation
87
+ and benchmarking of AI-security defenses, poisoning, evasion and extraction, and rigorous
88
+ measurement of whether a claimed safety mechanism holds. A measurement paper that ships a reusable
89
+ evaluation framework and an anonymized artifact fits the benchmark track; name the track in the
90
+ abstract.
91
+
92
+ ## Compose with
93
+
94
+ - `submit-paper` — the mechanics: HotCRP form, anonymous artifact hosting, "ready for review".
95
+ - `camera-ready` — de-anonymization and the release gate after acceptance.
96
+ - `pc-panel-review` — its ethics lens and artifact-runner lens (plant a leak, confirm it is caught).
97
+ - `paper-pipeline/references/artifact-checklist.md` and `paper-pipeline/references/anonymization.md`.
98
+
99
+ ## Camera-ready
100
+
101
+ AISec is an ACM venue, so the final's mechanics are the ACM ones in the `submit-paper` skill's
102
+ `references/publishers/acm.md`: eRights first (it needs the final title), the preamble out of
103
+ submission mode, source files beside the PDF, CCS concepts from the 2012 CCS browser. AISec's own
104
+ DOI, ISBN, copyright line and dates are added here when the venue publishes them.
105
+
106
+ ## What the preset resolves to
107
+
108
+ <!-- paperlint:preset-rules -->
109
+ <!-- prettier-ignore-start -->
110
+ <!-- Generated from aisec.jsonc by `npx eslint --fix` (rule preset/card-rules). Edit the preset, not this section. -->
111
+
112
+ **`paperlint:aisec`** — venue preset for AISec · call for papers: <https://aisec.cc/> · extends `paperlint:acm-sigconf`
113
+
114
+ No preset of this chain sets a rule: under it, every rule keeps paperlint's default.
115
+
116
+ <!-- prettier-ignore-end -->
117
+ <!-- /paperlint:preset-rules -->
@@ -24,7 +24,12 @@
24
24
  // aidc.jsonc). The planted defects fail as they should, measured on the same compsoc paper:
25
25
  // `a4paper` added to the options → page 8.264 x 11.694 in: pdf/geometry
26
26
  // Computer Modern (`\rmdefault{cmr}`) → fonts CMR10, CMBX12, …: pdf/fonts, no NimbusRomNo9L
27
+ //
28
+ // Its card, in prose: `ieee-conference.md` beside this file.
27
29
  {
30
+ // A template family: it names no venue, so no `name` and no `url` (the venues that extend it do).
31
+ "type": "family",
32
+
28
33
  "template": "\\documentclass[conference]{IEEEtran}",
29
34
 
30
35
  // TeX Live packages the IEEEtran template needs ON TOP OF tex-base.jsonc, each with the files that
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: "IEEE IEEEtran conference — template family card"
3
+ ---
4
+
5
+ # IEEE `IEEEtran` conference
6
+
7
+ The card of the template family `paperlint:ieee-conference`
8
+ ([`ieee-conference.jsonc`](ieee-conference.jsonc)). A family is what a publisher's template
9
+ decides, whatever the venue: it names no venue and has no call for papers. A venue preset extends
10
+ it and adds what its own call sets — the class options it names, the page limit of each kind of
11
+ paper, the sections it requires. The template is [IEEEtran on CTAN](https://ctan.org/pkg/ieeetran).
12
+
13
+ ## What the family encodes
14
+
15
+ - **The class**: `\documentclass[conference]{IEEEtran}`. A venue that requires `compsoc` names it
16
+ in its own template and its own text block (as `aidc` does).
17
+ - **The page**: US letter, 8.5 × 11 in; the text block of `[conference]`, 7.14 × 9.30 in; two
18
+ columns.
19
+ - **The fonts**: Times (the URW clone the PDF names NimbusRomNo9L) for text, headings and title;
20
+ body at 10 pt, the bibliography at 8 pt (IEEEtran sets it in `\footnotesize`).
21
+ - **TeX packages** on top of the base set: ieeetran, cite, psnfss and times.
22
+
23
+ The numbers are measured, not copied: IEEE's own template files (`bare_conf.tex`,
24
+ `bare_conf_compsoc.tex`) and a 13-page paper built on each with IEEEtran.cls V1.8b, on two TeX Live
25
+ versions. `compsoc` changes the text block and the headings, and nothing the `pdf/*` rules judge.
26
+
27
+ ## What the family resolves to
28
+
29
+ <!-- paperlint:preset-rules -->
30
+ <!-- prettier-ignore-start -->
31
+ <!-- Generated from ieee-conference.jsonc by `npx eslint --fix` (rule preset/card-rules). Edit the preset, not this section. -->
32
+
33
+ **`paperlint:ieee-conference`** — template family, no venue of its own · extended by `paperlint:aidc`, `paperlint:msr`
34
+
35
+ No preset of this chain sets a rule: under it, every rule keeps paperlint's default.
36
+
37
+ <!-- prettier-ignore-end -->
38
+ <!-- /paperlint:preset-rules -->
@@ -0,0 +1,71 @@
1
+ // MSR 2027 Technical Papers (the 24th International Conference on Mining Software Repositories) — a
2
+ // VENUE preset over the IEEE conference family. Everything the IEEEtran template decides (page
3
+ // size, columns, fonts, body size, TeX packages) comes from ieee-conference.jsonc; this file adds
4
+ // what MSR's call for papers sets.
5
+ //
6
+ // Verbatim from https://2027.msrconf.org/track/msr-2027-technical-papers (fetched 2026-10-05):
7
+ // «All submissions must conform to the IEEE conference proceedings template, specified in the
8
+ // IEEE Conference Proceedings Formatting Guidelines (title in 24pt font and full text in 10pt
9
+ // type, LaTeX users must use \documentclass[10pt,conference]{IEEEtran} without including the
10
+ // compsoc or compsocconf options).»
11
+ // «Note that IEEE format is being used this year, whereas last year it was ACM format.»
12
+ // «All submissions must not exceed 10 pages for the main text, inclusive of all figures, tables,
13
+ // appendices, etc. Two more pages containing only references are permitted. All submissions
14
+ // must be in PDF. Accepted papers will be allowed one extra page for the main text of the
15
+ // camera-ready version.»
16
+ // «The MSR 2027 Technical Track will employ a double-anonymous review process.»
17
+ //
18
+ // The dates are not lint facts; they are in the card, msr.md beside this file.
19
+ {
20
+ "type": "venue",
21
+ "name": "MSR",
22
+ // The call quoted above.
23
+ "url": "https://2027.msrconf.org/track/msr-2027-technical-papers",
24
+ "extends": "paperlint:ieee-conference",
25
+
26
+ // «The MSR 2027 Technical Track will employ a double-anonymous review process. Thus, no
27
+ // submission may reveal its authors' identities.» (the call above), and `"blind":true` in the
28
+ // portal's data (https://msr2027.hotcrp.com/deadlines, 2026-10-05). anonymity/identity then
29
+ // requires the paper's `identity`.
30
+ "blind": true,
31
+
32
+ // «Papers must be submitted through HotCRP: https://msr2027.hotcrp.com/» (the call above).
33
+ // Recorded 2026-10-05: `/api/whoami` on this site answers 401 "Missing credentials" without a
34
+ // token — the HotCRP API, there.
35
+ "portal": { "kind": "hotcrp", "url": "https://msr2027.hotcrp.com" },
36
+
37
+ // What the venue is called in a paper's text (tex/venue-leftover) — and only beside a year
38
+ // («MSR 2027», «MSR'27»): «MSR» is also Microsoft Research, and an acronym papers define for
39
+ // themselves («Manual Speech Recognition (MSR)», in an accepted ACSAC paper of
40
+ // fixtures/accepted-papers/, warned six times when any whole word counted).
41
+ "aliases": ["MSR"],
42
+ "mentions": "with-year",
43
+
44
+ // The class line the call names, with the two options it forbids (tex/template). The family's
45
+ // `[conference]` text block (7.14 x 9.30 in) is the one this line builds, so no `format` override.
46
+ "template": "\\documentclass[10pt,conference]{IEEEtran}",
47
+ "template_forbids": ["compsoc", "compsocconf"],
48
+
49
+ "format": {
50
+ // 🔴 THE MAIN TEXT INCLUDES THE APPENDICES, AND THE REFERENCE PAGES ARE THE ONES WITH ONLY
51
+ // REFERENCES — not banal's count. Measured 2026-10-05 on IEEEtran [10pt,conference] builds:
52
+ // 10 pages of main text, its appendix before the references, 2 reference-only pages
53
+ // → banal: body 9, references 3 (a page whose first heading reads «Appendix» is typed as
54
+ // bibliography) — a correct paper fails
55
+ // 11 pages of main text, the appendix after the references
56
+ // → banal: body 10, references 2 (the appendix taken for more references) — an over-long
57
+ // paper passes
58
+ // So format/page-limit counts from the text (`appendix_in_body`): the body is every page up to
59
+ // the references, that page too when body text stands above the heading, plus every page from
60
+ // an appendix that follows the references; the pages between are the reference pages
61
+ // (docs/rules/format/page-limit.md). An appendix after the references is found by hyperref's
62
+ // anchor: load hyperref.
63
+ "body_ends_at": "references",
64
+ "appendix_in_body": true,
65
+
66
+ // One kind: the Technical Track's papers. The camera-ready's extra page is not this limit.
67
+ "kinds": {
68
+ "technical": { "body_pages_max": 10, "ref_pages_max": 2 },
69
+ },
70
+ },
71
+ }
package/presets/msr.md ADDED
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: "MSR — venue card"
3
+ ---
4
+
5
+ # MSR (Technical Papers)
6
+
7
+ The card of the venue preset `paperlint:msr` ([`msr.jsonc`](msr.jsonc)): what the venue asks for,
8
+ in prose. The numbers a machine checks live in the preset; the section at the end is generated from
9
+ it. The `submit-paper` skill reads this card for the venue's specifics.
10
+
11
+ **Re-verify the call for papers every year**
12
+ ([2027.msrconf.org/track/msr-2027-technical-papers](https://2027.msrconf.org/track/msr-2027-technical-papers)):
13
+ the template changed from ACM to IEEE in 2027 («Note that IEEE format is being used this year,
14
+ whereas last year it was ACM format.»), and limits and dates change between editions.
15
+
16
+ ## The venue (2027 edition)
17
+
18
+ - **Venue**: the Technical Papers track of **MSR 2027**, the International Conference on Mining
19
+ Software Repositories.
20
+ - **Portal**: HotCRP, `https://msr2027.hotcrp.com/` («Papers must be submitted through HotCRP»).
21
+ - **Dates** (the call, «AoE (UTC-12h)»): abstract **2026-10-20**, paper **2026-10-23**; early
22
+ reject notification 2026-12-03; author response 2026-12-04 to 2026-12-08; notification
23
+ 2027-01-08; camera-ready 2027-01-26. The call's prose names the weekdays «Mon, 20 Oct 2026» and
24
+ «Thurs, 23 Oct 2026», its date table «Tue 20 Oct 2026» and «Fri 23 Oct 2026»; the calendar sides
25
+ with the table (2026-10-20 is a Tuesday).
26
+ - 🔴 **The portal closes earlier than the call says.** Read 2026-10-05 on
27
+ `https://msr2027.hotcrp.com/deadlines`: «Submission deadline: Tuesday Oct 20, 2026, 12 AM EDT»
28
+ (`"sub":1792468800`, 2026-10-20 04:00 UTC) and «Resubmission deadline: Friday Oct 23, 2026, 12 AM
29
+ EDT» («Completed submissions may be updated until this deadline»). Midnight EDT at the start of
30
+ each day is about a day and a half before the end of that day AoE. The portal is what refuses the
31
+ upload: plan for its times, and re-read the page, since chairs change them.
32
+ - **Format**, verbatim from the call: «LaTeX users must use \documentclass[10pt,conference]{IEEEtran}
33
+ without including the compsoc or compsocconf options», «title in 24pt font and full text in 10pt
34
+ type», and «Alterations of spacing, font size, and other changes that deviate from the
35
+ instructions may result in desk rejection without further review.»
36
+ - **Double-anonymous**: «The MSR 2027 Technical Track will employ a double-anonymous review process.
37
+ Thus, no submission may reveal its authors' identities.» The call adds: names omitted, prior work
38
+ cited in the third person, and a preprint must not say it was submitted to MSR. The portal's data
39
+ says `"blind":true`.
40
+ - **Attendance**: «If a submission is accepted, at least one author of the paper is required to
41
+ register for MSR 2027 and present the paper.» The call does not say whether a remote presentation
42
+ is allowed.
43
+ - **New in 2027**, from the call: a submission may be desk rejected for fabricated references
44
+ («citations to papers, authors, venues, datasets, tools, or other artifacts that do not exist»),
45
+ clear signs of unverified AI-generated text, or hidden instructions aimed at automated tools.
46
+
47
+ ## Paper kinds and limits
48
+
49
+ | kind | main-text pages | pages of only references | what the call says |
50
+ | ----------- | --------------: | -----------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
51
+ | `technical` | 10 | 2 | «All submissions must not exceed 10 pages for the main text, inclusive of all figures, tables, appendices, etc. Two more pages containing only references are permitted.» |
52
+
53
+ «Accepted papers will be allowed one extra page for the main text of the camera-ready version.» —
54
+ not the submission's limit, so not in the preset.
55
+
56
+ 🔴 **Appendices count in the ten pages**, and a page that holds anything but references is a
57
+ main-text page. banal's count gets both wrong on an IEEEtran build (an appendix before the
58
+ references turns its pages into «bibliography»; one after them into «references»), so the preset
59
+ counts from the text (`format.appendix_in_body`): the main text is every page up to the references —
60
+ that page too when text stands above the heading — and every page from an appendix that follows the
61
+ references; the pages between hold only references. **Load hyperref**: an appendix after the
62
+ references is found by hyperref's anchor, and without it is counted as reference pages. See
63
+ `docs/rules/format/page-limit.md`.
64
+
65
+ ## What else the preset encodes
66
+
67
+ - **The IEEE template**, through `extends: paperlint:ieee-conference` — letter paper, two columns,
68
+ Times at 10 pt, IEEEtran's TeX packages ([`ieee-conference.md`](ieee-conference.md)) — with
69
+ `10pt` and `conference` required in the class line and `compsoc` and `compsocconf` forbidden
70
+ (`tex/template`, `template_forbids`).
71
+ - **Double-blind review** (`blind`), so `anonymity/identity` checks the PDF against the paper's
72
+ declared `identity`.
73
+ - **Where submissions go** (`portal`): `paperlint submission` reads and updates a paper's
74
+ submission through HotCRP's API on that site.
75
+ - **Names**: `MSR`, what `tex/venue-leftover` looks for in another venue's paper — only with a year
76
+ beside it (`mentions: with-year`: «MSR 2027», «MSR'27»), since «MSR» is also Microsoft Research
77
+ and an acronym papers define for themselves.
78
+ - **Not encoded**: the capitalization of the title and headings (`tex/heading-case` stays off: the
79
+ IEEE guidelines' rule has not been read and quoted here), and the register of the body (no
80
+ accepted MSR paper in the IEEE template exists yet to anchor `tex/contrast-frames` and its
81
+ siblings).
82
+
83
+ ## What the preset resolves to
84
+
85
+ <!-- paperlint:preset-rules -->
86
+ <!-- prettier-ignore-start -->
87
+ <!-- Generated from msr.jsonc by `npx eslint --fix` (rule preset/card-rules). Edit the preset, not this section. -->
88
+
89
+ **`paperlint:msr`** — venue preset for MSR · call for papers: <https://2027.msrconf.org/track/msr-2027-technical-papers> · extends `paperlint:ieee-conference`
90
+
91
+ No preset of this chain sets a rule: under it, every rule keeps paperlint's default.
92
+
93
+ <!-- prettier-ignore-end -->
94
+ <!-- /paperlint:preset-rules -->
@@ -1,5 +1,5 @@
1
- // REALM @ EMNLP 2026 format profile — ACL family, NOT ACM. Prose is in `realm.md` nearby,
2
- // the family's shared rules are in `paper-pipeline/references/acl-venue-rules.md`.
1
+ // REALM @ EMNLP 2026 format profile — ACL family, NOT ACM. Prose is in its card, `realm.md`
2
+ // beside this file; the family's shared rules are in `paper-pipeline/references/acl-venue-rules.md`.
3
3
  //
4
4
  // 🔴 THE GEOMETRY NUMBERS ARE MEASURED, NOT COPIED. banal run against our own build
5
5
  // (`repro/build-submission.sh` → `build/acl_latex.pdf`, 2026-08-26):
@@ -8,6 +8,11 @@
8
8
  // acmart (letter 8.5x11, size 9, Libertine) shares NOTHING with this — copying the numbers from
9
9
  // `agenticdev.jsonc` would give a gate that reddens on a correct paper.
10
10
  {
11
+ "type": "venue",
12
+ "name": "REALM",
13
+ // The workshop's call for papers, which the page limits below are quoted from.
14
+ "url": "https://realm-workshop.github.io/call_for_papers",
15
+
11
16
  // ACL's template is not a class: `acl_latex.tex` opens with `\documentclass[11pt]{article}` and
12
17
  // loads `acl.sty` as a package (https://github.com/acl-org/acl-style-files, checked 2026-09-27).
13
18
  // So the class `tex/template` compares against is article, at 11pt.
@@ -0,0 +1,166 @@
1
+ ---
2
+ title: "REALM @ EMNLP — venue card"
3
+ ---
4
+
5
+ # REALM @ EMNLP
6
+
7
+ The card of the venue preset `paperlint:realm` ([`realm.jsonc`](realm.jsonc)): what the venue asks
8
+ for, in prose. The numbers a machine checks live in the preset; the section at the end is generated
9
+ from it. The `submit-paper` skill reads this card for the venue's specifics.
10
+
11
+ **Family: ACL.** What is ACL-wide (the appendix rule, Limitations and Ethics outside the limit,
12
+ anonymity, OpenReview mechanics) lives in `paper-pipeline/references/acl-venue-rules.md`; only
13
+ REALM's own facts are here. ACL's template is not a class — `acl_latex.tex` loads `acl.sty` into
14
+ `\documentclass[11pt]{article}` — so this preset extends no family and carries the template's
15
+ numbers itself.
16
+
17
+ Sources: the call for papers,
18
+ [realm-workshop.github.io/call_for_papers](https://realm-workshop.github.io/call_for_papers)
19
+ (fetched 2026-08-02 and 2026-08-03), and the OpenReview invitation schema.
20
+ 🔴 **Re-verify every cycle** — dates, limits and tracks move between editions.
21
+
22
+ ## The venue (2026 edition, the 2nd)
23
+
24
+ | field | value |
25
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------- |
26
+ | full name | REALM — workshop at EMNLP 2026 |
27
+ | edition | **2nd** (the 1st edition's accepted papers exist — mine them with `study-accepted-papers`) |
28
+ | direct submission deadline | **Wednesday 5 August 2026**, 23:59 **AoE** (= 6 August 11:59 UTC) |
29
+ | ARR commitment deadline | 31 August 2026, same AoE convention |
30
+ | archival | optional at submission; archival → **ACL Anthology proceedings** |
31
+ | blind | **double-blind** — names and affiliations omitted |
32
+ | preprints | allowed at any time, provided the PDF does not link to de-anonymized information |
33
+ | portal | `openreview.net/group?id=EMNLP/2026/Workshop/REALM` |
34
+ | format | **PDF only** |
35
+ | mandatory sections | none beyond ACL's Limitations; _"authors are expected to attest to the ethical considerations in their work"_ |
36
+ | venue mode | hybrid; Thursday 29 October, 9:00–17:30, Room P1 |
37
+
38
+ ## Paper kinds and limits
39
+
40
+ | kind | at submission | at camera-ready | references and appendices |
41
+ | ------- | ------------: | --------------: | ------------------------: |
42
+ | `long` | 8 pages | 9 pages | unlimited |
43
+ | `short` | 4 pages | 5 pages | unlimited |
44
+
45
+ 🔴 **The page limit is not gated by the preset**, and that is a measurement: banal counts
46
+ Limitations and Ethics as body, which ACL excludes from the limit, so a gate on its count reports a
47
+ paper inside the limit. The numbers sit in the preset's `page_limits_not_gated`, as data for a
48
+ counter that knows where the body ends; the two kinds exist so a paper can name its own.
49
+
50
+ ## What else the preset encodes
51
+
52
+ - **The template**: `\documentclass[11pt]{article}` (`tex/template`), A4, two columns, Times at
53
+ 11 pt, references between 9 and 11 pt — measured on a build, not copied from ACL's text.
54
+ - **TeX packages** `acl.sty` needs: lineno, and the Times, Helvetica, Courier, Symbol and Zapf
55
+ Dingbats fonts (without them: "Font ptmr8t not loadable" and no PDF).
56
+ - **Names**: `REALM` and `EMNLP`, what `tex/venue-leftover` looks for in another venue's paper.
57
+
58
+ ## 🔴 The submission form has no supplementary field
59
+
60
+ From `api2.openreview.net/invitations?id=EMNLP/2026/Workshop/REALM/-/Submission`, the form's
61
+ **complete** field list:
62
+
63
+ ```
64
+ title · authors · authorids · keywords · TLDR · abstract · pdf ·
65
+ archival · cross_submission_to · serve_as_reviewer · venue · venueid
66
+ ```
67
+
68
+ There is no Responsible NLP Checklist and no supplementary upload. So:
69
+
70
+ 1. **Host the artifact externally and anonymously**, with the URL inside the PDF — a submission
71
+ blocker, and an artifact reviewer refuses the Available badge without a resolving URL.
72
+ 2. **Do not confuse this route with ARR**, whose portal does have the checklist and separate
73
+ software and data uploads.
74
+ 3. **No checklist means no LLM-disclosure field here**: put the disclosure in Limitations or Ethical
75
+ considerations, both outside the page limit
76
+ (`paper-pipeline/references/acl-venue-rules.md`, §GenAI / LLM disclosure).
77
+
78
+ `keywords` is a form field, so a keyword line does **not** belong in the typeset PDF.
79
+
80
+ ## The submission form, field by field
81
+
82
+ What the live form shows, in order. Help text is quoted.
83
+
84
+ | # | field | required | type | what goes in |
85
+ | --- | ----------------------- | -------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
86
+ | 1 | **Title** | ✱ | one line | _"Add TeX formulas using $In-line$ or $$Block$$"_ — plain text otherwise. **Must match the PDF's title exactly**; a late title edit in the paper means re-uploading the PDF _and_ retyping this |
87
+ | 2 | **Authors** | ✱ | profile search | pre-filled with the submitting author. _"All authors must have an OpenReview profile prior to submitting"_ — a co-author without an active profile blocks the whole submission |
88
+ | 3 | **Keywords** | ✱ | comma-separated | free text, no controlled vocabulary. 🔴 **Because this is a form field, the keyword line does NOT belong in the typeset PDF** |
89
+ | 4 | **TL;DR** | — | one sentence, 🔴 **hard max 250 characters** | _"a short sentence describing your paper"_. The limit is **not in the help text** — it rejects on submit. Optional, but it is the first thing a bidding reviewer reads: name the mechanism, not the topic. Count the characters before pasting |
90
+ | 5 | **Abstract** | ✱ | markdown + TeX, Write/Preview tabs | paste the paper's abstract. Markdown emphasis renders; `**bold**` survives. Backticks render as code |
91
+ | 6 | **PDF** | ✱ | file upload | _"Upload a PDF file that ends with .pdf"_. No supplementary field anywhere on the form — see above |
92
+ | 7 | **Archival** | ✱ | radio: Archival / Non-archival | Archival → **ACL Anthology**. _"If your paper is a cross-submission (currently under review or already published at another venue), it cannot be archival, per ACL policies."_ Changeable at camera-ready |
93
+ | 8 | **Cross Submission To** | — | one line | leave **empty** unless the paper is genuinely under review elsewhere. Filling it forfeits archival |
94
+ | 9 | **Serve As Reviewer** | ✱ | profile search | _"reciprocal reviewing practice… nominate at least one author to serve as a reviewer using their OpenReview profile ID (e.g. ~First_Last1)"_. **A solo author nominates themself** — the field is required and there is nobody else |
95
+ | 10 | License | ✱ | fixed chip | **CC BY 4.0**, not editable |
96
+ | 11 | Readers | ✱ | fixed chips | `EMNLP 2026 Workshop REALM` + `authorids` |
97
+ | 12 | Signatures | ✱ | fixed chip | the submitting author |
98
+
99
+ Then **Submit** / Cancel.
100
+
101
+ 🔴 **The displayed deadline is not when writes stop.** An OpenReview invitation carries two dates
102
+ and the interface shows only the first:
103
+
104
+ | field | 2026 edition, UTC |
105
+ | -------------------------------------------------------------- | ----------------- |
106
+ | `duedate` — printed everywhere as the deadline | 2026-08-06 11:59 |
107
+ | `expdate` — when the invitation actually stops accepting edits | 2026-08-06 12:29 |
108
+
109
+ A 30-minute window, undocumented in the call and invisible on the form. Read it before the last
110
+ hour:
111
+
112
+ ```
113
+ curl -sS "https://api2.openreview.net/invitations?id=<VENUE-PATH>/-/Submission" \
114
+ | python3 -c "import json,sys,datetime;[print(k, datetime.datetime.utcfromtimestamp(i[k]/1000)) \
115
+ for i in json.load(sys.stdin)['invitations'] for k in ('duedate','expdate') if i.get(k)]"
116
+ ```
117
+
118
+ Do not plan around it — a venue may set `expdate == duedate`. It is room to recover from a defect
119
+ found at the deadline, not a schedule.
120
+
121
+ ## Traps
122
+
123
+ - **The title lives in two places, and they diverge silently.** Change the paper first, rebuild,
124
+ then fill the form — never the other way round.
125
+ - **"Serve As Reviewer" enrols the nominee.** The day after submission the program chairs assign
126
+ papers and set a review deadline (2026: submissions 5 August, reviews due 21 August AoE, sixteen
127
+ days). ACL's AI policy applies to the reviews, verbatim from the chairs' email: _"the use of
128
+ generative AI tools to write an entire review is prohibited. While such tools may be used for
129
+ minor editing (e.g., grammar or clarity), the content and assessment must be the reviewer's
130
+ own."_ The sanction lands on submissions to the next ARR cycle. Price the reviewing window in
131
+ before submitting, and check whether a decision about reviewing was already made before filling
132
+ a required field.
133
+ - **Keywords are a form field, not paper content.** Keep the list in a non-typeset comment in the
134
+ source and paste it here.
135
+ - **The abstract field accepts markdown**, so paste the source abstract. Extracting it from the
136
+ built PDF is a mistake: on a line-numbered build the extractor interleaves the margin numbers and
137
+ drops paragraphs.
138
+ - **The deadline's time zone is stated in a different sentence** of the call than the date. Read
139
+ the whole page, then convert.
140
+ - **OpenReview profile moderation is the critical path.** An author with no institutional email and
141
+ no DBLP record has no expedite route; start the profile weeks ahead.
142
+ - The workshop's hybrid status comes from REALM's own root page, not EMNLP's general one.
143
+
144
+ ## The ARR route is not a free fallback
145
+
146
+ The 31 August "ARR commitment" deadline commits a paper **already reviewed by ACL Rolling Review**.
147
+ A paper never submitted to ARR needs an ARR submission first, on ARR's own cycle.
148
+
149
+ ## Sources
150
+
151
+ - `realm-workshop.github.io/call_for_papers` — the call (fetched 2026-08-02, 2026-08-03)
152
+ - `realm-workshop.github.io/` — the root page, hybrid confirmation
153
+ - `api2.openreview.net/invitations?id=…/-/Submission` — the live form schema
154
+
155
+ ## What the preset resolves to
156
+
157
+ <!-- paperlint:preset-rules -->
158
+ <!-- prettier-ignore-start -->
159
+ <!-- Generated from realm.jsonc by `npx eslint --fix` (rule preset/card-rules). Edit the preset, not this section. -->
160
+
161
+ **`paperlint:realm`** — venue preset for REALM · call for papers: <https://realm-workshop.github.io/call_for_papers>
162
+
163
+ No preset of this chain sets a rule: under it, every rule keeps paperlint's default.
164
+
165
+ <!-- prettier-ignore-end -->
166
+ <!-- /paperlint:preset-rules -->
@@ -1,5 +1,5 @@
1
1
  % agenticdev.tex — venue numbers for the guards IN THE PREAMBLE. LaTeX doesn't read YAML, so the
2
- % values are duplicated from venues/agenticdev.jsonc (the source of truth — read by the
2
+ % values are duplicated from presets/agenticdev.jsonc (the source of truth — read by the
3
3
  % `pdf/profile` rule, see eslint-rules/pdf-facts.mjs:128). in = inches.
4
4
  %
5
5
  % 🔴 THIS USED TO SAY `venues/agenticdev.yaml`, AND NO SUCH FILE EXISTS (fixed 2026-09-12). The
@@ -14,7 +14,13 @@
14
14
  // cm-super — without it pdflatex silently RASTERIZES Computer Modern in some contexts (a Type 3
15
15
  // bitmap font in the PDF; measured 2026-09-01 on an ACL paper: 1 Type 3 font before, 0 after).
16
16
  // ACM and ACL both reject such a PDF, and the build does not complain.
17
+ //
18
+ // Its card, in prose: `tex-base.md` beside this file.
17
19
  {
20
+ // The base set: not a venue and not a template family. No preset extends it — every paper gets it
21
+ // anyway, under whatever it extends — so it holds `tex` and nothing else (the schema says so).
22
+ "type": "base",
23
+
18
24
  "tex": {
19
25
  "packages": {
20
26
  "latex": ["latex.ltx", "article.cls"],
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: "The TeX base set — card"
3
+ ---
4
+
5
+ # The TeX base set
6
+
7
+ The card of [`tex-base.jsonc`](tex-base.jsonc): the TeX Live packages **every** paper gets, and all
8
+ a paper gets when it extends no preset. It is neither a venue nor a template family, and no preset
9
+ extends it — a venue's or a family's `tex.packages` is added on top of it, never instead of it.
10
+ `paperlint toolchain` installs it with every preset's packages; `paperlint build` checks it is
11
+ present before building.
12
+
13
+ What it is for: a plain `article` paper with the usual tools, typeset in Type 1 fonts. Each package
14
+ names the files that prove it is installed — `kpsewhich` must find them after an install, because
15
+ an installer's exit code is not the criterion. `cm-super` is there because without it pdflatex
16
+ silently rasterizes Computer Modern in some contexts, a bitmap font that ACM and ACL both reject.
17
+ `texcount` and `checkcites` are programs the skills run, not files LaTeX loads.
18
+
19
+ ## What the preset resolves to
20
+
21
+ <!-- paperlint:preset-rules -->
22
+ <!-- prettier-ignore-start -->
23
+ <!-- Generated from tex-base.jsonc by `npx eslint --fix` (rule preset/card-rules). Edit the preset, not this section. -->
24
+
25
+ **`tex-base.jsonc`** — the TeX base set: every paper gets it, whatever it extends, and no preset extends it
26
+
27
+ No preset of this chain sets a rule: under it, every rule keeps paperlint's default.
28
+
29
+ <!-- prettier-ignore-end -->
30
+ <!-- /paperlint:preset-rules -->