paperlint 10.1.0 → 10.2.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 (72) hide show
  1. package/README.md +2 -0
  2. package/dist/adapters/study-registry/index.d.ts +6 -0
  3. package/dist/adapters/study-registry/index.d.ts.map +1 -0
  4. package/dist/adapters/study-registry/index.js +58 -0
  5. package/dist/adapters/study-registry/index.js.map +1 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +40 -2
  8. package/dist/cli.js.map +1 -1
  9. package/dist/domain/repro-layout.d.ts +12 -4
  10. package/dist/domain/repro-layout.d.ts.map +1 -1
  11. package/dist/domain/repro-layout.js +49 -18
  12. package/dist/domain/repro-layout.js.map +1 -1
  13. package/dist/domain/scaffold-layout.d.ts +4 -3
  14. package/dist/domain/scaffold-layout.d.ts.map +1 -1
  15. package/dist/domain/scaffold-layout.js +7 -4
  16. package/dist/domain/scaffold-layout.js.map +1 -1
  17. package/dist/domain/study-registry.d.ts +176 -0
  18. package/dist/domain/study-registry.d.ts.map +1 -0
  19. package/dist/domain/study-registry.js +371 -0
  20. package/dist/domain/study-registry.js.map +1 -0
  21. package/dist/ports/study-registry-codec.d.ts +11 -0
  22. package/dist/ports/study-registry-codec.d.ts.map +1 -0
  23. package/dist/ports/study-registry-codec.js +2 -0
  24. package/dist/ports/study-registry-codec.js.map +1 -0
  25. package/dist/repro-layout-rule.d.ts.map +1 -1
  26. package/dist/repro-layout-rule.js +4 -3
  27. package/dist/repro-layout-rule.js.map +1 -1
  28. package/dist/studies.d.ts +27 -0
  29. package/dist/studies.d.ts.map +1 -0
  30. package/dist/studies.js +160 -0
  31. package/dist/studies.js.map +1 -0
  32. package/dist/study-registry-rule.d.ts +17 -0
  33. package/dist/study-registry-rule.d.ts.map +1 -0
  34. package/dist/study-registry-rule.js +115 -0
  35. package/dist/study-registry-rule.js.map +1 -0
  36. package/docs/design/study-registry.md +130 -0
  37. package/docs/layout.md +47 -44
  38. package/docs/rules/paper/allowed-files-only.md +3 -2
  39. package/docs/rules/repro/allowed-files-only.md +40 -30
  40. package/docs/rules/repro/study-registered.md +162 -0
  41. package/docs/rules/study/declare-sample.md +1 -1
  42. package/docs/rules.md +2 -1
  43. package/package.json +1 -1
  44. package/skills/build-benchmark/SKILL.md +20 -1
  45. package/skills/build-benchmark/SKILL.md.spec.ts +19 -0
  46. package/skills/build-label-page/SKILL.md +7 -4
  47. package/skills/build-label-page/SKILL.md.spec.ts +6 -3
  48. package/skills/paper-pipeline/references/artifact-checklist.md +2 -1
  49. package/skills/paper-pipeline/references/pipeline-status-template.md +5 -3
  50. package/skills/render-paper/check-render.sh +9 -0
  51. package/skills/render-paper/render-paper.harness.mjs +102 -0
  52. package/skills/run-agent-grid/SKILL.md +8 -1
  53. package/skills/run-agent-grid/SKILL.md.spec.ts +7 -0
  54. package/src/adapters/study-registry/index.test.ts +144 -0
  55. package/src/adapters/study-registry/index.ts +70 -0
  56. package/src/cli.ts +51 -2
  57. package/src/domain/paper-layout.test.ts +1 -1
  58. package/src/domain/repro-layout.test.ts +18 -9
  59. package/src/domain/repro-layout.ts +58 -18
  60. package/src/domain/scaffold-layout.ts +7 -4
  61. package/src/domain/study-registry.test.ts +657 -0
  62. package/src/domain/study-registry.ts +598 -0
  63. package/src/folder-layout-hook.test.ts +10 -0
  64. package/src/new-paper.test.ts +28 -2
  65. package/src/ports/study-registry-codec.ts +11 -0
  66. package/src/repro-layout-rule.ts +4 -3
  67. package/src/rule-cases.test.ts +41 -0
  68. package/src/studies-cli.test.ts +113 -0
  69. package/src/studies.test.ts +353 -0
  70. package/src/studies.ts +259 -0
  71. package/src/study-registry-rule.test.ts +317 -0
  72. package/src/study-registry-rule.ts +172 -0
@@ -0,0 +1,371 @@
1
+ /**
2
+ * THE STUDY REGISTRY — `repro/studies.json`: one row per study, each with a stable id, a plain name and
3
+ * its status. The design is docs/design/study-registry.md; the rule is `repro/study-registered`
4
+ * (docs/rules/repro/study-registered.md).
5
+ *
6
+ * A paper's `repro/` once reached 79 study folders named `<slug>-YYYY-MM-DD`, and nobody could tell
7
+ * which was which, which had ended, or which a number in the paper came from. Now every study folder is
8
+ * `<id>-<slug>` (`P1-S03-baseline`), and its row says what it asks, where it stands and what it found.
9
+ *
10
+ * ── JSON, NEVER MARKDOWN ─────────────────────────────────────────────────────────
11
+ * The registry is data: its text is parsed once, where it enters, against the schema in
12
+ * `src/adapters/study-registry/` (`StudyRegistryCodec`). The index in `repro/README.md` is OUTPUT: it is
13
+ * generated from the registry and compared as a string, between two fixed markers. Nothing parses it.
14
+ *
15
+ * Pure: the caller lists `repro/`, reads the registry and the README, and says which result files exist.
16
+ */
17
+ import { isAbsolute, posix, win32 } from "node:path";
18
+ import { STUDIES_FILE, STUDY_SLUG } from "./repro-layout.js";
19
+ /** The registry, at the top of the paper's `repro/`; the layout allows it there. */
20
+ export { STUDIES_FILE };
21
+ export const STUDY_KINDS = [
22
+ "measurement",
23
+ "spike",
24
+ "tooling",
25
+ "data",
26
+ "artifact",
27
+ "salvage",
28
+ ];
29
+ export const STUDY_STATUSES = [
30
+ "designing",
31
+ "running",
32
+ "done",
33
+ "stopped",
34
+ "superseded",
35
+ "dropped",
36
+ ];
37
+ /** `registry`: listed in the registry only, not in the paper's text. */
38
+ export const IN_PAPER = ["yes", "no", "registry"];
39
+ /** A title is a plain name, not a sentence. */
40
+ export const MAX_TITLE_WORDS = 8;
41
+ /** A paper's prefix: a capital letter, then capitals or digits (`P1`). */
42
+ export const PREFIX_PATTERN = /^[A-Z][A-Z0-9]*$/u;
43
+ /** The kind `paperlint studies new` gives a study when none is named. */
44
+ export const DEFAULT_KIND = "measurement";
45
+ /** The markers around the generated index in `repro/README.md`. Fixed: the rule finds the block by them. */
46
+ export const INDEX_BEGIN = "<!-- studies:begin — generated from studies.json by `paperlint studies index`; do not edit -->";
47
+ export const INDEX_END = "<!-- studies:end -->";
48
+ /** The README written when `repro/` has none. */
49
+ const INDEX_HEADING = "# Reproduction index";
50
+ /** The number of an id of `prefix` (`P1-S07` → 7); null for an id of another shape. */
51
+ function idNumber(prefix, id) {
52
+ const m = new RegExp(`^${prefix}-S(\\d{2,})$`, "u").exec(id);
53
+ return m === null ? null : Number(m[1]);
54
+ }
55
+ /** The id after the highest one in `r`, at least two digits: `P1-S01` in an empty registry. */
56
+ export function nextStudyId(r) {
57
+ const numbers = r.studies
58
+ .map((s) => idNumber(r.prefix, s.id))
59
+ .filter((n) => n !== null);
60
+ const next = Math.max(0, ...numbers) + 1;
61
+ return `${r.prefix}-S${String(next).padStart(2, "0")}`;
62
+ }
63
+ /** The slug of a title: lowercase Latin letters and digits, words joined by single hyphens; "" when none. */
64
+ export const studySlug = (title) => title
65
+ .normalize("NFKD")
66
+ .replace(/\p{M}/gu, "")
67
+ .toLowerCase()
68
+ .replace(/[^a-z0-9]+/gu, "-")
69
+ .replace(/^-+|-+$/gu, "");
70
+ /** The number of words in a title. */
71
+ export const titleWords = (title) => title.split(/\s+/u).filter((w) => w !== "").length;
72
+ /**
73
+ * Whether `path` stays inside the folder it is relative to. A backslash or a Windows absolute path
74
+ * is refused outright: `posix.normalize` does not resolve `..\\`, while the host's `join` may.
75
+ */
76
+ const isInside = (path) => {
77
+ if (path.includes("\\") || isAbsolute(path) || win32.isAbsolute(path))
78
+ return false;
79
+ const n = posix.normalize(path);
80
+ return n !== ".." && !n.startsWith("../");
81
+ };
82
+ /** Whether the row is the first of the registry with its value of `key`. */
83
+ const isFirst = ({ r, s, i }, key) => r.studies.findIndex((o) => key(o) === key(s)) === i;
84
+ const badId = ({ r, s }) => idNumber(r.prefix, s.id) === null
85
+ ? { problem: "bad-id", id: s.id, prefix: r.prefix }
86
+ : null;
87
+ /** Reported once, on the first row that holds the id. */
88
+ const duplicateId = (row) => row.r.studies.filter((o) => o.id === row.s.id).length > 1 &&
89
+ isFirst(row, (o) => o.id)
90
+ ? { problem: "duplicate-id", id: row.s.id }
91
+ : null;
92
+ /** Reported once, on the first row that names the folder. */
93
+ const twoRows = (row) => {
94
+ const { r, s } = row;
95
+ const ids = r.studies.filter((o) => o.folder === s.folder).map((o) => o.id);
96
+ return ids.length > 1 && isFirst(row, (o) => o.folder)
97
+ ? { problem: "two-rows", folder: s.folder, ids }
98
+ : null;
99
+ };
100
+ /** A bad id is reported once, as an id: no folder can match it. */
101
+ const folderName = ({ r, s }) => idNumber(r.prefix, s.id) === null ||
102
+ (s.folder.startsWith(`${s.id}-`) &&
103
+ STUDY_SLUG.test(s.folder.slice(s.id.length + 1)))
104
+ ? null
105
+ : { problem: "folder-name", id: s.id, folder: s.folder };
106
+ const noFolder = ({ s, input }) => input.folders.includes(s.folder)
107
+ ? null
108
+ : { problem: "no-folder", id: s.id, folder: s.folder };
109
+ const longTitle = ({ s }) => {
110
+ const words = titleWords(s.title);
111
+ return words > MAX_TITLE_WORDS
112
+ ? { problem: "long-title", id: s.id, words }
113
+ : null;
114
+ };
115
+ const noResult = ({ s }) => {
116
+ const missing = [
117
+ ...(s.result === undefined ? ["result"] : []),
118
+ ...(s.result_file === undefined ? ["result_file"] : []),
119
+ ];
120
+ return s.status === "done" && missing.length > 0
121
+ ? { problem: "no-result", id: s.id, missing }
122
+ : null;
123
+ };
124
+ /** A `result_file` on any status must be a file inside the study's folder. */
125
+ const resultFile = ({ s, input }) => {
126
+ const path = s.result_file;
127
+ if (path === undefined)
128
+ return null;
129
+ if (!isInside(path))
130
+ return { problem: "result-file", id: s.id, path, why: "outside" };
131
+ return input.existingResults.has(`${s.folder}/${path}`)
132
+ ? null
133
+ : { problem: "result-file", id: s.id, path, why: "missing" };
134
+ };
135
+ const noSuccessor = ({ r, s }) => {
136
+ const by = s.superseded_by ?? null;
137
+ return s.status === "superseded" &&
138
+ (by === null || !r.studies.some((o) => o.id === by))
139
+ ? { problem: "no-successor", id: s.id, superseded_by: by }
140
+ : null;
141
+ };
142
+ /** The checks of a row, in the order their findings are reported. */
143
+ const ROW_CHECKS = [
144
+ badId,
145
+ duplicateId,
146
+ twoRows,
147
+ folderName,
148
+ noFolder,
149
+ longTitle,
150
+ noResult,
151
+ resultFile,
152
+ noSuccessor,
153
+ ];
154
+ /** What is wrong with a row, in a fixed order. */
155
+ const judgeRow = (row) => ROW_CHECKS.map((check) => check(row)).filter((f) => f !== null);
156
+ /** Whether the README's index is the one `r` generates; the finding when not. */
157
+ function judgeIndex(r, readme) {
158
+ if (readme === null)
159
+ return { problem: "stale-index", why: "no-readme" };
160
+ const block = embeddedIndex(readme);
161
+ if (block === null)
162
+ return { problem: "stale-index", why: "no-markers" };
163
+ return indexInSync(readme, r)
164
+ ? null
165
+ : { problem: "stale-index", why: "differs" };
166
+ }
167
+ /**
168
+ * Every defect of a paper's study registry, in a fixed order: the registry itself; the unregistered
169
+ * folders; each row's; the index. Pure.
170
+ */
171
+ export function judgeStudies(input) {
172
+ const state = input.registry;
173
+ if (state.kind === "absent")
174
+ return input.folders.length === 0
175
+ ? []
176
+ : [{ problem: "no-registry", folders: input.folders }];
177
+ if (state.kind === "unreadable")
178
+ return [{ problem: "unreadable", why: state.why }];
179
+ const r = state.registry;
180
+ const next = nextStudyId(r);
181
+ const index = judgeIndex(r, input.readme);
182
+ return [
183
+ ...input.folders
184
+ .filter((f) => !r.studies.some((s) => s.folder === f))
185
+ .map((folder) => ({
186
+ problem: "unregistered",
187
+ folder,
188
+ next,
189
+ })),
190
+ ...r.studies.flatMap((s, i) => judgeRow({ r, s, i, input })),
191
+ ...(index === null ? [] : [index]),
192
+ ];
193
+ }
194
+ // ── the index ─────────────────────────────────────────────────────────────────────
195
+ /** A cell's text: one line, a backslash and then a pipe escaped, so `a\\|b` stays one cell. */
196
+ const cell = (s) => s.replace(/\r?\n/gu, " ").replace(/\\/gu, "\\\\").replace(/\|/gu, "\\|");
197
+ /** The columns of the index: each one's header, and its cell for a study. */
198
+ const COLUMNS = [
199
+ { head: "id", of: (s) => s.id },
200
+ { head: "title", of: (s) => cell(s.title) },
201
+ { head: "status", of: (s) => s.status },
202
+ { head: "result", of: (s) => cell(s.result ?? "—") },
203
+ { head: "in paper", of: (s) => s.in_paper },
204
+ { head: "folder", of: (s) => `[${s.folder}/](${s.folder}/)` },
205
+ ];
206
+ /** The width a cell takes: its code points. */
207
+ const widthOf = (s) => Array.from(s).length;
208
+ /** `t` padded to `width`. */
209
+ const padded = (t, width) => t + " ".repeat(width - widthOf(t));
210
+ /**
211
+ * The index of `r`: a markdown table, a row per study in registry order, each column padded to its
212
+ * widest cell (at least 3), the way prettier writes a table — so formatting the README leaves it as
213
+ * it is.
214
+ */
215
+ export function studyIndex(r) {
216
+ const sized = COLUMNS.map((c) => ({
217
+ ...c,
218
+ width: Math.max(3, widthOf(c.head), ...r.studies.map((s) => widthOf(c.of(s)))),
219
+ }));
220
+ const line = (cells) => `| ${cells.join(" | ")} |`;
221
+ return [
222
+ line(sized.map((c) => padded(c.head, c.width))),
223
+ line(sized.map((c) => "-".repeat(c.width))),
224
+ ...r.studies.map((s) => line(sized.map((c) => padded(c.of(s), c.width)))),
225
+ ].join("\n");
226
+ }
227
+ /**
228
+ * What a markdown table says, whatever its padding: its rows, each cell trimmed, a separator cell as
229
+ * `---`. The index is judged on this, because the padding belongs to the formatter: prettier sizes a
230
+ * column by display width, so a wide character pads differently from a code-point count.
231
+ */
232
+ const cellsOf = (table) => table
233
+ .trim()
234
+ .split("\n")
235
+ .map((line) => line
236
+ .trim()
237
+ .replace(/^\||\|$/gu, "")
238
+ .split(/(?<!\\)\|/u)
239
+ .map((c) => c.trim().replace(/^:?-{3,}:?$/u, "---"))
240
+ .join("|"))
241
+ .join("\n");
242
+ /** Whether `readme` holds the index of `r`, whatever padding a formatter gave its table. */
243
+ export function indexInSync(readme, r) {
244
+ const block = readme === null ? null : embeddedIndex(readme);
245
+ return block !== null && cellsOf(block) === cellsOf(studyIndex(r));
246
+ }
247
+ /** The index between its markers, a blank line on each side. */
248
+ export const indexBlock = (r) => `${INDEX_BEGIN}\n\n${studyIndex(r)}\n\n${INDEX_END}`;
249
+ /**
250
+ * Where `marker` stands alone on a line of `text`, at or after `from`; -1 when it does not. A marker
251
+ * counts only there, where the generator writes it: prose can mention it and a cell can carry it, but
252
+ * neither puts it alone on a line.
253
+ */
254
+ const markerAt = (text, marker, from = 0) => {
255
+ const literal = marker.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
256
+ const m = new RegExp(`^${literal}$`, "mu").exec(text.slice(from));
257
+ return m === null ? -1 : from + m.index;
258
+ };
259
+ /** The text between the markers of `readme`; null when it has no begin marker followed by an end one. */
260
+ export function embeddedIndex(readme) {
261
+ const begin = markerAt(readme, INDEX_BEGIN);
262
+ const end = begin === -1 ? -1 : markerAt(readme, INDEX_END, begin);
263
+ return end === -1 ? null : readme.slice(begin + INDEX_BEGIN.length, end);
264
+ }
265
+ /**
266
+ * `readme` with its index regenerated from `r`: the block replaced in place, appended when the README
267
+ * has none, a README of its own when there is none.
268
+ */
269
+ export function withIndex(readme, r) {
270
+ if (readme === null)
271
+ return `${INDEX_HEADING}\n\n${indexBlock(r)}\n`;
272
+ const block = embeddedIndex(readme);
273
+ if (block === null)
274
+ return `${readme.trimEnd()}\n\n${indexBlock(r)}\n`;
275
+ const begin = markerAt(readme, INDEX_BEGIN);
276
+ const after = begin + INDEX_BEGIN.length + block.length + INDEX_END.length;
277
+ return `${readme.slice(0, begin)}${indexBlock(r)}${readme.slice(after)}`;
278
+ }
279
+ /** The registry's text as `paperlint studies new` writes it: JSON, two-space indented, a final newline. */
280
+ export const registryText = (r) => `${JSON.stringify(r, null, 2)}\n`;
281
+ // ── the messages ──────────────────────────────────────────────────────────────────
282
+ const REGISTRY = "`repro/studies.json`";
283
+ const NEW_STUDY = '`npx paperlint studies new <paper-dir> "<title>"`';
284
+ const RUN_INDEX = "What to do: run `npx paperlint studies index <paper-dir>`; the block is generated, never edited by hand.";
285
+ const RENAME = "give each other row the next free id and rename its folder to match";
286
+ const tick = (s) => `\`${s}\``;
287
+ const STALE_HEAD = {
288
+ differs: `The index in \`repro/README.md\` (between the \`studies:begin\` and \`studies:end\` markers) is not the one ${REGISTRY} generates.`,
289
+ "no-markers": "`repro/README.md` has no index of the studies (the `studies:begin` and `studies:end` markers).",
290
+ "no-readme": "`repro/README.md`, the index of the studies, does not exist.",
291
+ };
292
+ /** The first part of each finding's text: what is wrong, and what to do. */
293
+ const HEADS = {
294
+ "no-registry": (f) => `\`repro/\` holds study folders (${f.folders.map((d) => tick(`${d}/`)).join(", ")}) but no ${REGISTRY}, the registry that gives every study an id, a plain name and a status. What to do: write ${REGISTRY} with the paper's prefix — \`{ "prefix": "P1", "studies": [] }\` — then give each folder its row and rename it to \`<id>-<slug>\`; a new study is created with ${NEW_STUDY}.`,
295
+ unreadable: (f) => `${REGISTRY} is not a study registry: ${f.why}. Its shape is on the rule's page.`,
296
+ unregistered: (f) => `\`repro/${f.folder}/\` has no row in ${REGISTRY}, and every study folder has exactly one. What to do: add its row with the next free id, ${tick(f.next)}, and rename the folder to \`${f.next}-<slug>\`; a new study is created with ${NEW_STUDY}, which does both.`,
297
+ "no-folder": (f) => `${REGISTRY}: the row ${tick(f.id)} names the folder \`repro/${f.folder}/\`, which does not exist. What to do: rename the study's folder to it, or correct the row's \`folder\`.`,
298
+ "two-rows": (f) => `${REGISTRY}: the rows ${f.ids.map(tick).join(", ")} all name the folder \`repro/${f.folder}/\`, and a study folder has exactly one row. What to do: keep one row for it.`,
299
+ "bad-id": (f) => `${REGISTRY}: the id ${tick(f.id)} is not \`${f.prefix}-S\` followed by two or more digits (\`${f.prefix}-S01\`). What to do: give the row the next free id and rename its folder to match.`,
300
+ "duplicate-id": (f) => `${REGISTRY}: the id ${tick(f.id)} is on more than one row, and an id names one study. What to do: ${RENAME}.`,
301
+ "folder-name": (f) => `${REGISTRY}: the row ${tick(f.id)} names the folder ${tick(f.folder)}, which is not \`${f.id}-<slug>\` — the id, then lowercase letters and digits in words joined by hyphens. What to do: rename the folder and the row's \`folder\` together.`,
302
+ "long-title": (f) => `${REGISTRY}: the title of ${tick(f.id)} has ${String(f.words)} words; a title is a plain name of at most ${String(MAX_TITLE_WORDS)}. What to do: shorten it, and put the detail in \`question\`.`,
303
+ "no-result": (f) => `${REGISTRY}: ${tick(f.id)} is \`done\` without ${f.missing.map(tick).join(" and ")}. What to do: write the one-line result and the file it is read from (\`result\`, \`result_file\`), or set the status it really has.`,
304
+ "result-file": (f) => `${REGISTRY}: the \`result_file\` of ${tick(f.id)}, ${tick(f.path)}, ${f.why === "missing" ? "is not a file in its folder" : "is outside its folder"}. What to do: name a file that exists, relative to the study's folder.`,
305
+ "no-successor": (f) => `${REGISTRY}: ${tick(f.id)} is \`superseded\` ${f.superseded_by === null ? "without `superseded_by`" : `by ${tick(f.superseded_by)}, which is no study in the registry`}. What to do: name the id of the study that replaced it.`,
306
+ "stale-index": (f) => `${STALE_HEAD[f.why]} ${RUN_INDEX}`,
307
+ };
308
+ /** The head of finding `f` of problem `p`: the lookup, typed by the problem. */
309
+ const headOf = (p, f) => HEADS[p](f);
310
+ /** The one text a finding is reported with: what is wrong, what to do, and the rule's page. */
311
+ export const studyMessage = (f) => `${headOf(f.problem, f)}\nRule repro/study-registered: https://github.com/zernie/paperlint/blob/main/docs/rules/repro/study-registered.md`;
312
+ // ── a new study ───────────────────────────────────────────────────────────────────
313
+ /** Whether `s` names a kind of study. */
314
+ export const isStudyKind = (s) => STUDY_KINDS.some((k) => k === s);
315
+ /** Why `title` cannot name a study; null when it can. */
316
+ function titleProblem(title) {
317
+ const words = titleWords(title);
318
+ if (words === 0)
319
+ return "the title is empty";
320
+ if (words > MAX_TITLE_WORDS)
321
+ return `the title has ${String(words)} words; a title is a plain name of at most ${String(MAX_TITLE_WORDS)} — the detail goes in the row's \`question\``;
322
+ return studySlug(title) === ""
323
+ ? "the title has no Latin letter or digit to name the folder by; give it one (an English title, or a word such as the method's name)"
324
+ : null;
325
+ }
326
+ /**
327
+ * `r` with a new study appended: the next id, the folder `<id>-<slug>`, `status: designing`,
328
+ * `in_paper: no` and an empty question; or why the title cannot make one.
329
+ */
330
+ export function addStudy(r, n) {
331
+ const title = n.title.trim().replace(/\s+/gu, " ");
332
+ const why = titleProblem(title);
333
+ if (why !== null)
334
+ return { ok: false, why };
335
+ const id = nextStudyId(r);
336
+ const study = {
337
+ id,
338
+ folder: `${id}-${studySlug(title)}`,
339
+ title,
340
+ question: "",
341
+ kind: n.kind,
342
+ status: "designing",
343
+ date: n.date,
344
+ in_paper: "no",
345
+ };
346
+ return {
347
+ ok: true,
348
+ registry: { ...r, studies: [...r.studies, study] },
349
+ study,
350
+ };
351
+ }
352
+ /** The `README.md` a new study's folder starts with: its id and title in frontmatter, then the sections. */
353
+ export const studyReadme = (s) => [
354
+ "---",
355
+ `id: ${s.id}`,
356
+ `title: ${JSON.stringify(s.title)}`,
357
+ "---",
358
+ "",
359
+ `# ${s.id} — ${s.title}`,
360
+ "",
361
+ `Its row in \`../${STUDIES_FILE}\` holds its status. When the study ends, set \`status\`, \`result\`,`,
362
+ "`result_file` and `in_paper` there, then run `npx paperlint studies index <paper-dir>`.",
363
+ "",
364
+ "## Question",
365
+ "",
366
+ "## How to run",
367
+ "",
368
+ "## Result",
369
+ "",
370
+ ].join("\n");
371
+ //# sourceMappingURL=study-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-registry.js","sourceRoot":"","sources":["../../src/domain/study-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * How a `repro/studies.json` becomes a value: its text parsed once, where it enters, against the schema
3
+ * of `StudyRegistry` (`src/domain/study-registry.ts`). The one implementation is
4
+ * `src/adapters/study-registry/` (zod); `src/cli.ts` wires it.
5
+ */
6
+ import type { ParsedRegistry } from "../domain/study-registry.ts";
7
+ export interface StudyRegistryCodec {
8
+ /** A `studies.json`'s text: the registry, or the one reason it is not one of this schema. */
9
+ readonly parse: (text: string) => ParsedRegistry;
10
+ }
11
+ //# sourceMappingURL=study-registry-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-registry-codec.d.ts","sourceRoot":"","sources":["../../src/ports/study-registry-codec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,CAAC;CAClD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=study-registry-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-registry-codec.js","sourceRoot":"","sources":["../../src/ports/study-registry-codec.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"repro-layout-rule.d.ts","sourceRoot":"","sources":["../src/repro-layout-rule.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAkB5D;;;GAGG;AACH,eAAO,MAAM,UAAU,GACrB,KAAK,MAAM,EACX,SAAS,SAAS,WAAW,EAAE,EAC/B,OAAO,KAAK,KACX,SAAS,MAAM,EAC6C,CAAC;AAEhE,kGAAkG;AAClG,eAAO,MAAM,cAAc,GACzB,KAAK,MAAM,EACX,MAAM,gBAAgB,KACrB,SAAS,WAAW,EAMlB,CAAC;AAgBN,mDAAmD;AACnD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,GACrB,QAAQ,CAAC,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC,CAwB1D;AAED,+FAA+F;AAC/F,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,MAAM,CAAC,0BAA0B,EAAE,OAAO,CAAC,CACF,CAAC"}
1
+ {"version":3,"file":"repro-layout-rule.d.ts","sourceRoot":"","sources":["../src/repro-layout-rule.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAkB5D;;;GAGG;AACH,eAAO,MAAM,UAAU,GACrB,KAAK,MAAM,EACX,SAAS,SAAS,WAAW,EAAE,EAC/B,OAAO,KAAK,KACX,SAAS,MAAM,EAC6C,CAAC;AAEhE,kGAAkG;AAClG,eAAO,MAAM,cAAc,GACzB,KAAK,MAAM,EACX,MAAM,gBAAgB,KACrB,SAAS,WAAW,EAMlB,CAAC;AAgBN,mDAAmD;AACnD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,GACrB,QAAQ,CAAC,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC,CAwB1D;AAED,+FAA+F;AAC/F,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,MAAM,CAAC,0BAA0B,EAAE,OAAO,CAAC,CACF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
- * `repro/allowed-files-only` — the top of a paper's `repro/` holds an index, the shared `tools/` and
3
- * `data/`, and one dated folder per study, each with a `README.md`.
2
+ * `repro/allowed-files-only` — the top of a paper's `repro/` holds an index, the study registry, the
3
+ * shared `tools/` and `data/`, and one folder per study, each with a `README.md`. Whether each study
4
+ * folder has its row in the registry is `repro/study-registered`'s (src/study-registry-rule.ts).
4
5
  *
5
6
  * What may stand there, and why, is `src/domain/repro-layout.ts` and docs/rules/repro/allowed-files-only.md.
6
7
  * This file lists the folder and reports.
@@ -42,7 +43,7 @@ export const reproEntriesOf = (dir, deps) => [...deps.listDir(callerPath(join(di
42
43
  const META = {
43
44
  type: "suggestion",
44
45
  docs: {
45
- description: "the top of a paper's repro/ holds README.md, .gitignore, tools/, data/ and one <slug>-YYYY-MM-DD folder per study, each with a README.md",
46
+ description: "the top of a paper's repro/ holds README.md, studies.json, .gitignore, tools/, data/ and one <id>-<slug> (or <slug>-YYYY-MM-DD) folder per study, each with a README.md",
46
47
  url: rulePageUrl("repro/allowed-files-only"),
47
48
  },
48
49
  schema: [],
@@ -1 +1 @@
1
- {"version":3,"file":"repro-layout-rule.js","sourceRoot":"","sources":["../src/repro-layout-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"repro-layout-rule.js","sourceRoot":"","sources":["../src/repro-layout-rule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { Files } from "./ports/files.ts";
2
+ import type { StudyRegistryCodec } from "./ports/study-registry-codec.ts";
3
+ import type { ListDir } from "./ports/talk-media.ts";
4
+ /** What one `studies` run was asked, after the command line. */
5
+ export interface StudiesArgs {
6
+ readonly sub: string | undefined;
7
+ readonly paperDir: string | undefined;
8
+ /** `new`'s title; for `index`, an argument too many. */
9
+ readonly title: string | undefined;
10
+ /** Positional arguments past the title: refused. */
11
+ readonly extra: readonly string[];
12
+ /** `--kind <kind>`; null: the default. */
13
+ readonly kind: string | null;
14
+ }
15
+ export interface StudiesDeps {
16
+ readonly files: Files;
17
+ readonly listDir: ListDir;
18
+ readonly codec: StudyRegistryCodec;
19
+ readonly cwd: string;
20
+ /** Today, `YYYY-MM-DD`: the root reads the clock. */
21
+ readonly today: string;
22
+ readonly log: (line: string) => void;
23
+ readonly err: (line: string) => void;
24
+ }
25
+ /** The run: 0 done, 1 refused by the paper's state, 2 refused by the command line. */
26
+ export declare function runStudies(a: StudiesArgs, deps: StudiesDeps): number;
27
+ //# sourceMappingURL=studies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"studies.d.ts","sourceRoot":"","sources":["../src/studies.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAwLD,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAepE"}