paperlint 7.1.0 → 8.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/.github/workflows/ci.yml +3 -0
- package/.github/workflows/deadlines.yml +100 -0
- package/README.md +6 -0
- package/dist/adapters/hotcrp/deadlines.d.ts +8 -0
- package/dist/adapters/hotcrp/deadlines.d.ts.map +1 -0
- package/dist/adapters/hotcrp/deadlines.io.d.ts +6 -0
- package/dist/adapters/hotcrp/deadlines.io.d.ts.map +1 -0
- package/dist/adapters/hotcrp/deadlines.io.js +26 -0
- package/dist/adapters/hotcrp/deadlines.io.js.map +1 -0
- package/dist/adapters/hotcrp/deadlines.js +134 -0
- package/dist/adapters/hotcrp/deadlines.js.map +1 -0
- package/dist/adapters/hotcrp/index.d.ts +2 -0
- package/dist/adapters/hotcrp/index.d.ts.map +1 -1
- package/dist/adapters/hotcrp/index.js +2 -0
- package/dist/adapters/hotcrp/index.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +1 -6
- package/dist/build.js.map +1 -1
- package/dist/cli.d.ts +3 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +53 -47
- package/dist/cli.js.map +1 -1
- package/dist/cycle-rules.d.ts +24 -0
- package/dist/cycle-rules.d.ts.map +1 -0
- package/dist/cycle-rules.js +212 -0
- package/dist/cycle-rules.js.map +1 -0
- package/dist/domain/cycle.d.ts +148 -0
- package/dist/domain/cycle.d.ts.map +1 -0
- package/dist/domain/cycle.js +281 -0
- package/dist/domain/cycle.js.map +1 -0
- package/dist/domain/deadline.d.ts +128 -0
- package/dist/domain/deadline.d.ts.map +1 -0
- package/dist/domain/deadline.js +281 -0
- package/dist/domain/deadline.js.map +1 -0
- package/dist/eslint-rules/cycle-stage.d.ts +39 -0
- package/dist/eslint-rules/cycle-stage.d.ts.map +1 -0
- package/dist/eslint-rules/cycle-stage.js +119 -0
- package/dist/eslint-rules/cycle-stage.js.map +1 -0
- package/dist/eslint-rules/latex-language.d.ts.map +1 -1
- package/dist/eslint-rules/latex-language.js +10 -13
- package/dist/eslint-rules/latex-language.js.map +1 -1
- package/dist/eslint-rules/paper-context.js +2 -2
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
- package/dist/eslint-rules/paper-typography.js +22 -91
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/papers.d.ts +1 -3
- package/dist/eslint-rules/papers.d.ts.map +1 -1
- package/dist/eslint-rules/papers.js +2 -4
- package/dist/eslint-rules/papers.js.map +1 -1
- package/dist/eslint-rules/tex-build.d.ts.map +1 -1
- package/dist/eslint-rules/tex-build.js +8 -25
- package/dist/eslint-rules/tex-build.js.map +1 -1
- package/dist/init.d.ts +1 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +3 -9
- package/dist/init.js.map +1 -1
- package/dist/lib/markdown.d.ts +5 -81
- package/dist/lib/markdown.d.ts.map +1 -1
- package/dist/lib/markdown.js +5 -116
- package/dist/lib/markdown.js.map +1 -1
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +2 -2
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/lib/skill-eval-fixture.d.ts +6 -4
- package/dist/lib/skill-eval-fixture.d.ts.map +1 -1
- package/dist/lib/skill-eval-fixture.js +25 -18
- package/dist/lib/skill-eval-fixture.js.map +1 -1
- package/dist/new-paper.d.ts +5 -11
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +12 -23
- package/dist/new-paper.js.map +1 -1
- package/dist/paper-files.d.ts +4 -4
- package/dist/paper-prose.d.ts +17 -0
- package/dist/paper-prose.d.ts.map +1 -0
- package/dist/paper-prose.js +46 -0
- package/dist/paper-prose.js.map +1 -0
- package/dist/paper-settings.d.ts +7 -0
- package/dist/paper-settings.d.ts.map +1 -1
- package/dist/paper-settings.js +61 -8
- package/dist/paper-settings.js.map +1 -1
- package/dist/ports/venue-deadlines.d.ts +14 -0
- package/dist/ports/venue-deadlines.d.ts.map +1 -0
- package/dist/ports/venue-deadlines.js +2 -0
- package/dist/ports/venue-deadlines.js.map +1 -0
- package/dist/presets.d.ts +12 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +19 -11
- package/dist/presets.js.map +1 -1
- package/dist/structure.d.ts.map +1 -1
- package/dist/structure.js +4 -3
- package/dist/structure.js.map +1 -1
- package/dist/submission.d.ts +8 -0
- package/dist/submission.d.ts.map +1 -1
- package/dist/submission.js +41 -10
- package/dist/submission.js.map +1 -1
- package/dist/tex-requirements.d.ts +3 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +19 -0
- package/dist/tex-requirements.js.map +1 -1
- package/dist/tex-venue-rules.d.ts +19 -0
- package/dist/tex-venue-rules.d.ts.map +1 -1
- package/dist/tex-venue-rules.js +69 -0
- package/dist/tex-venue-rules.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts +10 -0
- package/dist/venue-rules.d.ts.map +1 -1
- package/dist/venue-rules.js +26 -10
- package/dist/venue-rules.js.map +1 -1
- package/docs/configuration.md +146 -20
- package/docs/e2e.md +4 -6
- package/docs/prior-art/paper-folder-scaffolding.md +24 -29
- package/docs/rules/cycle/evidence.md +87 -0
- package/docs/rules/cycle/port-done.md +75 -0
- package/docs/rules/cycle/record.md +152 -0
- package/docs/rules/cycle/stage.md +85 -0
- package/docs/rules/tex/claim-provenance.md +0 -1
- package/docs/rules.md +48 -47
- package/docs/submission.md +5 -0
- package/eslint-rules/cycle-stage.test.mjs +131 -0
- package/eslint-rules/cycle-stage.ts +141 -0
- package/eslint-rules/latex-language.harness.mjs +3 -3
- package/eslint-rules/latex-language.ts +10 -13
- package/eslint-rules/paper-context.ts +2 -2
- package/eslint-rules/paper-typography.test.mjs +17 -85
- package/eslint-rules/paper-typography.ts +22 -98
- package/eslint-rules/papers.harness.mjs +1 -1
- package/eslint-rules/papers.ts +2 -4
- package/eslint-rules/tex-build.harness.mjs +2 -2
- package/eslint-rules/tex-build.ts +8 -25
- package/eslint.config.mjs +41 -2
- package/hooks/hooks.harness.ts +15 -15
- package/hooks/paper-edit-guard.hook.mjs +5 -8
- package/hooks/paper-edit-guard.test.ts +12 -3
- package/hooks/paper-skills-nudge.hook.mjs +2 -3
- package/hooks/paper-skills-nudge.test.ts +13 -3
- package/hooks/paper-status-gates.hook.mjs +2 -2
- package/hooks/paper-status-gates.test.ts +14 -2
- package/lib/markdown.test.mjs +5 -60
- package/lib/markdown.ts +9 -136
- package/lib/paper-config.ts +3 -2
- package/lib/skill-checks.test.mjs +4 -1
- package/lib/skill-eval-fixture.ts +25 -18
- package/package.json +1 -3
- package/presets/aidc.jsonc +24 -3
- package/presets/aidc.md +6 -3
- package/presets/msr.jsonc +25 -1
- package/presets/msr.md +5 -1
- package/presets/realm.jsonc +1 -1
- package/presets/venue-profile.schema.json +39 -0
- package/scripts/check.ts +4 -0
- package/scripts/harness-api.frozen.json +0 -5
- package/scripts/refresh-deadlines.test.ts +431 -0
- package/scripts/refresh-deadlines.ts +387 -0
- package/skills/cold-read-diff/SKILL.md +3 -3
- package/skills/cold-read-diff/SKILL.md.spec.ts +2 -2
- package/skills/grade-paper-writing/SKILL.md +14 -22
- package/skills/grade-paper-writing/SKILL.md.spec.ts +13 -21
- package/skills/grade-paper-writing/__snapshots__/prose-lint.test.ts.snap +40 -26
- package/skills/grade-paper-writing/prose-lint.mjs +108 -278
- package/skills/grade-paper-writing/prose-lint.test.ts +184 -81
- 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 +9 -12
- package/skills/paper-pipeline/SKILL.md.spec.ts +8 -11
- package/skills/paper-pipeline/description-language.eval.mjs +25 -15
- package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +25 -15
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +25 -15
- package/skills/paper-pipeline/pipeline-firing.eval.mjs +27 -16
- package/skills/paper-pipeline/pipeline-language.eval.mjs +25 -15
- package/skills/paper-pipeline/references/acceptance-gate.md +16 -20
- package/skills/paper-pipeline/references/artifact-checklist.md +4 -5
- package/skills/paper-pipeline/references/pipeline-status-template.md +1 -1
- package/skills/paper-pipeline/scripts/README.md +0 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +8 -72
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +48 -156
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +81 -75
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +3 -3
- package/skills/paper-status/SKILL.md +2 -2
- package/skills/paper-status/SKILL.md.spec.ts +1 -1
- package/skills/render-paper/SKILL.md +2 -2
- package/skills/render-paper/SKILL.md.spec.ts +1 -1
- package/skills/render-paper/extract-pdf-facts.mjs +2 -2
- package/skills/tighten-paper/SKILL.md +29 -42
- package/skills/tighten-paper/SKILL.md.spec.ts +28 -41
- package/skills/verify-citations/scripts/bib-authors.check.test.mjs +0 -13
- package/skills/verify-citations/scripts/bib-authors.cli.test.ts +23 -11
- package/skills/verify-citations/scripts/bib-authors.mjs +8 -93
- package/skills/verify-citations/scripts/bib-authors.test.mjs +1 -44
- package/src/adapters/hotcrp/cassette/README.md +22 -0
- package/src/adapters/hotcrp/cassette/deadlines-aidc26.html +17 -0
- package/src/adapters/hotcrp/cassette/deadlines-fse2027.html +24 -0
- package/src/adapters/hotcrp/cassette/deadlines-icse2027.html +25 -0
- package/src/adapters/hotcrp/cassette/deadlines-msr2027.html +25 -0
- package/src/adapters/hotcrp/cassette/deadlines-nosuch.html +18 -0
- package/src/adapters/hotcrp/cassette/deadlines-sosp26.html +26 -0
- package/src/adapters/hotcrp/deadlines.io.test.ts +86 -0
- package/src/adapters/hotcrp/deadlines.io.ts +27 -0
- package/src/adapters/hotcrp/deadlines.test.ts +170 -0
- package/src/adapters/hotcrp/deadlines.ts +161 -0
- package/src/adapters/hotcrp/index.ts +2 -0
- package/src/build.harness.mjs +2 -2
- package/src/build.test.ts +1 -1
- package/src/build.ts +1 -6
- package/src/cli.harness.mjs +26 -46
- package/src/cli.test.ts +41 -40
- package/src/cli.ts +57 -58
- package/src/cycle-rules.test.ts +278 -0
- package/src/cycle-rules.ts +273 -0
- package/src/domain/cycle.test.ts +456 -0
- package/src/domain/cycle.ts +432 -0
- package/src/domain/deadline.test.ts +386 -0
- package/src/domain/deadline.ts +472 -0
- package/src/folder-venue-rule.test.ts +1 -1
- package/src/init.test.ts +6 -7
- package/src/init.ts +3 -22
- package/src/lint-fix.test.ts +10 -4
- package/src/new-paper.harness.mjs +9 -28
- package/src/new-paper.test.ts +7 -6
- package/src/new-paper.ts +11 -30
- package/src/paper-files.test.ts +5 -4
- package/src/paper-files.ts +4 -4
- package/src/paper-prose.test.ts +49 -0
- package/src/paper-prose.ts +67 -0
- package/src/paper-settings.test.ts +167 -0
- package/src/paper-settings.ts +85 -11
- package/src/parse-args.test.ts +0 -1
- package/src/ports/venue-deadlines.ts +14 -0
- package/src/presets.test.ts +105 -0
- package/src/presets.ts +43 -10
- package/src/rule-cases.test.ts +144 -0
- package/src/structure.harness.ts +5 -11
- package/src/structure.ts +4 -3
- package/src/submission.test.ts +105 -1
- package/src/submission.ts +73 -12
- package/src/tex-requirements.ts +31 -0
- package/src/tex-venue-rules.test.ts +76 -0
- package/src/tex-venue-rules.ts +85 -0
- package/src/types.ts +0 -2
- package/src/venue-rules.test.ts +82 -0
- package/src/venue-rules.ts +44 -12
- package/fixtures/real-markdown-paper/baseline.json +0 -22
- package/fixtures/real-markdown-paper/baseline.ts +0 -70
- package/skills/paper-pipeline/PIPELINE-MAP.md +0 -381
- package/skills/paper-pipeline/pipeline-firing.baseline.json +0 -270
- package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +0 -585
- package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +0 -492
- package/skills/paper-pipeline/scripts/artifact-coverage.mjs +0 -397
- package/skills/paper-pipeline/scripts/artifact-coverage.test.ts +0 -86
- package/skills/paper-pipeline/scripts/check-provenance.mjs +0 -184
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +0 -135
- package/skills/paper-pipeline/scripts/population-map.mjs +0 -188
- package/skills/paper-pipeline/scripts/population-map.test.mjs +0 -154
- package/skills/paper-pipeline/scripts/provenance.harness.mjs +0 -266
- package/skills/paper-pipeline/scripts/round-diff.harness.ts +0 -907
- package/skills/paper-pipeline/scripts/round-diff.mjs +0 -583
- package/skills/paper-pipeline/scripts/round-diff.test.mjs +0 -159
- package/skills/tighten-paper/__snapshots__/structure.test.ts.snap +0 -133
- package/skills/tighten-paper/structure.mjs +0 -364
- package/skills/tighten-paper/structure.test.ts +0 -117
- package/templates/paper/paper.md +0 -4
|
@@ -16,10 +16,6 @@ still left to a human copying something by hand?**
|
|
|
16
16
|
> - `--hooks=local` is **deferred, not implemented**; `init` refuses it by name.
|
|
17
17
|
>
|
|
18
18
|
> Where the build differed from this text, it is listed at the end, in § 8.
|
|
19
|
-
>
|
|
20
|
-
> **Later, 2026-09-24:** Markdown papers are deprecated and being removed
|
|
21
|
-
> ([#57](https://github.com/zernie/research-paper-pipeline/issues/57)). Where this record mentions
|
|
22
|
-
> `paper.md` or `--format md`, it describes the tool as it was when written.
|
|
23
19
|
|
|
24
20
|
1. A paper folder needs a `PIPELINE-STATUS.md`, and today nothing makes it — you copy a template.
|
|
25
21
|
Should there be a command, and where should per-paper settings live: in a file in every paper
|
|
@@ -66,11 +62,11 @@ changes, no migration.
|
|
|
66
62
|
(`src/init.ts:448`), offers a CI workflow, reports missing programs, and **prints** the two
|
|
67
63
|
`/plugin` lines (`src/init.ts:257-258`). It never creates the papers directory and never creates
|
|
68
64
|
a paper.
|
|
69
|
-
- **A directory is a paper** if it holds any of `PIPELINE-STATUS.md`, `paper.tex`, `
|
|
70
|
-
|
|
71
|
-
- **`rpp lint` requires `PIPELINE-STATUS.md`** in every such directory, plus
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
- **A directory is a paper** if it holds any of `PIPELINE-STATUS.md`, `paper.tex`, `venue.json`
|
|
66
|
+
(`src/build.ts`, `src/structure.ts`). Detection is generous.
|
|
67
|
+
- **`rpp lint` requires `PIPELINE-STATUS.md`** in every such directory, plus `paper.tex`
|
|
68
|
+
(`src/structure.ts`). A paper with only `paper.tex` fails the very first `rpp lint` with
|
|
69
|
+
`missing PIPELINE-STATUS.md` — that is the README's own "First run" example.
|
|
74
70
|
|
|
75
71
|
⚠️ **One inconsistency worth knowing.** `paper/stages` says in its header that a missing `stages`
|
|
76
72
|
field is _legitimate_ — "a paper that has shipped nothing owes nothing" (`eslint-rules/paper-stages.mjs:24-27`) —
|
|
@@ -101,7 +97,7 @@ human to copy and tick them.
|
|
|
101
97
|
## 2. What `PIPELINE-STATUS.md` actually holds — the split
|
|
102
98
|
|
|
103
99
|
Read from the template (`skills/paper-pipeline/references/pipeline-status-template.md`), the
|
|
104
|
-
fixtures (`fixtures/paper-stages
|
|
100
|
+
fixtures (`fixtures/paper-stages/*`) and four real files in the
|
|
105
101
|
owner's corpus. Real sizes: 86, 95, 1 057 and 1 301 lines. In the two big ones the machine-read
|
|
106
102
|
part is the first 10–25 lines of front matter; the rest is a dated journal of decisions. (No
|
|
107
103
|
content of those files is reproduced here.)
|
|
@@ -110,7 +106,6 @@ content of those files is reproduced here.)
|
|
|
110
106
|
| ------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
111
107
|
| paper short name / title | **config** | human, once — `rpp new` can prefill from the folder name |
|
|
112
108
|
| venue, deadline, blind model (the `Venue:` header line) | **config** | human; changes when the paper is re-targeted |
|
|
113
|
-
| format (`.tex` vs `.md`) | **derived** | from which source file exists |
|
|
114
109
|
| venue profile, paper kind, pdf path (a separate `venue.json` in one real paper) | **config** | human; already a per-paper file in practice |
|
|
115
110
|
| typography allowance (`typographyDebt`) | **config** | human, but it sits in the root key keyed by path today |
|
|
116
111
|
| `stages[]`: `stage`, `date`, `venue` | **state** | **tool** at the moment of freezing (`rpp freeze`, a later step) |
|
|
@@ -172,9 +167,9 @@ parsing markdown — the fix is to ship the template as its own file and have th
|
|
|
172
167
|
(entry front matter), Cargo (member `Cargo.toml`), Eleventy (directory data). The tools that put
|
|
173
168
|
per-unit settings in the root (ESLint `files`, Vale sections) are _linters of code_, where units
|
|
174
169
|
have no identity of their own — a paper does.
|
|
175
|
-
3. **Front matter of the source itself is not available to rpp**, because
|
|
176
|
-
|
|
177
|
-
|
|
170
|
+
3. **Front matter of the source itself is not available to rpp**, because a paper is LaTeX, which
|
|
171
|
+
has no YAML front matter. Quarto and Astro can use the document's own header only because their
|
|
172
|
+
documents carry one. So rpp needs a per-paper **file**, and it already has one:
|
|
178
173
|
`PIPELINE-STATUS.md`, whose front matter is exactly where Quarto would put these fields.
|
|
179
174
|
4. **Root-level keys that are really per-paper** (`typographyDebt: { "papers/my-paper": … }`,
|
|
180
175
|
`src/cli.ts:104`) are the ESLint-overrides style. They work, but they break silently on a folder
|
|
@@ -209,9 +204,9 @@ written once at freeze time, then checked forever — and today a human types it
|
|
|
209
204
|
|
|
210
205
|
### Commands
|
|
211
206
|
|
|
212
|
-
**`rpp new <name
|
|
207
|
+
**`rpp new <name>`** — creates `<papers>/<name>/` with:
|
|
213
208
|
|
|
214
|
-
- `paper.tex`
|
|
209
|
+
- `paper.tex` (a minimal stub);
|
|
215
210
|
- `PIPELINE-STATUS.md` from a **template file** shipped in the package, with the name filled in and
|
|
216
211
|
**no** `stages` field (a new paper has shipped nothing — `paper-stages.mjs:24`).
|
|
217
212
|
|
|
@@ -228,7 +223,7 @@ Rules for it, each taken from a tool above:
|
|
|
228
223
|
**Later step, NOT part of this change — `rpp freeze <paper> <stage> [--pdf <file>] [--date <iso>]`**,
|
|
229
224
|
the release-please move, recorded so the design is not lost:
|
|
230
225
|
|
|
231
|
-
- copies the built pdf and the source into `versions/<date>-<stage>.pdf|.tex
|
|
226
|
+
- copies the built pdf and the source into `versions/<date>-<stage>.pdf|.tex`;
|
|
232
227
|
- **appends** one record to `stages` with `stage`, `date`, `pdf`, `bytes`, `source`, `sourceBytes`;
|
|
233
228
|
- refuses a stage outside `STAGES` (`paper-stages.mjs:53`) and a date/stage pair already present.
|
|
234
229
|
|
|
@@ -259,15 +254,15 @@ the skills tell agents to update them.
|
|
|
259
254
|
|
|
260
255
|
- **Existing folders with a `PIPELINE-STATUS.md`** (the owner's four): nothing changes. Their
|
|
261
256
|
front matter is already the per-paper carrier; a later `rpp freeze` would append to their lists.
|
|
262
|
-
- **Existing folders without one** (a draft that has only `paper.
|
|
263
|
-
the missing file and touches nothing else.
|
|
257
|
+
- **Existing folders without one** (a draft that has only `paper.tex`): `rpp new <that-name>`
|
|
258
|
+
fills the missing file and touches nothing else.
|
|
264
259
|
- **No `rpp migrate` is needed** for this recommendation. One would be needed only if the carrier
|
|
265
260
|
later moves to `paper.yml`.
|
|
266
261
|
|
|
267
262
|
### The smallest first step
|
|
268
263
|
|
|
269
264
|
Move the template out of the code fence into its own file (say
|
|
270
|
-
`templates/paper/PIPELINE-STATUS.md`, plus `paper.tex`
|
|
265
|
+
`templates/paper/PIPELINE-STATUS.md`, plus a `paper.tex` stub), make
|
|
271
266
|
`pipeline-status-template.md` point at it instead of containing it, and add `rpp new` that copies
|
|
272
267
|
it. Then the README sentence "Nothing generates it and no command refreshes it" becomes "`rpp new`
|
|
273
268
|
creates it". No rule changes, no consumer migration. `rpp freeze` is step two; `init` offering to
|
|
@@ -435,13 +430,13 @@ unset **and** no `--yes`._
|
|
|
435
430
|
|
|
436
431
|
### What `init` asks, and what it does without asking
|
|
437
432
|
|
|
438
|
-
| decision | human at a terminal
|
|
439
|
-
| ----------------- |
|
|
440
|
-
| papers directory | asked only if several candidates (today)
|
|
441
|
-
| **hooks** | "Wire the three paper hooks into `.claude/settings.json` (committed, shared)? **[Y/n]**"
|
|
442
|
-
| CI workflow | "Add a GitHub Actions workflow? **[y/N]**" (today)
|
|
443
|
-
| first paper | only when the papers dir holds no paper: "Create a first paper? name: [skip]"
|
|
444
|
-
| external programs | reported (today)
|
|
433
|
+
| decision | human at a terminal | agent / CI / `--yes` | flag |
|
|
434
|
+
| ----------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
|
435
|
+
| papers directory | asked only if several candidates (today) | first candidate, said so (today) | `init <dir>` then the key |
|
|
436
|
+
| **hooks** | "Wire the three paper hooks into `.claude/settings.json` (committed, shared)? **[Y/n]**" | **yes** — the guard is what the package is for, the edit is idempotent and shows up in `git diff` | `--no-hooks` (`--hooks=local` deferred) |
|
|
437
|
+
| CI workflow | "Add a GitHub Actions workflow? **[y/N]**" (today) | **no** (today) — it writes into `.github/` and spends Actions minutes, which are metered | `--ci` / `--no-ci` |
|
|
438
|
+
| first paper | only when the papers dir holds no paper: "Create a first paper? name: [skip]" | **no**, unless `--paper <name>` is given | `--paper <name>` |
|
|
439
|
+
| external programs | reported (today) | reported (today) | — |
|
|
445
440
|
|
|
446
441
|
Why the hooks default is "yes" even without asking, while CI is "no": the rule `install.md` already
|
|
447
442
|
adopted from Playwright is _"ask only about what cannot be guessed or is expensive"_. Installing a
|
|
@@ -495,8 +490,8 @@ Recorded so the design and the code do not quietly disagree.
|
|
|
495
490
|
- **`rpp new` lints the new folder itself** (`rpp lint <papers>/<name>`), so the structure check —
|
|
496
491
|
which looks at the subdirectories of the path it is given — does not run there; the folder was
|
|
497
492
|
just made with the required files, so there is nothing for it to find.
|
|
498
|
-
- **Interactive `init` asks "Create a first paper? name: [skip]"
|
|
499
|
-
|
|
493
|
+
- **Interactive `init` asks "Create a first paper? name: [skip]"** only when the papers directory
|
|
494
|
+
holds no paper.
|
|
500
495
|
|
|
501
496
|
## Sources checked
|
|
502
497
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# cycle/evidence
|
|
2
|
+
|
|
3
|
+
**Level:** error · **Reads:** the paper's `paperlint.json` (`cycles`) and the paper folder ·
|
|
4
|
+
**Reported on:** the first line of the paper's `PIPELINE-STATUS.md`
|
|
5
|
+
|
|
6
|
+
## What it catches
|
|
7
|
+
|
|
8
|
+
A closed cycle — `outcome.kind` is `accepted`, `rejected` or `withdrawn` — names an `evidence`
|
|
9
|
+
file that is not in the paper folder: the decision mail, the reviews, or the note that records the
|
|
10
|
+
withdrawal was never saved, or the path is wrong.
|
|
11
|
+
|
|
12
|
+
The same for a deadline's `override`: the instant a human decided binds instead of what the pages
|
|
13
|
+
said rests on its `evidence` — the chairs' mail that extended the deadline, a saved page — and that
|
|
14
|
+
file must be in the paper folder.
|
|
15
|
+
|
|
16
|
+
## Why
|
|
17
|
+
|
|
18
|
+
The outcome of an attempt is a claim about what a venue decided, and the record is read by people
|
|
19
|
+
and programs that were not there when the mail arrived: a status command, a scorecard check, the
|
|
20
|
+
next attempt's prior-work delta. A decision whose evidence is not in the folder is a claim with
|
|
21
|
+
nothing behind it, and the day it is doubted there is nowhere to look. The record therefore refuses
|
|
22
|
+
an outcome without `evidence` at all, and this rule requires the file to exist.
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
Failing — `paperlint.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"cycles": [
|
|
31
|
+
{
|
|
32
|
+
"id": "first-2026",
|
|
33
|
+
"venue": { "kind": "preset", "extends": "paperlint:acm-sigconf" },
|
|
34
|
+
"opened": "2026-07-01",
|
|
35
|
+
"outcome": {
|
|
36
|
+
"kind": "rejected",
|
|
37
|
+
"date": "2026-09-08",
|
|
38
|
+
"evidence": "reviews/decision.md"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
with no `reviews/decision.md` in the paper folder:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
papers/my-paper/PIPELINE-STATUS.md
|
|
49
|
+
1:1 error cycle «first-2026» is rejected (2026-09-08) with evidence `reviews/decision.md`, which is
|
|
50
|
+
not in the paper folder — save the decision mail, the reviews or the note that records
|
|
51
|
+
the decision there, or correct the path cycle/evidence
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
An override whose evidence was never saved:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
1:1 error cycle «msr-2027»: the override of the "submission" deadline (2026-10-27T04:00:00Z)
|
|
58
|
+
rests on `mail/extension.eml`, which is not in the paper folder — save the mail or the
|
|
59
|
+
page that grants it there, or correct the path cycle/evidence
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Passing:
|
|
63
|
+
|
|
64
|
+
- the same record with `reviews/decision.md` present;
|
|
65
|
+
- an open cycle (`"outcome": { "kind": "open" }`, or no `outcome`): nothing has been decided;
|
|
66
|
+
- a paper whose `paperlint.json` has no `cycles`.
|
|
67
|
+
|
|
68
|
+
## Options / preset fields
|
|
69
|
+
|
|
70
|
+
No rule options. `evidence` is a path relative to the paper folder; it may name any file — the
|
|
71
|
+
saved mail, a markdown note with the reviews, a PDF.
|
|
72
|
+
|
|
73
|
+
## What it does not check
|
|
74
|
+
|
|
75
|
+
- What the file says. A rejection recorded as `accepted` with the rejection mail as evidence passes
|
|
76
|
+
here; the person who records the outcome reads the mail. Likewise an override's mail is not read
|
|
77
|
+
for its date.
|
|
78
|
+
- The `date`. It must be a day (`YYYY-MM-DD`), nothing more.
|
|
79
|
+
- Whether a `desk` rejection is marked as such (`"desk": true`); it changes what work follows, not
|
|
80
|
+
whether the record is consistent.
|
|
81
|
+
|
|
82
|
+
## How to fix
|
|
83
|
+
|
|
84
|
+
Save the decision in the paper folder — the mail as it arrived, the reviews as the portal shows
|
|
85
|
+
them, or a dated note that records a withdrawal and why — and name that file in `evidence`. If the
|
|
86
|
+
file exists under another name, correct the path. For an override, save the mail or page that moved
|
|
87
|
+
the deadline and name it in the override's `evidence`.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# cycle/port-done
|
|
2
|
+
|
|
3
|
+
**Level:** error · **Reads:** `paper.tex` → the paper's `paperlint.json` (`cycles`) → the venue
|
|
4
|
+
preset's `template` · **Reported on:** `paper.tex`
|
|
5
|
+
|
|
6
|
+
## What it catches
|
|
7
|
+
|
|
8
|
+
The current cycle declares `"phase": "porting"` — the source is still in the previous venue's
|
|
9
|
+
template, so the venue's format rules are silent — and the paper's `\documentclass` is already the
|
|
10
|
+
one the venue's preset requires. The port is done and the declaration is stale.
|
|
11
|
+
|
|
12
|
+
## Why
|
|
13
|
+
|
|
14
|
+
`"phase": "porting"` is a record of open work, not a softer severity: the day a new venue is chosen
|
|
15
|
+
the source is still in the old venue's template, and a page count under the wrong template says
|
|
16
|
+
nothing about the new limit. While the phase is declared, every `pdf/*`, `format/*`, `anonymity/*`
|
|
17
|
+
and `tex/*` venue rule stays silent for that paper. A declaration that silences rules must not be
|
|
18
|
+
able to stay on after its reason is gone: once the class line is the venue's, this rule fires, and
|
|
19
|
+
the only way to be quiet again is to drop the phase — which turns the format rules back on.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
Failing — `paperlint.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"cycles": [
|
|
28
|
+
{
|
|
29
|
+
"id": "blind-2027",
|
|
30
|
+
"venue": { "kind": "preset", "extends": "./blindconf.jsonc" },
|
|
31
|
+
"opened": "2026-09-09",
|
|
32
|
+
"phase": "porting"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
where the preset's `template` is `\documentclass[conference,compsoc]{IEEEtran}`, and `paper.tex`
|
|
39
|
+
begins with that very line:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
papers/my-paper/paper.tex
|
|
43
|
+
1:1 error the \documentclass is already `\documentclass[conference,compsoc]{IEEEtran}`, which
|
|
44
|
+
BlindConf requires, and the cycle «blind-2027» still declares "phase": "porting" — the
|
|
45
|
+
port is done: remove the phase, so the venue's format rules judge this paper again
|
|
46
|
+
cycle/port-done
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Passing:
|
|
50
|
+
|
|
51
|
+
- the same paper with the phase removed (or `"phase": "prepared"`);
|
|
52
|
+
- a cycle still porting whose `paper.tex` still has the old venue's class line — the port is open
|
|
53
|
+
work, as declared;
|
|
54
|
+
- a preset that names no `template`: there is nothing to compare, as for `tex/template`;
|
|
55
|
+
- a paper whose `paperlint.json` has no `cycles`.
|
|
56
|
+
|
|
57
|
+
## Options / preset fields
|
|
58
|
+
|
|
59
|
+
No rule options. It reads the preset's `template`, the field [`tex/template`](../tex/template.md)
|
|
60
|
+
reads, and compares the way that rule does.
|
|
61
|
+
|
|
62
|
+
## What it does not check
|
|
63
|
+
|
|
64
|
+
- Whether the port is complete beyond the class line — the page limit, the fonts, the sections. Those
|
|
65
|
+
are the format rules' to judge, and they judge again the moment the phase is dropped.
|
|
66
|
+
- A cycle declared `porting` whose class line is still the old one: that is the state the phase
|
|
67
|
+
describes.
|
|
68
|
+
- A `porting` cycle that has already sent a PDF — [`cycle/stage`](stage.md) reports that on the
|
|
69
|
+
scorecard.
|
|
70
|
+
|
|
71
|
+
## How to fix
|
|
72
|
+
|
|
73
|
+
Remove `"phase": "porting"` from the current cycle in `paperlint.json`, then run `paperlint lint`
|
|
74
|
+
and `paperlint build`: the venue's format rules judge the paper again, and what they report is the
|
|
75
|
+
rest of the port.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# cycle/record
|
|
2
|
+
|
|
3
|
+
**Level:** error · **Reads:** the paper's `paperlint.json` (`cycles`) and the venue presets it names ·
|
|
4
|
+
**Reported on:** the first line of the paper's `PIPELINE-STATUS.md`
|
|
5
|
+
|
|
6
|
+
## What it catches
|
|
7
|
+
|
|
8
|
+
The paper's `cycles` — its attempts at venues, one entry each, oldest first — do not describe one
|
|
9
|
+
consistent history:
|
|
10
|
+
|
|
11
|
+
- **one source's deadlines are out of order.** The order a venue's deadlines keep is
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
registration ≤ submission ≤ resubmission < notification < camera-ready
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
and it is checked within each source: the portal's readings among themselves, the call's among
|
|
18
|
+
themselves, the overrides among themselves. A call's abstract day after its own paper day is a
|
|
19
|
+
date typed wrong or an AoE day miscounted.
|
|
20
|
+
|
|
21
|
+
- **a portal reading the venue's preset already carries.** A cycle whose venue is a preset derives
|
|
22
|
+
the portal's readings from it (`presets/msr.jsonc` carries MSR's); the same reading typed into the
|
|
23
|
+
paper is a second copy, and it goes stale the day paperlint updates the preset.
|
|
24
|
+
|
|
25
|
+
The structural problems of the record — a bare date where an instant is needed, two open cycles, an
|
|
26
|
+
open cycle that is not the last, two cycles with one id, one deadline in two entries, two readings
|
|
27
|
+
from one source, an override without its reason or evidence, an unknown key anywhere in the record
|
|
28
|
+
— are refused earlier, by `paperlint lint` itself before any rule runs, with one line naming the
|
|
29
|
+
file, the place and the problem, and exit code 2, the same way an unknown key in `paperlint.json` is
|
|
30
|
+
refused. This rule judges what the record parses with.
|
|
31
|
+
|
|
32
|
+
## Why
|
|
33
|
+
|
|
34
|
+
A deadline is the one fact in the record whose error costs the attempt. The record keeps what each
|
|
35
|
+
page said — the portal, which refuses the upload, and the call, which only announces — with where and
|
|
36
|
+
when it was read, and the **earlier** reading binds unless a human override says otherwise. That the
|
|
37
|
+
portal and the call disagree is expected and is not a finding: at MSR 2027 the portal's "submissions
|
|
38
|
+
must be completed by" falls at 04:00 UTC on the call's _abstract_ day, four days before the call's
|
|
39
|
+
_paper_ day, and keeping both is how the earlier one is seen. What is a finding is a source that
|
|
40
|
+
contradicts itself, and a fact recorded in two places.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
Failing — `paperlint.json`, the call's own dates inverted:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"cycles": [
|
|
49
|
+
{
|
|
50
|
+
"id": "conf-2027",
|
|
51
|
+
"venue": { "kind": "preset", "extends": "paperlint:acm-sigconf" },
|
|
52
|
+
"opened": "2026-09-09",
|
|
53
|
+
"deadlines": [
|
|
54
|
+
{
|
|
55
|
+
"what": "registration",
|
|
56
|
+
"observed": [
|
|
57
|
+
{
|
|
58
|
+
"at": "2026-10-25 AoE",
|
|
59
|
+
"source": "call",
|
|
60
|
+
"url": "https://conf.example/cfp",
|
|
61
|
+
"read": "2026-09-09"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"what": "submission",
|
|
67
|
+
"observed": [
|
|
68
|
+
{
|
|
69
|
+
"at": "2026-10-23 AoE",
|
|
70
|
+
"source": "call",
|
|
71
|
+
"url": "https://conf.example/cfp",
|
|
72
|
+
"read": "2026-09-09"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
papers/my-paper/PIPELINE-STATUS.md
|
|
84
|
+
1:1 error paperlint.json, cycle «conf-2027»: the call's "registration" (2026-10-26T11:59:59Z) is
|
|
85
|
+
after its "submission" (2026-10-24T11:59:59Z) — a date typed wrong, or an AoE day
|
|
86
|
+
miscounted (write a call's date as "YYYY-MM-DD AoE" and paperlint converts it)
|
|
87
|
+
cycle/record
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Failing — a cycle at `paperlint:msr` that copies the portal's reading the preset carries:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
1:1 error paperlint.json, cycle «msr-2027»: the "submission" deadline records a portal reading,
|
|
94
|
+
and the preset paperlint:msr carries the portal's reading of it (2026-10-20T04:00:00Z,
|
|
95
|
+
read 2026-10-05) — a second copy drifts when paperlint updates the preset: delete this
|
|
96
|
+
one (the call's reading and an override stay) cycle/record
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Passing:
|
|
100
|
+
|
|
101
|
+
- the first record with the registration on `2026-10-20 AoE`;
|
|
102
|
+
- a cycle at `paperlint:msr` recording the call's abstract day as `registration` (`2026-10-20 AoE`)
|
|
103
|
+
and its paper day as `submission` (`2026-10-23 AoE`): the preset's portal `submission`
|
|
104
|
+
(`2026-10-20T04:00:00Z`) is earlier than both, binds, and is not a contradiction;
|
|
105
|
+
- a cycle with no `deadlines` at all;
|
|
106
|
+
- a paper whose `paperlint.json` has no `cycles` (the flat form, `"extends": "paperlint:…"`).
|
|
107
|
+
|
|
108
|
+
## Options / preset fields
|
|
109
|
+
|
|
110
|
+
No rule options. One deadline entry:
|
|
111
|
+
|
|
112
|
+
```jsonc
|
|
113
|
+
{
|
|
114
|
+
"what": "submission", // registration (the call's abstract) · submission (the full paper) · resubmission · notification · camera-ready
|
|
115
|
+
"observed": [
|
|
116
|
+
{
|
|
117
|
+
"at": "2026-10-23 AoE", // or an instant with its zone: 2026-10-20T04:00:00Z
|
|
118
|
+
"source": "call", // or "portal"
|
|
119
|
+
"url": "https://conf.example/cfp",
|
|
120
|
+
"read": "2026-10-05", // the day the page was read
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
// optional; wins over every reading
|
|
124
|
+
"override": {
|
|
125
|
+
"at": "2026-10-27T04:00:00Z",
|
|
126
|
+
"reason": "the chairs extended the deadline by mail",
|
|
127
|
+
"evidence": "mail/extension.eml",
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The preset field is `deadlines` in a venue preset: a list of readings `{ "what", "at", "source",
|
|
133
|
+
"url", "read" }`, `at` in UTC. Shipped presets carry their portal's readings and are refreshed by a
|
|
134
|
+
scheduled workflow in paperlint's repository; your own preset may carry readings the same way.
|
|
135
|
+
|
|
136
|
+
## What it does not check
|
|
137
|
+
|
|
138
|
+
- Whether a reading is still what the page says. The rule has no network and no clock; a shipped
|
|
139
|
+
preset's readings are re-read daily in paperlint's repository and reach you as a patch release.
|
|
140
|
+
A venue without a preset (`"kind": "named"`) is re-read by you.
|
|
141
|
+
- Whether a deadline has passed, or how long is left.
|
|
142
|
+
- A disagreement between sources — that is what the record holds; the earlier reading binds.
|
|
143
|
+
- Whether an override's evidence exists — that is [`cycle/evidence`](evidence.md).
|
|
144
|
+
- Whether the scorecard's stages name these cycles — that is [`cycle/stage`](stage.md).
|
|
145
|
+
|
|
146
|
+
## How to fix
|
|
147
|
+
|
|
148
|
+
Correct the date. For a deadline read from a call for papers, write it as the call prints it,
|
|
149
|
+
`"YYYY-MM-DD AoE"`, and let paperlint do the arithmetic; for one read from a portal, write the instant
|
|
150
|
+
the portal shows with its zone. Delete a portal reading the venue's preset already carries. A
|
|
151
|
+
deadline the chairs moved by mail is an `override`, with the mail saved in the paper folder as its
|
|
152
|
+
`evidence`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# cycle/stage
|
|
2
|
+
|
|
3
|
+
**Level:** error · **Reads:** the paper's `PIPELINE-STATUS.md` frontmatter (`stages`) and its
|
|
4
|
+
`paperlint.json` (`cycles`) · **Reported on:** the frontmatter of `PIPELINE-STATUS.md`
|
|
5
|
+
|
|
6
|
+
## What it catches
|
|
7
|
+
|
|
8
|
+
With `cycles` declared in the paper's `paperlint.json`, a `stages` entry in the scorecard's
|
|
9
|
+
frontmatter must say which attempt it belongs to, `cycle: <id>`, and that attempt must exist. Three
|
|
10
|
+
things can be wrong:
|
|
11
|
+
|
|
12
|
+
- a stage names no `cycle`;
|
|
13
|
+
- a stage names a `cycle` no declared cycle has as its `id`;
|
|
14
|
+
- a `submitted` or `camera-ready` stage belongs to a cycle whose `phase` is still `porting` — a PDF
|
|
15
|
+
was sent to the venue while the record says the source is still in the previous venue's template.
|
|
16
|
+
|
|
17
|
+
Without `cycles` (the flat form) the rule is silent and `venue:` stays what it was.
|
|
18
|
+
|
|
19
|
+
## Why
|
|
20
|
+
|
|
21
|
+
A paper's attempts are recorded once, in `paperlint.json`; the scorecard's stages are the evidence
|
|
22
|
+
— which PDF, how many bytes, when. A stage that names its cycle says which attempt the evidence
|
|
23
|
+
belongs to, and the venue's name is then spelled once, in the preset, instead of as a free string
|
|
24
|
+
retyped per stage (`REALM @ EMNLP 2026`, `AISec 2026 @ ACM CCS`, …). A stage whose cycle does not
|
|
25
|
+
exist is evidence of nothing.
|
|
26
|
+
|
|
27
|
+
The `porting` case is the other half of a declaration: `"phase": "porting"` silences the venue's
|
|
28
|
+
format rules because the source is, by declaration, not yet in the venue's template. A PDF sent
|
|
29
|
+
from such a cycle contradicts that declaration — either the port is done and the phase is stale, or
|
|
30
|
+
the stage is wrong.
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
Failing — `paperlint.json` declares one cycle, `open-2027`, and `PIPELINE-STATUS.md` has
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
---
|
|
38
|
+
stages:
|
|
39
|
+
- stage: submitted
|
|
40
|
+
date: 2026-07-22
|
|
41
|
+
pdf: versions/a.pdf
|
|
42
|
+
bytes: 1
|
|
43
|
+
---
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
papers/my-paper/PIPELINE-STATUS.md
|
|
48
|
+
1:1 error the «submitted» stage (2026-07-22) names no `cycle` — this paper declares `cycles` in
|
|
49
|
+
paperlint.json, so each stage says which attempt it belongs to: `cycle: <id>`, one of
|
|
50
|
+
open-2027 cycle/stage
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Passing:
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
---
|
|
57
|
+
stages:
|
|
58
|
+
- stage: submitted
|
|
59
|
+
cycle: open-2027
|
|
60
|
+
date: 2026-07-22
|
|
61
|
+
pdf: versions/a.pdf
|
|
62
|
+
bytes: 1
|
|
63
|
+
---
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Also passing: a paper without `cycles`, whatever its stages say.
|
|
67
|
+
|
|
68
|
+
## Options / preset fields
|
|
69
|
+
|
|
70
|
+
No rule options.
|
|
71
|
+
|
|
72
|
+
## What it does not check
|
|
73
|
+
|
|
74
|
+
- The PDF, its bytes, or the frozen source — [`paper/stages`](../../rules.md) and `paper/source`
|
|
75
|
+
do.
|
|
76
|
+
- Whether a stage's `date` falls inside its cycle (after `opened`, before the outcome's `date`).
|
|
77
|
+
- Whether a cycle without any `submitted` stage was in fact submitted; that is the portal's record
|
|
78
|
+
(`paperlint submission`), not the scorecard's.
|
|
79
|
+
- The rest of the cycle record — [`cycle/record`](record.md) does.
|
|
80
|
+
|
|
81
|
+
## How to fix
|
|
82
|
+
|
|
83
|
+
Add `cycle: <id>` to each stage, with the id of the cycle the PDF was sent in. For a stage whose
|
|
84
|
+
cycle is still `porting`: if the port is done, remove `"phase": "porting"` from the cycle
|
|
85
|
+
([`cycle/port-done`](port-done.md) says when); if no PDF was sent, remove the stage.
|
|
@@ -68,7 +68,6 @@ any other rule.
|
|
|
68
68
|
3 of the model_) is read as a quantity, and so is the number of a name that opens the sentence
|
|
69
69
|
(_Claude 3 fails …_).
|
|
70
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
71
|
|
|
73
72
|
## How to fix
|
|
74
73
|
|