paperlint 4.1.0 → 5.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.
- package/CLAUDE.md +26 -2
- package/CONTRIBUTING.md +7 -0
- package/README.md +15 -4
- package/action.harness.mjs +54 -36
- package/action.yml +12 -27
- package/dist/adapters/latex/document-class.d.ts +6 -5
- package/dist/adapters/latex/document-class.d.ts.map +1 -1
- package/dist/adapters/latex/document-class.js +18 -10
- package/dist/adapters/latex/document-class.js.map +1 -1
- package/dist/adapters/latex/includes.d.ts +16 -0
- package/dist/adapters/latex/includes.d.ts.map +1 -0
- package/dist/adapters/latex/includes.js +48 -0
- package/dist/adapters/latex/includes.js.map +1 -0
- package/dist/adapters/latex/index.d.ts +9 -5
- package/dist/adapters/latex/index.d.ts.map +1 -1
- package/dist/adapters/latex/index.js +8 -1
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/nodes.d.ts +5 -1
- package/dist/adapters/latex/nodes.d.ts.map +1 -1
- package/dist/adapters/latex/nodes.js +6 -2
- package/dist/adapters/latex/nodes.js.map +1 -1
- package/dist/adapters/latex/parse.d.ts.map +1 -1
- package/dist/adapters/latex/parse.js +1 -0
- package/dist/adapters/latex/parse.js.map +1 -1
- package/dist/adapters/latex/prose.d.ts +8 -0
- package/dist/adapters/latex/prose.d.ts.map +1 -0
- package/dist/adapters/latex/prose.js +353 -0
- package/dist/adapters/latex/prose.js.map +1 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +7 -3
- package/dist/build.js.map +1 -1
- package/dist/claim-provenance.d.ts +34 -0
- package/dist/claim-provenance.d.ts.map +1 -0
- package/dist/claim-provenance.js +146 -0
- package/dist/claim-provenance.js.map +1 -0
- package/dist/cli.d.ts +2 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +81 -31
- package/dist/cli.js.map +1 -1
- package/dist/domain/paper-source.d.ts +58 -0
- package/dist/domain/paper-source.d.ts.map +1 -0
- package/dist/domain/paper-source.js +109 -0
- package/dist/domain/paper-source.js.map +1 -0
- package/dist/domain/sentences.d.ts +26 -0
- package/dist/domain/sentences.d.ts.map +1 -0
- package/dist/domain/sentences.js +48 -0
- package/dist/domain/sentences.js.map +1 -0
- package/dist/domain/tex-document.d.ts +39 -4
- package/dist/domain/tex-document.d.ts.map +1 -1
- package/dist/domain/tex-document.js.map +1 -1
- package/dist/eslint-rules/latex-language.d.ts +5 -1
- package/dist/eslint-rules/latex-language.d.ts.map +1 -1
- package/dist/eslint-rules/latex-language.js +6 -3
- package/dist/eslint-rules/latex-language.js.map +1 -1
- package/dist/eslint-rules/paper-context.d.ts +20 -0
- package/dist/eslint-rules/paper-context.d.ts.map +1 -0
- package/dist/eslint-rules/paper-context.js +44 -0
- package/dist/eslint-rules/paper-context.js.map +1 -0
- package/dist/eslint-rules/paper-typography.d.ts +8 -1
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
- package/dist/eslint-rules/paper-typography.js +85 -19
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/tex-build.d.ts.map +1 -1
- package/dist/eslint-rules/tex-build.js +7 -1
- package/dist/eslint-rules/tex-build.js.map +1 -1
- package/dist/init.d.ts +4 -19
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +24 -29
- package/dist/init.js.map +1 -1
- package/dist/package-dirs.d.ts +2 -0
- package/dist/package-dirs.d.ts.map +1 -1
- package/dist/package-dirs.js +8 -0
- package/dist/package-dirs.js.map +1 -1
- package/dist/paper-files.d.ts +2 -2
- package/dist/paper-includes.d.ts +17 -0
- package/dist/paper-includes.d.ts.map +1 -0
- package/dist/paper-includes.js +51 -0
- package/dist/paper-includes.js.map +1 -0
- package/dist/ports/latex.d.ts +12 -1
- package/dist/ports/latex.d.ts.map +1 -1
- package/dist/register.d.ts +40 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +134 -0
- package/dist/register.js.map +1 -0
- package/dist/rules-config.d.ts +1 -0
- package/dist/rules-config.d.ts.map +1 -1
- package/dist/rules-config.js.map +1 -1
- package/dist/structure.js +1 -1
- package/dist/structure.js.map +1 -1
- package/dist/tex-paper.d.ts +33 -0
- package/dist/tex-paper.d.ts.map +1 -0
- package/dist/tex-paper.js +103 -0
- package/dist/tex-paper.js.map +1 -0
- package/dist/tex-venue-rules.d.ts +7 -2
- package/dist/tex-venue-rules.d.ts.map +1 -1
- package/dist/tex-venue-rules.js +31 -17
- package/dist/tex-venue-rules.js.map +1 -1
- package/docs/configuration.md +5 -4
- package/docs/install.md +8 -8
- package/docs/prior-art/paper-folder-scaffolding.md +4 -7
- package/docs/rules/tex/claim-provenance.md +83 -0
- package/docs/rules/tex/register.md +77 -0
- package/docs/rules/tex/required-section.md +3 -1
- package/docs/rules/tex/template.md +12 -0
- package/docs/rules/tex/venue-leftover.md +4 -2
- package/docs/rules.md +17 -10
- package/eslint-rules/latex-language.ts +10 -4
- package/eslint-rules/paper-context.test.ts +47 -0
- package/eslint-rules/paper-context.ts +57 -0
- package/eslint-rules/paper-typography.test.mjs +48 -1
- package/eslint-rules/paper-typography.ts +139 -24
- package/eslint-rules/tex-build.ts +8 -1
- package/eslint.config.mjs +1 -0
- package/fixtures/real-markdown-paper/baseline.json +1 -2
- package/fixtures/real-markdown-paper/baseline.ts +8 -7
- package/package.json +2 -1
- package/scripts/check.ts +2 -2
- package/scripts/eslint-report-guard.mjs +5 -2
- package/scripts/harness-api.frozen.json +0 -1
- package/skills/cold-read-diff/SKILL.md +31 -10
- package/skills/cold-read-diff/SKILL.md.spec.ts +30 -9
- package/skills/draft-paper/SKILL.md +2 -2
- package/skills/draft-paper/SKILL.md.spec.ts +1 -1
- package/skills/grade-paper-writing/SKILL.md +109 -44
- package/skills/grade-paper-writing/SKILL.md.spec.ts +108 -43
- package/skills/harden-paper/SKILL.md +35 -36
- package/skills/harden-paper/SKILL.md.spec.ts +34 -35
- package/skills/paper-adversarial-review/SKILL.md +2 -2
- package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -1
- package/skills/paper-pipeline/SKILL.md +3 -3
- package/skills/paper-pipeline/SKILL.md.spec.ts +2 -2
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +6 -6
- package/skills/paper-pipeline/references/pipeline-status-template.md +2 -16
- package/skills/paper-pipeline/references/writing-craft.md +53 -18
- package/skills/pc-panel-review/SKILL.md +36 -11
- package/skills/pc-panel-review/SKILL.md.spec.ts +35 -10
- package/src/adapters/latex/document-class.ts +20 -12
- package/src/adapters/latex/includes.ts +74 -0
- package/src/adapters/latex/index.test.ts +183 -1
- package/src/adapters/latex/index.ts +14 -4
- package/src/adapters/latex/nodes.ts +11 -2
- package/src/adapters/latex/parse.ts +1 -0
- package/src/adapters/latex/prose.ts +484 -0
- package/src/build.harness.mjs +4 -2
- package/src/build.test.ts +18 -1
- package/src/build.ts +7 -3
- package/src/claim-provenance.test.ts +352 -0
- package/src/claim-provenance.ts +217 -0
- package/src/cli.harness.mjs +22 -54
- package/src/cli.test.ts +2 -18
- package/src/cli.ts +92 -36
- package/src/domain/paper-source.test.ts +156 -0
- package/src/domain/paper-source.ts +233 -0
- package/src/domain/sentences.ts +67 -0
- package/src/domain/tex-document.ts +36 -3
- package/src/init.test.ts +33 -13
- package/src/init.ts +25 -48
- package/src/linted-set.test.ts +11 -1
- package/src/new-paper.harness.mjs +1 -5
- package/src/package-dirs.ts +9 -0
- package/src/paper-files.ts +2 -2
- package/src/paper-includes.test.ts +161 -0
- package/src/paper-includes.ts +77 -0
- package/src/ports/latex.ts +13 -0
- package/src/register.test.ts +165 -0
- package/src/register.ts +177 -0
- package/src/rule-cases.test.ts +43 -23
- package/src/rule-docs.test.ts +0 -1
- package/src/rules-config.ts +1 -0
- package/src/structure.harness.ts +1 -3
- package/src/structure.ts +1 -1
- package/src/tex-paper.test.ts +148 -0
- package/src/tex-paper.ts +161 -0
- package/src/tex-venue-rules.test.ts +87 -5
- package/src/tex-venue-rules.ts +62 -30
- package/templates/paper/PIPELINE-STATUS.md +0 -4
- package/dist/action-ref.d.ts +0 -12
- package/dist/action-ref.d.ts.map +0 -1
- package/dist/action-ref.js +0 -16
- package/dist/action-ref.js.map +0 -1
- package/dist/eslint-rules/paper-research-question.d.ts +0 -31
- package/dist/eslint-rules/paper-research-question.d.ts.map +0 -1
- package/dist/eslint-rules/paper-research-question.js +0 -188
- package/dist/eslint-rules/paper-research-question.js.map +0 -1
- package/eslint-rules/paper-research-question.harness.mjs +0 -212
- package/eslint-rules/paper-research-question.ts +0 -199
- package/fixtures/paper-research-question/comment-only/PIPELINE-STATUS.md +0 -9
- package/fixtures/paper-research-question/comment-only/paper.tex +0 -7
- package/fixtures/paper-research-question/declared-not-in-paper/PIPELINE-STATUS.md +0 -10
- package/fixtures/paper-research-question/declared-not-in-paper/paper.tex +0 -6
- package/fixtures/paper-research-question/draft/PIPELINE-STATUS.md +0 -6
- package/fixtures/paper-research-question/draft/paper.tex +0 -2
- package/fixtures/paper-research-question/markdown-no-rq/PIPELINE-STATUS.md +0 -9
- package/fixtures/paper-research-question/markdown-no-rq/paper.md +0 -4
- package/fixtures/paper-research-question/shipped-no-rq/PIPELINE-STATUS.md +0 -12
- package/fixtures/paper-research-question/shipped-no-rq/paper.tex +0 -3
- package/fixtures/paper-research-question/shipped-with-rq/PIPELINE-STATUS.md +0 -10
- package/fixtures/paper-research-question/shipped-with-rq/paper.tex +0 -2
- package/skills/harden-paper/fixtures/uncited-assertions-sample.md +0 -43
- package/skills/harden-paper/fixtures/uncited-assertions-sample.tex +0 -77
- package/src/action-ref.test.ts +0 -26
- package/src/action-ref.ts +0 -15
package/dist/tex-venue-rules.js
CHANGED
|
@@ -24,6 +24,7 @@ import { basename, dirname, join } from "node:path";
|
|
|
24
24
|
import { CONFIG_FILE } from "#lib/paper-config";
|
|
25
25
|
import { collapse, documentClassLine, missingOptions, runText, spanIn, } from "./domain/tex-document.js";
|
|
26
26
|
import { paperPreset, resolvePreset, SHIPPED_PREFIX, shippedPresets, } from "./presets.js";
|
|
27
|
+
import { readPaper, reportInPaper } from "./tex-paper.js";
|
|
27
28
|
// ── the judges: what the source says + a resolved preset → findings. Pure. ─────────
|
|
28
29
|
/** A place as a finding points at it: its span, or null — the top of the file — when unplaced. */
|
|
29
30
|
const spanOf = (p) => (p.kind === "at" ? p.span : null);
|
|
@@ -38,6 +39,22 @@ function judgeClass(line, want, data) {
|
|
|
38
39
|
at,
|
|
39
40
|
}));
|
|
40
41
|
}
|
|
42
|
+
/** A candidate as the message names it: its line, or an empty `\documentclass{}`. */
|
|
43
|
+
const candidateLine = (c) => c.kind === "class" ? documentClassLine(c) : "\\documentclass{}";
|
|
44
|
+
/**
|
|
45
|
+
* Several class lines behind a TeX switch: satisfied when any candidate is the template's class
|
|
46
|
+
* with its options; otherwise one finding, at the first candidate, naming every one.
|
|
47
|
+
*/
|
|
48
|
+
function judgeCandidates(candidates, want, data) {
|
|
49
|
+
const matches = candidates.some((c) => c.kind === "class" && judgeClass(c, want, data).length === 0);
|
|
50
|
+
if (matches)
|
|
51
|
+
return [];
|
|
52
|
+
const named = candidates.map((c) => `\`${candidateLine(c)}\``).join(", ");
|
|
53
|
+
const found = { ...data, count: candidates.length, candidates: named };
|
|
54
|
+
return [
|
|
55
|
+
{ messageId: "noCandidate", data: found, at: spanOf(candidates[0].place) },
|
|
56
|
+
];
|
|
57
|
+
}
|
|
41
58
|
/** The paper's class line against a template that was read: present, naming a class, that class. */
|
|
42
59
|
function judgeClassLine(line, want, data) {
|
|
43
60
|
switch (line.kind) {
|
|
@@ -47,6 +64,8 @@ function judgeClassLine(line, want, data) {
|
|
|
47
64
|
return [{ messageId: "emptyClass", data, at: spanOf(line.place) }];
|
|
48
65
|
case "class":
|
|
49
66
|
return judgeClass(line, want, data);
|
|
67
|
+
case "ambiguous":
|
|
68
|
+
return judgeCandidates(line.candidates, want, data);
|
|
50
69
|
}
|
|
51
70
|
}
|
|
52
71
|
/**
|
|
@@ -148,6 +167,7 @@ const RULES = {
|
|
|
148
167
|
badTemplate: '{{file}}: the preset\'s "template" {{text}} is neither a \\documentclass line nor a class name, so the class cannot be checked',
|
|
149
168
|
wrongClass: "the class is `{{got}}`, and {{venue}} requires `{{template}}` — the page size, fonts and layout the venue checks come from the class",
|
|
150
169
|
missingOption: "the class option `{{option}}` is missing: {{venue}} requires `{{template}}`",
|
|
170
|
+
noCandidate: "none of the {{count}} \\documentclass lines is `{{template}}`, which {{venue}} requires: {{candidates}}. The source picks one behind a TeX switch, which is not evaluated; make one of them the venue's",
|
|
151
171
|
},
|
|
152
172
|
},
|
|
153
173
|
},
|
|
@@ -201,8 +221,9 @@ export function otherVenues(preset, fromFile, deps) {
|
|
|
201
221
|
});
|
|
202
222
|
}
|
|
203
223
|
/**
|
|
204
|
-
* What a judge reads for the paper whose `paper.tex` is `filename
|
|
205
|
-
* resolved preset (`pdf/measured` and
|
|
224
|
+
* What a judge reads for the paper whose `paper.tex` is `filename` — the paper with its includes
|
|
225
|
+
* spliced (`readPaper`) — or null when the paper has no resolved preset (`pdf/measured` and
|
|
226
|
+
* `pdf/profile` already say so).
|
|
206
227
|
*/
|
|
207
228
|
function readingOf(filename, src, deps) {
|
|
208
229
|
const dir = dirname(filename);
|
|
@@ -211,18 +232,11 @@ function readingOf(filename, src, deps) {
|
|
|
211
232
|
return null;
|
|
212
233
|
const preset = p.preset;
|
|
213
234
|
const others = () => otherVenues(preset, join(dir, CONFIG_FILE), deps);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
findings.forEach((f) => {
|
|
220
|
-
context.report({
|
|
221
|
-
loc: { start: at(f.at?.start ?? 0), end: at(f.at?.end ?? 0) },
|
|
222
|
-
messageId: f.messageId,
|
|
223
|
-
data: f.data,
|
|
224
|
-
});
|
|
225
|
-
});
|
|
235
|
+
const paper = readPaper(filename, src, deps);
|
|
236
|
+
return {
|
|
237
|
+
reading: { src: paper.text, latex: deps.latex, preset, others },
|
|
238
|
+
paper,
|
|
239
|
+
};
|
|
226
240
|
}
|
|
227
241
|
function rule(name, deps) {
|
|
228
242
|
const { judge, meta } = RULES[name];
|
|
@@ -235,9 +249,9 @@ function rule(name, deps) {
|
|
|
235
249
|
return {
|
|
236
250
|
root() {
|
|
237
251
|
const sc = context.sourceCode;
|
|
238
|
-
const
|
|
239
|
-
if (
|
|
240
|
-
|
|
252
|
+
const r = readingOf(context.filename, sc.raw ?? sc.text, deps);
|
|
253
|
+
if (r !== null)
|
|
254
|
+
reportInPaper(context, meta.messages, r.paper, judge(r.reading));
|
|
241
255
|
},
|
|
242
256
|
};
|
|
243
257
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tex-venue-rules.js","sourceRoot":"","sources":["../src/tex-venue-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,MAAM,
|
|
1
|
+
{"version":3,"file":"tex-venue-rules.js","sourceRoot":"","sources":["../src/tex-venue-rules.ts"],"names":[],"mappings":"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"}
|
package/docs/configuration.md
CHANGED
|
@@ -230,15 +230,16 @@ write. It prints its plan first, one line per step, then runs it:
|
|
|
230
230
|
|
|
231
231
|
```
|
|
232
232
|
papers/my-paper
|
|
233
|
-
inputs: TEXINPUTS += <paperlint>/presets/tex
|
|
233
|
+
inputs: TEXINPUTS += the paper's directory, then <paperlint>/presets/tex
|
|
234
234
|
compile: paper.tex (\documentclass[sigconf,screen]{acmart}, venue agenticdev)
|
|
235
235
|
measure: pdf.js → _build/paper.facts.json (facts for the lint rules; nothing is judged here)
|
|
236
236
|
✓ paper.pdf — 4 pdflatex passes, 1 bibtex run; facts: _build/paper.facts.json, last page 621.5 / 264.8 pt
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
- **inputs** — paperlint's own venue files
|
|
240
|
-
so `\input{paper-guards}` in a preamble resolves with no
|
|
241
|
-
|
|
239
|
+
- **inputs** — `TEXINPUTS` is the paper's directory, then paperlint's own venue files
|
|
240
|
+
(`paper-guards.tex`, `<venue>.tex`), so `\input{paper-guards}` in a preamble resolves with no
|
|
241
|
+
setup and a file of the paper's own wins over paperlint's of the same name. The system tree still
|
|
242
|
+
resolves after them. `paperlint lint` looks for an included file in the same places.
|
|
242
243
|
- **compile** — `pdflatex -interaction=nonstopmode -halt-on-error -file-line-error`, then `bibtex`
|
|
243
244
|
when the `.aux` names a bibliography, then pdflatex again until the `.aux`, `.toc`, `.out` and
|
|
244
245
|
`.bbl` stop changing and the log stops asking for a rerun. bibtex runs again only when the cited
|
package/docs/install.md
CHANGED
|
@@ -33,7 +33,7 @@ In order:
|
|
|
33
33
|
on the defaults gets no config file at all.
|
|
34
34
|
3. **Links each shipped skill** into `.claude/skills/<name>`, where Claude Code looks for skills.
|
|
35
35
|
4. **Writes the hook commands** into `.claude/settings.json`, beside your own entries.
|
|
36
|
-
5. **Offers a GitHub Actions workflow
|
|
36
|
+
5. **Offers a GitHub Actions workflow** that runs `npm ci`, then the action from `node_modules`.
|
|
37
37
|
6. **Offers a first paper** (`paperlint new`) if the papers directory has none.
|
|
38
38
|
7. **Offers TeX Live** for `paperlint build` (`paperlint toolchain`, ~270 MB, ~3 min, once), with
|
|
39
39
|
the size in the question and NO as the default. Without a terminal it asks nothing and lists the
|
|
@@ -47,13 +47,13 @@ question (Ctrl+D) also takes the default.
|
|
|
47
47
|
|
|
48
48
|
## What `paperlint init` writes
|
|
49
49
|
|
|
50
|
-
| what
|
|
51
|
-
|
|
|
52
|
-
| `{ "papersDir": … }` naming your papers directory
|
|
53
|
-
| the three hook commands, merged in beside your own entries
|
|
54
|
-
| a GitHub Actions workflow
|
|
55
|
-
| a first paper, via `paperlint new`
|
|
56
|
-
| one relative symlink per shipped skill, into the installed package
|
|
50
|
+
| what | where | when |
|
|
51
|
+
| -------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `{ "papersDir": … }` naming your papers directory | `paperlint.json` | only when it is not the default `papers` |
|
|
53
|
+
| the three hook commands, merged in beside your own entries | `.claude/settings.json` | by default. A human at a terminal is asked [Y/n]; an agent, CI or `--yes` gets YES; `--no-hooks` skips. Hand-wired under another spelling: nothing written, so nothing runs twice |
|
|
54
|
+
| a GitHub Actions workflow: `npm ci`, then `./node_modules/paperlint` | `.github/workflows/` | only if you say yes; it asks once, and only when a human is at a terminal (stdin and stdout, no `CI`, no `--yes`) |
|
|
55
|
+
| a first paper, via `paperlint new` | `<papers>/<name>/` | only when the papers directory holds none: asked of a human at a terminal, otherwise only with `--paper <name>` |
|
|
56
|
+
| one relative symlink per shipped skill, into the installed package | `.claude/skills/<name>` | always — except where that name is already taken (a directory, a file, a link elsewhere): that entry is left as it is and named in the report |
|
|
57
57
|
|
|
58
58
|
It installs no software you did not say yes to, and touches nothing else. Commit `.claude/settings.json` so every clone
|
|
59
59
|
gets the hooks; the hook commands run files inside `node_modules`, so a fresh clone needs
|
|
@@ -86,7 +86,6 @@ listed so nobody thinks the two are consistent.
|
|
|
86
86
|
| `paper/stages` (error) | `eslint-rules/paper-stages.mjs:91`, glob `src/cli.ts:126` | front matter `stages[]`: `stage`, `date`, `pdf`, `bytes`; and lists `versions/*.pdf` |
|
|
87
87
|
| `paper/source` (error) | `eslint-rules/paper-stages.mjs:377`, `:415`, `:442` | `stages[].source`, `sourceBytes`, `sourceLost` |
|
|
88
88
|
| `paper/author-list` (warn) | `eslint-rules/paper-stages.mjs:296`, marker `:325` | `stages[]` + searches the scorecard **table cells** for the marker `bib-authors` |
|
|
89
|
-
| `paper/research-question` (warn) | `eslint-rules/paper-research-question.mjs:142` | reads the status file from disk while linting `paper.tex`/`paper.md`: `stages`, `researchQuestion` |
|
|
90
89
|
| `paper/typography` (warn) | `src/cli.ts:118` | **not** the status file — its per-paper allowance lives in the ROOT key `typographyDebt`, keyed by paper path |
|
|
91
90
|
| `pipeline-check.mjs` (skill script) | `skills/paper-pipeline/scripts/pipeline-check.mjs:231-321` | the `Venue:` / `Deadline:` header line, the verdict line, the five section tables |
|
|
92
91
|
| `paper-status-gates` hook | `hooks/paper-status-gates.hook.mjs` | surfaces the verdict and unrun gates after an edit |
|
|
@@ -111,7 +110,6 @@ content of those files is reproduced here.)
|
|
|
111
110
|
| ------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
112
111
|
| paper short name / title | **config** | human, once — `rpp new` can prefill from the folder name |
|
|
113
112
|
| venue, deadline, blind model (the `Venue:` header line) | **config** | human; changes when the paper is re-targeted |
|
|
114
|
-
| `researchQuestion` | **config** | human, once |
|
|
115
113
|
| format (`.tex` vs `.md`) | **derived** | from which source file exists |
|
|
116
114
|
| venue profile, paper kind, pdf path (a separate `venue.json` in one real paper) | **config** | human; already a per-paper file in practice |
|
|
117
115
|
| typography allowance (`typographyDebt`) | **config** | human, but it sits in the root key keyed by path today |
|
|
@@ -202,7 +200,7 @@ written once at freeze time, then checked forever — and today a human types it
|
|
|
202
200
|
- **Root (`package.json` key): the papers directory only.** Unchanged. It stays a scope, like
|
|
203
201
|
Quarto's project dir or Astro's collection glob. No list of papers.
|
|
204
202
|
- **Per paper: the paper folder's `PIPELINE-STATUS.md` front matter** holds that paper's config
|
|
205
|
-
(
|
|
203
|
+
(the venue/deadline fields that today live in a prose header line) and
|
|
206
204
|
its stage records. Unchanged carrier, so every existing paper keeps working.
|
|
207
205
|
- **Not recommended now: a separate `paper.yml`.** It would split config from the journal cleanly
|
|
208
206
|
(the 1 300-line files are 98% journal), but it moves every rule's input and every consumer's
|
|
@@ -214,9 +212,8 @@ written once at freeze time, then checked forever — and today a human types it
|
|
|
214
212
|
**`rpp new <name> [--format tex|md]`** — creates `<papers>/<name>/` with:
|
|
215
213
|
|
|
216
214
|
- `paper.tex` or `paper.md` (a minimal stub; `--format` defaults to `tex` — ask when interactive);
|
|
217
|
-
- `PIPELINE-STATUS.md` from a **template file** shipped in the package, with the name filled in
|
|
218
|
-
|
|
219
|
-
shipped nothing — `paper-stages.mjs:24`).
|
|
215
|
+
- `PIPELINE-STATUS.md` from a **template file** shipped in the package, with the name filled in and
|
|
216
|
+
**no** `stages` field (a new paper has shipped nothing — `paper-stages.mjs:24`).
|
|
220
217
|
|
|
221
218
|
Rules for it, each taken from a tool above:
|
|
222
219
|
|
|
@@ -251,7 +248,7 @@ the skills tell agents to update them.
|
|
|
251
248
|
| ------------------------------------------ | ------------------------- | ----------------------------------------------------------------------- |
|
|
252
249
|
| the folder and source stub | human | `rpp new` |
|
|
253
250
|
| `PIPELINE-STATUS.md` skeleton | human copies a code fence | `rpp new` |
|
|
254
|
-
|
|
|
251
|
+
| venue, deadline | human | human (unchanged) |
|
|
255
252
|
| `stages` records, bytes, the frozen copies | human types byte counts | still human; `rpp freeze` is the later step that takes it over |
|
|
256
253
|
| `sourceLost` exceptions | human | human (unchanged) |
|
|
257
254
|
| `State:`, `Updated:`, `Requires` cells | human | still human; **derivable** — candidates to drop from the template later |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# tex/claim-provenance
|
|
2
|
+
|
|
3
|
+
**Level:** warn · **Reads:** `paper.tex`
|
|
4
|
+
|
|
5
|
+
## What it catches
|
|
6
|
+
|
|
7
|
+
A sentence of the body that states a number and does not say whose the number is. The sentence is
|
|
8
|
+
reported once, however many numbers it holds. Any one of these owners silences it:
|
|
9
|
+
|
|
10
|
+
| owner | in the sentence |
|
|
11
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
12
|
+
| a work outside the paper | a `\cite` (any of natbib's or biblatex's forms), a `\url`, an `\href`, or a footnote that cites or links |
|
|
13
|
+
| the authors | _we_, _our_, _ours_, _us_ (the capitalised country _US_ is not the authors) |
|
|
14
|
+
| a place in the paper | `\ref`, `\cref`, `\autoref` and their kin, or the words _Section 4_, _Table 2_, _Fig. 3_, _Appendix B_, _§4_ |
|
|
15
|
+
| a claimant named as one | _advertises_, _claims_: _"the skill advertises a 65% reduction"_, _"(claim 63%)"_ |
|
|
16
|
+
| the sample the number counts | _n = 134_ (in prose or in math), or a count followed by what it counts: _48 runs_, _48 independent runs_, _of 1,836 repositories_ |
|
|
17
|
+
|
|
18
|
+
It reads the body of the whole paper — `paper.tex` with the files it `\input`s, `\include`s or
|
|
19
|
+
`\subfile`s spliced in — from the start of the document, the abstract included, to `\appendix` or the
|
|
20
|
+
bibliography. A sentence in an included file is reported at that include, with the file and line at
|
|
21
|
+
the front of the message. Footnotes are read as sentences of their own. A citation or a footnote set right after
|
|
22
|
+
the full stop belongs to the sentence the full stop ends.
|
|
23
|
+
|
|
24
|
+
A number is digits a reader sees — `42\%`, `0.37`, `1,836`, `3x`, `3×`. Not a number: a year on its
|
|
25
|
+
own (1900–2099); a number right after a capitalised word inside the sentence (_Claude 3_, _Python
|
|
26
|
+
3.12_, _Node 22_), which is a name; the level of an interval (the 95 of _95% CI_); digits glued to a letter, a hyphen or a point (`GPT-4`, `COVID-19`, `v1.2`, `10k`,
|
|
27
|
+
`0x1F`); anything inside math, a table, a figure, a caption, a heading (a run-in one too: `\textbf{Threats.}` opening a paragraph), code, a comment, a macro
|
|
28
|
+
definition, or the title block.
|
|
29
|
+
|
|
30
|
+
## Why
|
|
31
|
+
|
|
32
|
+
A reviewer who cannot tell a property of the world from a cited finding from the authors' own
|
|
33
|
+
measurement says so, and scores the paper's soundness on it. Academic prose carries the owner by
|
|
34
|
+
default — _we found_, _[12] report_, _(Table 2)_ — and a sentence rewritten for punch loses it first:
|
|
35
|
+
_"Under test the rules held in 97% of cases"_ has no subject, and a reader takes it
|
|
36
|
+
for a result from the literature. This rule is the floor under the rules that shorten sentences.
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
```latex
|
|
41
|
+
Agents ignore 42\% of the rules they are given. % warns
|
|
42
|
+
Under test the rules held in 97\% of cases. % warns: no one ran the test
|
|
43
|
+
We find that agents ignore 42\% of the rules. % silent: the authors
|
|
44
|
+
Agents ignore 42\% of the rules~\cite{smith2025}. % silent: a citation
|
|
45
|
+
Agents ignore 42\% of the rules (Table~\ref{t:rates}). % silent: a place in the paper
|
|
46
|
+
Of 1,836 repositories, 12\% ship hooks. % silent: the sample
|
|
47
|
+
In 2024 the first agents shipped with GPT-4. % silent: a year and a name
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The first line reports:
|
|
51
|
+
|
|
52
|
+
> «42%» — whose number is this? A reader cannot tell a cited finding from your own measurement from
|
|
53
|
+
> a general fact. Say it in the sentence: cite the work (\cite), claim it (we measured, our census),
|
|
54
|
+
> point to where it is shown (\ref, Section N, Table N), or name the sample it counts (n = 134, 48
|
|
55
|
+
> runs)
|
|
56
|
+
|
|
57
|
+
## Options / preset fields
|
|
58
|
+
|
|
59
|
+
None. It is on, as a warning, for every `paper.tex`; turn it off or up in the `rules` setting like
|
|
60
|
+
any other rule.
|
|
61
|
+
|
|
62
|
+
## What it does not check
|
|
63
|
+
|
|
64
|
+
- Whether the owner is the right one: a citation that does not report the number, or a _we_ in a
|
|
65
|
+
sentence about someone else's work, silences the sentence all the same.
|
|
66
|
+
- What a custom macro prints: `\rate{}` defined as `42\%` is not a number here.
|
|
67
|
+
- Which numbers are names, beyond the two shapes it knows: a number after a lowercase word (_version
|
|
68
|
+
3 of the model_) is read as a quantity, and so is the number of a name that opens the sentence
|
|
69
|
+
(_Claude 3 fails …_).
|
|
70
|
+
- Whether a count followed by a plural noun is really the sample (_3 times faster_ passes as one).
|
|
71
|
+
- Markdown papers (`paper.md`): it reads the LaTeX parse tree only.
|
|
72
|
+
|
|
73
|
+
## How to fix
|
|
74
|
+
|
|
75
|
+
Say whose the number is, in the sentence — usually by putting back the subject a punchy rewrite took
|
|
76
|
+
out: _"We ran the rules in 48 sessions and saw no violation"_, not _"No violation in 48 runs."_ A
|
|
77
|
+
number that is common knowledge, or quoted on purpose, keeps its sentence with ESLint's directive and
|
|
78
|
+
the reason:
|
|
79
|
+
|
|
80
|
+
```latex
|
|
81
|
+
% eslint-disable-next-line tex/claim-provenance -- the venue's own page limit, quoted
|
|
82
|
+
The limit is 8.
|
|
83
|
+
```
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# tex/register
|
|
2
|
+
|
|
3
|
+
**Level:** warn · **Reads:** `paper.tex` and the files it includes
|
|
4
|
+
|
|
5
|
+
## What it catches
|
|
6
|
+
|
|
7
|
+
A body in which more than 0.8 sentences per 1000 words open with _And_, _So_, _But_, _Nor_, _Or_ or
|
|
8
|
+
_Yet_. It is reported once, at the body's first sentence, with the count, the rate and the first
|
|
9
|
+
three such sentences.
|
|
10
|
+
|
|
11
|
+
It reads the body of the whole paper — `paper.tex` with the files it `\input`s, `\include`s or
|
|
12
|
+
`\subfile`s spliced in — from the start of the document, the abstract included, to `\appendix` or the
|
|
13
|
+
bibliography: paragraphs, list items and footnotes. Headings are not sentences, and neither is a
|
|
14
|
+
run-in heading — a bold or italic phrase ending in `.` or `:` that opens a paragraph or an item
|
|
15
|
+
(`\textbf{Threats.} …`). Captions, tables, figures, code and math environments are left out. A
|
|
16
|
+
citation, a cross-reference or inline math counts as one word, as it reads on the page. Sentences
|
|
17
|
+
are cut exactly as [`tex/claim-provenance`](claim-provenance.md) cuts them.
|
|
18
|
+
|
|
19
|
+
A conjunction counts only as the capitalised first word of a sentence; the _and_ that opens a list
|
|
20
|
+
item continuing the sentence before the list does not.
|
|
21
|
+
|
|
22
|
+
A body under 2 000 words is not judged: there one sentence decides the rate.
|
|
23
|
+
|
|
24
|
+
## Why
|
|
25
|
+
|
|
26
|
+
Reviewers called our prose "too informal" and "a blogpost". Measured against eleven accepted
|
|
27
|
+
papers, sentences opening with a coordinating conjunction set our four drafts apart:
|
|
28
|
+
|
|
29
|
+
| measure | 11 accepted papers | our 4 drafts |
|
|
30
|
+
| ------------------------------------------------------------ | ---------------------------: | -----------: |
|
|
31
|
+
| sentences opening with And/So/But/Nor/Or/Yet, per 1000 words | 0–0.58 (the ACSAC papers: 0) | 0.29–2.98 |
|
|
32
|
+
|
|
33
|
+
The limit sits above the accepted range with room to spare: the rule flags a body that has drifted
|
|
34
|
+
to a post's register, not one a little above the median. Mean sentence length did not separate the
|
|
35
|
+
two groups. The share of sentences under eight words did not either, once measured on the parse
|
|
36
|
+
tree: 3.3–7.3% on the two accepted papers in this repository's corpus, 5.1–7.0% on three of ours.
|
|
37
|
+
|
|
38
|
+
On the corpus (`fixtures/accepted-papers/`) the rule measures:
|
|
39
|
+
|
|
40
|
+
| paper | per 1000 words |
|
|
41
|
+
| ----------------------------------- | -------------: |
|
|
42
|
+
| `secure-acsac24` (ACSAC 2024) | 0.00 |
|
|
43
|
+
| `llm-splained-acsac25` (ACSAC 2025) | 0.00 |
|
|
44
|
+
| `agenticdev-acm26` (ours, accepted) | 1.60 |
|
|
45
|
+
|
|
46
|
+
The vocabulary of machine-written text (_delve_, _crucial_) is a different question, and a different
|
|
47
|
+
check; a paper can avoid every such word and still read as a post.
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
```latex
|
|
52
|
+
We measured the cost on four tools. But the bill barely moves. % a conjunction start
|
|
53
|
+
We measured the cost on four tools, and the bill barely moves. % none
|
|
54
|
+
We measured the cost on four tools. However, the bill barely moves. % none
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
On a body where such sentences run above the limit, the rule reports:
|
|
58
|
+
|
|
59
|
+
> 7 sentences open with And, So, But, Nor, Or or Yet — 1.60 per 1000 words (first: «…», «…», «…»).
|
|
60
|
+
> Accepted papers measured 0–0.58; this rule warns above 0.8. Join the sentence to the one before,
|
|
61
|
+
> or open with the connective a paper uses (However, Therefore, Moreover)
|
|
62
|
+
|
|
63
|
+
## Options / preset fields
|
|
64
|
+
|
|
65
|
+
In a paper's `paperlint.json`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"rules": {
|
|
70
|
+
"tex/register": ["warn", { "conjunctionStartsPer1000": 0.8 }]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| option | default | what it is |
|
|
76
|
+
| -------------------------- | ------: | ---------------------------------------------------------- |
|
|
77
|
+
| `conjunctionStartsPer1000` | 0.8 | the conjunction starts per 1000 words above which it warns |
|
|
@@ -9,6 +9,9 @@ the required sections by title in `required_sections`; the paper must have a `\s
|
|
|
9
9
|
`\section*` with exactly that title (whitespace collapsed), and, when the preset says
|
|
10
10
|
`position: "last"`, no section of the main text may come after it.
|
|
11
11
|
|
|
12
|
+
It reads the sections of the whole paper, the files `paper.tex` includes spliced in where they are
|
|
13
|
+
included, so a required section kept in `sections/llm-usage.tex` counts.
|
|
14
|
+
|
|
12
15
|
It only knows the sections a preset lists. A paper whose `paperlint.json` names no preset, or a
|
|
13
16
|
preset with no `required_sections`, gets no finding.
|
|
14
17
|
|
|
@@ -66,7 +69,6 @@ the bibliography or an appendix is fine. Without `position`, anywhere will do.
|
|
|
66
69
|
## What it does not check
|
|
67
70
|
|
|
68
71
|
- Whether LLMs were used, or what the section says.
|
|
69
|
-
- Sections pulled in with `\input` or `\include`: the rule reads `paper.tex` alone.
|
|
70
72
|
|
|
71
73
|
## How to fix
|
|
72
74
|
|
|
@@ -8,6 +8,17 @@ The paper is not set in the class its venue requires. The rule compares the `\do
|
|
|
8
8
|
of `paper.tex` with the preset's `template`: the class must be the same, and every option the
|
|
9
9
|
template names must be there. The paper may add options of its own.
|
|
10
10
|
|
|
11
|
+
A source that keeps one file for several venues and picks the class behind a TeX switch has several
|
|
12
|
+
`\documentclass` lines. The switch is not evaluated: each line is a candidate, the paper passes when
|
|
13
|
+
one of them is the template's class with its options, and when none is, one finding at the first
|
|
14
|
+
candidate names every one:
|
|
15
|
+
|
|
16
|
+
```latex
|
|
17
|
+
\def\venue{2}
|
|
18
|
+
\if\venue1 \documentclass{article} \fi
|
|
19
|
+
\if\venue2 \documentclass[conference,compsoc]{IEEEtran} \fi % passes: the second candidate matches
|
|
20
|
+
```
|
|
21
|
+
|
|
11
22
|
It only knows the class a preset names. A paper whose `paperlint.json` names no preset, or a
|
|
12
23
|
preset with no `template`, gets no finding.
|
|
13
24
|
|
|
@@ -55,6 +66,7 @@ and no option. A value that is neither is reported as a finding that names the p
|
|
|
55
66
|
requires is there.
|
|
56
67
|
- The version of the class file (#94).
|
|
57
68
|
- A `\documentclass` inside a comment: the rule reads the parse tree, so it does not count.
|
|
69
|
+
- Which branch of a TeX switch builds: with several class lines, one matching candidate is enough.
|
|
58
70
|
|
|
59
71
|
## How to fix
|
|
60
72
|
|
|
@@ -11,7 +11,9 @@ now going to VenueB.
|
|
|
11
11
|
It only knows the venues paperlint ships a preset for, by each preset's `name` and `aliases`. A
|
|
12
12
|
venue with no preset is not recognized.
|
|
13
13
|
|
|
14
|
-
It
|
|
14
|
+
It reads the whole paper — `paper.tex` with the files it `\input`s, `\include`s or `\subfile`s
|
|
15
|
+
spliced in; a name found in an included file is reported at that include, with the file and line at
|
|
16
|
+
the front of the message. It looks at what a reader sees — prose, the author block, captions, footnotes, a citation's note in
|
|
15
17
|
square brackets, and front-matter macros such as `\acmConference` — and ignores comments, citation
|
|
16
18
|
keys, labels, URLs (a `\url`, and the address of an `\href` — its link text is read), math, code and
|
|
17
19
|
the bibliography. Names are matched as whole words, case-sensitive.
|
|
@@ -58,7 +60,7 @@ reported.
|
|
|
58
60
|
## What it does not check
|
|
59
61
|
|
|
60
62
|
- A venue no shipped preset describes.
|
|
61
|
-
- A name split by markup (`\textbf{AI}Sec`)
|
|
63
|
+
- A name split by markup (`\textbf{AI}Sec`).
|
|
62
64
|
|
|
63
65
|
## How to fix
|
|
64
66
|
|
package/docs/rules.md
CHANGED
|
@@ -8,19 +8,20 @@ reads and when it fails. Errors fail `paperlint lint`; warnings print and do not
|
|
|
8
8
|
| `paper/stages` | error | `PIPELINE-STATUS.md` | a declared stage's PDF is missing, or the `bytes:` it names does not match the file's real size, or a frozen PDF exists that no stage declares |
|
|
9
9
|
| `paper/source` | error | `PIPELINE-STATUS.md` | a declared stage has no frozen `.tex` beside its PDF (a commit hash does not count — squash and gc destroy it) |
|
|
10
10
|
| `paper/author-list` | error | `paper.tex` → `_build/references.json` | an entry's authors are not those of the version it cites — typically the arXiv preprint's list under a published venue. Checked online by `paperlint build` (DBLP), reported on the entry's own line |
|
|
11
|
-
| `paper/
|
|
12
|
-
| `paper/
|
|
13
|
-
| `paper/
|
|
14
|
-
| `paper/figure-ref-style` | warn | `paper.tex` | `Fig.~\ref` and `Figure~\ref` mixed in one document; each minority occurrence is reported. **Fixable:** `--fix` writes the majority form |
|
|
11
|
+
| `paper/section-word` | warn | `paper.tex` and its body files, `paper.md` | `§` or `\S\ref` instead of the word Section. **Fixable:** `--fix` writes `Section~\ref{…}` / `Section 5` |
|
|
12
|
+
| `paper/leading-zero` | warn | `paper.tex` and its body files, `paper.md` | a decimal below 1 without its leading zero (`.05` instead of `0.05`, IEEE / ISO 80000-1 style), counted only where the reader sees it — prose, math and table cells, not macro options, column specs, comments, code or tikz. A number right after `¶` or `§` (`¶¶.42`) is a paragraph designator and is not reported; in a paragraph that cites numbers that way, another bare decimal is reported without a fix, with the zero as a suggestion. **Fixable** |
|
|
13
|
+
| `paper/figure-ref-style` | warn | `paper.tex` and its body files | `Fig.~\ref` and `Figure~\ref` mixed in one document; each minority occurrence is reported. **Fixable:** `--fix` writes the majority form |
|
|
15
14
|
| `bib/reachable-entry` | warn | `paper.tex` (its `filecontents` bibliography) | an entry has no doi, url or arXiv id — a reader has nothing to follow. Reported on the entry; no fix, the link has to be looked up |
|
|
16
15
|
| `paper/cite-exists` | error | `paper.tex` → `_build/references.json` | an entry's doi or arXiv id resolves to nothing, or to a different work. Checked online by `paperlint build`; a work that was merely not found is not a finding |
|
|
17
16
|
| `paper/refs-fresh` | error | `paper.tex` → `_build/references.json` | the bibliography changed since the build checked it (its SHA-256 differs) — run `npx paperlint build` |
|
|
18
17
|
| `paper/refs-checked` | warn | `paper.tex` → `_build/references.json` | the paper has a bibliography and no build has checked it, or the last build could not (no network) — so the two rules above did not run |
|
|
19
|
-
| `tex/future-promise` | warn | `paper.tex`
|
|
18
|
+
| `tex/future-promise` | warn | `paper.tex` and its body files | a camera-ready build still says "will be released" about something already handed over |
|
|
20
19
|
| `tex/acm-frontmatter-override` | error | `paper.tex` | an `acmart` build overrides ACM's front-matter commands and drops template elements from page 1 |
|
|
21
20
|
| [`tex/template`](rules/tex/template.md) | error | `paper.tex` → `paperlint.json` | the `\documentclass` is not the preset's `template` class, or lacks an option it names — [page](rules/tex/template.md) |
|
|
22
21
|
| [`tex/required-section`](rules/tex/required-section.md) | error | `paper.tex` → `paperlint.json` | a section the preset requires (AIDC: «LLM Usage Statement», last) is missing or not where it must be — [page](rules/tex/required-section.md) |
|
|
23
22
|
| [`tex/venue-leftover`](rules/tex/venue-leftover.md) | warn | `paper.tex` → `paperlint.json` | the text names another shipped venue than the one the paper extends («Submission to VenueA 2026» in a paper now set for VenueB) — [page](rules/tex/venue-leftover.md) |
|
|
23
|
+
| [`tex/claim-provenance`](rules/tex/claim-provenance.md) | warn | `paper.tex` | a sentence of the body states a number and does not say whose it is — no citation or link, no _we_/_our_, no `\ref` or "Table 2", no sample ("n = 134", "48 runs") — [page](rules/tex/claim-provenance.md) |
|
|
24
|
+
| [`tex/register`](rules/tex/register.md) | warn | `paper.tex` and the files it includes | the body runs to a post's register: more than 0.8 sentences per 1000 words open with _And_, _So_, _But_, _Nor_, _Or_ or _Yet_ — the limit is an option — [page](rules/tex/register.md) |
|
|
24
25
|
| `review/frontmatter` | error | `reviews/*.md` | the review's frontmatter fails paperlint's JSON Schema — a `findings` record without `id`/`status`, an unknown field, or an **open** finding with no `cause` (`skill-defect` · `missing-skill` · `hook` · `rule`). A review with no `findings` key is not checked for findings |
|
|
25
26
|
| `sibling/frontmatter` | warn | `siblings/*.md` (not `README.md`) | a sibling card's frontmatter has no `read:` saying how much of the competing paper was read (`full` · `abstract` · `none`) |
|
|
26
27
|
| `pdf/fresh` | error | `paper.tex` → `_build/paper.facts.json` | the paper names a venue and the facts cannot be judged: not JSON, a schema other than 2, or they describe a PDF that is gone or differs from the one on disk (its SHA-256) |
|
|
@@ -31,6 +32,13 @@ reads and when it fails. Errors fail `paperlint lint`; warnings print and do not
|
|
|
31
32
|
| `pdf/body-size` | warn | `paper.tex` → `_build/paper.facts.json` | the body font size is more than `body_pt_tol` off the preset's. A warning: banal measures the mode of the rendered text, not the declared size (9.30 pt measured at a declared 9) |
|
|
32
33
|
| `pdf/measured` | warn | `paper.tex` → `_build/paper.facts.json` | the paper's `paperlint.json` names no venue preset yet; or it names one and there are no facts (it was not built), or the facts carry no page geometry (banal was not found) — so the checks above did not run |
|
|
33
34
|
|
|
35
|
+
**Body files** are the files `paper.tex` includes from its document body (`\input`, `\include`,
|
|
36
|
+
`\subfile`, nested ones too), found in the paper's directory — not a preamble include, not a file
|
|
37
|
+
found only in paperlint's own inputs, and not any other `.tex` beside the paper (`versions/`). A
|
|
38
|
+
finding in one is reported at that file and line, and `--fix` edits that file. Which reference form
|
|
39
|
+
is the majority and whether the build is a review build are decided over the whole paper. An include
|
|
40
|
+
that names no file is printed as a note: lint did not read it, and the build will stop on it.
|
|
41
|
+
|
|
34
42
|
`tex/required-section` requires AIDC's «LLM Usage Statement» **always**. ACSAC asks for it «if
|
|
35
43
|
LLMs are used», which no rule can know; an author who used none says so in the section
|
|
36
44
|
([page](rules/tex/required-section.md)).
|
|
@@ -211,10 +219,10 @@ Presets from npm packages are not supported yet.
|
|
|
211
219
|
|
|
212
220
|
## The paper is LaTeX
|
|
213
221
|
|
|
214
|
-
The paper body is `paper.tex`, and it gets
|
|
215
|
-
`
|
|
216
|
-
|
|
217
|
-
the
|
|
222
|
+
The paper body is `paper.tex`, and it gets three rules of its own: `paper/typography`,
|
|
223
|
+
`tex/future-promise` and `tex/acm-frontmatter-override` — plus the `pdf/` venue rules above, which
|
|
224
|
+
run on it but judge the files beside it. The scorecard and the review notes are Markdown files, and
|
|
225
|
+
the other five rules read those.
|
|
218
226
|
|
|
219
227
|
A Markdown body (`paper.md`, or `draft.md`) is still read today and gets only the two `paper/`
|
|
220
228
|
rules, which is why they list it above. Markdown papers are deprecated and being removed
|
|
@@ -238,7 +246,6 @@ stages:
|
|
|
238
246
|
bytes: 305412
|
|
239
247
|
source: versions/2026-07-22-submitted.tex
|
|
240
248
|
sourceBytes: 57210
|
|
241
|
-
researchQuestion: "Does pruning the state space reduce review cost?"
|
|
242
249
|
---
|
|
243
250
|
```
|
|
244
251
|
|
|
@@ -51,9 +51,12 @@
|
|
|
51
51
|
* paper. The projection counts differently: the same place gave 1239 words before macro
|
|
52
52
|
* blanking and 1208 after — a 2.5% discrepancy. The discrepancy is ACCEPTED deliberately;
|
|
53
53
|
* the thresholds were not recalibrated.
|
|
54
|
-
* 4.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
54
|
+
* 4. ONE FILE AT A TIME. `\input` / `\include` are in OPAQUE: the projection of `paper.tex`
|
|
55
|
+
* does not hold what they pull in. `paperlint lint` hands ESLint each file the paper includes
|
|
56
|
+
* from its body as a file of its own (src/paper-includes.ts), and a file with no `document`
|
|
57
|
+
* environment is projected as body throughout — so an included file is read where it is,
|
|
58
|
+
* and its findings point into it. An ESLint run outside `paperlint lint` reads only the
|
|
59
|
+
* files it was given.
|
|
57
60
|
* 5. `\appendix` IS NOT IMPLEMENTED and is INEXPRESSIBLE in a length-preserving projection:
|
|
58
61
|
* `\appendix` is 9 characters, `## Appendix` is 11, the synthesis does not fit. On the
|
|
59
62
|
* first paper with a real `\appendix`, `appendix-ref` / `appendix-ratio` yield a silent
|
|
@@ -209,6 +212,9 @@ export type MdNode =
|
|
|
209
212
|
readonly value: string;
|
|
210
213
|
};
|
|
211
214
|
|
|
215
|
+
/** The root of a projection: a node that has children. */
|
|
216
|
+
export type MdRoot = Extract<MdNode, { readonly type: "root" | "strong" }>;
|
|
217
|
+
|
|
212
218
|
/** An inline-config comment: an `html` node's text and where it sits. */
|
|
213
219
|
interface ConfigNode {
|
|
214
220
|
readonly value: string;
|
|
@@ -305,7 +311,7 @@ export function texToMdast(
|
|
|
305
311
|
{
|
|
306
312
|
parse = (s: string): TexRoot => getParser().parse(s),
|
|
307
313
|
}: { parse?: (s: string) => TexRoot } = {},
|
|
308
|
-
): { root:
|
|
314
|
+
): { root: MdRoot; text: string } {
|
|
309
315
|
const ast = parse(src);
|
|
310
316
|
const chars = src.split("");
|
|
311
317
|
const blank = (from: number, to: number) => {
|