@tiphys/kernel 0.0.0 → 0.1.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 (181) hide show
  1. package/AGENTS.md +611 -0
  2. package/LICENSE +202 -0
  3. package/assurance-modes.yaml +278 -0
  4. package/checklists/clean-room.yaml +325 -0
  5. package/checklists/env-failure-diagnosis.yaml +68 -0
  6. package/checklists/flake-playbook.yaml +68 -0
  7. package/checklists/hazard-review.yaml +144 -0
  8. package/checklists/plan-review.yaml +103 -0
  9. package/dist/bin/tiphys.d.ts +2 -0
  10. package/dist/bin/tiphys.js +14 -0
  11. package/dist/src/brief.d.ts +32 -0
  12. package/dist/src/brief.js +59 -0
  13. package/dist/src/checklists.d.ts +169 -0
  14. package/dist/src/checklists.js +310 -0
  15. package/dist/src/checks.d.ts +828 -0
  16. package/dist/src/checks.js +3314 -0
  17. package/dist/src/cli.d.ts +9 -0
  18. package/dist/src/cli.js +57 -0
  19. package/dist/src/commands/brief.d.ts +92 -0
  20. package/dist/src/commands/brief.js +320 -0
  21. package/dist/src/commands/checklist.d.ts +42 -0
  22. package/dist/src/commands/checklist.js +168 -0
  23. package/dist/src/commands/doctor.d.ts +35 -0
  24. package/dist/src/commands/doctor.js +605 -0
  25. package/dist/src/commands/gates.d.ts +9 -0
  26. package/dist/src/commands/gates.js +360 -0
  27. package/dist/src/commands/init.d.ts +30 -0
  28. package/dist/src/commands/init.js +128 -0
  29. package/dist/src/commands/lock.d.ts +1 -0
  30. package/dist/src/commands/lock.js +229 -0
  31. package/dist/src/commands/mode.d.ts +40 -0
  32. package/dist/src/commands/mode.js +134 -0
  33. package/dist/src/commands/plan.d.ts +20 -0
  34. package/dist/src/commands/plan.js +105 -0
  35. package/dist/src/commands/pool.d.ts +1 -0
  36. package/dist/src/commands/pool.js +128 -0
  37. package/dist/src/commands/spawn.d.ts +1 -0
  38. package/dist/src/commands/spawn.js +146 -0
  39. package/dist/src/commands/status.d.ts +19 -0
  40. package/dist/src/commands/status.js +120 -0
  41. package/dist/src/commands/teardown.d.ts +1 -0
  42. package/dist/src/commands/teardown.js +79 -0
  43. package/dist/src/commands/tuition.d.ts +21 -0
  44. package/dist/src/commands/tuition.js +218 -0
  45. package/dist/src/commands/validate.d.ts +78 -0
  46. package/dist/src/commands/validate.js +360 -0
  47. package/dist/src/commands/watch.d.ts +1 -0
  48. package/dist/src/commands/watch.js +172 -0
  49. package/dist/src/exec/env.d.ts +128 -0
  50. package/dist/src/exec/env.js +190 -0
  51. package/dist/src/fleet.d.ts +51 -0
  52. package/dist/src/fleet.js +80 -0
  53. package/dist/src/gates/adapters/http-json.d.ts +5 -0
  54. package/dist/src/gates/adapters/http-json.js +283 -0
  55. package/dist/src/gates/adapters/migrations-command.d.ts +1 -0
  56. package/dist/src/gates/adapters/migrations-command.js +373 -0
  57. package/dist/src/gates/citations.d.ts +408 -0
  58. package/dist/src/gates/citations.js +1163 -0
  59. package/dist/src/gates/coverage.d.ts +284 -0
  60. package/dist/src/gates/coverage.js +701 -0
  61. package/dist/src/gates/credentials.d.ts +74 -0
  62. package/dist/src/gates/credentials.js +533 -0
  63. package/dist/src/gates/deploy.d.ts +1 -0
  64. package/dist/src/gates/deploy.js +33 -0
  65. package/dist/src/gates/manifest.d.ts +99 -0
  66. package/dist/src/gates/manifest.js +208 -0
  67. package/dist/src/gates/migrations.d.ts +1 -0
  68. package/dist/src/gates/migrations.js +36 -0
  69. package/dist/src/gates/pin.d.ts +114 -0
  70. package/dist/src/gates/pin.js +154 -0
  71. package/dist/src/gates/red-witness.d.ts +22 -0
  72. package/dist/src/gates/red-witness.js +390 -0
  73. package/dist/src/gates/release.d.ts +283 -0
  74. package/dist/src/gates/release.js +820 -0
  75. package/dist/src/gates/result.d.ts +116 -0
  76. package/dist/src/gates/result.js +91 -0
  77. package/dist/src/gates/run.d.ts +566 -0
  78. package/dist/src/gates/run.js +1536 -0
  79. package/dist/src/gates/schemas/citation-config.schema.json +59 -0
  80. package/dist/src/gates/schemas/coverage-config.schema.json +77 -0
  81. package/dist/src/gates/schemas/gate-manifest.schema.json +125 -0
  82. package/dist/src/gates/schemas/gate-result.schema.json +160 -0
  83. package/dist/src/gates/schemas/phase-declaration.schema.json +42 -0
  84. package/dist/src/gates/schemas/release-record.schema.json +119 -0
  85. package/dist/src/gates/schemas/verifier-config.schema.json +101 -0
  86. package/dist/src/gates/schemas/witness-spec.schema.json +110 -0
  87. package/dist/src/gates/scope.d.ts +131 -0
  88. package/dist/src/gates/scope.js +1018 -0
  89. package/dist/src/gates/suite.d.ts +217 -0
  90. package/dist/src/gates/suite.js +927 -0
  91. package/dist/src/gates/validate.d.ts +121 -0
  92. package/dist/src/gates/validate.js +414 -0
  93. package/dist/src/hooks.d.ts +32 -0
  94. package/dist/src/hooks.js +62 -0
  95. package/dist/src/liveness.d.ts +321 -0
  96. package/dist/src/liveness.js +396 -0
  97. package/dist/src/lock.d.ts +178 -0
  98. package/dist/src/lock.js +500 -0
  99. package/dist/src/modes.d.ts +149 -0
  100. package/dist/src/modes.js +258 -0
  101. package/dist/src/path-identity.d.ts +2 -0
  102. package/dist/src/path-identity.js +10 -0
  103. package/dist/src/plan.d.ts +73 -0
  104. package/dist/src/plan.js +153 -0
  105. package/dist/src/pool.d.ts +130 -0
  106. package/dist/src/pool.js +721 -0
  107. package/dist/src/roles.d.ts +430 -0
  108. package/dist/src/roles.js +734 -0
  109. package/dist/src/spawn.d.ts +177 -0
  110. package/dist/src/spawn.js +332 -0
  111. package/dist/src/status.d.ts +91 -0
  112. package/dist/src/status.js +119 -0
  113. package/dist/src/task.d.ts +264 -0
  114. package/dist/src/task.js +305 -0
  115. package/dist/src/teardown.d.ts +32 -0
  116. package/dist/src/teardown.js +314 -0
  117. package/dist/src/tuition.d.ts +159 -0
  118. package/dist/src/tuition.js +311 -0
  119. package/dist/src/validate.d.ts +230 -0
  120. package/dist/src/validate.js +732 -0
  121. package/dist/src/version.d.ts +3 -0
  122. package/dist/src/version.js +38 -0
  123. package/dist/src/watcher.d.ts +275 -0
  124. package/dist/src/watcher.js +859 -0
  125. package/dist/src/witness/run.d.ts +274 -0
  126. package/dist/src/witness/run.js +1327 -0
  127. package/dist/src/witness/spec.d.ts +102 -0
  128. package/dist/src/witness/spec.js +253 -0
  129. package/dist/tsconfig.src.tsbuildinfo +1 -0
  130. package/gate-registry.yaml +390 -0
  131. package/gates.manifest.json +195 -0
  132. package/package.json +57 -3
  133. package/role-model-config.yaml +88 -0
  134. package/roles/README.md +128 -0
  135. package/roles/_shared-dispatch-contract.md +87 -0
  136. package/roles/adversarial-plan-reviewer.md +80 -0
  137. package/roles/clean-room-reviewer.md +140 -0
  138. package/roles/implementer.md +460 -0
  139. package/roles/investigator.md +138 -0
  140. package/roles/plan-writer.md +95 -0
  141. package/schemas/README.md +81 -0
  142. package/schemas/assurance-modes.schema.json +264 -0
  143. package/schemas/charter.schema.json +166 -0
  144. package/schemas/checklist.schema.json +114 -0
  145. package/schemas/decision-record.schema.json +88 -0
  146. package/schemas/final-report.schema.json +90 -0
  147. package/schemas/finding.schema.json +106 -0
  148. package/schemas/gate-registry.schema.json +260 -0
  149. package/schemas/mechanism-index.schema.json +94 -0
  150. package/schemas/plan.schema.json +300 -0
  151. package/schemas/report.schema.json +579 -0
  152. package/schemas/role-brief.schema.json +105 -0
  153. package/schemas/role-model-config.schema.json +90 -0
  154. package/schemas/status-line.schema.json +40 -0
  155. package/schemas/tuition.schema.json +191 -0
  156. package/schemas/verdict.schema.json +289 -0
  157. package/schemas/work-history.schema.json +183 -0
  158. package/templates/charter.example.yaml +54 -0
  159. package/templates/decision-record.example.yaml +27 -0
  160. package/templates/final-report.example.yaml +80 -0
  161. package/templates/plan.example.yaml +87 -0
  162. package/templates/report.example.yaml +236 -0
  163. package/templates/warnings.md +74 -0
  164. package/templates/work-history.example.yaml +185 -0
  165. package/tuition/README.md +76 -0
  166. package/tuition/T-001.yaml +48 -0
  167. package/tuition/T-002.yaml +51 -0
  168. package/tuition/T-003.yaml +100 -0
  169. package/tuition/T-004.yaml +52 -0
  170. package/tuition/T-005.yaml +72 -0
  171. package/tuition/T-006.yaml +81 -0
  172. package/tuition/T-007.yaml +56 -0
  173. package/tuition/T-008.yaml +111 -0
  174. package/tuition/T-009.yaml +50 -0
  175. package/tuition/T-015.yaml +36 -0
  176. package/tuition/T-016.yaml +36 -0
  177. package/tuition/T-017.yaml +46 -0
  178. package/tuition/T-018.yaml +84 -0
  179. package/tuition/T-021.yaml +40 -0
  180. package/tuition/T-022.yaml +36 -0
  181. package/tuition/mechanism-index.yaml +256 -0
