@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,260 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://tiphys.dev/schemas/gate-registry.schema.json",
4
+ "title": "Tiphys canonical gate registry",
5
+ "$comment": "R-094: the canonical list of gates per assurance mode, intended as the single source consumed by CI and by the role briefs. As delivered by M3-P2 the BRIEFS half is real (CLAUDE.md's gate section is rendered from the registry) and the CI half is not (CI invokes the runner with --manifest gates.manifest.json); gate-registry.yaml's own header states the divergence and test/gate-registry.test.ts asserts it in both directions. Kernel plan M3, M3-P2 step 2. A SUPERSET of the M2-P1 gate manifest (src/gates/schemas/gate-manifest.schema.json): every field that schema defines is defined here with the same meaning, and this document adds four, `modes` (made live from the field M2 reserved), `events`, `verified-by` and `probe`, plus the top-level `preflight` list. SC-011 is carried over unchanged: a gate whose precondition is unmet reports not-applicable and NEVER green.",
6
+ "description": "One registry per repository. Which gates exist, how each is invoked, which assurance modes select it, which CI events evaluate it, whether a script or a clean-room checklist probe verifies it, and which commands can destroy work.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": ["kind", "version", "preflight", "gates", "destructiveCommands"],
10
+ "properties": {
11
+ "kind": {
12
+ "description": "The artifact type, so `tiphys validate --type auto` resolves this document without being told. Every M3-P1 artifact type carries one and this mirrors them.",
13
+ "type": "string",
14
+ "const": "gate-registry"
15
+ },
16
+ "note": {
17
+ "description": "Free prose for the registry's own readers.",
18
+ "type": "string"
19
+ },
20
+ "version": {
21
+ "$comment": "A closed set rather than a minimum, because the authoring vocabulary of schemas/README.md has no `minimum` keyword and a bare `type: integer` would admit 0 and negatives.",
22
+ "type": "integer",
23
+ "enum": [1]
24
+ },
25
+ "preflight": {
26
+ "$comment": "R-094. The ordered local commands every change must pass before any registry gate means anything. They live IN the registry rather than beside it because CLAUDE.md's gate section is rendered from this document IN FULL (M3-P2 criterion 6, scripts/render-agent-rules-gates.mjs), and a step left outside the registry would be exactly the hand-maintained gate list criterion 6 forbids.",
27
+ "type": "array",
28
+ "minItems": 1,
29
+ "items": {
30
+ "$ref": "#/$defs/preflightStep"
31
+ }
32
+ },
33
+ "gates": {
34
+ "description": "Append-only registry keyed by id. No minItems, matching the M2 manifest: a registry with zero gates must reach the runner and be reported as no applicable gate, not rejected at load.",
35
+ "type": "array",
36
+ "items": {
37
+ "$ref": "#/$defs/gate"
38
+ }
39
+ },
40
+ "destructiveCommands": {
41
+ "description": "CLI commands and module paths whose operations can destroy work. Carried over from the M2 manifest unchanged; M2-P2 rule (e) DERIVES a witness class from it rather than trusting an implementer's declaration.",
42
+ "type": "array",
43
+ "items": {
44
+ "type": "string"
45
+ }
46
+ }
47
+ },
48
+ "$defs": {
49
+ "commandArray": {
50
+ "description": "argv array. The runner appends --result and --evidence, plus one flag per declared parameter. Defined once in $defs because strict mode requires every `required` name to be declared in `properties` at the SAME level, so the conditional rules below must restate it and a second copy of the constraint would be a second thing to keep in sync.",
51
+ "type": "array",
52
+ "minItems": 1,
53
+ "items": {
54
+ "type": "string"
55
+ }
56
+ },
57
+ "probeId": {
58
+ "description": "The checklist probe id M3-P7 must supply. Required exactly when verified-by is clean-room-checklist.",
59
+ "type": "string",
60
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
61
+ },
62
+ "preflightStep": {
63
+ "type": "object",
64
+ "additionalProperties": false,
65
+ "required": ["command", "note"],
66
+ "properties": {
67
+ "command": {
68
+ "description": "argv array, run in the repository root.",
69
+ "type": "array",
70
+ "minItems": 1,
71
+ "items": {
72
+ "type": "string"
73
+ }
74
+ },
75
+ "note": {
76
+ "type": "string",
77
+ "minLength": 1
78
+ }
79
+ }
80
+ },
81
+ "gate": {
82
+ "$comment": "THREE conditional rules, chained through $ref rather than stacked in one object, because JSON Schema allows one `if`/`then` pair per schema object and `allOf` is outside the authoring vocabulary of schemas/README.md. Each link adds exactly one rule and each rule has its own acceptance criterion. This link: M3-P2 criterion 4. A gate declared `conditional` is one that MAY report not-applicable, and SC-011 says not-applicable ASSERTS an evaluated, unmet precondition; a conditional gate with no precondition can therefore report not-applicable with nothing evaluated, which is the vacuous pass this registry exists to make impossible. `deploy` and `migrations` are the two conditional entries this rule binds.",
83
+ "$ref": "#/$defs/gateProbeRule",
84
+ "if": {
85
+ "type": "object",
86
+ "required": ["applicability"],
87
+ "properties": {
88
+ "applicability": {
89
+ "const": "conditional"
90
+ }
91
+ }
92
+ },
93
+ "then": {
94
+ "type": "object",
95
+ "required": ["precondition"],
96
+ "properties": {
97
+ "precondition": {
98
+ "$ref": "#/$defs/precondition"
99
+ }
100
+ }
101
+ }
102
+ },
103
+ "gateProbeRule": {
104
+ "$comment": "M3-P2 criterion 2. A clean-room-checklist entry with no probe names no question, so nothing can ever verify it and the entry is a gate id with nothing behind it. D-11 settles that R-043 and R-044 are verified this way.",
105
+ "$ref": "#/$defs/gateCommandRule",
106
+ "if": {
107
+ "type": "object",
108
+ "required": ["verified-by"],
109
+ "properties": {
110
+ "verified-by": {
111
+ "const": "clean-room-checklist"
112
+ }
113
+ }
114
+ },
115
+ "then": {
116
+ "type": "object",
117
+ "required": ["probe"],
118
+ "properties": {
119
+ "probe": {
120
+ "$ref": "#/$defs/probeId"
121
+ }
122
+ }
123
+ }
124
+ },
125
+ "gateCommandRule": {
126
+ "$comment": "A `script` gate is verified by running a process, so it must say which one. A `clean-room-checklist` gate has no process and carries no command, which is why `command` is not in the base required list.",
127
+ "$ref": "#/$defs/gateShape",
128
+ "if": {
129
+ "type": "object",
130
+ "required": ["verified-by"],
131
+ "properties": {
132
+ "verified-by": {
133
+ "const": "script"
134
+ }
135
+ }
136
+ },
137
+ "then": {
138
+ "type": "object",
139
+ "required": ["command"],
140
+ "properties": {
141
+ "command": {
142
+ "$ref": "#/$defs/commandArray"
143
+ }
144
+ }
145
+ }
146
+ },
147
+ "gateShape": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "required": ["id", "unitLabel", "applicability", "verified-by", "modes", "events"],
151
+ "properties": {
152
+ "$comment": {
153
+ "description": "Clause ids this entry discharges, per schemas/README.md.",
154
+ "type": "string"
155
+ },
156
+ "id": {
157
+ "type": "string",
158
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
159
+ },
160
+ "command": {
161
+ "$ref": "#/$defs/commandArray"
162
+ },
163
+ "unitLabel": {
164
+ "type": "string",
165
+ "minLength": 1
166
+ },
167
+ "applicability": {
168
+ "description": "required: an unmet precondition fails the run. conditional: an unmet precondition does not.",
169
+ "type": "string",
170
+ "enum": ["required", "conditional"]
171
+ },
172
+ "verified-by": {
173
+ "$comment": "D-11. R-043 and R-044 are not reliably computable from a diff, so their gate is a clean-room checklist probe rather than a script, and the registry SAYS which of the two a reader is looking at instead of leaving it to be inferred from whether a command happens to be present.",
174
+ "type": "string",
175
+ "enum": ["script", "clean-room-checklist"]
176
+ },
177
+ "probe": {
178
+ "$ref": "#/$defs/probeId"
179
+ },
180
+ "modes": {
181
+ "$comment": "The field the M2 manifest schema RESERVED (src/gates/schemas/gate-manifest.schema.json line 70, validated if present and ignored by the M2 runner), made LIVE here. Blueprint section 5: the canonical list of gates PER ASSURANCE MODE. The item enum is the three mode ids M3-P3 defines.",
182
+ "type": "array",
183
+ "minItems": 1,
184
+ "uniqueItems": true,
185
+ "items": {
186
+ "type": "string",
187
+ "enum": ["full", "direct-pr", "local-only"]
188
+ }
189
+ },
190
+ "events": {
191
+ "$comment": "T-009, D-M3-34. A gate result is evidence only for the configuration that produced it, and this repository's workflow runs DIFFERENT bundles on `pull_request` and on `push` to `main`. An entry that does not say which events evaluate it carries a claim nobody can check. For every entry PROMOTED from gates.manifest.json the value is derived from the two bundle definitions in scripts/m2-exit-test.sh and never assigned by judgment; for an entry that is not in that manifest it is derived from whatever mechanism does evaluate it, which for agent-rules-drift is a workflow step carrying no `if:`. Both derivations are asserted in test/gate-registry.test.ts.",
192
+ "type": "array",
193
+ "minItems": 1,
194
+ "uniqueItems": true,
195
+ "items": {
196
+ "type": "string",
197
+ "enum": ["pull_request", "push"]
198
+ }
199
+ },
200
+ "parameters": {
201
+ "description": "Run parameters this gate's command REQUIRES. Declared rather than inferred. An absent declared parameter makes the gate error, never not-applicable (M2-C-3).",
202
+ "type": "array",
203
+ "items": {
204
+ "type": "string",
205
+ "enum": ["base", "head", "phase"]
206
+ }
207
+ },
208
+ "precondition": {
209
+ "$ref": "#/$defs/precondition"
210
+ }
211
+ }
212
+ },
213
+ "precondition": {
214
+ "$comment": "SC-011, carried over from the M2-P1 manifest schema UNCHANGED, field for field. A gate whose precondition is unmet reports not-applicable and never green; not-applicable ASSERTS that a precondition was evaluated and found unmet.",
215
+ "type": "object",
216
+ "additionalProperties": false,
217
+ "required": ["id", "kind"],
218
+ "properties": {
219
+ "id": {
220
+ "type": "string"
221
+ },
222
+ "kind": {
223
+ "description": "The closed set. Kind-specific required fields are checked by src/gates/manifest.ts, which emits the same INVALID <pointer> <message> diagnostics.",
224
+ "type": "string",
225
+ "enum": [
226
+ "file-exists",
227
+ "file-absent",
228
+ "branch-matches",
229
+ "diff-touches",
230
+ "command-exit-zero"
231
+ ]
232
+ },
233
+ "path": {
234
+ "description": "file-exists and file-absent.",
235
+ "type": "string"
236
+ },
237
+ "pattern": {
238
+ "description": "branch-matches. A JavaScript regular expression source that is ANCHORED: it is compiled as ^(?:<pattern>)$ and must match the WHOLE branch name. The token {phase} is replaced by the --phase value, REGEX-ESCAPED.",
239
+ "type": "string"
240
+ },
241
+ "paths": {
242
+ "description": "diff-touches. Path prefixes; the precondition is met when the diff changes a path under any of them.",
243
+ "type": "array",
244
+ "minItems": 1,
245
+ "items": {
246
+ "type": "string"
247
+ }
248
+ },
249
+ "command": {
250
+ "description": "command-exit-zero. argv array, run in the runner's working directory.",
251
+ "type": "array",
252
+ "minItems": 1,
253
+ "items": {
254
+ "type": "string"
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
@@ -0,0 +1,94 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://tiphys.dev/schemas/mechanism-index.schema.json",
4
+ "title": "Tiphys mechanism index",
5
+ "$comment": "Kernel plan M3, M3-P6 criterion 8 and D-M3-23. T-005's structural consequence: a rule M1-P3 paid for in a multi-hour investigation did not reach M1-P5, which reimplemented the same claim-file mechanism silently and produced the most severe defect found in M1. The implementer there had read the plan, the agent-rules file, the constraint list, the environment warnings and three work histories, and NONE of them carried the rule, because a rule about a MECHANISM has no home in a document organised by phase. This document is that home. THE SCHEMA SHIPS HERE AND THE GENERATOR SHIPS AT M3-P8, which is the only forward reference in M3-P6 and is why D-M3-23 exists: M3-P8 EDITS this document to add `machine-readable-form` and does not create it. WHAT THIS SCHEMA CANNOT DO. It cannot tell a rule from a platitude: `rule` is a string, and whether its text is something an implementer can obey or a sentiment they can agree with is judgment. It cannot check that `evidence[]` resolves; entries are prose citations of artifacts that may live in delivery/, which the kernel does not ship, so resolution is not computable from an installed package. And it cannot tell whether the index is COMPLETE, which is the property M3-P6's registered superset test and M3-P8 criterion 4c cover from the two ends.",
6
+ "description": "One document per project. Every mechanism this project has already learned something about, the rule that learning established, the sibling implementations that share the mechanism, and the artifacts that paid for it. Read the row before you use the mechanism.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": ["kind", "version", "mechanisms"],
10
+ "properties": {
11
+ "kind": {
12
+ "type": "string",
13
+ "const": "mechanism-index"
14
+ },
15
+ "version": {
16
+ "$comment": "Document format version, not a project version. A closed set rather than a minimum, for the reason schemas/gate-registry.schema.json:21 already records: the authoring vocabulary has no `minimum` keyword, so a bare `type: integer` would admit 0 and negatives.",
17
+ "type": "integer",
18
+ "enum": [1]
19
+ },
20
+ "supersedes": {
21
+ "$comment": "The interim artifact this index replaces, by path, when there is one. Carried so a reader of the index can find what it was converted FROM, and so M3-P8's generated projection can be checked against the same source rather than against a memory of it. Optional: a project with no interim file omits it.",
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "pattern": "\\S"
25
+ },
26
+ "mechanisms": {
27
+ "$comment": "minItems 1, because an index with no mechanisms is a file that satisfies every lookup obligation by having nothing to look up. That is the third row of M3-P6's own hazard table ('the index it names is the stub nobody replaced'), and the schema closes the degenerate end of it; the other end is the registered superset test, which no schema can express.",
28
+ "type": "array",
29
+ "minItems": 1,
30
+ "items": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["key", "name", "rule", "evidence"],
34
+ "properties": {
35
+ "key": {
36
+ "$comment": "The stable id, and the thing a citation elsewhere names. DERIVED FROM `name` rather than invented: lowercase, every run of characters outside [a-z0-9] replaced by a single hyphen, leading and trailing hyphens removed. M3-P6's registered test applies that derivation to `name` and compares, so a key that drifts from its name is red rather than merely odd. Ids are never renumbered and a retired key is never reused, which is the rule CLAUDE.md's identifier-schemes section states for every scheme in this project.",
37
+ "type": "string",
38
+ "minLength": 1,
39
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
40
+ },
41
+ "name": {
42
+ "$comment": "The mechanism in the words a reader would search for. For a row converted from an interim index, this is the interim table's own first column VERBATIM, which is what makes the conversion checkable against the file it came from instead of against a paraphrase of it.",
43
+ "type": "string",
44
+ "minLength": 1,
45
+ "pattern": "\\S"
46
+ },
47
+ "rule": {
48
+ "$comment": "What this project learned, stated as something to DO or NOT DO. Not a description of the mechanism: an implementer who reads this row and changes nothing has read a description, and the row has failed.",
49
+ "type": "string",
50
+ "minLength": 1,
51
+ "pattern": "\\S"
52
+ },
53
+ "siblings": {
54
+ "$comment": "The other implementations that share this mechanism, by path. The `mechanism-sibling` clause in roles/implementer.md is the instruction that keeps this list current: a phase establishing a rule about a mechanism records it here AND names the siblings, because the recorded cost of not doing so is one silent reimplementation two phases later. Optional, and an EMPTY list is meaningful: it says the mechanism has exactly one implementation today.",
55
+ "type": "array",
56
+ "items": {
57
+ "type": "string",
58
+ "minLength": 1,
59
+ "pattern": "\\S"
60
+ }
61
+ },
62
+ "machine-readable-form": {
63
+ "$comment": "ADDED BY M3-P8 (D-M3-23's forward reference, step 2). Where the SAME rule exists as data: a path plus the key inside it. The `destructive-git-operation` row is the worked example and the reason the field exists: its prose rule and the `destructiveCommands` list in `gates.manifest.json` are two views of one thing (M2 plan section 2 item 10), and a citation is what stops them drifting apart silently. PROJECTED, NEVER AUTHORED HERE: this document is generated from the tuition feed's `mechanisms[]` by `tiphys tuition index`, so the field is written in the entry that established the rule. The derived check mechanism-rule-evidence-resolves resolves both halves against the real document, so a key M2 renames reddens rather than rotting. Optional: most rules exist only as prose, which is a fact about the rule and not a defect.",
64
+ "type": "object",
65
+ "additionalProperties": false,
66
+ "required": ["path", "key"],
67
+ "properties": {
68
+ "path": {
69
+ "type": "string",
70
+ "minLength": 1,
71
+ "pattern": "\\S"
72
+ },
73
+ "key": {
74
+ "type": "string",
75
+ "minLength": 1,
76
+ "pattern": "\\S"
77
+ }
78
+ }
79
+ },
80
+ "evidence": {
81
+ "$comment": "What paid for the rule: a defect, a fix round, an investigation, a review finding, a tuition entry. minItems 1 is the load-bearing constraint of this whole document. The interim index states it in prose ('a rule with no citation is not a rule'), and prose is what this project has recorded three times as not surviving; here it is a validation failure.",
82
+ "type": "array",
83
+ "minItems": 1,
84
+ "items": {
85
+ "type": "string",
86
+ "minLength": 1,
87
+ "pattern": "\\S"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,300 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://tiphys.dev/schemas/plan.schema.json",
4
+ "title": "Tiphys delivery plan",
5
+ "description": "The plan artifact of the orchestrated delivery process, section 1c. Kernel plan M3, M3-P1 step 2. Every object level sets additionalProperties: false, so a misspelled property is a failure and never a silently ignored field (criterion 5).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "kind",
10
+ "status",
11
+ "baseline-commit",
12
+ "binding-rule",
13
+ "process-summary",
14
+ "standing-context",
15
+ "report-code-disagreement",
16
+ "phases",
17
+ "decisions",
18
+ "open-questions",
19
+ "parked"
20
+ ],
21
+ "properties": {
22
+ "kind": {
23
+ "$comment": "R-016. The discriminator tiphys validate --type auto reads.",
24
+ "type": "string",
25
+ "const": "plan"
26
+ },
27
+ "status": {
28
+ "type": "string",
29
+ "enum": ["draft", "approved", "superseded"]
30
+ },
31
+ "baseline-commit": {
32
+ "type": "string",
33
+ "pattern": "^[0-9a-f]{7,40}$"
34
+ },
35
+ "binding-rule": {
36
+ "$comment": "R-017. A required const carrying the process document's exact sentence (delivery/intake/orchestrated-delivery-process.md section 1c), so a plan cannot ship a softened paraphrase of the rule that keeps ten agents from improvising.",
37
+ "type": "string",
38
+ "const": "If it is not written here, it is not being made. Unanswered questions go to the orchestrator."
39
+ },
40
+ "process-summary": {
41
+ "type": "string",
42
+ "minLength": 1
43
+ },
44
+ "standing-context": {
45
+ "$comment": "R-018. What previous runs bought, what is already fixed, what the deploy state is.",
46
+ "type": "string",
47
+ "minLength": 1
48
+ },
49
+ "report-code-disagreement": {
50
+ "$comment": "R-011, and the input to the derived check plan-verification-first-present. An entry with verified: false whose owning phase has no verification-first step makes the plan invalid; that is a foreign-key lookup across two arrays and is Kind B, in src/checks.ts.",
51
+ "type": "array",
52
+ "items": {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "required": ["phase", "claim", "verified"],
56
+ "properties": {
57
+ "phase": {
58
+ "type": "string",
59
+ "pattern": "^M[0-9]+-P[0-9]+$"
60
+ },
61
+ "claim": {
62
+ "type": "string",
63
+ "minLength": 1
64
+ },
65
+ "verified": {
66
+ "type": "boolean"
67
+ }
68
+ }
69
+ }
70
+ },
71
+ "phases": {
72
+ "type": "array",
73
+ "minItems": 1,
74
+ "items": {
75
+ "$ref": "#/$defs/phase"
76
+ }
77
+ },
78
+ "decisions": {
79
+ "$comment": "R-021. Every non-obvious call, numbered, so disagreement targets a number instead of re-litigating prose.",
80
+ "type": "array",
81
+ "items": {
82
+ "type": "object",
83
+ "additionalProperties": false,
84
+ "required": ["id", "statement"],
85
+ "properties": {
86
+ "id": {
87
+ "type": "string",
88
+ "pattern": "^D-[0-9]+$"
89
+ },
90
+ "statement": {
91
+ "type": "string",
92
+ "minLength": 1
93
+ }
94
+ }
95
+ }
96
+ },
97
+ "open-questions": {
98
+ "$comment": "D-7 and SC-009: an open question IS a decision record with status open, so the plan carries references and never a second parallel register.",
99
+ "type": "array",
100
+ "items": {
101
+ "type": "string",
102
+ "pattern": "^DR-[0-9]{4}$"
103
+ }
104
+ },
105
+ "parked": {
106
+ "type": "array",
107
+ "items": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "required": ["item", "reason"],
111
+ "properties": {
112
+ "item": {
113
+ "type": "string",
114
+ "minLength": 1
115
+ },
116
+ "reason": {
117
+ "type": "string",
118
+ "minLength": 1
119
+ }
120
+ }
121
+ }
122
+ }
123
+ },
124
+ "$defs": {
125
+ "phase": {
126
+ "$comment": "R-019 plus the blueprint section 5 superset (conflicts-with, parallelizable). A strict SUPERSET of the M2-P4 scope auditor's phase-declaration projection, which tiphys plan project emits (D-M3-18).",
127
+ "type": "object",
128
+ "additionalProperties": false,
129
+ "required": [
130
+ "id",
131
+ "branch",
132
+ "intent",
133
+ "grounding",
134
+ "severity",
135
+ "verified-root-cause",
136
+ "steps",
137
+ "files-to-touch",
138
+ "extras",
139
+ "acceptance",
140
+ "hazard-classes",
141
+ "migrations",
142
+ "conflicts-with",
143
+ "parallelizable",
144
+ "citations"
145
+ ],
146
+ "properties": {
147
+ "id": {
148
+ "type": "string",
149
+ "pattern": "^M[0-9]+-P[0-9]+$"
150
+ },
151
+ "branch": {
152
+ "type": "string",
153
+ "pattern": "^claude/m[0-9]+-p[0-9]+-.+$"
154
+ },
155
+ "intent": {
156
+ "type": "string",
157
+ "minLength": 1
158
+ },
159
+ "grounding": {
160
+ "type": "string",
161
+ "minLength": 1
162
+ },
163
+ "severity": {
164
+ "type": "string",
165
+ "enum": ["low", "medium", "high", "critical"]
166
+ },
167
+ "verified-root-cause": {
168
+ "type": "string",
169
+ "minLength": 1
170
+ },
171
+ "steps": {
172
+ "type": "array",
173
+ "minItems": 1,
174
+ "items": {
175
+ "type": "object",
176
+ "additionalProperties": false,
177
+ "required": ["text"],
178
+ "properties": {
179
+ "text": {
180
+ "type": "string",
181
+ "minLength": 1
182
+ },
183
+ "kind": {
184
+ "$comment": "R-012. A step that confirms a claim before building on it. The derived check plan-verification-first-present requires one in any phase named by an unverified report-code-disagreement entry.",
185
+ "type": "string",
186
+ "const": "verification-first"
187
+ }
188
+ }
189
+ }
190
+ },
191
+ "files-to-touch": {
192
+ "$comment": "M2R-016. Literal paths, or literal directories with a trailing slash. A parenthetical gloss is permitted HERE, because this document is authored for humans; tiphys plan project strips it, and that stripping is the one place the plan's vocabulary and the auditor's meet.",
193
+ "type": "array",
194
+ "minItems": 1,
195
+ "items": {
196
+ "type": "string",
197
+ "minLength": 1
198
+ }
199
+ },
200
+ "extras": {
201
+ "$comment": "Projected as declaredExtras. Required rather than optional because the scope auditor treats declaredExtras as required; the standing pre-authorized extras (test/behaviors.json and the phase work history) are added by the auditor itself and are never listed here.",
202
+ "type": "array",
203
+ "items": {
204
+ "type": "string",
205
+ "minLength": 1
206
+ }
207
+ },
208
+ "acceptance": {
209
+ "$comment": "R-019: falsifiable statements. minItems 1 because a phase with no acceptance criterion has declared nothing to walk.",
210
+ "type": "array",
211
+ "minItems": 1,
212
+ "items": {
213
+ "type": "object",
214
+ "additionalProperties": false,
215
+ "required": ["id", "criterion"],
216
+ "properties": {
217
+ "id": {
218
+ "type": "string",
219
+ "minLength": 1
220
+ },
221
+ "criterion": {
222
+ "type": "string",
223
+ "minLength": 1
224
+ }
225
+ }
226
+ }
227
+ },
228
+ "hazard-classes": {
229
+ "$comment": "T-007, D-M3-32 and D-M3-35. minItems 1 and NOT optional: an optional field is the version of this rule that did not survive. T-007 records a phase meeting fifteen of fifteen executed criteria while live-locking every supervision command, and the reviewer who found it differed in its BRIEF, not in its model. addressed-by is resolved by the derived check plan-hazard-classes-addressed-by-resolves (section 2.6).",
230
+ "type": "array",
231
+ "minItems": 1,
232
+ "items": {
233
+ "type": "object",
234
+ "additionalProperties": false,
235
+ "required": ["id", "statement", "addressed-by"],
236
+ "properties": {
237
+ "id": {
238
+ "type": "string",
239
+ "minLength": 1
240
+ },
241
+ "statement": {
242
+ "type": "string",
243
+ "minLength": 1
244
+ },
245
+ "addressed-by": {
246
+ "$comment": "Either `criterion <id>` naming a criterion in the SAME phase's acceptance list, or one of section 2.6's three admissible reasons with its named target. The pattern is the Kind A half; resolving the target is Kind B.",
247
+ "type": "string",
248
+ "pattern": "^(criterion .+|judgment-property-of-prose: .+|state-not-entered: .+|later-phase: M[0-9]+-P[0-9]+)$"
249
+ }
250
+ }
251
+ }
252
+ },
253
+ "migrations": {
254
+ "type": "string",
255
+ "minLength": 1
256
+ },
257
+ "conflicts-with": {
258
+ "type": "array",
259
+ "items": {
260
+ "type": "string",
261
+ "minLength": 1
262
+ }
263
+ },
264
+ "parallelizable": {
265
+ "type": "boolean"
266
+ },
267
+ "citations": {
268
+ "type": "array",
269
+ "items": {
270
+ "type": "string",
271
+ "minLength": 1
272
+ }
273
+ },
274
+ "fill-in": {
275
+ "$comment": "R-014. Present and unfilled means the phase is valid for REVIEW and invalid for DISPATCH. That is a computed property of the slots rather than of one field, so it is Kind B: the derived check plan-dispatchable reports it.",
276
+ "type": "object",
277
+ "additionalProperties": false,
278
+ "required": ["filled", "root-cause", "fix-shape", "files"],
279
+ "properties": {
280
+ "filled": {
281
+ "type": "boolean"
282
+ },
283
+ "root-cause": {
284
+ "type": "string"
285
+ },
286
+ "fix-shape": {
287
+ "type": "string"
288
+ },
289
+ "files": {
290
+ "type": "array",
291
+ "items": {
292
+ "type": "string"
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }