@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,48 @@
1
+ # T-001: cross-model review caught findings that survived three same-model
2
+ # rounds. Promoted from the delivering project's own log by M3-P8; the
3
+ # long-form account stays there.
4
+ kind: tuition
5
+ version: 1
6
+ id: T-001
7
+ project: tiphys-kernel
8
+ date: 2026-08-04
9
+ stage: planning, before any implementation dispatch
10
+ kernel-relevant: true
11
+ what-happened: >-
12
+ The kernel plan went through three adversarial review rounds plus one
13
+ targeted verification, all by the same model family, producing 28 applied
14
+ findings. An external review by a different model family then found two
15
+ genuine defects that had survived every internal round: lease renewal was
16
+ never required to fail after expiry, so an expired-but-alive holder racing a
17
+ legitimate takeover could produce dual mutation; and fleet initialization
18
+ assumed a configured git identity, which a clean cloud environment does not
19
+ have. A second data point arrived the same day, with decorrelation in place:
20
+ two clean-room reviews of one head, given deliberately different starting
21
+ questions, found different defects, and the hazard-framed one surfaced two
22
+ highs the criteria walk did not raise at all.
23
+ lesson:
24
+ - >-
25
+ Same-family reviewers share blind spots, and the deterministic verifier
26
+ layer does not cover design-level races or environment assumptions at
27
+ planning time.
28
+ - >-
29
+ The narrower lesson is not "use two models". It is that two reviews with
30
+ different STARTING QUESTIONS find different things, and model diversity
31
+ makes that difference harder to collapse.
32
+ structural-consequence:
33
+ - target: role-model-config.yaml
34
+ status: applied
35
+ change: >-
36
+ The role-to-model binding carries a review-model-family field, so which
37
+ family produced a review is configuration rather than a dispatch habit.
38
+ - target: checklists/clean-room.yaml
39
+ status: ticketed
40
+ change: >-
41
+ The review checklists must vary the ENTRY POINT rather than only the
42
+ reviewer, so the two contracts of a dual review start from different
43
+ questions by construction.
44
+ record: delivery/plan/kernel-plan-m3.md, M3-P7 step 3
45
+ evidence:
46
+ - delivery/review/plan-review-r4-external.md, the external review with its verdict and findings
47
+ - delivery/review/plan-review-r1.md, delivery/review/plan-review-r2.md and delivery/review/plan-review-r3.md, the internal rounds that missed both defects
48
+ - delivery/review/clean-room-m1-p4.md and delivery/review/clean-room-m1-p4-second.md, the first dual review with two framings
@@ -0,0 +1,51 @@
1
+ # T-002: agent death mid fix round, and salvage exercised for real. Promoted
2
+ # from the delivering project's own log by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-002
6
+ project: tiphys-kernel
7
+ date: 2026-08-04
8
+ stage: M1-P3 fix round (session lock and worktree pool)
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ An implementer hit a provider usage limit part way through a fix round and
12
+ stopped, leaving uncommitted work in its worktree and no turn-end record.
13
+ The stop was clean and quiet: nothing crashed, nothing timed out, and no exit
14
+ code said anything had gone wrong. The work was salvaged by hand into a
15
+ commit marked WIP-UNREVIEWED, which is the discipline the process document
16
+ mandates and which nothing in the system detects or performs.
17
+ lesson:
18
+ - >-
19
+ Agent death from a provider limit is a distinct failure class from a crash
20
+ or a timeout, and it looks exactly like an ordinary completion to anything
21
+ keyed on process exit.
22
+ - >-
23
+ A missing turn-end record must never be read as success. Task open, no
24
+ turn-end, worktree dirty is the abandoned-task state and deserves its own
25
+ wake reason rather than being discovered later.
26
+ - >-
27
+ Salvage is currently manual. Detection belongs with the watcher and the
28
+ liveness guard, because a rule that depends on somebody noticing is the
29
+ thing that failed here.
30
+ structural-consequence:
31
+ - target: src/teardown.ts
32
+ status: applied
33
+ change: >-
34
+ teardown --salvage commits a dirty worktree under a fixed
35
+ WIP-UNREVIEWED prefix, so the audit trail of a salvage is uniform rather
36
+ than per-incident.
37
+ - target: src/watcher.ts
38
+ status: applied
39
+ change: >-
40
+ The watcher treats an open task with no turn-end record as a wake
41
+ condition with its own reason line, so the human is told rather than
42
+ finding out afterwards.
43
+ - target: roles/implementer.md
44
+ status: applied
45
+ change: >-
46
+ The R-081b clause makes incremental, committed output an obligation of
47
+ the dispatched agent, so a death leaves a partial result rather than
48
+ nothing.
49
+ evidence:
50
+ - delivery/work-history/m1-p3.md, fix-round section, with the measured salvage state
51
+ - delivery/intake/orchestrated-delivery-process.md section 6, the salvage discipline
@@ -0,0 +1,100 @@
1
+ # T-003: a fix round for low-severity findings introduced two high-severity
2
+ # defects. Promoted from the delivering project's own log by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-003
6
+ project: tiphys-kernel
7
+ date: 2026-08-04
8
+ stage: M1-P3 (session lock and worktree pool), after clean-room APPROVE
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ A fix round addressing four LOW findings introduced two HIGH defects. One
12
+ gave a worktree destroy the authority to force-delete a branch, justified by
13
+ a component scheduled for a later phase that would refuse first. The other
14
+ narrowed a git contention matcher using hand-written example strings chosen
15
+ to match the new pattern, so real racing-git messages fell outside it. The
16
+ round's own tests were green and worthless for both: the destroy test
17
+ destroyed a branch still at its base commit, so no data could be lost, and
18
+ the concurrency test never advanced the upstream, so no ref transaction was
19
+ ever opened. The work history then stated as measured fact a universal claim
20
+ that concealed the second defect from the next reader.
21
+ lesson:
22
+ - >-
23
+ A fix round is not lower risk than the work it fixes, and it receives less
24
+ scrutiny. The severity of the findings being fixed says nothing about the
25
+ severity of the defects the fixes can introduce.
26
+ - >-
27
+ Tests written alongside a fix test the fix, not the behaviour the fix
28
+ endangers. A test must be red against the DANGEROUS state, not merely
29
+ against the absence of the feature.
30
+ - >-
31
+ An unfalsified universal claim in a work history is worse than no claim:
32
+ the document whose purpose is to let a reviewer trust the round is what
33
+ hid the defect.
34
+ mechanisms:
35
+ - mechanism: Lease compare-and-swap
36
+ rule: >-
37
+ Liveness is lease freshness, never pid, process probing or signals
38
+ (constraint C-2). Expiry does not block a release, but it DOES block a
39
+ renew and it DOES block teardown's holdership check, which fails closed.
40
+ siblings:
41
+ - src/lock.ts
42
+ - src/task.ts
43
+ evidence:
44
+ - src/lock.ts
45
+ - checkHoldership in src/task.ts
46
+ - CR-680 in delivery/review/clean-room-m1-p6-round3-hazard.md
47
+ - mechanism: Append-only log
48
+ rule: >-
49
+ Never read current state from the tail of a log (constraint C-1).
50
+ Currency comes from `meta.json` and turn-end files only.
51
+ siblings:
52
+ - src/task.ts
53
+ evidence:
54
+ - plan v1 section 3, C-1 (FM-052)
55
+ - mechanism: Worktree removal and force branch delete
56
+ rule: >-
57
+ Resolve, evaluate, then apply. No policy decision may be taken after a
58
+ destructive action has begun, and destructive authority is never
59
+ inherited from a component that does not exist yet.
60
+ siblings:
61
+ - src/pool.ts
62
+ - src/teardown.ts
63
+ machine-readable-form:
64
+ path: gates.manifest.json
65
+ key: destructiveCommands
66
+ evidence:
67
+ - delivery/review/verification-m1-p3-fix-round.md V-1 and V-3
68
+ - mechanism: Classifying another program's errors
69
+ rule: >-
70
+ Derive the signature from REAL captured output under forced conditions,
71
+ never from hand-written examples chosen to match the implementation. 312
72
+ captured contention failures, every one of the dropped shape.
73
+ siblings:
74
+ - src/pool.ts
75
+ evidence:
76
+ - V-2 in delivery/review/verification-m1-p3-fix-round.md
77
+ - CLAUDE.md environment warning 10
78
+ structural-consequence:
79
+ - target: assurance-modes.yaml
80
+ status: applied
81
+ change: >-
82
+ Full mode carries a fix-round-verification stage, so an independent
83
+ verification of a fix round is a declared pipeline stage rather than
84
+ orchestrator discretion.
85
+ - target: schemas/report.schema.json
86
+ status: applied
87
+ change: >-
88
+ The shared claims[] contract makes a universal claim carry the executed
89
+ construction that could have falsified it, or be restated as an open
90
+ question.
91
+ - target: gates.manifest.json
92
+ status: applied
93
+ change: >-
94
+ The destructiveCommands list names every command that can destroy work,
95
+ which is the machine-readable view of this entry's destructive-operation
96
+ rule and the list the derived-class rule consumes.
97
+ evidence:
98
+ - delivery/review/verification-m1-p3-fix-round.md, findings V-1 and V-2 with the unrefuted candidates
99
+ - delivery/review/clean-room-m1-p3.md, the APPROVE and the four LOW findings that triggered the round
100
+ - delivery/work-history/m1-p3.md, the round's own record including the claim named above
@@ -0,0 +1,52 @@
1
+ # T-004: verification lenses sharing one worktree can manufacture a phantom
2
+ # defect. Promoted from the delivering project's own log by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-004
6
+ project: tiphys-kernel
7
+ date: 2026-08-04
8
+ stage: M1-P3 verification and the investigation that followed it
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ Two verification lenses ran against the same worktree. One was running a
12
+ disciplined sabotage window (copy, mutate, measure, restore) while the other
13
+ ran tests. The second lens observed a failure that came from the first lens's
14
+ mutation and reported it as a defect. By the time anyone inspected the tree it
15
+ was byte-clean, so the evidence of contamination was gone while the finding
16
+ survived, and closing it took two multi-hour investigations.
17
+ lesson:
18
+ - >-
19
+ Shared mutable ground turns one lens's experiment into another lens's
20
+ discovery, and the contamination erases itself while the finding remains.
21
+ - >-
22
+ The dispatch instruction was the defect. The briefs PERMITTED isolation
23
+ rather than REQUIRING it, and permitting is not requiring.
24
+ - >-
25
+ A test run is only evidence if you can prove what it ran. A run that
26
+ cannot name what it executed is an anecdote.
27
+ mechanisms:
28
+ - mechanism: Shared worktree
29
+ rule: >-
30
+ A verification lens works in its OWN clone, never in a tree another agent
31
+ is editing, and a run that cannot pin the source it ran against is not
32
+ evidence and must label itself so.
33
+ siblings:
34
+ - src/pool.ts
35
+ evidence:
36
+ - delivery/verification/u2-race-flake-investigation.md, the U-2 phantom and the four hypotheses each run in a private clone
37
+ - delivery/review/verification-m1-p3-fix-round.md, the round whose lenses shared a tree
38
+ structural-consequence:
39
+ - target: schemas/report.schema.json
40
+ status: applied
41
+ change: >-
42
+ A report declares the source it ran against, so a finding produced by a
43
+ run that cannot pin its source is labelled unpinned rather than inherited
44
+ as fact.
45
+ - target: roles/investigator.md
46
+ status: applied
47
+ change: >-
48
+ The investigator brief requires a private clone and a reproduction, so
49
+ isolation is a role obligation rather than a dispatch-time permission.
50
+ evidence:
51
+ - delivery/verification/u2-race-flake-investigation.md, the whole investigation
52
+ - delivery/review/verification-m1-p3-fix-round.md, the run that produced the phantom
@@ -0,0 +1,72 @@
1
+ # T-005: a lesson the codebase had already paid for did not reach the next
2
+ # phase that needed it. Promoted from the delivering project's own log by
3
+ # M3-P8; the long-form account stays there.
4
+ kind: tuition
5
+ version: 1
6
+ id: T-005
7
+ project: tiphys-kernel
8
+ date: 2026-08-05
9
+ stage: M1-P5 (watcher and liveness guard), first dual review
10
+ kernel-relevant: true
11
+ what-happened: >-
12
+ M1-P3 established, in a multi-hour investigation, that a claim file which
13
+ cannot be taken must fail loudly and name the stuck file. Two phases later
14
+ M1-P5 implemented the same claim-file pattern for the watcher's seen state
15
+ and absorbed the timeout silently. A stranded claim file then made every
16
+ subsequent watcher pass report that there was nothing to surface, for a
17
+ genuinely pending signal, while the beacon kept advancing so the liveness
18
+ guard reported the fleet healthy throughout. It was the most severe defect
19
+ found in M1. The implementer had read the plan, the agent-rules file, the
20
+ constraint list, the environment warnings and three prior work histories,
21
+ and none of them carried the rule: it lived in the M1-P3 source and in an
22
+ investigation report filed under the mystery it solved rather than under the
23
+ mechanism it constrained.
24
+ lesson:
25
+ - >-
26
+ A lesson attached to a component does not travel to the next component
27
+ that needs it. Documents organised by phase, by incident or by environment
28
+ each fail this for their own reason, and none of them is carelessness.
29
+ - >-
30
+ The missing artifact is an index from MECHANISM to RULE, so an implementer
31
+ reaching for a claim file, a lease, an append-only log or a destructive
32
+ git operation can ask what the project already learned and get an answer.
33
+ - >-
34
+ That index is a PROJECTION of the tuition feed rather than a second thing
35
+ to maintain, because two copies of a rule is the state that produced this
36
+ defect in the first place.
37
+ mechanisms:
38
+ - mechanism: Claim file (mutual exclusion by O_EXCL)
39
+ rule: >-
40
+ A claim that cannot be taken must fail LOUDLY and name the stuck file. A
41
+ silent timeout is indistinguishable from an absence of contention. There
42
+ are now THREE claim-file users (the lock, the watcher seen-state, and
43
+ M2-P1's evidence-directory run claim); the next one reads `src/lock.ts`
44
+ first, and the M2-P1 instance is the worked example of doing that and
45
+ stating the one difference (no expiry, because an evidence directory must
46
+ not have a lease that lapses).
47
+ siblings:
48
+ - src/lock.ts
49
+ - src/watch.ts
50
+ - src/gates/run.ts
51
+ evidence:
52
+ - delivery/verification/u2-race-flake-investigation.md D-3
53
+ - delivery/tuition/T-005, the silent reimplementation two phases later that became M1's most severe defect
54
+ structural-consequence:
55
+ - target: tuition/mechanism-index.yaml
56
+ status: applied
57
+ change: >-
58
+ The mechanism index exists and is generated by `tiphys tuition index` as
59
+ a projection of every tuition entry's mechanisms[] field, so a rule is
60
+ recorded once and read from one place.
61
+ - target: roles/implementer.md
62
+ status: applied
63
+ change: >-
64
+ The mandated reading list names the mechanism index, and the
65
+ `mechanism-lookup` and `mechanism-sibling` clauses require an implementer
66
+ to look up every mechanism it is about to use and to record the siblings
67
+ when it establishes a rule.
68
+ evidence:
69
+ - delivery/verification/u2-race-flake-investigation.md, defect D-3 and the structural-fix section
70
+ - delivery/review/clean-room-m1-p5-second.md, finding 1, with the reproduction
71
+ - delivery/work-history/m1-p5.md, fix-round section
72
+ - delivery/intake/orchestrated-delivery-v1.md section 9, the tuition flow
@@ -0,0 +1,81 @@
1
+ # T-006: claimed impossibilities and claimed safety nets, written without
2
+ # execution. Promoted from the delivering project's own log by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-006
6
+ project: tiphys-kernel
7
+ date: 2026-08-05
8
+ stage: M1-P5 (watcher and liveness guard), across its fix rounds
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ Three times in one phase, a work history stated something about the world
12
+ that had never been executed: an arm that "cannot be forced", a case another
13
+ guard "already catches", a path that "recovers anyway". Each was written by an
14
+ implementer who had done real work, and each survived into a document a
15
+ reviewer was expected to trust. The orchestrator then did the same thing the
16
+ same day, reporting a remote as unreachable on the strength of a read
17
+ operation that says nothing about write access.
18
+ lesson:
19
+ - >-
20
+ An impossibility claim, a coverage claim or a remedy claim must carry the
21
+ executed construction, or be restated as an open question.
22
+ - >-
23
+ The honest restatement costs nothing and is more useful: "I did not find a
24
+ way to force this arm" is true and invites the next reader to try, where
25
+ "this arm cannot be forced here" is false and closes the question.
26
+ - >-
27
+ A reminder does not survive a busy session. The mechanism is a grep over
28
+ the work history before it is submitted.
29
+ mechanisms:
30
+ - mechanism: Reading a path whose type is not established
31
+ rule: >-
32
+ lstat the link, stat what it resolves to, open ONLY a regular file. A
33
+ block is not an exception, so try/catch does not touch it.
34
+ siblings:
35
+ - src/task.ts
36
+ - src/lock.ts
37
+ - src/pool.ts
38
+ - src/brief.ts
39
+ - src/hooks.ts
40
+ evidence:
41
+ - CR-520 and the four M1-P5 rounds
42
+ - delivery/verification/cr-520-orchestrator-reproduction.md
43
+ - mechanism: Atomic file replacement
44
+ rule: >-
45
+ Stage under a name no other pass can collide with. A fixed
46
+ `${path}.stage` lets two concurrent passes share one temporary; the loser
47
+ dies on ENOENT after advancing its seen state, dropping a signal in a
48
+ protocol whose rule is duplicate-rather-than-drop.
49
+ siblings:
50
+ - src/lock.ts
51
+ - src/watch.ts
52
+ evidence:
53
+ - M1-P5 round 4, verified pre-existing against a pristine build
54
+ - mechanism: Verifying access to a remote
55
+ rule: >-
56
+ `git push --dry-run` authenticates against receive-pack and updates no
57
+ ref. `clone` and `ls-remote` are READ operations and witness nothing
58
+ about write access.
59
+ evidence:
60
+ - delivery/tuition/T-006-unexecuted-claims-about-the-world.md, the orchestrator's own instance
61
+ structural-consequence:
62
+ - target: schemas/work-history.schema.json
63
+ status: applied
64
+ change: >-
65
+ The shared claims[] section requires an executed construction beside any
66
+ impossibility, coverage or remedy claim, so the claim and its settlement
67
+ travel together.
68
+ - target: schemas/report.schema.json
69
+ status: applied
70
+ change: >-
71
+ The same claims[] definition is shared by the report contract, so a
72
+ review making an unexecuted claim is subject to the same rule as the work
73
+ it reviews.
74
+ - target: roles/implementer.md
75
+ status: applied
76
+ change: >-
77
+ The claim-grep clause carries the grep command verbatim, so hunting these
78
+ claims is a command rather than a habit.
79
+ evidence:
80
+ - delivery/work-history/m1-p5.md, the three claims and their fix rounds
81
+ - delivery/review/clean-room-m1-p5-round4-hazard.md, the review that named the pattern
@@ -0,0 +1,56 @@
1
+ # T-007: a phase met fifteen of fifteen executed acceptance criteria and still
2
+ # live-locked every supervision command. Promoted by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-007
6
+ project: tiphys-kernel
7
+ date: 2026-08-05
8
+ stage: M1-P5 (watcher and liveness guard), third dual review
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ Every one of a phase's fifteen acceptance criteria was walked and met, and the
12
+ delivered component still blocked forever on a named pipe at a path it read,
13
+ taking every supervision command with it. Two reviews ran on one head: the
14
+ criteria walk approved, and the hazard-framed review, given the question "what
15
+ can block, what can be lost, what can never exit", found the defect. The two
16
+ agreed on every mechanical fact; they disagreed on the verdict because they
17
+ were asking different questions.
18
+ lesson:
19
+ - >-
20
+ Acceptance criteria inherit the blind spots of whoever wrote them, so a
21
+ criteria walk cannot find a defect the criteria could not express. "All
22
+ criteria met" is one input, never a terminal green.
23
+ - >-
24
+ A code phase needs two review CONTRACTS, not two reviewers, and the second
25
+ one must be a declared artifact rather than something the dispatch prompt
26
+ is trusted to remember.
27
+ - >-
28
+ The hazard question is derivable from the component's nature, which means
29
+ it belongs in the plan rather than in a prompt.
30
+ structural-consequence:
31
+ - target: schemas/plan.schema.json
32
+ status: applied
33
+ change: >-
34
+ A phase declares its hazard-classes[] beside its acceptance criteria, so
35
+ the second review contract is derived from the plan rather than improvised
36
+ per dispatch.
37
+ - target: assurance-modes.yaml
38
+ status: applied
39
+ change: >-
40
+ review-contracts[] are declared per mode, so a mode says how many
41
+ contracts a review round carries and what each one asks.
42
+ - target: roles/clean-room-reviewer.md
43
+ status: applied
44
+ change: >-
45
+ The brief carries a review-contract field, so a reviewer knows which
46
+ contract it is executing and a hazard contract cannot be silently
47
+ dropped.
48
+ - target: checklists/hazard-review.yaml
49
+ status: ticketed
50
+ change: >-
51
+ The hazard contract gets its own checklist, so the second contract has
52
+ probes rather than only a framing.
53
+ record: delivery/plan/kernel-plan-m3.md, M3-P7
54
+ evidence:
55
+ - delivery/review/clean-room-m1-p5-third-hazard.md and delivery/review/clean-room-m1-p5-third-criteria.md, the two verdicts on one head
56
+ - delivery/review/arbitration-m1-p5-third-round.md, the arbitration
@@ -0,0 +1,111 @@
1
+ # T-008: the orchestrator supervised two agents with no beacon and no guard,
2
+ # and lost nine hours. Promoted by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-008
6
+ project: tiphys-kernel
7
+ date: 2026-08-06
8
+ stage: M1-P6, fifth review pass
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ Two review agents died within minutes of dispatch and the orchestrator did not
12
+ notice for nine hours and eleven minutes, while answering the owner and
13
+ dispatching other work throughout. Its supervision was "wait for a completion
14
+ notification", which is process liveness: a dead process sends no
15
+ notification, and no notification is indistinguishable from work in progress.
16
+ The first watchdog written after the incident then tested whether the report
17
+ file EXISTED, so it fired two minutes in, reported success, and said nothing.
18
+ lesson:
19
+ - >-
20
+ Supervision is a freshness watchdog armed in the same turn as the
21
+ dispatch, never a wait for a completion notification.
22
+ - >-
23
+ Every dispatched agent writes its output incrementally, so its artifact's
24
+ mtime is a beacon and a death leaves a salvageable partial result.
25
+ - >-
26
+ A guard whose condition does not test the property that matters is green
27
+ and worthless, which is the red-witness rule one level up.
28
+ mechanisms:
29
+ - mechanism: Supervising a dispatched agent
30
+ rule: >-
31
+ Supervision is a FRESHNESS watchdog armed in the same turn as the
32
+ dispatch, never a wait for a completion notification and never a probe of
33
+ process liveness (constraint C-2). The watchdog must test freshness, never
34
+ existence and never completion, must watch the union of the paths the
35
+ agent actually writes (measured, not predicted), and must exclude the
36
+ supervisor's own trees, because a watchdog that cannot go red is worse
37
+ than none.
38
+ siblings:
39
+ - src/watcher.ts
40
+ - src/liveness.ts
41
+ evidence:
42
+ - delivery/tuition/T-008-the-orchestrator-had-no-beacon.md, nine hours and eleven minutes measured
43
+ - delivery/tuition/T-014-the-watchdog-watched-the-wrong-place-six-times.md, six wrong applications of the same rule in one session
44
+ - mechanism: Parsing another program's reporter output
45
+ rule: >-
46
+ PIN the format as a controlled input rather than widening the parse. A
47
+ format-agnostic regex is a union of formats known on the day, and the
48
+ default already differs between the two toolchains this project runs.
49
+ siblings:
50
+ - src/gates/suite.ts
51
+ evidence:
52
+ - M1-P6 floor defect
53
+ - "`NODE_OPTIONS=--test-reporter=tap` scoped to the child"
54
+ - mechanism: Deciding what another program will do by pattern-matching the text of a file it consumes
55
+ rule: >-
56
+ A regex over a file and the consuming program's evaluation of that file
57
+ are DIFFERENT FUNCTIONS, so every finding is another input where they
58
+ differ, and rounds close instances forever. Three tiers instead, each
59
+ labelled by what enforces it: execute the extractable part against stubs;
60
+ PIN the accepted shapes and fail closed on anything else, never widen the
61
+ pattern; and where a denylist is unavoidable, DERIVE it by walking the
62
+ consuming program's closed documented vocabulary once, publishing the
63
+ walk. Name what remains unguarded rather than chasing it.
64
+ siblings:
65
+ - test/exit-test-local.test.ts
66
+ - test/m2-exit-test.test.ts
67
+ evidence:
68
+ - Four M1-P6 rounds, CR-640, CR-661, CR-681, CR-720 to CR-725
69
+ - the derived walk found two members no reviewer had named (`working-directory`, a custom `shell` template)
70
+ - "the widen-the-regex approach produced a guard that both missed real defangs and rejected `needs: [test, lint]`, an edit that STRENGTHENS the guarded property"
71
+ - mechanism: Asserting a CI step is wired
72
+ rule: >-
73
+ Assert BEHAVIOUR, not text. A text assertion catches deletion and misses
74
+ defanging. Extract the step and execute it against stubs. A witness for a
75
+ class must redden under at least two structurally different members.
76
+ siblings:
77
+ - test/exit-test-local.test.ts
78
+ - test/m2-exit-test.test.ts
79
+ - test/implementer-brief.test.ts
80
+ evidence:
81
+ - CR-640, CR-661, CR-681
82
+ - delivery/verification/cr-661-orchestrator-reproduction.md
83
+ - mechanism: A guard's own failure path
84
+ rule: >-
85
+ A guard whose correctness depends on a crash is not a guard. Make the
86
+ success path total, so removing the explicit failure is visible.
87
+ siblings:
88
+ - test/exit-test-local.test.ts
89
+ evidence:
90
+ - M1-P6 fix round 2, the D3 defang the implementer caught in its own fix
91
+ structural-consequence:
92
+ - target: roles/implementer.md
93
+ status: applied
94
+ change: >-
95
+ The incremental-output and beacon-is-not-a-claim clauses make the beacon
96
+ an obligation of the dispatched agent and forbid reading its existence as
97
+ progress.
98
+ - target: roles/clean-room-reviewer.md
99
+ status: applied
100
+ change: >-
101
+ The same two clauses bind review agents, which is the half of the dispatch
102
+ contract this incident actually needed.
103
+ - target: AGENTS.md
104
+ status: ticketed
105
+ change: >-
106
+ The orchestrator's supervision section states the watchdog rule and the
107
+ three questions a dispatch turn answers in writing before arming one.
108
+ record: delivery/plan/kernel-plan-m3.md, M3-P9
109
+ evidence:
110
+ - delivery/tuition/T-008-the-orchestrator-had-no-beacon.md, the measured nine hours and eleven minutes
111
+ - delivery/work-history/m1-p6.md, the phase running while the two agents were dead
@@ -0,0 +1,50 @@
1
+ # T-009: main was red for four hours and twenty-one minutes while every pull
2
+ # request check was green. Promoted by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-009
6
+ project: tiphys-kernel
7
+ date: 2026-08-07
8
+ stage: M2 tail
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ The CI workflow fires on two events and they run different bundles: the pull
12
+ request event runs the strong bundle with a phase id derived from the head
13
+ ref, and a push to the default branch runs a main bundle with no phase. A
14
+ defect on the arm only one event takes was invisible to the other, so the
15
+ default branch stayed red across five consecutive push runs while every pull
16
+ request check was green, and four more merges landed on it. The owner
17
+ surfaced it, not the process.
18
+ lesson:
19
+ - >-
20
+ A gate result is evidence only for the configuration it ran under. "CI is
21
+ green" is never a complete sentence: the complete sentence names the event
22
+ and the head sha.
23
+ - >-
24
+ A merge is not complete until the post-merge run on the new head is
25
+ observed to completion. Not the check on the branch: the run whose head
26
+ sha is the new tip.
27
+ - >-
28
+ Where behaviour forks on the CI event, BOTH arms need a witness. One
29
+ witnessed arm and one unwitnessed arm is the exact shape that broke here,
30
+ and the unwitnessed one is the one that broke.
31
+ structural-consequence:
32
+ - target: schemas/report.schema.json
33
+ status: applied
34
+ change: >-
35
+ A reported gate result carries the event and the head it ran under, so a
36
+ green cannot be quoted outside the configuration that produced it.
37
+ - target: gate-registry.yaml
38
+ status: applied
39
+ change: >-
40
+ Every gate declares the CI events it runs on, so the two arms are data a
41
+ reader can compare rather than a property of a workflow file.
42
+ - target: AGENTS.md
43
+ status: ticketed
44
+ change: >-
45
+ The orchestrator's merge duty includes observing the post-merge run on the
46
+ new head before the phase is closed.
47
+ record: delivery/plan/kernel-plan-m3.md, M3-P9
48
+ evidence:
49
+ - delivery/tuition/T-009-green-on-the-wrong-event.md, the five red push runs and the four merges
50
+ - delivery/work-history/m2-p9.md, the exit-test harness the incident ran through
@@ -0,0 +1,36 @@
1
+ # T-015: a citation into a newest-at-top file rots on every append. Promoted
2
+ # by M3-P8.
3
+ kind: tuition
4
+ version: 1
5
+ id: T-015
6
+ project: tiphys-kernel
7
+ date: 2026-08-12
8
+ stage: orchestrator paperwork, across one branch
9
+ kernel-relevant: true
10
+ what-happened: >-
11
+ A document that grows at the TOP moves every line below the insertion point.
12
+ A citation of the form path:line into such a file is therefore correct when
13
+ written and wrong after the next append, and it fails silently: the line still
14
+ exists, so the citation resolves, and it now points at something else. Four
15
+ instances were found in one branch, every one of them by re-running the check
16
+ after the final edit rather than by reading.
17
+ lesson:
18
+ - >-
19
+ A positional citation into an append-at-top document decays on every
20
+ append, and the decayed form RESOLVES, so nothing reddens.
21
+ - >-
22
+ Prefer citing something that does not move, and where the positional
23
+ citation is the right one anyway, resolve it after the final edit and not
24
+ before.
25
+ - >-
26
+ The check that catches this is a re-run, not a reading.
27
+ structural-consequence:
28
+ - target: gate-registry.yaml
29
+ status: proposed
30
+ change: >-
31
+ The citations gate's document globs reach only the delivery tree today.
32
+ Extending them to root-level authored files would put this region under
33
+ the same check as everything else; the change belongs to the phase that
34
+ owns the registry rather than to this record.
35
+ evidence:
36
+ - delivery/tuition/T-015-a-citation-into-a-newest-at-top-file-rots-on-every-append.md, the four instances and the measurement