paperlint 10.2.0 → 10.4.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 (147) hide show
  1. package/.github/workflows/ci.yml +15 -4
  2. package/README.md +1 -0
  3. package/dist/adapters/git/index.d.ts +10 -0
  4. package/dist/adapters/git/index.d.ts.map +1 -0
  5. package/dist/adapters/git/index.js +151 -0
  6. package/dist/adapters/git/index.js.map +1 -0
  7. package/dist/adapters/memory/index.d.ts +6 -0
  8. package/dist/adapters/memory/index.d.ts.map +1 -1
  9. package/dist/adapters/memory/index.js +8 -0
  10. package/dist/adapters/memory/index.js.map +1 -1
  11. package/dist/adapters/node/index.d.ts +1 -0
  12. package/dist/adapters/node/index.d.ts.map +1 -1
  13. package/dist/adapters/node/index.js +1 -0
  14. package/dist/adapters/node/index.js.map +1 -1
  15. package/dist/adapters/node/list-entries.io.d.ts +3 -0
  16. package/dist/adapters/node/list-entries.io.d.ts.map +1 -0
  17. package/dist/adapters/node/list-entries.io.js +24 -0
  18. package/dist/adapters/node/list-entries.io.js.map +1 -0
  19. package/dist/adapters/study-registry/index.d.ts +412 -1
  20. package/dist/adapters/study-registry/index.d.ts.map +1 -1
  21. package/dist/adapters/study-registry/index.js +245 -8
  22. package/dist/adapters/study-registry/index.js.map +1 -1
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +38 -6
  25. package/dist/cli.js.map +1 -1
  26. package/dist/domain/decide-first.d.ts +100 -0
  27. package/dist/domain/decide-first.d.ts.map +1 -0
  28. package/dist/domain/decide-first.js +102 -0
  29. package/dist/domain/decide-first.js.map +1 -0
  30. package/dist/domain/index-columns.d.ts +45 -0
  31. package/dist/domain/index-columns.d.ts.map +1 -0
  32. package/dist/domain/index-columns.js +62 -0
  33. package/dist/domain/index-columns.js.map +1 -0
  34. package/dist/domain/study-mode.d.ts +37 -0
  35. package/dist/domain/study-mode.d.ts.map +1 -0
  36. package/dist/domain/study-mode.js +45 -0
  37. package/dist/domain/study-mode.js.map +1 -0
  38. package/dist/domain/study-registry.d.ts +253 -10
  39. package/dist/domain/study-registry.d.ts.map +1 -1
  40. package/dist/domain/study-registry.js +325 -27
  41. package/dist/domain/study-registry.js.map +1 -1
  42. package/dist/outputs-before-decision-rule.d.ts +17 -0
  43. package/dist/outputs-before-decision-rule.d.ts.map +1 -0
  44. package/dist/outputs-before-decision-rule.js +90 -0
  45. package/dist/outputs-before-decision-rule.js.map +1 -0
  46. package/dist/ports/git-history.d.ts +44 -0
  47. package/dist/ports/git-history.d.ts.map +1 -0
  48. package/dist/ports/git-history.js +2 -0
  49. package/dist/ports/git-history.js.map +1 -0
  50. package/dist/ports/list-entries.d.ts +17 -0
  51. package/dist/ports/list-entries.d.ts.map +1 -0
  52. package/dist/ports/list-entries.js +2 -0
  53. package/dist/ports/list-entries.js.map +1 -0
  54. package/dist/ports/study-registry-codec.d.ts +9 -2
  55. package/dist/ports/study-registry-codec.d.ts.map +1 -1
  56. package/dist/studies.d.ts +4 -0
  57. package/dist/studies.d.ts.map +1 -1
  58. package/dist/studies.js +55 -24
  59. package/dist/studies.js.map +1 -1
  60. package/dist/study-gate.d.ts +14 -0
  61. package/dist/study-gate.d.ts.map +1 -0
  62. package/dist/study-gate.js +95 -0
  63. package/dist/study-gate.js.map +1 -0
  64. package/dist/study-index-input.d.ts +5 -0
  65. package/dist/study-index-input.d.ts.map +1 -0
  66. package/dist/study-index-input.js +13 -0
  67. package/dist/study-index-input.js.map +1 -0
  68. package/dist/study-modes.d.ts +45 -0
  69. package/dist/study-modes.d.ts.map +1 -0
  70. package/dist/study-modes.js +70 -0
  71. package/dist/study-modes.js.map +1 -0
  72. package/dist/study-registry-rule.d.ts +29 -6
  73. package/dist/study-registry-rule.d.ts.map +1 -1
  74. package/dist/study-registry-rule.js +91 -40
  75. package/dist/study-registry-rule.js.map +1 -1
  76. package/dist/study-run.d.ts +19 -0
  77. package/dist/study-run.d.ts.map +1 -0
  78. package/dist/study-run.js +9 -0
  79. package/dist/study-run.js.map +1 -0
  80. package/docs/design/study-modes.md +247 -0
  81. package/docs/design/study-registry.md +137 -15
  82. package/docs/e2e.md +8 -4
  83. package/docs/layout.md +26 -21
  84. package/docs/rules/repro/outputs-before-decision.md +119 -0
  85. package/docs/rules/repro/study-plan-name.md +70 -0
  86. package/docs/rules/repro/study-registered.md +206 -15
  87. package/docs/rules.md +54 -52
  88. package/docs/testing.md +1 -0
  89. package/package.json +2 -1
  90. package/scripts/check.ts +6 -0
  91. package/skills/build-benchmark/SKILL.md +24 -12
  92. package/skills/build-benchmark/SKILL.md.spec.ts +23 -11
  93. package/skills/build-label-page/SKILL.md +9 -7
  94. package/skills/build-label-page/SKILL.md.spec.ts +8 -6
  95. package/skills/camera-ready/SKILL.md +6 -1
  96. package/skills/camera-ready/SKILL.md.spec.ts +5 -0
  97. package/skills/draft-paper/SKILL.md +11 -3
  98. package/skills/draft-paper/SKILL.md.spec.ts +10 -2
  99. package/skills/harden-paper/SKILL.md +12 -2
  100. package/skills/harden-paper/SKILL.md.spec.ts +11 -1
  101. package/skills/osf-artifact-upload/SKILL.md +7 -1
  102. package/skills/osf-artifact-upload/SKILL.md.spec.ts +6 -0
  103. package/skills/pc-panel-review/SKILL.md +10 -3
  104. package/skills/pc-panel-review/SKILL.md.spec.ts +9 -2
  105. package/skills/run-agent-grid/SKILL.md +10 -5
  106. package/skills/run-agent-grid/SKILL.md.spec.ts +9 -4
  107. package/skills/tighten-paper/SKILL.md +5 -1
  108. package/skills/tighten-paper/SKILL.md.spec.ts +4 -0
  109. package/src/adapters/git/history.test.ts +121 -0
  110. package/src/adapters/git/index.test.ts +268 -0
  111. package/src/adapters/git/index.ts +227 -0
  112. package/src/adapters/memory/index.test.ts +15 -1
  113. package/src/adapters/memory/index.ts +13 -0
  114. package/src/adapters/node/index.ts +1 -0
  115. package/src/adapters/node/list-entries.io.ts +26 -0
  116. package/src/adapters/node/list-entries.test.ts +43 -0
  117. package/src/adapters/study-registry/index.test.ts +343 -0
  118. package/src/adapters/study-registry/index.ts +374 -10
  119. package/src/adapters/study-registry/mode.test.ts +162 -0
  120. package/src/cli.ts +52 -6
  121. package/src/domain/decide-first.test.ts +258 -0
  122. package/src/domain/decide-first.ts +243 -0
  123. package/src/domain/index-columns.test.ts +216 -0
  124. package/src/domain/index-columns.ts +105 -0
  125. package/src/domain/study-measurements.test.ts +633 -0
  126. package/src/domain/study-mode.test.ts +55 -0
  127. package/src/domain/study-mode.ts +78 -0
  128. package/src/domain/study-registry.test.ts +48 -32
  129. package/src/domain/study-registry.ts +621 -36
  130. package/src/new-paper.test.ts +6 -1
  131. package/src/outputs-before-decision-rule.test.ts +206 -0
  132. package/src/outputs-before-decision-rule.ts +124 -0
  133. package/src/ports/git-history.ts +44 -0
  134. package/src/ports/list-entries.ts +18 -0
  135. package/src/ports/study-registry-codec.ts +13 -2
  136. package/src/rule-cases.test.ts +103 -1
  137. package/src/studies-cli.test.ts +2 -2
  138. package/src/studies-index-modes.test.ts +129 -0
  139. package/src/studies.test.ts +39 -9
  140. package/src/studies.ts +99 -29
  141. package/src/study-gate.test.ts +316 -0
  142. package/src/study-gate.ts +161 -0
  143. package/src/study-index-input.ts +23 -0
  144. package/src/study-modes.ts +120 -0
  145. package/src/study-registry-rule.test.ts +333 -7
  146. package/src/study-registry-rule.ts +145 -41
  147. package/src/study-run.ts +21 -0
