paperlint 9.0.1 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +68 -128
  2. package/dist/build.d.ts +1 -1
  3. package/dist/build.js +1 -1
  4. package/dist/cli.d.ts +5 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +52 -6
  7. package/dist/cli.js.map +1 -1
  8. package/dist/domain/layout-tree.d.ts +19 -0
  9. package/dist/domain/layout-tree.d.ts.map +1 -0
  10. package/dist/domain/layout-tree.js +32 -0
  11. package/dist/domain/layout-tree.js.map +1 -0
  12. package/dist/domain/lookup-cache.d.ts +2 -2
  13. package/dist/domain/lookup-cache.js +2 -2
  14. package/dist/domain/paper-layout.d.ts +81 -0
  15. package/dist/domain/paper-layout.d.ts.map +1 -0
  16. package/dist/domain/paper-layout.js +259 -0
  17. package/dist/domain/paper-layout.js.map +1 -0
  18. package/dist/domain/repro-layout.d.ts +80 -0
  19. package/dist/domain/repro-layout.d.ts.map +1 -0
  20. package/dist/domain/repro-layout.js +247 -0
  21. package/dist/domain/repro-layout.js.map +1 -0
  22. package/dist/domain/scaffold-layout.d.ts +28 -0
  23. package/dist/domain/scaffold-layout.d.ts.map +1 -0
  24. package/dist/domain/scaffold-layout.js +81 -0
  25. package/dist/domain/scaffold-layout.js.map +1 -0
  26. package/dist/eslint-rules/prereg-coverage.d.ts +98 -0
  27. package/dist/eslint-rules/prereg-coverage.d.ts.map +1 -0
  28. package/dist/eslint-rules/prereg-coverage.js +274 -0
  29. package/dist/eslint-rules/prereg-coverage.js.map +1 -0
  30. package/dist/folder-layout-hook.d.ts +21 -0
  31. package/dist/folder-layout-hook.d.ts.map +1 -0
  32. package/dist/folder-layout-hook.js +117 -0
  33. package/dist/folder-layout-hook.js.map +1 -0
  34. package/dist/folder-layout-rule.d.ts +22 -0
  35. package/dist/folder-layout-rule.d.ts.map +1 -0
  36. package/dist/folder-layout-rule.js +107 -0
  37. package/dist/folder-layout-rule.js.map +1 -0
  38. package/dist/init.js +1 -1
  39. package/dist/init.js.map +1 -1
  40. package/dist/new-paper.d.ts +4 -1
  41. package/dist/new-paper.d.ts.map +1 -1
  42. package/dist/new-paper.js +40 -6
  43. package/dist/new-paper.js.map +1 -1
  44. package/dist/references.d.ts +1 -1
  45. package/dist/references.d.ts.map +1 -1
  46. package/dist/references.js +2 -2
  47. package/dist/references.js.map +1 -1
  48. package/dist/repro-layout-rule.d.ts +16 -0
  49. package/dist/repro-layout-rule.d.ts.map +1 -0
  50. package/dist/repro-layout-rule.js +81 -0
  51. package/dist/repro-layout-rule.js.map +1 -0
  52. package/docs/ci.md +60 -0
  53. package/docs/configuration.md +2 -0
  54. package/docs/e2e.md +2 -2
  55. package/docs/install.md +20 -16
  56. package/docs/layout.md +154 -0
  57. package/docs/optional-rules.md +5 -4
  58. package/docs/references.md +5 -2
  59. package/docs/rules/paper/allowed-files-only.md +192 -0
  60. package/docs/rules/repro/allowed-files-only.md +128 -0
  61. package/docs/rules/study/declare-sample.md +146 -0
  62. package/docs/rules.md +53 -50
  63. package/docs/skills.md +6 -3
  64. package/docs/venues.md +94 -0
  65. package/eslint-rules/prereg-coverage.test.ts +448 -0
  66. package/eslint-rules/prereg-coverage.ts +419 -0
  67. package/lib/skill-trigger-cases.harness.mjs +51 -5
  68. package/lib/skill-trigger-cases.mjs +53 -15
  69. package/package.json +1 -1
  70. package/plugin/hooks/hooks.json +9 -0
  71. package/skills/analyze-sibling-paper/SKILL.md +2 -2
  72. package/skills/analyze-sibling-paper/SKILL.md.spec.ts +1 -1
  73. package/skills/build-benchmark/SKILL.md +14 -1
  74. package/skills/build-benchmark/SKILL.md.spec.ts +13 -0
  75. package/skills/build-label-page/SKILL.md +118 -0
  76. package/skills/build-label-page/SKILL.md.spec.ts +129 -0
  77. package/skills/build-label-page/build-label-page.eval.mjs +15 -0
  78. package/skills/build-label-page/build-label-page.test.ts +959 -0
  79. package/skills/build-label-page/references/checklist.md +148 -0
  80. package/skills/build-label-page/references/example-generator.py +803 -0
  81. package/skills/find-venue/SKILL.md +5 -3
  82. package/skills/find-venue/SKILL.md.spec.ts +4 -2
  83. package/skills/grade-paper-writing/SKILL.md +7 -7
  84. package/skills/grade-paper-writing/SKILL.md.spec.ts +6 -6
  85. package/skills/map-prior-work/SKILL.md +2 -2
  86. package/skills/map-prior-work/SKILL.md.spec.ts +1 -1
  87. package/skills/paper-pipeline/SKILL.md +8 -6
  88. package/skills/paper-pipeline/SKILL.md.spec.ts +7 -5
  89. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +19 -9
  90. package/skills/paper-pipeline/references/acceptance-gate.md +19 -19
  91. package/skills/paper-pipeline/references/artifact-checklist.md +5 -0
  92. package/skills/paper-pipeline/references/pipeline-status-template.md +30 -1
  93. package/skills/paper-pipeline/repro/2026-08-07-fork-check.log +1 -1
  94. package/skills/paper-pipeline/repro/2026-08-07-fork-check2.log +1 -1
  95. package/skills/paper-pipeline/repro/2026-08-07-language-eval-pilot.log +1 -1
  96. package/skills/paper-pipeline/repro/2026-08-07-language-eval-raw.log +1 -1
  97. package/skills/paper-pipeline/repro/2026-08-08-framing-vs-vocabulary-oracle.log +48 -48
  98. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-A6-oracle.log +8 -8
  99. package/skills/paper-pipeline/repro/2026-08-08-grade-paper-writing-ablation-oracle.log +48 -48
  100. package/skills/paper-pipeline/repro/2026-08-08-parent-replication-gpw.log +2 -2
  101. package/skills/paper-pipeline/repro/2026-08-08-parent-replication.mjs +3 -3
  102. package/skills/paper-pipeline/repro/2026-10-13-grade-paper-writing-ablation-preflight-after.log +81 -0
  103. package/skills/paper-pipeline/repro/2026-10-13-grade-paper-writing-ablation-preflight-before.log +81 -0
  104. package/skills/paper-pipeline/repro/2026-10-13-grade-paper-writing-ablation-setupdiff.log +59 -0
  105. package/skills/paper-pipeline/repro/2026-10-13-grade-paper-writing-trigger.jsonl +1 -0
  106. package/skills/paper-pipeline/repro/2026-10-13-grade-paper-writing-trigger.log +22 -0
  107. package/skills/paper-pipeline/repro/README.md +4 -0
  108. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +2 -2
  109. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +2 -2
  110. package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +4 -2
  111. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +7 -2
  112. package/skills/paper-pipeline/scripts/generated-code.mjs +8 -4
  113. package/skills/paper-pipeline/scripts/generated-code.test.ts +15 -1
  114. package/skills/paper-status/SKILL.md +2 -2
  115. package/skills/paper-status/SKILL.md.spec.ts +1 -1
  116. package/skills/study-accepted-papers/SKILL.md +163 -161
  117. package/skills/study-accepted-papers/SKILL.md.spec.ts +167 -165
  118. package/skills/study-accepted-papers/references/base-rates.md +69 -0
  119. package/skills/study-accepted-papers/references/mechanisms.md +181 -0
  120. package/skills/verify-citations/SKILL.md +2 -2
  121. package/skills/verify-citations/SKILL.md.spec.ts +1 -1
  122. package/src/build.ts +1 -1
  123. package/src/cli.harness.mjs +42 -0
  124. package/src/cli.test.ts +90 -6
  125. package/src/cli.ts +78 -5
  126. package/src/domain/layout-tree.test.ts +32 -0
  127. package/src/domain/layout-tree.ts +47 -0
  128. package/src/domain/lookup-cache.ts +2 -2
  129. package/src/domain/paper-layout.test.ts +264 -0
  130. package/src/domain/paper-layout.ts +336 -0
  131. package/src/domain/repro-layout.test.ts +222 -0
  132. package/src/domain/repro-layout.ts +311 -0
  133. package/src/domain/scaffold-layout.ts +104 -0
  134. package/src/folder-layout-hook.test.ts +214 -0
  135. package/src/folder-layout-hook.ts +141 -0
  136. package/src/folder-layout-rule.test.ts +235 -0
  137. package/src/folder-layout-rule.ts +151 -0
  138. package/src/hooks-settings.harness.ts +9 -8
  139. package/src/init.ts +1 -1
  140. package/src/layout-docs.test.ts +52 -0
  141. package/src/new-paper.harness.mjs +23 -1
  142. package/src/new-paper.test.ts +299 -6
  143. package/src/new-paper.ts +51 -5
  144. package/src/paper-files.test.ts +9 -6
  145. package/src/references.test.ts +5 -5
  146. package/src/references.ts +2 -2
  147. package/src/repro-layout-rule.test.ts +114 -0
  148. package/src/repro-layout-rule.ts +121 -0
  149. package/src/rule-cases.test.ts +98 -0
  150. package/templates/paper/PIPELINE-STATUS.md +41 -7