@@ -0,0 +1,103 @@
1
+ # THE ADVERSARIAL PLAN-REVIEW CHECKLIST (kernel plan M3, M3-P7 step 2).
2
+ #
3
+ # Run against a PLAN, before any of it is dispatched. The three canonical
4
+ # probes are R-026b, R-027 and R-028a, and each one is written to be
5
+ # unanswerable without opening something: R-027 carries the process document's
6
+ # own zero-amount-rows illustration, and R-028a names the artifact that counts
7
+ # as proof so a testability claim cannot be admired instead of tested.
8
+ kind: checklist
9
+ id: plan-review
10
+ applies-to: >-
11
+ a plan document before dispatch, read adversarially: the reviewer is looking
12
+ for the phase that cannot be built as written, not for reasons to approve.
13
+
14
+ probes:
15
+ # R-026b. Hidden dependencies and semantic coupling ABOVE the file-overlap
16
+ # floor. File overlap is what the M5 pre-pass computes mechanically; this
17
+ # probe is the part no pre-pass reaches.
18
+ - id: hidden-dependency-above-file-overlap
19
+ probe: >-
20
+ Which phases share MEANING rather than files? Two phases with disjoint
21
+ file lists still collide when one renames a key the other reads, changes
22
+ a value's vocabulary, moves an ordering another relies on, or changes
23
+ what a shared registry row means. The file-overlap pre-pass computes the
24
+ floor and cannot see any of those. Name each pair you found, the shared
25
+ concept, and the phase whose assumption breaks; then name the pairs you
26
+ examined and cleared, because a list of collisions with no stated scope
27
+ is indistinguishable from a search that looked in the wrong place.
28
+ applies-to: plan-structure
29
+ evidence-required: true
30
+
31
+ - id: grounding-names-a-real-artifact
32
+ probe: >-
33
+ Does each phase's `grounding` name artifacts that will EXIST when it
34
+ starts, and does its `blocked-by` follow from that rather than from
35
+ habit? A `blocked-by` naming a phase whose artifacts the grounding never
36
+ mentions is an ordering habit serialising work that could run in
37
+ parallel; the reverse, a grounding consuming a phase the `blocked-by`
38
+ does not name, is a phase that will be dispatched before its inputs
39
+ exist. Check both directions per phase and say which you found.
40
+ applies-to: plan-structure
41
+ evidence-required: true
42
+
43
+ # R-027. Probe every fix shape for THE STATE THAT CAN NO LONGER EXIT, with
44
+ # the process document's own illustration carried in the probe text so the
45
+ # question cannot be answered from the phrase alone.
46
+ - id: fix-shape-state-that-cannot-exit
47
+ probe: >-
48
+ For every fix this plan proposes, what state does it create that can no
49
+ longer be exited? The process document's own illustration: a repair that
50
+ writes rows with a ZERO amount leaves records that are structurally
51
+ valid, that every later query counts, and that no reconciliation can
52
+ distinguish from real ones, so the system can enter that state and never
53
+ leave it. Walk each fix and name the state, the transition INTO it, and
54
+ the transition OUT of it. A fix with no stated exit is the finding.
55
+ applies-to: fix-shapes
56
+ evidence-required: true
57
+
58
+ - id: fix-shape-partial-application
59
+ probe: >-
60
+ What does each fix leave behind if it is interrupted halfway? Name the
61
+ point of no return in each one, and whether re-running it from the start
62
+ is safe. A fix that is only correct when it completes is a fix that has
63
+ not been designed for the case it exists to handle.
64
+ applies-to: fix-shapes
65
+ evidence-required: true
66
+
67
+ # R-028a. TEST THE TESTABILITY CLAIMS. The accepted evidence is the M2-P2
68
+ # red-witness harness's own evidence file, not the plan's assertion that
69
+ # something is testable.
70
+ - id: testability-claim-tested
71
+ probe: >-
72
+ For every claim in this plan that something is testable, guarded or
73
+ witnessed, what is the accepted proof? The harness's captured evidence
74
+ file (`witness-records.json`, whose per-member `runs[].exitCode` and
75
+ `failedNamedTests` record what actually ran) is the proof; the plan's
76
+ own sentence is not. Where no such file can exist yet because the
77
+ behaviour is not built, say so in those words and mark the claim as
78
+ owed, rather than letting an untested assertion pass as a tested one.
79
+ applies-to: testability
80
+ evidence-required: true
81
+
82
+ - id: acceptance-criterion-is-falsifiable
83
+ probe: >-
84
+ Is each acceptance criterion FALSIFIABLE? "Works correctly" is banned;
85
+ the register is a command, its exit code and a count ("node --test exits
86
+ 0 and reports N tests, N greater than zero"). Quote every criterion that
87
+ names no command, no observable output and no count, and propose the
88
+ falsifiable form. A criterion nobody can fail is a criterion nobody has
89
+ to meet.
90
+ applies-to: testability
91
+ evidence-required: true
92
+
93
+ - id: hazard-class-is-not-the-criteria-reworded
94
+ probe: >-
95
+ Does each phase's declared hazard class name something its own
96
+ acceptance criteria CANNOT reach? T-007 records a phase meeting fifteen
97
+ of fifteen executed criteria while live-locking every supervision
98
+ command. A hazard class that is the criteria list reworded reproduces
99
+ that failure while appearing to fix it. For each class, name the
100
+ criterion that reaches it or state that none does and name the
101
+ instrument that does.
102
+ applies-to: plan-structure
103
+ evidence-required: true
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { EX_USAGE, run } from "../src/cli.js";
3
+ function singleLine(text) {
4
+ return text.replace(/\s+/g, " ").trim();
5
+ }
6
+ try {
7
+ process.exitCode = await run(process.argv.slice(2));
8
+ }
9
+ catch (error) {
10
+ const usage = error?.usage === true;
11
+ const message = error instanceof Error ? error.message : String(error);
12
+ process.stderr.write(`tiphys: ${singleLine(message)}\n`);
13
+ process.exitCode = usage ? EX_USAGE : 1;
14
+ }
@@ -0,0 +1,32 @@
1
+ import type { Fleet } from "./fleet.ts";
2
+ /**
3
+ * Brief assembly (kernel plan v1, M1-P4 step 2; R-033b, R-083b).
4
+ *
5
+ * The brief for a task is written once, at spawn, to tasks/<id>/brief.md:
6
+ * the operator's brief file verbatim, followed by the fleet's
7
+ * environment-warnings file verbatim when the fleet has one. The
8
+ * warnings file is <fleet>/warnings.md (fleet root, tracked content, not
9
+ * the ignored state/ area). When no warnings file exists, brief.md is
10
+ * byte-identical to the brief file.
11
+ *
12
+ * Verbatim means verbatim: no heading, no banner, no rewriting. A brief
13
+ * is the durable instruction an implementer is judged against, and a
14
+ * kernel that edits it makes the audit trail lie. The only byte this
15
+ * module may add is a single newline between the two documents when the
16
+ * brief does not already end in one.
17
+ */
18
+ /** The fleet's environment-warnings file, appended to every brief. */
19
+ export declare const WARNINGS_FILE = "warnings.md";
20
+ export declare function warningsPath(fleet: Fleet): string;
21
+ export type BriefResult = {
22
+ ok: true;
23
+ value: string;
24
+ } | {
25
+ ok: false;
26
+ reason: string;
27
+ };
28
+ /**
29
+ * Assemble tasks/<id>/brief.md from briefFile. Returns the written path.
30
+ * The task directory must already exist.
31
+ */
32
+ export declare function assembleBrief(fleet: Fleet, taskId: string, briefFile: string): BriefResult;
@@ -0,0 +1,59 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { briefPath } from "./task.js";
4
+ /**
5
+ * Brief assembly (kernel plan v1, M1-P4 step 2; R-033b, R-083b).
6
+ *
7
+ * The brief for a task is written once, at spawn, to tasks/<id>/brief.md:
8
+ * the operator's brief file verbatim, followed by the fleet's
9
+ * environment-warnings file verbatim when the fleet has one. The
10
+ * warnings file is <fleet>/warnings.md (fleet root, tracked content, not
11
+ * the ignored state/ area). When no warnings file exists, brief.md is
12
+ * byte-identical to the brief file.
13
+ *
14
+ * Verbatim means verbatim: no heading, no banner, no rewriting. A brief
15
+ * is the durable instruction an implementer is judged against, and a
16
+ * kernel that edits it makes the audit trail lie. The only byte this
17
+ * module may add is a single newline between the two documents when the
18
+ * brief does not already end in one.
19
+ */
20
+ /** The fleet's environment-warnings file, appended to every brief. */
21
+ export const WARNINGS_FILE = "warnings.md";
22
+ export function warningsPath(fleet) {
23
+ return join(fleet.root, WARNINGS_FILE);
24
+ }
25
+ /**
26
+ * Assemble tasks/<id>/brief.md from briefFile. Returns the written path.
27
+ * The task directory must already exist.
28
+ */
29
+ export function assembleBrief(fleet, taskId, briefFile) {
30
+ let brief;
31
+ try {
32
+ brief = readFileSync(briefFile, "utf8");
33
+ }
34
+ catch (error) {
35
+ return {
36
+ ok: false,
37
+ reason: `cannot read brief file ${briefFile}: ${error.message}`,
38
+ };
39
+ }
40
+ let content = brief;
41
+ const warnings = warningsPath(fleet);
42
+ if (existsSync(warnings)) {
43
+ let warningsText;
44
+ try {
45
+ warningsText = readFileSync(warnings, "utf8");
46
+ }
47
+ catch (error) {
48
+ return {
49
+ ok: false,
50
+ reason: `cannot read fleet warnings file ${warnings}: ${error.message}`,
51
+ };
52
+ }
53
+ const separator = content === "" || content.endsWith("\n") ? "" : "\n";
54
+ content = `${content}${separator}${warningsText}`;
55
+ }
56
+ const target = briefPath(fleet, taskId);
57
+ writeFileSync(target, content);
58
+ return { ok: true, value: target };
59
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * READING AND RESOLVING REVIEW CHECKLISTS (kernel plan M3, M3-P7 steps 2 to
3
+ * 5; R-054, T-001).
4
+ *
5
+ * `checklists/` ships at the package root beside `gate-registry.yaml`,
6
+ * `assurance-modes.yaml` and `schemas/`. This module locates it, decodes a
7
+ * checklist, merges a per-phase extra probe file into it, and orders the
8
+ * result under a declared framing. It answers one question: WHICH PROBES, IN
9
+ * WHICH ORDER, does this reviewer answer.
10
+ *
11
+ * NO VALIDATION HAPPENS HERE, deliberately, and this is the same split
12
+ * `src/modes.ts` documents: `tiphys validate --type checklist` decides whether
13
+ * a document is well formed, and duplicating its rules in a reader would
14
+ * produce a second opinion to keep in sync. The COMMAND validates before it
15
+ * serves (`src/commands/checklist.ts`), which is where the M3-P3 fix round put
16
+ * that duty after shipping a reader that printed without checking.
17
+ *
18
+ * THE MERGE FAILURES ARE FAILURES HERE AND NOT WARNINGS. An extra file
19
+ * reusing a canonical probe id is a COLLISION and names both sources; an
20
+ * extra probe missing `evidence-required` is a refusal; and, added in fix
21
+ * round 2, an extra file DECLARING A FRAMING is a refusal, because framings
22
+ * are read from the canonical checklist only and the entry point was
23
+ * previously dropped without a word. Last-wins and silent-drop are the same
24
+ * dangerous state seen from two sides: the phase's own hazard class names "an
25
+ * extra-probe merge that silently overrides a canonical probe instead of
26
+ * colliding", and a silent anything is how a per-phase file quietly diverges
27
+ * from the standing checklist.
28
+ *
29
+ * ORDERING IS BY SCOPE AND FILE POSITION, NEVER BY PROBE ID. A framing names
30
+ * `applies-to` scopes; probes in a named scope lead, scope by scope, and
31
+ * inside one scope the FILE ORDER decides. That is what makes CLAUDE.md's
32
+ * "the reviewer's FIRST check is item 3" falsifiable: move the probe later in
33
+ * the file and the resolved head changes. A framing that named probe ids
34
+ * would pin the head wherever the probe sat, which is the hazard class's
35
+ * "ordering expressed as a comment rather than as position" one level up.
36
+ */
37
+ /** The shipped directory's basename, at the package root. */
38
+ export declare const CHECKLISTS_DIRNAME = "checklists";
39
+ /** One probe as the document declares it. */
40
+ export interface Probe {
41
+ id: string;
42
+ probe: string;
43
+ appliesTo: string;
44
+ evidenceRequired: boolean;
45
+ verifiesGate?: string;
46
+ /** Where this probe came from, for the collision message. */
47
+ source: string;
48
+ }
49
+ /** One declared entry point into the same probe list. */
50
+ export interface Framing {
51
+ id: string;
52
+ entryPoint: string;
53
+ ordersProbes: string[];
54
+ }
55
+ export interface Checklist {
56
+ id: string;
57
+ appliesTo: string;
58
+ probes: Probe[];
59
+ framings: Framing[];
60
+ /** The decoded document, for the validator to see unaltered. */
61
+ raw: unknown;
62
+ /** The file this was read from. */
63
+ path: string;
64
+ }
65
+ type Read<T> = {
66
+ ok: true;
67
+ value: T;
68
+ } | {
69
+ ok: false;
70
+ reason: string;
71
+ };
72
+ /** The shipped `checklists/` directory, found by walking up from this module. */
73
+ export declare function checklistsDirectory(): string;
74
+ /** Every checklist id the shipped directory declares, by filename, sorted. */
75
+ export declare function shippedChecklistIds(): string[];
76
+ /**
77
+ * Project a decoded checklist document into the shape the resolver uses.
78
+ *
79
+ * FIELDS ABSENT FROM THE DOCUMENT STAY ABSENT rather than becoming defaults,
80
+ * with one exception stated here so it is not a surprise: `evidence-required`
81
+ * is projected as `false` when it is absent, and the CALLER is what refuses
82
+ * such a probe. Defaulting it to `true` would let a probe missing the field
83
+ * merge in as though it carried the stronger obligation, which is R-054's
84
+ * second named failure passing silently.
85
+ */
86
+ export declare function projectChecklist(document: unknown, path: string, source: string): Read<Checklist>;
87
+ /**
88
+ * Read a checklist document from an explicit path.
89
+ *
90
+ * The path is OPERATOR-SUPPLIED (D-M3-27), so it is classified before it is
91
+ * opened rather than opened and hoped about: a named pipe at `--extra` is a
92
+ * reported refusal, never a command that blocks forever.
93
+ */
94
+ export declare function readChecklistFile(path: string, source: string): Read<Checklist>;
95
+ /** Read a shipped checklist by id, or say which ids exist. */
96
+ export declare function readShippedChecklist(id: string): Read<Checklist>;
97
+ export interface MergeProblem {
98
+ /** The probe id at fault. */
99
+ probe: string;
100
+ reason: string;
101
+ }
102
+ /**
103
+ * Merge an extra probe file into a canonical checklist.
104
+ *
105
+ * BOTH FAILURES ARE COLLECTED RATHER THAN THROWN AT THE FIRST, so an author
106
+ * fixing an extra file sees every problem in one run instead of one per
107
+ * invocation.
108
+ */
109
+ export declare function mergeExtraProbes(canonical: Checklist, extra: Checklist): {
110
+ probes: Probe[];
111
+ problems: MergeProblem[];
112
+ };
113
+ /**
114
+ * An extra file may not declare a framing, and saying so is a REFUSAL.
115
+ *
116
+ * M3-P7 FIX ROUND 2, H-2 MEMBER 2. `resolveChecklist` reads
117
+ * `request.checklist.framings` and only that, so a framing declared in an
118
+ * `--extra` file was neither merged nor mentioned: the run exited 0 with an
119
+ * empty stderr and the author's entry point was gone. That is a SILENT NO-OP
120
+ * on R-054's own use case, and the extra file validates as a full checklist
121
+ * document, so declaring a framing in one is the natural thing to try.
122
+ *
123
+ * BOTH SHAPES ARE REFUSED, colliding and not, because the mechanism is the
124
+ * same one: the extra document's framings are never read. Refusing only the
125
+ * COLLIDING one would fix the instance the review constructed and leave the
126
+ * mechanism, which is exactly the fix-round failure CLAUDE.md's contract
127
+ * exists against. The two get different messages because the consequences
128
+ * differ: a collision is also the shape that would let a per-phase file
129
+ * shadow a standing entry point if the merge were ever added, and the
130
+ * message says which document wins today.
131
+ *
132
+ * IT IS A REFUSAL RATHER THAN A MERGE. Merging extra framings would be a new
133
+ * capability, and nothing asks for one; what was wrong was the silence.
134
+ * Nothing depends on the old behaviour: `framings` is not in the checklist
135
+ * schema's `required`, so an extra file that declares none is unaffected.
136
+ */
137
+ export declare function extraFramingRefusals(canonical: Checklist, extra: Checklist): string[];
138
+ /**
139
+ * Order probes under a framing.
140
+ *
141
+ * Probes whose `applies-to` scope is named by the framing come first, scope
142
+ * by scope in the framing's order, and inside a scope in FILE ORDER. Every
143
+ * probe in no named scope follows, also in file order. NOTHING IS DROPPED: a
144
+ * framing changes what a reviewer reads first and never what they read at
145
+ * all, because a framing that filtered would let an entry point silently
146
+ * retire a probe.
147
+ */
148
+ export declare function orderUnderFraming(probes: readonly Probe[], framing: Framing): Probe[];
149
+ export interface ResolveRequest {
150
+ checklist: Checklist;
151
+ extra?: Checklist;
152
+ framingId?: string;
153
+ }
154
+ export interface Resolution {
155
+ probes: Probe[];
156
+ framing?: Framing;
157
+ }
158
+ export type ResolveOutcome = {
159
+ ok: true;
160
+ value: Resolution;
161
+ } | {
162
+ ok: false;
163
+ reasons: string[];
164
+ };
165
+ /** Merge, then order. The two failures above and an unknown framing are refusals. */
166
+ export declare function resolveChecklist(request: ResolveRequest): ResolveOutcome;
167
+ /** The resolved list as lines, the framing's entry point at the head. */
168
+ export declare function renderResolution(checklist: Checklist, resolution: Resolution): string[];
169
+ export {};