@@ -0,0 +1,45 @@
1
+ import type { StudyMode } from "./domain/study-mode.ts";
2
+ import type { NotAFile } from "./domain/decide-first.ts";
3
+ import { type PlanTextField, type Study } from "./domain/study-registry.ts";
4
+ import type { Files } from "./ports/files.ts";
5
+ import type { StudyRegistryCodec } from "./ports/study-registry-codec.ts";
6
+ import type { ListEntries } from "./ports/list-entries.ts";
7
+ import type { ListDir } from "./ports/talk-media.ts";
8
+ /** What reading a paper's studies needs: the disk, its listings with and without kinds, and the parsers. */
9
+ export interface StudyDeps {
10
+ readonly files: Files;
11
+ readonly listDir: ListDir;
12
+ readonly entries: ListEntries;
13
+ readonly codec: StudyRegistryCodec;
14
+ }
15
+ /** What a decision path names on disk: a file, nothing, or something git cannot vouch for. */
16
+ export type OnDisk = "file" | "absent" | NotAFile;
17
+ /**
18
+ * What `p` is on disk, read from its directory's entries without following a link: a decision must
19
+ * be a regular file — git answers for a directory with the commits of anything under it, and for a
20
+ * link with the link, not the file it points to.
21
+ */
22
+ export declare const onDisk: (p: string, deps: Pick<StudyDeps, "entries">) => OnDisk;
23
+ /**
24
+ * Every file under `dir`, relative to it, `/`-separated; none when it is not a directory. A symbolic
25
+ * link is listed as a file — git stores it as one — and never followed: a link to the folder itself
26
+ * would recurse forever, and one to a tree outside would bring its files into the study.
27
+ */
28
+ export declare const filesUnder: (dir: string, deps: Pick<StudyDeps, "entries">, prefix?: string) => readonly string[];
29
+ /**
30
+ * A study whose plan parsed with a mode: its row, the plan's path in its folder, the mode, and the
31
+ * plan's empty texts — none when it is ready. Only a ready plan's mode decides anything: a draft may
32
+ * name no outputs, or an empty decision file.
33
+ */
34
+ export interface ModeStudy {
35
+ readonly row: Study;
36
+ readonly plan: string;
37
+ readonly mode: StudyMode;
38
+ readonly empty: readonly PlanTextField[];
39
+ }
40
+ /**
41
+ * Every study of the paper folder `paper` whose plan declares a mode, in registry order. A plan that
42
+ * does not parse is `repro/study-registered`'s to report; here it declares nothing.
43
+ */
44
+ export declare const modeStudies: (paper: string, deps: Pick<StudyDeps, "files" | "codec" | "entries">) => readonly ModeStudy[];
45
+ //# sourceMappingURL=study-modes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-modes.d.ts","sourceRoot":"","sources":["../src/study-modes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,KAAK,EACX,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAY,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,4GAA4G;AAC5G,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;CACpC;AAED,8FAA8F;AAC9F,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAQlD;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,GAAG,MAAM,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,KAAG,MAKpE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,KAAK,MAAM,EACX,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAChC,eAAW,KACV,SAAS,MAAM,EAId,CAAC;AAEL;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C;AA6BD;;;GAGG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,EACb,MAAM,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC,KACnD,SAAS,SAAS,EAOpB,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Reading a paper's studies with their modes: each registered study whose `plan.json` parses with a
3
+ * `mode`, and the files under a study's folder. What `repro/outputs-before-decision`, `studies gate`
4
+ * and the index's mode columns read with (docs/design/study-modes.md). A row whose folder is not one
5
+ * folder inside `repro/` is never read through.
6
+ */
7
+ import { basename, dirname, join } from "node:path";
8
+ import { callerPath } from "./caller-path.js";
9
+ import { REPRO_DIR } from "./domain/repro-layout.js";
10
+ import { isInside, } from "./domain/study-registry.js";
11
+ import { readableFolders, registryOf, textAt } from "./study-registry-rule.js";
12
+ const ON_DISK = {
13
+ file: "file",
14
+ dir: "directory",
15
+ symlink: "symbolic link",
16
+ };
17
+ /**
18
+ * What `p` is on disk, read from its directory's entries without following a link: a decision must
19
+ * be a regular file — git answers for a directory with the commits of anything under it, and for a
20
+ * link with the link, not the file it points to.
21
+ */
22
+ export const onDisk = (p, deps) => {
23
+ const e = deps
24
+ .entries(callerPath(dirname(p)))
25
+ .find((x) => x.name === basename(p));
26
+ return e === undefined ? "absent" : ON_DISK[e.kind];
27
+ };
28
+ /**
29
+ * Every file under `dir`, relative to it, `/`-separated; none when it is not a directory. A symbolic
30
+ * link is listed as a file — git stores it as one — and never followed: a link to the folder itself
31
+ * would recurse forever, and one to a tree outside would bring its files into the study.
32
+ */
33
+ export const filesUnder = (dir, deps, prefix = "") => deps.entries(callerPath(dir)).flatMap(({ name, kind }) => {
34
+ const rel = prefix === "" ? name : `${prefix}/${name}`;
35
+ return kind === "dir" ? filesUnder(join(dir, name), deps, rel) : [rel];
36
+ });
37
+ /**
38
+ * The study `s`'s plan, when it is a plan inside a folder every reader may read through
39
+ * (`readableFolders`), by the registry rule's own containment test (`isInside`), that parsed with a
40
+ * mode; else null.
41
+ */
42
+ const modeStudyOf = (paper, s, deps, readable) => {
43
+ const plan = s.plan;
44
+ const text = plan === undefined ||
45
+ !readable(s.folder) ||
46
+ !isInside(plan) ||
47
+ plan.includes("\0")
48
+ ? null
49
+ : textAt(deps.files, join(paper, REPRO_DIR, s.folder, plan));
50
+ if (plan === undefined || text === null)
51
+ return null;
52
+ const parsed = deps.codec.parsePlan(text, s.kind);
53
+ if (parsed.kind === "unreadable" || parsed.plan.mode === undefined)
54
+ return null;
55
+ const empty = parsed.kind === "draft" ? parsed.empty : [];
56
+ return { row: s, plan, mode: parsed.plan.mode, empty };
57
+ };
58
+ /**
59
+ * Every study of the paper folder `paper` whose plan declares a mode, in registry order. A plan that
60
+ * does not parse is `repro/study-registered`'s to report; here it declares nothing.
61
+ */
62
+ export const modeStudies = (paper, deps) => {
63
+ const r = registryOf(paper, deps);
64
+ const readable = readableFolders(paper, deps);
65
+ return (r.kind === "read" ? r.registry.studies : []).flatMap((s) => {
66
+ const m = modeStudyOf(paper, s, deps, readable);
67
+ return m === null ? [] : [m];
68
+ });
69
+ };
70
+ //# sourceMappingURL=study-modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-modes.js","sourceRoot":"","sources":["../src/study-modes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,OAAO,EACL,QAAQ,GAGT,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAa/E,MAAM,OAAO,GAA+C;IAC1D,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,WAAW;IAChB,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,IAAgC,EAAU,EAAE;IAC5E,MAAM,CAAC,GAAG,IAAI;SACX,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;SAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,GAAW,EACX,IAAgC,EAChC,MAAM,GAAG,EAAE,EACQ,EAAE,CACrB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;IACvD,MAAM,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;IACvD,OAAO,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAcL;;;;GAIG;AACH,MAAM,WAAW,GAAG,CAClB,KAAa,EACb,CAAQ,EACR,IAAwC,EACxC,QAAqC,EACnB,EAAE;IACpB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IACpB,MAAM,IAAI,GACR,IAAI,KAAK,SAAS;QAClB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnB,CAAC,QAAQ,CAAC,IAAI,CAAC;QACf,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACjB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;QAChE,OAAO,IAAI,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;AACzD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,KAAa,EACb,IAAoD,EAC9B,EAAE;IACxB,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACjE,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAChD,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -1,17 +1,40 @@
1
- import { type RegistryState, type StudyFinding } from "./domain/study-registry.ts";
1
+ import { type PlanState, type RegistryState, type StudyFinding } from "./domain/study-registry.ts";
2
2
  import type { FolderLayoutDeps } from "./folder-layout-rule.ts";
3
3
  import type { FolderRuleModule } from "./folder-venue-rule.ts";
4
+ import type { Files } from "./ports/files.ts";
5
+ import type { ListEntries } from "./ports/list-entries.ts";
4
6
  import type { StudyRegistryCodec } from "./ports/study-registry-codec.ts";
5
7
  /** What the rule reads with: the disk, its listings, and the registry's parser. */
6
8
  export interface StudyRegistryDeps extends FolderLayoutDeps {
7
9
  readonly codec: StudyRegistryCodec;
10
+ /** `repro/`'s entries, links not followed: a study folder that is a link is never read through. */
11
+ readonly entries: ListEntries;
8
12
  }
13
+ /**
14
+ * The test every reader of a study's folder passes a row through: its folder is one folder name
15
+ * inside `repro/` (`isFolderName`) and not a symbolic link, which would lead the reads anywhere.
16
+ */
17
+ export declare const readableFolders: (dir: string, deps: Pick<StudyRegistryDeps, "entries">) => ((folder: string) => boolean);
18
+ /** The text of the file at `p`; null when there is none, or a directory sits there. */
19
+ export declare const textAt: (files: Files, p: string) => string | null;
9
20
  /** The registry of the paper folder `dir`: absent, unreadable with why, or read. */
10
21
  export declare function registryOf(dir: string, deps: Pick<StudyRegistryDeps, "files" | "codec">): RegistryState;
11
- /** Every finding of the paper folder `dir`'s study registry — THE function behind the rule. */
22
+ /**
23
+ * The plan each row of `r` names, read and parsed, by `<folder>/<plan>`; a plan not there is left out.
24
+ * A plan still named `prereg.json` is parsed by the loose schema of its old name.
25
+ */
26
+ export declare const plansOf: (dir: string, r: RegistryState, deps: Pick<StudyRegistryDeps, "files" | "codec">, readable: (folder: string) => boolean) => ReadonlyMap<string, PlanState>;
27
+ /** Every finding of the paper folder `dir`'s study registry — THE function behind both rules. */
12
28
  export declare function studyFindings(dir: string, deps: StudyRegistryDeps): readonly StudyFinding[];
13
- /** The rule, reading the folder through `deps`. */
14
- export declare function studyRegistryRules(deps: StudyRegistryDeps): Readonly<Record<"study-registered", FolderRuleModule>>;
15
- /** The level it is on at in paperlint's own config, for every paper's `PIPELINE-STATUS.md`. */
16
- export declare const STUDY_REGISTRY_RULE_LEVELS: Readonly<Record<"repro/study-registered", "error">>;
29
+ /**
30
+ * The two rules, reading the folder through `deps`: `study-registered`, the registry's errors, and
31
+ * `study-plan-name`, a warning for a plan still named `prereg.json` — read as the plan, so a paper
32
+ * that wrote one before `plan.json` existed is not broken, and told the name to move to.
33
+ */
34
+ export declare function studyRegistryRules(deps: StudyRegistryDeps): Readonly<Record<"study-registered" | "study-plan-name", FolderRuleModule>>;
35
+ /** The levels they are on at in paperlint's own config, for every paper's `PIPELINE-STATUS.md`. */
36
+ export declare const STUDY_REGISTRY_RULE_LEVELS: Readonly<{
37
+ "repro/study-registered": "error";
38
+ "repro/study-plan-name": "warn";
39
+ }>;
17
40
  //# sourceMappingURL=study-registry-rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"study-registry-rule.d.ts","sourceRoot":"","sources":["../src/study-registry-rule.ts"],"names":[],"mappings":"AA0BA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAM1E,mFAAmF;AACnF,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;CACpC;AAQD,oFAAoF;AACpF,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAAC,GAC/C,aAAa,CAOf;AAgCD,+FAA+F;AAC/F,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,iBAAiB,GACtB,SAAS,YAAY,EAAE,CAQzB;AA+BD,mDAAmD;AACnD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,iBAAiB,GACtB,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC,CAqBxD;AAED,+FAA+F;AAC/F,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAC/C,MAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CACF,CAAC"}
1
+ {"version":3,"file":"study-registry-rule.d.ts","sourceRoot":"","sources":["../src/study-registry-rule.ts"],"names":[],"mappings":"AA2BA,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAM1E,mFAAmF;AACnF,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,mGAAmG;IACnG,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAcD;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,MAAM,EACX,MAAM,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,KACvC,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAG9B,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,MAAM,GAAI,OAAO,KAAK,EAAE,GAAG,MAAM,KAAG,MAAM,GAAG,IAGzD,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAAC,GAC/C,aAAa,CAOf;AAmCD;;;GAGG;AACH,eAAO,MAAM,OAAO,GAClB,KAAK,MAAM,EACX,GAAG,aAAa,EAChB,MAAM,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAAC,EAChD,UAAU,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,KACpC,WAAW,CAAC,MAAM,EAAE,SAAS,CAkB7B,CAAC;AAEJ,iGAAiG;AACjG,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,iBAAiB,GACtB,SAAS,YAAY,EAAE,CAUzB;AA+DD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,iBAAiB,GACtB,QAAQ,CAAC,MAAM,CAAC,kBAAkB,GAAG,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,CAqB5E;AAED,mGAAmG;AACnG,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC;IAChD,wBAAwB,EAAE,OAAO,CAAC;IAClC,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAA0E,CAAC"}
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * `repro/study-registered` — every study folder at the top of a paper's `repro/` has exactly one row in
3
- * `repro/studies.json`, every row names a folder that exists, and the index in `repro/README.md` is the
4
- * one the registry generates.
3
+ * `repro/studies.json`, every row names a folder that exists, a row's measurement and plan hold
4
+ * together, and the index in `repro/README.md` is the one the registry generates. Beside it,
5
+ * `repro/study-plan-name`, a warning: a plan still named `prereg.json`.
5
6
  *
6
7
  * What is judged, and why, is `src/domain/study-registry.ts` and docs/rules/repro/study-registered.md.
7
- * This file lists `repro/`, reads the registry, the README and the result files, and reports.
8
+ * This file lists `repro/`, reads the registry, the README, the result files and the plans, and reports.
8
9
  *
9
10
  * ── WHY A RULE OF ITS OWN, NOT MORE OF `repro/allowed-files-only` ─────────────────────
10
11
  * `repro/allowed-files-only` judges what may stand at the top of `repro/`, by name, and accepts the
@@ -16,15 +17,28 @@
16
17
  * `PIPELINE-STATUS.md`, first line, like the layout rules: every paper has it, and ESLint lints no
17
18
  * file in `repro/`.
18
19
  */
19
- import { basename, dirname, join } from "node:path";
20
+ import { basename, dirname, join, posix } from "node:path";
20
21
  import { callerPath } from "./caller-path.js";
21
22
  import { README, REPRO_BYPRODUCTS, REPRO_DIR, REPRO_DIRS, } from "./domain/repro-layout.js";
22
- import { STUDIES_FILE, judgeStudies, studyMessage, } from "./domain/study-registry.js";
23
+ import { LEGACY_PLAN_FILE, PLAN_NAME_PROBLEMS, STUDIES_FILE, isFolderName, judgeStudies, planRefs, studyMessage, } from "./domain/study-registry.js";
23
24
  import { reproEntriesOf } from "./repro-layout-rule.js";
24
25
  import { rulePageUrl } from "./venue-rules.js";
25
26
  const STATUS_FILE = "PIPELINE-STATUS.md";
27
+ /** The names at the top of `<dir>/repro/` that are symbolic links. */
28
+ const linksIn = (dir, deps) => new Set(deps
29
+ .entries(callerPath(join(dir, REPRO_DIR)))
30
+ .filter((e) => e.kind === "symlink")
31
+ .map((e) => e.name));
32
+ /**
33
+ * The test every reader of a study's folder passes a row through: its folder is one folder name
34
+ * inside `repro/` (`isFolderName`) and not a symbolic link, which would lead the reads anywhere.
35
+ */
36
+ export const readableFolders = (dir, deps) => {
37
+ const links = linksIn(dir, deps);
38
+ return (folder) => isFolderName(folder) && !links.has(folder);
39
+ };
26
40
  /** The text of the file at `p`; null when there is none, or a directory sits there. */
27
- const textAt = (files, p) => {
41
+ export const textAt = (files, p) => {
28
42
  const b = files.isFile(callerPath(p)) ? files.readBytes(callerPath(p)) : null;
29
43
  return b === null ? null : new TextDecoder().decode(b);
30
44
  };
@@ -45,22 +59,47 @@ const studyFolders = (dir, deps) => reproEntriesOf(dir, deps)
45
59
  !REPRO_BYPRODUCTS.includes(e.name))
46
60
  .map((e) => e.name);
47
61
  /** Each `<folder>/<result_file>` of `r` that is a file. */