@@ -0,0 +1,148 @@
1
+ # Labelling-page checklist
2
+
3
+ Seven rules for a page where a person labels items from a paper's study (gold labels, a blind review of
4
+ model outputs, "is this a real boundary case"). Each rule says what to do, why, and how to check it.
5
+ They come from four such pages built in one week; each rule is a defect one of them shipped, or a
6
+ failure the next answer would have hidden.
7
+
8
+ The generator beside this file, `example-generator.py`, does rules 2 to 5 and 7 by construction. Rules
9
+ 1 and 6 are things the agent does. Read the rule before changing the part of the generator that
10
+ carries it.
11
+
12
+ ## 1. Test it in the claude.ai phone viewer before sending the link
13
+
14
+ **Do.** Open the published artifact in the claude.ai viewer at phone width (the person's own phone
15
+ is the real test), answer one item, reload, press "Next unanswered", and only then send the link.
16
+ If you cannot open the viewer yourself, say so in the hand-over and ask for a one-minute smoke test
17
+ (answer one item, reload, check that the answer is still there) before the real run. Then list the
18
+ store (`ArtifactData` `list` of `answers`) and confirm the test answer is in it.
19
+
20
+ **Why.** The viewer can size its frame to the page. A page that grows with its content cannot scroll
21
+ itself, so `scrollIntoView` does nothing, and a fixed-position toast can sit outside the visible part
22
+ of the frame. A test in a plain browser passes on both and proves nothing about the viewer.
23
+
24
+ **Check.** The hand-over says what was exercised in the viewer and what was not. "Tested in a
25
+ browser" is not that sentence.
26
+
27
+ ## 2. Navigation never relies on in-page scrolling or toasts
28
+
29
+ **Do.** Make "Next unanswered" a filter. It hides every finished item and every finished group,
30
+ leaving only what is left, and a note at the top lists those items and what each still needs
31
+ ("G004 needs correct?; boundary"). Put every message (saving, saved, failed, missing) inline in the
32
+ card it is about. No `scrollIntoView`, no `position: fixed`, no toast, no `100vh` height.
33
+
34
+ **Why.** Rule 1: in the viewer, jumping to the next item does nothing and a toast may never be seen. A
35
+ filter works in any frame, because the next thing to answer is simply the first thing on the page.
36
+
37
+ **Check.** `grep -E 'scrollIntoView|position: *fixed|100vh|alert\(' page.html` finds nothing.
38
+
39
+ ## 3. An item counts as done only when every question on it is answered
40
+
41
+ **Do.** Done means all questions answered. The card shows which one is missing ("Still needs:
42
+ boundary"). The progress counter counts complete items only, so "7 of 12" means 7 items with every
43
+ question answered. A group is finished when all its items are and its familiarity question (rule 5)
44
+ is answered.
45
+
46
+ **Why.** An item with one of two questions answered looks finished on a scan, drops out of the count,
47
+ and surfaces weeks later as a gap in the data. A counter that counts partial items reports progress
48
+ that the analysis cannot use.
49
+
50
+ **Check.** Answer one question of a two-question item: the counter stays put and the card names the
51
+ other question.
52
+
53
+ ## 4. Blind: the page tells the labeller nothing about the answer or the source
54
+
55
+ **Do.**
56
+
57
+ - Neutral ids (`G001`, `G002`, ...). The link from id to source id lives in `key.json`, which is not
58
+ part of the page.
59
+ - The order is fixed by a seed and does not follow the input order or the source.
60
+ - No model answer, check verdict, difficulty tag or source label on the page.
61
+ - The generator refuses to build when an item carries a field outside an allow-list. It does not drop
62
+ the field quietly. A field is added to the allow-list on purpose, after asking whether it tells
63
+ the labeller the answer or the source; this holds for new question wording that rides on an item
64
+ (a `hint`, a `note`) as much as for any other field.
65
+ - A source id typed into a visible text is refused as well.
66
+
67
+ **Why.** A blind page fails by what leaked in, and a field nobody listed is the one nobody thought
68
+ of. A deny-list ("never show `verdict`") only covers the leaks someone already imagined; an
69
+ allow-list covers the next one, and a refusal is loud where a silent drop is not.
70
+
71
+ **Check.** Build with a `model_answer` field on one item: the build stops and names it. Then read the
72
+ first screen of the page yourself as the labeller would: the allow-list controls fields, not what
73
+ the text of an allowed field says.
74
+
75
+ ## 5. Ask only what the labeller can answer
76
+
77
+ **Do.**
78
+
79
+ - Restrict the items to the languages and tools the labeller knows (`labeller_knows`). Items of
80
+ other groups are not put on the page and get no id.
81
+ - Add one question per group, "how well do you know this language / tool" (well / somewhat / not
82
+ really). It is an analysis filter: the study can report the labels with and without the groups
83
+ the labeller does not know well.
84
+ - The per-item judgement "clear-cut or a real boundary case" is the labeller's. The study design
85
+ does not decide it in advance and does not pre-fill it.
86
+
87
+ **Why.** A label given outside the labeller's competence is noise that looks like data. The familiarity
88
+ answer is the only way to find it afterwards. And a boundary case is boundary because a competent
89
+ person hesitates; a designer who tags it in advance has measured the design, not the item.
90
+
91
+ **Check.** The build prints how many items were left out; the export has a familiarity value for
92
+ every group.
93
+
94
+ ## 6. Export into the repository right away
95
+
96
+ **Do.**
97
+
98
+ - When the labeller says they are done (or stops), export the store at once: one JSON file per
99
+ page, into the study's `data/` folder, named with the export date
100
+ (`<study>-labels-YYYY-MM-DD.json`), and commit it in the same pass.
101
+ - Answers the labeller gives in chat go into the same file with `source: "chat"`; answers from the
102
+ page carry `source: "page"`. The two are never mixed up afterwards.
103
+ - The build refuses an option without a non-empty `value` and `label`, and records the allowed
104
+ values (each question's options, and the three familiarity values) once, in both the page and
105
+ `key.json`. A stored value counts as an answer only if it is one of them, on the page and in the
106
+ export alike: a typo from a chat answer, or a value from an earlier build's options, shows as
107
+ unanswered on the page and is not counted in the export. The export marks the item (or the group's
108
+ familiarity) incomplete, keeps the raw value under `invalid_answers` (`invalid_familiarity`), and
109
+ the report names the item or group. Fix it in the dump and export again.
110
+ - If the page fails, take the last answers in chat. Patch the page blind at most once.
111
+
112
+ **Why.** The store lives with the artifact: not in the repository, not in the paper's history, and
113
+ gone if the artifact is deleted. Labels that exist only there are not part of the study. Patching a
114
+ page you cannot see on the person's phone loses more time than asking: each blind fix is another
115
+ round trip, and the person's answers are the thing that cannot wait.
116
+
117
+ **Check.** `data/<study>-labels-<date>.json` is in `git log`, and `complete_items` in it equals the
118
+ count the page showed.
119
+
120
+ ## 7. Save each answer on click, show when, survive reload, work without the store
121
+
122
+ **Do.**
123
+
124
+ - One tap saves one answer: no submit button, no "save all".
125
+ - Each card shows "Saved <time>" once the store confirms, "Saving..." while it waits, and
126
+ "Not saved (<code>)" when the store refuses.
127
+ - Reload restores everything from the store; the page keeps no answer only in memory.
128
+ - Write to a document one at a time (the next write waits for the previous one), and only on a tap.
129
+ Subscribe to a collection once.
130
+ - When the store is unavailable (`claude.use("db")` is `null`, or the subscription fails), the
131
+ page still renders every item, disables the buttons and says in a banner at the top that answers
132
+ cannot be saved in this view.
133
+
134
+ **Why.** On a phone, a submit button gets forgotten and a session gets interrupted. A per-item
135
+ "Saved" is the labeller's only evidence the answer is not lost. A page that renders nothing when
136
+ the store is missing hides the real problem (a link opened without access) behind a blank screen.
137
+
138
+ **Check.** Answer, reload, the answer is there with its time. Open the page where the store does
139
+ not run: banner, items readable, buttons off.
140
+
141
+ ---
142
+
143
+ ## Who can answer
144
+
145
+ A page with the `db` capability opens only for people with access to the artifact: the owner, or a
146
+ Contributor. A link sent to someone without access shows "Only people with access" and no page.
147
+ Share the artifact with the labeller as a Contributor, or have the labeller open it from their own
148
+ account, before you send the link.