@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.
- package/AGENTS.md +611 -0
- package/LICENSE +202 -0
- package/assurance-modes.yaml +278 -0
- package/checklists/clean-room.yaml +325 -0
- package/checklists/env-failure-diagnosis.yaml +68 -0
- package/checklists/flake-playbook.yaml +68 -0
- package/checklists/hazard-review.yaml +144 -0
- package/checklists/plan-review.yaml +103 -0
- package/dist/bin/tiphys.d.ts +2 -0
- package/dist/bin/tiphys.js +14 -0
- package/dist/src/brief.d.ts +32 -0
- package/dist/src/brief.js +59 -0
- package/dist/src/checklists.d.ts +169 -0
- package/dist/src/checklists.js +310 -0
- package/dist/src/checks.d.ts +828 -0
- package/dist/src/checks.js +3314 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.js +57 -0
- package/dist/src/commands/brief.d.ts +92 -0
- package/dist/src/commands/brief.js +320 -0
- package/dist/src/commands/checklist.d.ts +42 -0
- package/dist/src/commands/checklist.js +168 -0
- package/dist/src/commands/doctor.d.ts +35 -0
- package/dist/src/commands/doctor.js +605 -0
- package/dist/src/commands/gates.d.ts +9 -0
- package/dist/src/commands/gates.js +360 -0
- package/dist/src/commands/init.d.ts +30 -0
- package/dist/src/commands/init.js +128 -0
- package/dist/src/commands/lock.d.ts +1 -0
- package/dist/src/commands/lock.js +229 -0
- package/dist/src/commands/mode.d.ts +40 -0
- package/dist/src/commands/mode.js +134 -0
- package/dist/src/commands/plan.d.ts +20 -0
- package/dist/src/commands/plan.js +105 -0
- package/dist/src/commands/pool.d.ts +1 -0
- package/dist/src/commands/pool.js +128 -0
- package/dist/src/commands/spawn.d.ts +1 -0
- package/dist/src/commands/spawn.js +146 -0
- package/dist/src/commands/status.d.ts +19 -0
- package/dist/src/commands/status.js +120 -0
- package/dist/src/commands/teardown.d.ts +1 -0
- package/dist/src/commands/teardown.js +79 -0
- package/dist/src/commands/tuition.d.ts +21 -0
- package/dist/src/commands/tuition.js +218 -0
- package/dist/src/commands/validate.d.ts +78 -0
- package/dist/src/commands/validate.js +360 -0
- package/dist/src/commands/watch.d.ts +1 -0
- package/dist/src/commands/watch.js +172 -0
- package/dist/src/exec/env.d.ts +128 -0
- package/dist/src/exec/env.js +190 -0
- package/dist/src/fleet.d.ts +51 -0
- package/dist/src/fleet.js +80 -0
- package/dist/src/gates/adapters/http-json.d.ts +5 -0
- package/dist/src/gates/adapters/http-json.js +283 -0
- package/dist/src/gates/adapters/migrations-command.d.ts +1 -0
- package/dist/src/gates/adapters/migrations-command.js +373 -0
- package/dist/src/gates/citations.d.ts +408 -0
- package/dist/src/gates/citations.js +1163 -0
- package/dist/src/gates/coverage.d.ts +284 -0
- package/dist/src/gates/coverage.js +701 -0
- package/dist/src/gates/credentials.d.ts +74 -0
- package/dist/src/gates/credentials.js +533 -0
- package/dist/src/gates/deploy.d.ts +1 -0
- package/dist/src/gates/deploy.js +33 -0
- package/dist/src/gates/manifest.d.ts +99 -0
- package/dist/src/gates/manifest.js +208 -0
- package/dist/src/gates/migrations.d.ts +1 -0
- package/dist/src/gates/migrations.js +36 -0
- package/dist/src/gates/pin.d.ts +114 -0
- package/dist/src/gates/pin.js +154 -0
- package/dist/src/gates/red-witness.d.ts +22 -0
- package/dist/src/gates/red-witness.js +390 -0
- package/dist/src/gates/release.d.ts +283 -0
- package/dist/src/gates/release.js +820 -0
- package/dist/src/gates/result.d.ts +116 -0
- package/dist/src/gates/result.js +91 -0
- package/dist/src/gates/run.d.ts +566 -0
- package/dist/src/gates/run.js +1536 -0
- package/dist/src/gates/schemas/citation-config.schema.json +59 -0
- package/dist/src/gates/schemas/coverage-config.schema.json +77 -0
- package/dist/src/gates/schemas/gate-manifest.schema.json +125 -0
- package/dist/src/gates/schemas/gate-result.schema.json +160 -0
- package/dist/src/gates/schemas/phase-declaration.schema.json +42 -0
- package/dist/src/gates/schemas/release-record.schema.json +119 -0
- package/dist/src/gates/schemas/verifier-config.schema.json +101 -0
- package/dist/src/gates/schemas/witness-spec.schema.json +110 -0
- package/dist/src/gates/scope.d.ts +131 -0
- package/dist/src/gates/scope.js +1018 -0
- package/dist/src/gates/suite.d.ts +217 -0
- package/dist/src/gates/suite.js +927 -0
- package/dist/src/gates/validate.d.ts +121 -0
- package/dist/src/gates/validate.js +414 -0
- package/dist/src/hooks.d.ts +32 -0
- package/dist/src/hooks.js +62 -0
- package/dist/src/liveness.d.ts +321 -0
- package/dist/src/liveness.js +396 -0
- package/dist/src/lock.d.ts +178 -0
- package/dist/src/lock.js +500 -0
- package/dist/src/modes.d.ts +149 -0
- package/dist/src/modes.js +258 -0
- package/dist/src/path-identity.d.ts +2 -0
- package/dist/src/path-identity.js +10 -0
- package/dist/src/plan.d.ts +73 -0
- package/dist/src/plan.js +153 -0
- package/dist/src/pool.d.ts +130 -0
- package/dist/src/pool.js +721 -0
- package/dist/src/roles.d.ts +430 -0
- package/dist/src/roles.js +734 -0
- package/dist/src/spawn.d.ts +177 -0
- package/dist/src/spawn.js +332 -0
- package/dist/src/status.d.ts +91 -0
- package/dist/src/status.js +119 -0
- package/dist/src/task.d.ts +264 -0
- package/dist/src/task.js +305 -0
- package/dist/src/teardown.d.ts +32 -0
- package/dist/src/teardown.js +314 -0
- package/dist/src/tuition.d.ts +159 -0
- package/dist/src/tuition.js +311 -0
- package/dist/src/validate.d.ts +230 -0
- package/dist/src/validate.js +732 -0
- package/dist/src/version.d.ts +3 -0
- package/dist/src/version.js +38 -0
- package/dist/src/watcher.d.ts +275 -0
- package/dist/src/watcher.js +859 -0
- package/dist/src/witness/run.d.ts +274 -0
- package/dist/src/witness/run.js +1327 -0
- package/dist/src/witness/spec.d.ts +102 -0
- package/dist/src/witness/spec.js +253 -0
- package/dist/tsconfig.src.tsbuildinfo +1 -0
- package/gate-registry.yaml +390 -0
- package/gates.manifest.json +195 -0
- package/package.json +57 -3
- package/role-model-config.yaml +88 -0
- package/roles/README.md +128 -0
- package/roles/_shared-dispatch-contract.md +87 -0
- package/roles/adversarial-plan-reviewer.md +80 -0
- package/roles/clean-room-reviewer.md +140 -0
- package/roles/implementer.md +460 -0
- package/roles/investigator.md +138 -0
- package/roles/plan-writer.md +95 -0
- package/schemas/README.md +81 -0
- package/schemas/assurance-modes.schema.json +264 -0
- package/schemas/charter.schema.json +166 -0
- package/schemas/checklist.schema.json +114 -0
- package/schemas/decision-record.schema.json +88 -0
- package/schemas/final-report.schema.json +90 -0
- package/schemas/finding.schema.json +106 -0
- package/schemas/gate-registry.schema.json +260 -0
- package/schemas/mechanism-index.schema.json +94 -0
- package/schemas/plan.schema.json +300 -0
- package/schemas/report.schema.json +579 -0
- package/schemas/role-brief.schema.json +105 -0
- package/schemas/role-model-config.schema.json +90 -0
- package/schemas/status-line.schema.json +40 -0
- package/schemas/tuition.schema.json +191 -0
- package/schemas/verdict.schema.json +289 -0
- package/schemas/work-history.schema.json +183 -0
- package/templates/charter.example.yaml +54 -0
- package/templates/decision-record.example.yaml +27 -0
- package/templates/final-report.example.yaml +80 -0
- package/templates/plan.example.yaml +87 -0
- package/templates/report.example.yaml +236 -0
- package/templates/warnings.md +74 -0
- package/templates/work-history.example.yaml +185 -0
- package/tuition/README.md +76 -0
- package/tuition/T-001.yaml +48 -0
- package/tuition/T-002.yaml +51 -0
- package/tuition/T-003.yaml +100 -0
- package/tuition/T-004.yaml +52 -0
- package/tuition/T-005.yaml +72 -0
- package/tuition/T-006.yaml +81 -0
- package/tuition/T-007.yaml +56 -0
- package/tuition/T-008.yaml +111 -0
- package/tuition/T-009.yaml +50 -0
- package/tuition/T-015.yaml +36 -0
- package/tuition/T-016.yaml +36 -0
- package/tuition/T-017.yaml +46 -0
- package/tuition/T-018.yaml +84 -0
- package/tuition/T-021.yaml +40 -0
- package/tuition/T-022.yaml +36 -0
- 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
|