48
- const existingResults = (dir, r, files) => new Set((r.kind === "read" ? r.registry.studies : [])
62
+ const existingResults = (dir, r, files, readable) => new Set((r.kind === "read" ? r.registry.studies : [])
63
+ // A row whose folder is not one inside `repro/`, or is a link, is never read through.
64
+ .filter((s) => readable(s.folder))
49
65
  .flatMap((s) => s.result_file === undefined ? [] : [`${s.folder}/${s.result_file}`])
50
66
  // A NUL is no path the disk can hold, and probing one throws: such a row reads as missing.
51
67
  .filter((p) => !p.includes("\0") &&
52
68
  files.isFile(callerPath(join(dir, REPRO_DIR, p)))));
53
- /** Every finding of the paper folder `dir`'s study registry — THE function behind the rule. */
69
+ /**
70
+ * The plan each row of `r` names, read and parsed, by `<folder>/<plan>`; a plan not there is left out.
71
+ * A plan still named `prereg.json` is parsed by the loose schema of its old name.
72
+ */
73
+ export const plansOf = (dir, r, deps, readable) => new Map((r.kind === "read" ? planRefs(r.registry) : [])
74
+ // A NUL is no path the disk can hold, and probing one throws: such a plan reads as missing. A
75
+ // folder that is a link is never read through.
76
+ .filter(({ key, folder }) => !key.includes("\0") && readable(folder))
77
+ .flatMap(({ key, kind }) => {
78
+ const text = textAt(deps.files, join(dir, REPRO_DIR, key));
79
+ if (text === null)
80
+ return [];
81
+ return [
82
+ [
83
+ key,
84
+ posix.basename(key) === LEGACY_PLAN_FILE
85
+ ? deps.codec.parseLegacyPlan(text)
86
+ : deps.codec.parsePlan(text, kind),
87
+ ],
88
+ ];
89
+ }));
90
+ /** Every finding of the paper folder `dir`'s study registry — THE function behind both rules. */
54
91
  export function studyFindings(dir, deps) {
92
+ const readable = readableFolders(dir, deps);
55
93
  const registry = registryOf(dir, deps);
56
94
  return judgeStudies({
57
95
  folders: studyFolders(dir, deps),
58
96
  registry,
59
97
  readme: textAt(deps.files, join(dir, REPRO_DIR, README)),
60
- existingResults: existingResults(dir, registry, deps.files),
98
+ existingResults: existingResults(dir, registry, deps.files, readable),
99
+ plans: plansOf(dir, registry, deps, readable),
61
100
  });
62
101
  }
63
- /** The problems a finding can be, each its own message id; the text is `studyMessage`. */
102
+ /** The problems `repro/study-registered` reports, each its own message id; the text is `studyMessage`. */
64
103
  const PROBLEMS = [
65
104
  "no-registry",
66
105
  "unreadable",
@@ -75,41 +114,53 @@ const PROBLEMS = [
75
114
  "result-file",
76
115
  "no-successor",
77
116
  "stale-index",
117
+ "unknown-measurement",
118
+ "empty-measurement",
119
+ "unknown-requirement",
120
+ "headline-approval",
121
+ "bad-plan",
122
+ "author-check",
78
123
  ];
79
- const META = {
124
+ /** A rule's meta: its page, and a message id per problem, the whole text being `studyMessage`. */
125
+ const metaOf = (name, description, problems) => ({
80
126
  type: "suggestion",
81
- docs: {
82
- description: "every study folder at the top of a paper's repro/ has exactly one row in repro/studies.json, every row names a folder that exists, and repro/README.md's index is the one the registry generates",
83
- url: rulePageUrl("repro/study-registered"),
84
- },
127
+ docs: { description, url: rulePageUrl(name) },
85
128
  schema: [],
86
- // The whole text is `studyMessage` (src/domain/study-registry.ts).
87
- messages: Object.fromEntries(PROBLEMS.map((p) => [p, "{{text}}"])),
88
- };
89
- /** The rule, reading the folder through `deps`. */
129
+ messages: Object.fromEntries(problems.map((p) => [p, "{{text}}"])),
130
+ });
131
+ /** A rule that reports the findings of `problems`, reading the folder through `deps`. */
132
+ const ruleOf = (meta, problems, deps) => ({
133
+ meta,
134
+ create(context) {
135
+ if (basename(context.filename) !== STATUS_FILE)
136
+ return {};
137
+ return {
138
+ root() {
139
+ const at = context.sourceCode.getLocFromIndex(0);
140
+ studyFindings(dirname(context.filename), deps)
141
+ .filter((f) => problems.includes(f.problem))
142
+ .forEach((f) => {
143
+ context.report({
144
+ loc: { start: at, end: at },
145
+ messageId: f.problem,
146
+ data: { text: studyMessage(f) },
147
+ });
148
+ });
149
+ },
150
+ };
151
+ },
152
+ });
153
+ /**
154
+ * The two rules, reading the folder through `deps`: `study-registered`, the registry's errors, and
155
+ * `study-plan-name`, a warning for a plan still named `prereg.json` — read as the plan, so a paper
156
+ * that wrote one before `plan.json` existed is not broken, and told the name to move to.
157
+ */
90
158
  export function studyRegistryRules(deps) {
91
159
  return {
92
- "study-registered": {
93
- meta: META,
94
- create(context) {
95
- if (basename(context.filename) !== STATUS_FILE)
96
- return {};
97
- return {
98
- root() {
99
- const at = context.sourceCode.getLocFromIndex(0);
100
- studyFindings(dirname(context.filename), deps).forEach((f) => {
101
- context.report({
102
- loc: { start: at, end: at },
103
- messageId: f.problem,
104
- data: { text: studyMessage(f) },
105
- });
106
- });
107
- },
108
- };
109
- },
110
- },
160
+ "study-registered": ruleOf(metaOf("repro/study-registered", "every study folder at the top of a paper's repro/ has exactly one row in repro/studies.json, every row names a folder that exists, its measurement and its plan hold together, and repro/README.md's index is the one the registry generates", PROBLEMS), PROBLEMS, deps),
161
+ "study-plan-name": ruleOf(metaOf("repro/study-plan-name", "a study's plan is named plan.json, not prereg.json", PLAN_NAME_PROBLEMS), PLAN_NAME_PROBLEMS, deps),
111
162
  };
112
163
  }
113
- /** The level it is on at in paperlint's own config, for every paper's `PIPELINE-STATUS.md`. */
114
- export const STUDY_REGISTRY_RULE_LEVELS = { "repro/study-registered": "error" };
164
+ /** The levels they are on at in paperlint's own config, for every paper's `PIPELINE-STATUS.md`. */
165
+ export const STUDY_REGISTRY_RULE_LEVELS = { "repro/study-registered": "error", "repro/study-plan-name": "warn" };
115
166
  //# sourceMappingURL=study-registry-rule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"study-registry-rule.js","sourceRoot":"","sources":["../src/study-registry-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"study-registry-rule.js","sourceRoot":"","sources":["../src/study-registry-rule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** What a `paperlint studies` command on one study comes to: the lines it prints, or its refusal. */
2
+ /** A refusal: the exit code, and the line that explains it. */
3
+ export interface StudyRefusal {
4
+ readonly code: 1 | 2;
5
+ readonly line: string;
6
+ }
7
+ /** What a run came to: the lines it printed, or the refusal. */
8
+ export type StudyRun = {
9
+ readonly ok: true;
10
+ readonly lines: readonly string[];
11
+ } | {
12
+ readonly ok: false;
13
+ readonly refusal: StudyRefusal;
14
+ };
15
+ /** A refusal for the paper's state: exit 1. */
16
+ export declare const refusal: (line: string) => StudyRefusal;
17
+ /** The run that is `r`. */
18
+ export declare const refused: (r: StudyRefusal) => StudyRun;
19
+ //# sourceMappingURL=study-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-run.d.ts","sourceRoot":"","sources":["../src/study-run.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAErG,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,gEAAgE;AAChE,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3D,+CAA+C;AAC/C,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,KAAG,YAAmC,CAAC;AAE3E,2BAA2B;AAC3B,eAAO,MAAM,OAAO,GAAI,GAAG,YAAY,KAAG,QAGxC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** What a `paperlint studies` command on one study comes to: the lines it prints, or its refusal. */
2
+ /** A refusal for the paper's state: exit 1. */
3
+ export const refusal = (line) => ({ code: 1, line });
4
+ /** The run that is `r`. */
5
+ export const refused = (r) => ({
6
+ ok: false,
7
+ refusal: r,
8
+ });
9
+ //# sourceMappingURL=study-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"study-run.js","sourceRoot":"","sources":["../src/study-run.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAarG,+CAA+C;AAC/C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3E,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAe,EAAY,EAAE,CAAC,CAAC;IACrD,EAAE,EAAE,KAAK;IACT,OAAO,EAAE,CAAC;CACX,CAAC,CAAC"}