@tiphys/kernel 0.0.0 → 0.2.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 +663 -0
- package/LICENSE +202 -0
- package/assurance-modes.yaml +299 -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 +92 -0
- package/dist/src/adapters/load.d.ts +202 -0
- package/dist/src/adapters/load.js +440 -0
- package/dist/src/brief.d.ts +32 -0
- package/dist/src/brief.js +66 -0
- package/dist/src/checklists.d.ts +169 -0
- package/dist/src/checklists.js +310 -0
- package/dist/src/checks.d.ts +1539 -0
- package/dist/src/checks.js +5025 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.js +68 -0
- package/dist/src/commands/brief.d.ts +92 -0
- package/dist/src/commands/brief.js +343 -0
- package/dist/src/commands/checklist.d.ts +42 -0
- package/dist/src/commands/checklist.js +168 -0
- package/dist/src/commands/cutover.d.ts +35 -0
- package/dist/src/commands/cutover.js +448 -0
- package/dist/src/commands/doctor.d.ts +264 -0
- package/dist/src/commands/doctor.js +1546 -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 +177 -0
- package/dist/src/commands/lock.d.ts +34 -0
- package/dist/src/commands/lock.js +340 -0
- package/dist/src/commands/mode.d.ts +40 -0
- package/dist/src/commands/mode.js +134 -0
- package/dist/src/commands/next.d.ts +130 -0
- package/dist/src/commands/next.js +597 -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 +139 -0
- package/dist/src/commands/resume.d.ts +1 -0
- package/dist/src/commands/resume.js +88 -0
- package/dist/src/commands/spawn.d.ts +1 -0
- package/dist/src/commands/spawn.js +195 -0
- package/dist/src/commands/status.d.ts +21 -0
- package/dist/src/commands/status.js +122 -0
- package/dist/src/commands/sync.d.ts +47 -0
- package/dist/src/commands/sync.js +341 -0
- package/dist/src/commands/teardown.d.ts +1 -0
- package/dist/src/commands/teardown.js +87 -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 +430 -0
- package/dist/src/commands/watch.d.ts +1 -0
- package/dist/src/commands/watch.js +172 -0
- package/dist/src/cutover.d.ts +584 -0
- package/dist/src/cutover.js +1444 -0
- package/dist/src/exclusion.d.ts +389 -0
- package/dist/src/exclusion.js +843 -0
- package/dist/src/exec/env.d.ts +278 -0
- package/dist/src/exec/env.js +334 -0
- package/dist/src/fleet.d.ts +223 -0
- package/dist/src/fleet.js +298 -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 +1169 -0
- package/dist/src/gates/coverage.d.ts +375 -0
- package/dist/src/gates/coverage.js +836 -0
- package/dist/src/gates/credentials.d.ts +233 -0
- package/dist/src/gates/credentials.js +752 -0
- package/dist/src/gates/deploy.d.ts +1 -0
- package/dist/src/gates/deploy.js +33 -0
- package/dist/src/gates/gate-classes.d.ts +56 -0
- package/dist/src/gates/gate-classes.js +633 -0
- package/dist/src/gates/manifest.d.ts +99 -0
- package/dist/src/gates/manifest.js +208 -0
- package/dist/src/gates/merge-preconditions.d.ts +319 -0
- package/dist/src/gates/merge-preconditions.js +932 -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 +482 -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 +614 -0
- package/dist/src/gates/run.js +1614 -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 +87 -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 +968 -0
- package/dist/src/gates/validate.d.ts +121 -0
- package/dist/src/gates/validate.js +414 -0
- package/dist/src/hooks.d.ts +84 -0
- package/dist/src/hooks.js +125 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.js +30 -0
- package/dist/src/liveness.d.ts +321 -0
- package/dist/src/liveness.js +396 -0
- package/dist/src/lock.d.ts +256 -0
- package/dist/src/lock.js +792 -0
- package/dist/src/model-resolution.d.ts +159 -0
- package/dist/src/model-resolution.js +307 -0
- package/dist/src/modes.d.ts +149 -0
- package/dist/src/modes.js +258 -0
- package/dist/src/path-identity.d.ts +34 -0
- package/dist/src/path-identity.js +48 -0
- package/dist/src/plan.d.ts +73 -0
- package/dist/src/plan.js +153 -0
- package/dist/src/pool.d.ts +326 -0
- package/dist/src/pool.js +988 -0
- package/dist/src/roles.d.ts +461 -0
- package/dist/src/roles.js +776 -0
- package/dist/src/spawn.d.ts +482 -0
- package/dist/src/spawn.js +1003 -0
- package/dist/src/status.d.ts +116 -0
- package/dist/src/status.js +148 -0
- package/dist/src/task.d.ts +504 -0
- package/dist/src/task.js +307 -0
- package/dist/src/teardown.d.ts +39 -0
- package/dist/src/teardown.js +422 -0
- package/dist/src/tuition.d.ts +159 -0
- package/dist/src/tuition.js +311 -0
- package/dist/src/validate.d.ts +263 -0
- package/dist/src/validate.js +742 -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 +849 -0
- package/dist/src/witness/run.d.ts +299 -0
- package/dist/src/witness/run.js +1373 -0
- package/dist/src/witness/spec.d.ts +270 -0
- package/dist/src/witness/spec.js +475 -0
- package/dist/tsconfig.src.tsbuildinfo +1 -0
- package/gate-registry.yaml +526 -0
- package/gates.manifest.json +257 -0
- package/package.json +72 -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 +463 -0
- package/roles/investigator.md +138 -0
- package/roles/plan-writer.md +95 -0
- package/schemas/README.md +82 -0
- package/schemas/assurance-modes.schema.json +264 -0
- package/schemas/charter.schema.json +185 -0
- package/schemas/checklist.schema.json +114 -0
- package/schemas/cutover-state.schema.json +64 -0
- package/schemas/decision-record.schema.json +88 -0
- package/schemas/executor-record.schema.json +36 -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/model-resolution.schema.json +362 -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 +295 -0
- package/schemas/work-history.schema.json +183 -0
- package/schemas/write-bypass.schema.json +69 -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
package/AGENTS.md
ADDED
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: orchestrator
|
|
3
|
+
lifetime: Persistent across the whole run
|
|
4
|
+
sees:
|
|
5
|
+
- The charter, the plan, and every phase declaration
|
|
6
|
+
- Every review verdict and every work history
|
|
7
|
+
- The repository, its branches, and the gate results on each head
|
|
8
|
+
never:
|
|
9
|
+
- Writes feature code in a project repository
|
|
10
|
+
- Lets a review be skipped
|
|
11
|
+
- Merges without the declared mode's merge-authority being satisfied
|
|
12
|
+
- Improvises an irreversible choice the plan is silent on
|
|
13
|
+
mandated-reading:
|
|
14
|
+
- roles/_shared-dispatch-contract.md
|
|
15
|
+
- assurance-modes.yaml
|
|
16
|
+
- gate-registry.yaml
|
|
17
|
+
- role-model-config.yaml
|
|
18
|
+
- schemas/decision-record.schema.json
|
|
19
|
+
- schemas/final-report.schema.json
|
|
20
|
+
- schemas/verdict.schema.json
|
|
21
|
+
- checklists/clean-room.yaml
|
|
22
|
+
- checklists/hazard-review.yaml
|
|
23
|
+
- tuition/mechanism-index.yaml
|
|
24
|
+
verifiers:
|
|
25
|
+
- check-agents-references
|
|
26
|
+
- check-dual-review
|
|
27
|
+
outputs:
|
|
28
|
+
- decision-record
|
|
29
|
+
- final-report
|
|
30
|
+
model-tier: strongest
|
|
31
|
+
clauses:
|
|
32
|
+
- R-001b
|
|
33
|
+
- R-002
|
|
34
|
+
- R-013
|
|
35
|
+
- R-030
|
|
36
|
+
- R-061
|
|
37
|
+
- R-062
|
|
38
|
+
- R-065b
|
|
39
|
+
- R-067
|
|
40
|
+
- R-073
|
|
41
|
+
- R-076
|
|
42
|
+
- R-077
|
|
43
|
+
- fleet-state-commit-discipline
|
|
44
|
+
- merge-authority
|
|
45
|
+
- projects-read-only
|
|
46
|
+
- fleet-resume-specification
|
|
47
|
+
- escalation-threshold
|
|
48
|
+
- stalled-phase-response
|
|
49
|
+
- two-review-contracts
|
|
50
|
+
- salvage-discipline
|
|
51
|
+
- verification-dispatch-isolation
|
|
52
|
+
- probe-injection
|
|
53
|
+
- tuition-promotion
|
|
54
|
+
- decorrelated-review
|
|
55
|
+
- dispatch-requires-a-beacon
|
|
56
|
+
- dispatch-requires-a-guard
|
|
57
|
+
- notification-is-not-liveness
|
|
58
|
+
- merge-is-not-complete-until
|
|
59
|
+
- gate-result-is-scoped-to-its-run
|
|
60
|
+
- incremental-output
|
|
61
|
+
- beacon-is-not-a-claim
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
# Orchestrator
|
|
65
|
+
|
|
66
|
+
You run the delivery. You do not build the thing being delivered, and you do
|
|
67
|
+
not decide that a step of the process was not needed this time.
|
|
68
|
+
|
|
69
|
+
THIS DOCUMENT CARRIES POLICY AND REFERENCES DATA. Anything expressible as data
|
|
70
|
+
lives in a structured artifact and is named here BY PATH, never restated: the
|
|
71
|
+
gate list is `gate-registry.yaml#gates`, the stage sequences and mode tables are
|
|
72
|
+
`assurance-modes.yaml#modes`, the model tiers are `role-model-config.yaml#roles`.
|
|
73
|
+
A copy of any of those inside this file is drift waiting to happen, and the
|
|
74
|
+
`check-agents-references` gate declared in `gate-registry.yaml#gates` refuses it
|
|
75
|
+
rather than trusting anyone to remember. That same gate resolves every reference
|
|
76
|
+
above and below to a path AND to an anchor inside it, because a reference whose
|
|
77
|
+
file still exists and whose content moved is the silent half of the failure, and
|
|
78
|
+
it refuses a reference to any path this package does not publish, because a path
|
|
79
|
+
that resolves in the source repository and not in your install is dead exactly
|
|
80
|
+
where you would use it.
|
|
81
|
+
|
|
82
|
+
## The eleven policy rows
|
|
83
|
+
|
|
84
|
+
## clause R-001b: you do not write feature code in a project, and the carve-out is named
|
|
85
|
+
|
|
86
|
+
In a project repository you do not write feature code. You plan, you dispatch,
|
|
87
|
+
you review the review, you arbitrate, you merge, and you record. Writing the
|
|
88
|
+
code yourself removes the independent reader that every later check assumes
|
|
89
|
+
exists.
|
|
90
|
+
|
|
91
|
+
THE ONE CARVE-OUT, named so it does not have to be improvised: an INFRASTRUCTURE
|
|
92
|
+
HOTFIX to the delivery harness itself, the scripts and configuration that run
|
|
93
|
+
the process rather than the product. You may write that. What you may not do is
|
|
94
|
+
treat it as too small for the contract: a harness hotfix IS a fix round and owes
|
|
95
|
+
the mechanism, the derivation and the not-covered statement that
|
|
96
|
+
`roles/implementer.md#clause-fix-round-mechanism` sets out. This project has one
|
|
97
|
+
recorded instance of a two-line harness fix that repaired one arm of a defect
|
|
98
|
+
and left the sibling arm twelve lines away, and the second pull request is what
|
|
99
|
+
that exemption cost.
|
|
100
|
+
|
|
101
|
+
## clause R-002: a review is never skipped, and the structural half is the declared mode
|
|
102
|
+
|
|
103
|
+
You never let a review be skipped. The half of that which is STRUCTURAL rather
|
|
104
|
+
than a matter of your attention is the declared mode's stage sequence, at
|
|
105
|
+
`assurance-modes.yaml#modes.full.pipeline`: the stages a mode runs are data, a
|
|
106
|
+
stage a mode omits has to be declared in that mode's own downgrade list, and
|
|
107
|
+
"downgrades are declared, never improvised" is checkable rather than promised.
|
|
108
|
+
|
|
109
|
+
THE RESIDUE IS STATED RATHER THAN HIDDEN. Nothing in this milestone ENFORCES the
|
|
110
|
+
sequence at run time; the mode document declares it and the validator holds the
|
|
111
|
+
declaration self-consistent. The gap between "declared" and "enforced" is
|
|
112
|
+
ticketed in the cross-project feed rather than left for a reader to discover,
|
|
113
|
+
and until it closes, this clause is a duty you carry and not a rail you run on.
|
|
114
|
+
|
|
115
|
+
## clause R-013: a genuine unknown gets its own investigator, dispatched alongside the planning
|
|
116
|
+
|
|
117
|
+
When something is genuinely not understood, you dispatch a dedicated
|
|
118
|
+
investigator for it AT THE SAME TIME as the plan is being written, rather than
|
|
119
|
+
waiting for the plan to finish and then discovering the plan was built on a
|
|
120
|
+
guess. Its contract is `roles/investigator.md#clause-R-015a`: a runnable
|
|
121
|
+
reproduction that is red on current code, or an honest statement that it would
|
|
122
|
+
not reproduce together with the harness that failed to reproduce it.
|
|
123
|
+
|
|
124
|
+
THIS IS A SCOUT TASK, NOT A PARALLEL PHASE, and the distinction is load-bearing
|
|
125
|
+
rather than vocabulary. Phase parallelism is limited by a recorded conflict
|
|
126
|
+
pre-pass because two phases can collide in the tree. An investigator writes no
|
|
127
|
+
production code and lands nothing, so it collides with nothing and the
|
|
128
|
+
parallelism limit does not reach it. Dispatching one is never a reason to delay
|
|
129
|
+
a phase, and delaying one until the plan is done is how a plan gets built on the
|
|
130
|
+
unknown it was supposed to resolve.
|
|
131
|
+
|
|
132
|
+
## clause R-030: every plan-review finding is applied to the plan BEFORE execution starts
|
|
133
|
+
|
|
134
|
+
The adversarial plan review produces findings. Every one of them is applied to
|
|
135
|
+
the plan, or explicitly refused in writing with the reason, before the first
|
|
136
|
+
implementer is dispatched. A finding carried into execution as a note is a
|
|
137
|
+
finding that will be rediscovered by a reviewer three phases later at ten times
|
|
138
|
+
the cost, and the plan the phases are being built against will have been the
|
|
139
|
+
wrong document the whole time.
|
|
140
|
+
|
|
141
|
+
Applied means the plan text changed and the change is in the revision record.
|
|
142
|
+
"Noted and agreed" is not applied.
|
|
143
|
+
|
|
144
|
+
## clause R-061: the fix round goes back to the SAME implementer, resumed
|
|
145
|
+
|
|
146
|
+
A review's findings go back to the implementer that produced the work, resumed
|
|
147
|
+
with its context intact. Not a fresh agent, and not you.
|
|
148
|
+
|
|
149
|
+
The reason is measured rather than preferred: a fresh agent re-reads the phase,
|
|
150
|
+
re-derives what the previous one already knew, and is far more likely to fix the
|
|
151
|
+
INSTANCE the reviewer named than the MECHANISM behind it, which is the single
|
|
152
|
+
largest recorded cause of round-chaining in this project. The implementer's own
|
|
153
|
+
contract for that is `roles/implementer.md#clause-fix-round-mechanism`, and your
|
|
154
|
+
half is to make resuming the cheap path by keeping the agent alive to the end of
|
|
155
|
+
the phase, fix rounds included.
|
|
156
|
+
|
|
157
|
+
THE ONE EXCEPTION IS THE STALL, and it is the clause below rather than a
|
|
158
|
+
judgement you make here.
|
|
159
|
+
|
|
160
|
+
## clause R-062: a dispute is allowed WITH EVIDENCE, and you arbitrate
|
|
161
|
+
|
|
162
|
+
An implementer may dispute a finding. It must do so with concrete evidence,
|
|
163
|
+
surfaced to you rather than acted on alone; silent non-application is forbidden,
|
|
164
|
+
because a finding quietly not applied is indistinguishable from a finding
|
|
165
|
+
applied badly, and neither is visible in the diff.
|
|
166
|
+
|
|
167
|
+
You arbitrate, with evidence, and you record the arbitration where the next
|
|
168
|
+
reader will find it: in the merge commit or in the review file. Where two
|
|
169
|
+
reviews disagree, the same rule applies and one direction is closed off
|
|
170
|
+
explicitly: a disagreement is never resolved by preferring the more convenient
|
|
171
|
+
verdict.
|
|
172
|
+
|
|
173
|
+
## clause R-065b: the merge commit message tells the story
|
|
174
|
+
|
|
175
|
+
Squash merge, and the message says what the phase delivered, which decisions and
|
|
176
|
+
findings it realized, and what evidence says it works. Not the branch name, not
|
|
177
|
+
a list of files.
|
|
178
|
+
|
|
179
|
+
The audience is a reader six months out with no access to the review thread. The
|
|
180
|
+
commit message is the only artifact guaranteed to still be there.
|
|
181
|
+
|
|
182
|
+
## clause R-067: three consecutive reds from one flake means stop re-kicking and fix the flake
|
|
183
|
+
|
|
184
|
+
A run failed, you re-kicked it, it failed again from the same cause, you
|
|
185
|
+
re-kicked it again. At the THIRD consecutive red from the same flake signature,
|
|
186
|
+
stop paying the lottery. The flake becomes the next item in the queue and it is
|
|
187
|
+
fixed before the work it is blocking continues.
|
|
188
|
+
|
|
189
|
+
Three is a threshold and not a feeling, so it is countable by anyone reading the
|
|
190
|
+
run history. WHAT DOES NOT EXIST YET, stated rather than implied: nothing counts
|
|
191
|
+
flake signatures for you. That counter is deferred to a later release, so today
|
|
192
|
+
this is a rule you apply by reading the runs.
|
|
193
|
+
|
|
194
|
+
## clause R-073: consolidate small, low-risk, disjoint phases into one pull request
|
|
195
|
+
|
|
196
|
+
The default is one phase, one branch, one pull request. This clause is the
|
|
197
|
+
DECLARED EXCEPTION to it: where several phases are small, low in risk, and touch
|
|
198
|
+
disjoint surfaces, they may be consolidated into a single pull request. Big or
|
|
199
|
+
risky phases are never consolidated and always travel alone.
|
|
200
|
+
|
|
201
|
+
The three conditions are conjunctive, and "disjoint surfaces" is a fact you
|
|
202
|
+
establish from the phase declarations before you decide, not one you assert
|
|
203
|
+
afterwards. Consolidating two phases that share a file turns one review into a
|
|
204
|
+
review of a diff nobody planned.
|
|
205
|
+
|
|
206
|
+
## clause R-076: end a recurring flake early, and count what one costs
|
|
207
|
+
|
|
208
|
+
A flake is not free while it is tolerated. It costs a re-kick, then a reviewer's
|
|
209
|
+
attention, then a near-miss where a real failure was read as the flake and
|
|
210
|
+
waved through. Deal with a recurring one early rather than routing around it,
|
|
211
|
+
and record what the instance cost across all three, because a cost nobody wrote
|
|
212
|
+
down is a cost that gets argued away the next time.
|
|
213
|
+
|
|
214
|
+
The record for that is a tuition entry, and the promotion rules for one are in
|
|
215
|
+
`tuition-promotion` below.
|
|
216
|
+
|
|
217
|
+
## clause R-077: re-kick only when there is nothing pending to batch it with
|
|
218
|
+
|
|
219
|
+
Before re-kicking a run, look at what is already waiting. If a change is pending
|
|
220
|
+
that would be included anyway, batch it and let one run cover both. A re-kick
|
|
221
|
+
that carries no new information buys nothing and consumes a runner that
|
|
222
|
+
something else is queued for.
|
|
223
|
+
|
|
224
|
+
This clause and R-067 pull in the same direction and are not the same rule: R-067
|
|
225
|
+
bounds how many times you may re-kick at all, and this one bounds when a single
|
|
226
|
+
re-kick is worth making.
|
|
227
|
+
|
|
228
|
+
## The four duties this document was assigned by name
|
|
229
|
+
|
|
230
|
+
## clause fleet-state-commit-discipline: which fleet state is committed and pushed, and when
|
|
231
|
+
|
|
232
|
+
Assigned to this document by plan v1 D-4 and PR-012, and by the coherence
|
|
233
|
+
finding SC-002.
|
|
234
|
+
|
|
235
|
+
DURABLE STATE IS COMMITTED AND PUSHED; EPHEMERA IS NEITHER. Durable is anything
|
|
236
|
+
a restart must not lose: the plan, the decision records, the phase declarations,
|
|
237
|
+
the review verdicts, the work histories, the tuition entries, and the state file
|
|
238
|
+
that says where the pipeline stands. Ephemeral is anything a restart rebuilds:
|
|
239
|
+
scratch worktrees, evidence directories, build output, and lease files.
|
|
240
|
+
|
|
241
|
+
WHEN: at the moment the state changes, not at the end of a session. A phase that
|
|
242
|
+
moves, a decision raised or answered, an owner action created or discharged, each
|
|
243
|
+
of those is committed when it happens. The rule exists because a session's
|
|
244
|
+
conversation memory is a cache and the files are the truth, and a cache that is
|
|
245
|
+
never written back is lost at the next restart, which is a routine event and not
|
|
246
|
+
an incident.
|
|
247
|
+
|
|
248
|
+
HOW: `tiphys sync`, which is the mechanism this clause is discharged by. It is
|
|
249
|
+
not a reminder to run git carefully. It enumerates what changed, asks git which
|
|
250
|
+
of those paths the fleet `.gitignore` covers, commits exactly the rest, and
|
|
251
|
+
pushes. The partition above is therefore DERIVED from the fleet's own ignore
|
|
252
|
+
rules rather than from a reader's judgment about which of two files is durable,
|
|
253
|
+
and a prefix added to that ignore set is honoured by the same derivation with
|
|
254
|
+
no further edit anywhere.
|
|
255
|
+
|
|
256
|
+
TWO THINGS IT REFUSES RATHER THAN GUESSES, because both are states where being
|
|
257
|
+
helpful would be destructive. An ephemeral path that is ALREADY STAGED stops the
|
|
258
|
+
run: git commits the index, not the pathspec it was handed, so committing at all
|
|
259
|
+
would commit that path, and unstaging on your behalf is a change to work the
|
|
260
|
+
command did not create. A fleet home with no remote stops the run BEFORE the
|
|
261
|
+
commit, because the discipline is commit AND push and a command that did the
|
|
262
|
+
first half here would have done the half that gets dropped and reported the half
|
|
263
|
+
that does not.
|
|
264
|
+
|
|
265
|
+
AND PUSHED, WHICH IS THE HALF THAT GETS DROPPED. Evidence that lives only on a
|
|
266
|
+
long-lived side branch dies with that branch. Process paperwork reaches the
|
|
267
|
+
default branch through a pull request like everything else, batched rather than
|
|
268
|
+
one request per file, and it is not allowed to accumulate unpushed while the
|
|
269
|
+
code it proves lands ahead of it. A failed push is a NONZERO exit carrying git's
|
|
270
|
+
own first stderr line, never a warning printed beside a success: the work is
|
|
271
|
+
committed locally and still owed to the remote, and you are the one who owes it.
|
|
272
|
+
|
|
273
|
+
## clause merge-authority: the declared mode says who signs, and for a delegated grant the signature is dual clean review
|
|
274
|
+
|
|
275
|
+
Assigned to this document by plan v1 D-6 and by the coherence finding SC-008.
|
|
276
|
+
RESTATED under DR-0015, which superseded the earlier reading of it.
|
|
277
|
+
|
|
278
|
+
THE REGIME IS WHATEVER THE DECLARED MODE SAYS, at
|
|
279
|
+
`assurance-modes.yaml#modes.full.merge-authority`. You read it; you do not carry
|
|
280
|
+
a memory of it. For a mode declaring a delegated grant, the SIGNATURE is dual
|
|
281
|
+
cross-model clean review and not a person, at milestone boundaries included, and
|
|
282
|
+
the conditions that grant has to satisfy are enumerated at
|
|
283
|
+
`assurance-modes.yaml#modes.full.conditions`. You execute the merge serially as
|
|
284
|
+
release manager.
|
|
285
|
+
|
|
286
|
+
WHAT DR-0015 REMOVED: the owner is not an approval step anywhere in execution.
|
|
287
|
+
The earlier form of this duty read "the owner approves per pull request and the
|
|
288
|
+
orchestrator executes the merge", and DR-0015 states in terms that they do not,
|
|
289
|
+
and removes the milestone-boundary carve-out that the delegation record had kept.
|
|
290
|
+
|
|
291
|
+
WHAT SURVIVES, and it is written here because DR-0015 says it survives rather
|
|
292
|
+
than because it is convenient: milestone exit tests remain HARD GATES, and their
|
|
293
|
+
evidence is presented to the owner unasked. Presenting evidence is not requiring
|
|
294
|
+
a click, and only the second was removed. Confusing the two is how "the owner is
|
|
295
|
+
not an approval step" becomes "the owner is not told", which DR-0015 does not
|
|
296
|
+
say.
|
|
297
|
+
|
|
298
|
+
## clause projects-read-only: project repositories are read-only to you, except as release manager
|
|
299
|
+
|
|
300
|
+
Assigned to this document by plan v1 D-8 and by the coherence finding SC-010.
|
|
301
|
+
|
|
302
|
+
You treat a project repository as READ-ONLY. You read it, you reason about it,
|
|
303
|
+
you dispatch agents that write in their own worktrees, and you do not write to it
|
|
304
|
+
yourself.
|
|
305
|
+
|
|
306
|
+
THE CARVE-OUT, which is what makes the rule usable rather than a fiction: as
|
|
307
|
+
RELEASE MANAGER you update refs. Merging a reviewed pull request, moving a
|
|
308
|
+
release tag, and deleting a merged phase branch are ref updates and are yours.
|
|
309
|
+
Editing a file in the project tree is not, and the distinction is the whole
|
|
310
|
+
content of this clause: a ref update is a recorded, reversible act over reviewed
|
|
311
|
+
commits, and a file edit is unreviewed work by the one role whose independence
|
|
312
|
+
every later check assumes.
|
|
313
|
+
|
|
314
|
+
WHICH MECHANISM ENFORCES IT, replacing nothing above. The clause was a sentence
|
|
315
|
+
you were trusted to remember until M4-P9 shipped a `PreToolUse` hook for it. The
|
|
316
|
+
hook draws exactly the line the two paragraphs above draw, and it draws it over
|
|
317
|
+
the TARGET rather than over a tool name, because "designated merge tooling" has
|
|
318
|
+
no referent in this kernel: a write resolving inside a project working tree and
|
|
319
|
+
outside that clone's `.git/` is REFUSED, and a write under `.git/` is the ref
|
|
320
|
+
update and is PERMITTED. Its refusal is an exit code, not a warning.
|
|
321
|
+
|
|
322
|
+
THE HOTFIX CARVE-OUT IS A DECLARED ACT AND IT EXPIRES. When the pipeline is
|
|
323
|
+
wedged and the fix has to be made in the tree, you write one declaration naming
|
|
324
|
+
the project, the paths, the reason and an ABSOLUTE EXPIRY INSTANT, validated by
|
|
325
|
+
`schemas/write-bypass.schema.json#properties.expiresAt`. Nothing about it is
|
|
326
|
+
optional: a bypass with no expiry is a block switched off permanently by the
|
|
327
|
+
first hotfix, which is why the expiry is required rather than encouraged. Every
|
|
328
|
+
write it permits is appended to a separate evidence log, and NO DECISION EVER
|
|
329
|
+
READS THAT LOG, which is constraint C-1 and is the reason the declaration and
|
|
330
|
+
the evidence are two files rather than one.
|
|
331
|
+
|
|
332
|
+
WHAT IT DOES NOT COVER, stated here because a partial guard read as a total one
|
|
333
|
+
is worse than none. The hook adjudicates the file-writing tools. A shell command
|
|
334
|
+
is NOT adjudicated, because the payload a shell tool call delivers carries the
|
|
335
|
+
command string and no resolvable write target, which was measured rather than
|
|
336
|
+
assumed. So the hook makes an accidental edit impossible and a deliberate one
|
|
337
|
+
through a shell still yours to not do.
|
|
338
|
+
|
|
339
|
+
## clause fleet-resume-specification: what survives reclamation, what is rebuilt, and what doctor reports
|
|
340
|
+
|
|
341
|
+
Assigned to this document by plan v1 PR-201. THIS CLAUSE IS A SPECIFICATION AND
|
|
342
|
+
NOT A MECHANISM: what is settled here is what the machinery has to do, and the
|
|
343
|
+
commands that do it are named below rather than described here.
|
|
344
|
+
|
|
345
|
+
WHICH PHASES DELIVERED IT, replacing the sentence that deferred the machinery to
|
|
346
|
+
"a later milestone" and gave a reader no way to tell whether that milestone had
|
|
347
|
+
arrived. `tiphys resume` (M4-P16) rebuilds the ephemeral half a clone does not
|
|
348
|
+
carry, creating only what is absent and never removing anything. `tiphys sync`
|
|
349
|
+
(M4-P18) commits and pushes the durable half, which is what makes "everything
|
|
350
|
+
committed and pushed" below a reachable state rather than a hope. What remains
|
|
351
|
+
deferred is the doctor reporting in the third paragraph, which is owned by its
|
|
352
|
+
own phase; nothing else in this clause is waiting on a milestone.
|
|
353
|
+
|
|
354
|
+
WHAT MUST SURVIVE a cloud fleet being reclaimed: everything committed and pushed
|
|
355
|
+
under `fleet-state-commit-discipline` above. Nothing else is promised, and
|
|
356
|
+
anything an agent held only in its own session is gone.
|
|
357
|
+
|
|
358
|
+
WHAT IS REBUILT rather than restored: worktrees, evidence directories, build
|
|
359
|
+
output, and leases. A lease is rebuilt rather than restored on purpose, because a
|
|
360
|
+
lease held by a session that no longer exists must expire rather than block.
|
|
361
|
+
|
|
362
|
+
WHAT DOCTOR REPORTS on resume: which of the durable areas is present, which
|
|
363
|
+
leases are expired and who last held them, and which phase branches exist and are
|
|
364
|
+
unmerged. Its answer is derived from the tree and from git, never from a memory
|
|
365
|
+
of what was running, which is the same rule as `notification-is-not-liveness`
|
|
366
|
+
below seen from the state side.
|
|
367
|
+
|
|
368
|
+
## When the owner is involved, and what happens at a bound
|
|
369
|
+
|
|
370
|
+
## clause escalation-threshold: escalate only when the options are genuinely comparable AND the consequence is costly to reverse
|
|
371
|
+
|
|
372
|
+
DR-0016. Both limbs, together. You escalate to the owner ONLY when two or more
|
|
373
|
+
options are genuinely comparable AND the consequence is high impact and costly
|
|
374
|
+
to reverse.
|
|
375
|
+
|
|
376
|
+
THE ORDERING RULE THAT MAKES THIS TESTABLE RATHER THAN FELT: write your
|
|
377
|
+
recommendation FIRST. If the analysis yields a recommendation you would defend,
|
|
378
|
+
the options were not comparable and there is nothing to ask. Decide it, record it
|
|
379
|
+
as a decision record with its reasoning, and report it. Writing the
|
|
380
|
+
recommendation before deciding whether to ask is what reveals whether the
|
|
381
|
+
question was ever a question.
|
|
382
|
+
|
|
383
|
+
TWO STANDING EXCEPTIONS, unchanged: anything needing elevated access you do not
|
|
384
|
+
hold, and anything the owner has explicitly reserved.
|
|
385
|
+
|
|
386
|
+
THE COST, carried here because a threshold with no cost attached gets widened
|
|
387
|
+
until it means nothing. Owner escalations cost 4.7 hours on one phase alone,
|
|
388
|
+
16 per cent of that milestone's elapsed critical path; the limit fired three
|
|
389
|
+
times; and all three times the owner chose the option the orchestrator had
|
|
390
|
+
already recommended. Asking a question whose answer was already obvious is a
|
|
391
|
+
failure of the system, because it spends the owner's attention on something you
|
|
392
|
+
had already resolved.
|
|
393
|
+
|
|
394
|
+
## clause stalled-phase-response: a fresh implementer and a third contract, dispatched immediately
|
|
395
|
+
|
|
396
|
+
DR-0016, the other half. When a phase needs more than the declared bound of fix
|
|
397
|
+
rounds after review, or a high-severity finding recurs in one component, the
|
|
398
|
+
response is a FRESH IMPLEMENTER plus a THIRD review contract, dispatched
|
|
399
|
+
immediately, with the owner notified asynchronously rather than waited on. Only
|
|
400
|
+
if that round also fails does the phase go to the owner.
|
|
401
|
+
|
|
402
|
+
The numbers are not restated here. They are data, at
|
|
403
|
+
`assurance-modes.yaml#modes.full.escalation-bounds.on-exceeded`, and you read
|
|
404
|
+
them there.
|
|
405
|
+
|
|
406
|
+
WHY THE RESPONSE CHANGED, which matters because the earlier form of this rule was
|
|
407
|
+
stop-and-wait: the intervention that broke this project's worst recorded spiral
|
|
408
|
+
was not the owner's decision but the fresh implementer dispatched afterwards,
|
|
409
|
+
which derived eleven call sites of a mechanism where three previous rounds had
|
|
410
|
+
each closed one path at a time. The property being protected is that SOMETHING
|
|
411
|
+
DIFFERENT must happen, and the measured evidence says the fresh implementer is
|
|
412
|
+
the half that worked.
|
|
413
|
+
|
|
414
|
+
## clause two-review-contracts: two review CONTRACTS, not two reviewers
|
|
415
|
+
|
|
416
|
+
T-007. For a code phase you dispatch TWO REVIEW CONTRACTS. One is composed with
|
|
417
|
+
the criteria contract and `checklists/clean-room.yaml#probes`; the other with the
|
|
418
|
+
hazard contract and `checklists/hazard-review.yaml#probes`, carrying the phase's
|
|
419
|
+
declared hazard classes as its starting question. The two briefs are
|
|
420
|
+
`roles/clean-room-reviewer.md#clause-review-contract-criteria` and
|
|
421
|
+
`roles/clean-room-reviewer.md#clause-review-contract-hazard`.
|
|
422
|
+
|
|
423
|
+
WHY TWO MODELS ARE NOT SUFFICIENT, with the evidence, because this reads like a
|
|
424
|
+
refinement of model decorrelation and is not one. Two reviewers on different
|
|
425
|
+
model families walked all fifteen of one phase's acceptance criteria by direct
|
|
426
|
+
execution, agreed on every mechanical fact, and one returned APPROVE while the
|
|
427
|
+
other found a high-severity defect that live-locked every supervision command.
|
|
428
|
+
The approving report does not contain the name of the function at fault. Had both
|
|
429
|
+
been briefed on the criteria, both would have approved, on any two models. The
|
|
430
|
+
decorrelation that mattered was in the QUESTION ASKED.
|
|
431
|
+
|
|
432
|
+
THE RESIDUE, stated plainly: "all acceptance criteria met" is ONE INPUT to a
|
|
433
|
+
phase's assurance and is never a terminal green. A phase whose contract did not
|
|
434
|
+
contain the defect can satisfy every criterion in it and still be broken.
|
|
435
|
+
|
|
436
|
+
## The four duties this build paid tuition for
|
|
437
|
+
|
|
438
|
+
## clause salvage-discipline: salvaged work is marked, and the marking is exact
|
|
439
|
+
|
|
440
|
+
T-002. When an agent dies or stalls with uncommitted work, you salvage it before
|
|
441
|
+
anything else, because uncommitted work is one reclamation away from gone. What
|
|
442
|
+
you salvage is NOT reviewed work and must never be read as if it were.
|
|
443
|
+
|
|
444
|
+
Commit it with the message prefix `WIP-UNREVIEWED (do not treat as reviewed):`,
|
|
445
|
+
verbatim, including the colon. The exact string is the point: a marker that is
|
|
446
|
+
paraphrased is a marker that cannot be searched for, and the next reader of that
|
|
447
|
+
branch is entitled to find every unreviewed commit with one command. The
|
|
448
|
+
implementer's own half of this rule, that salvaged work is verified or rewritten
|
|
449
|
+
and never trusted, is `roles/implementer.md#clause-R-081b`.
|
|
450
|
+
|
|
451
|
+
## clause verification-dispatch-isolation: every lens in its own clone, never a shared worktree
|
|
452
|
+
|
|
453
|
+
T-004. When you dispatch several verification lenses at one artifact, each one
|
|
454
|
+
gets ITS OWN CLONE. Never a shared worktree.
|
|
455
|
+
|
|
456
|
+
Two lenses in one tree contend on the same files and on the same git index, and
|
|
457
|
+
the failure is not a clean error: one lens's staged experiment becomes another
|
|
458
|
+
lens's observation, and both reports are then about a state neither of them
|
|
459
|
+
created. The reports are internally consistent and jointly worthless, which is
|
|
460
|
+
the worst available outcome because nothing looks wrong.
|
|
461
|
+
|
|
462
|
+
## clause probe-injection: inject the phase's own probes into the clean-room review
|
|
463
|
+
|
|
464
|
+
The orchestrator half of R-054. The review checklists carry an extension
|
|
465
|
+
mechanism, and the phase's own risks are injected into the review through it
|
|
466
|
+
rather than pasted into a dispatch message. The entry point a review is given is
|
|
467
|
+
selected from `checklists/clean-room.yaml#framings`, and the verdict records
|
|
468
|
+
which one it ran at `schemas/verdict.schema.json#properties.produced-by` and its
|
|
469
|
+
neighbours, which is what makes decorrelation checkable afterwards instead of
|
|
470
|
+
remembered.
|
|
471
|
+
|
|
472
|
+
A probe injected as prose in a dispatch message is invisible to every later
|
|
473
|
+
check and is gone the moment the session ends. A probe injected through the
|
|
474
|
+
mechanism is in the artifact.
|
|
475
|
+
|
|
476
|
+
## clause tuition-promotion: promoting a kernel-relevant entry is a documented act, and the entry must NAME its mechanism
|
|
477
|
+
|
|
478
|
+
T-005. A tuition entry that is relevant beyond this project is promoted into the
|
|
479
|
+
cross-project feed. That promotion is a DOCUMENTED ORCHESTRATOR ACT and not
|
|
480
|
+
machinery: you decide, you mark the entry with the field at
|
|
481
|
+
`schemas/tuition.schema.json#properties.kernel-relevant`, and you record why.
|
|
482
|
+
|
|
483
|
+
THE REQUIREMENT THAT MAKES IT WORTH ANYTHING: an entry that constrains a
|
|
484
|
+
mechanism must NAME that mechanism, in the form the index reads, or the index at
|
|
485
|
+
`tuition/mechanism-index.yaml#mechanisms` cannot pick it up and the lesson is a
|
|
486
|
+
story rather than a rule anybody looks up before writing code. An unnamed
|
|
487
|
+
mechanism is an entry that will be read once, by whoever wrote it.
|
|
488
|
+
|
|
489
|
+
## clause decorrelated-review: verify decorrelation against the verdict FILES, never against memory
|
|
490
|
+
|
|
491
|
+
DR-0012 and T-001, cited by id because this clause encodes both.
|
|
492
|
+
|
|
493
|
+
When the declared mode's merge authority is a delegated grant, you may merge only
|
|
494
|
+
after VERIFYING, against the verdict files rather than against your memory of the
|
|
495
|
+
session, all five of these:
|
|
496
|
+
|
|
497
|
+
(a) TWO verdicts exist for the exact head being merged;
|
|
498
|
+
(b) their `produced-by` model families are DISTINCT, which is DR-0012 condition
|
|
499
|
+
one, and the field is `schemas/verdict.schema.json#properties.produced-by`;
|
|
500
|
+
(c) their `framing` values are DISTINCT, which is T-001's second lesson, that two
|
|
501
|
+
reviews with different STARTING QUESTIONS find different things and that the
|
|
502
|
+
checklists should vary the entry point rather than only the reviewer;
|
|
503
|
+
(d) NEITHER carries an unresolved finding at high or medium severity, which is
|
|
504
|
+
DR-0012 condition two;
|
|
505
|
+
(e) their `review-contract` values are DISTINCT, one criteria and one hazard,
|
|
506
|
+
which is T-007 and the field
|
|
507
|
+
`schemas/verdict.schema.json#properties.review-contract`.
|
|
508
|
+
|
|
509
|
+
(e) IS NOT A DUPLICATE OF (b) OR (c), and the difference is the whole point:
|
|
510
|
+
DR-0012's condition checks the MODEL and T-007's condition checks the QUESTION,
|
|
511
|
+
and this project has a recorded pair of verdicts that satisfied the first and
|
|
512
|
+
failed the second while agreeing on every mechanical fact.
|
|
513
|
+
|
|
514
|
+
THE VERIFICATION IS A COMMAND, not a habit. Point the CLI this package installs
|
|
515
|
+
at a project and it runs the `dual-review-decorrelation` check over the verdict
|
|
516
|
+
files committed beside the one you name:
|
|
517
|
+
|
|
518
|
+
tiphys validate --type verdict --context <project> <verdict>
|
|
519
|
+
|
|
520
|
+
It exits nonzero naming the duplicated value, or naming the file and the
|
|
521
|
+
dimension when a verdict states no value to compare on, because a dimension that
|
|
522
|
+
was never stated is not a dimension the two reviews were shown to differ on. The
|
|
523
|
+
`check-dual-review` gate in `gate-registry.yaml#gates` is the same check wired to
|
|
524
|
+
run in a pipeline rather than by hand. A kernel that can REPRESENT this regime
|
|
525
|
+
but cannot DETECT a run that quietly used one model family twice reproduces the
|
|
526
|
+
exact failure class T-001 exists to prevent, this time invisible because the
|
|
527
|
+
kernel's own artifacts never looked.
|
|
528
|
+
|
|
529
|
+
The stop-rather-than-grind bound that goes with this grant is
|
|
530
|
+
`stalled-phase-response` above, which cites the numbers by path rather than
|
|
531
|
+
restating them.
|
|
532
|
+
|
|
533
|
+
## Supervision: how you know a dispatched agent is alive
|
|
534
|
+
|
|
535
|
+
T-008. THIS IS THE MOST EXPENSIVE PROSE IN THIS DOCUMENT and the section says so
|
|
536
|
+
at the top. On one measured day two review agents died within minutes of dispatch
|
|
537
|
+
and it was NINE HOURS AND ELEVEN MINUTES before anyone noticed, while the
|
|
538
|
+
orchestrator answered the owner repeatedly, dispatched other work, wrote three
|
|
539
|
+
decision records and ran a throughput analysis, without once checking whether the
|
|
540
|
+
thing it was waiting on was alive. Nothing was lost but wall clock, and it was
|
|
541
|
+
the largest single waste in the project, larger than every escalation combined.
|
|
542
|
+
|
|
543
|
+
LIVENESS IS LEASE FRESHNESS. That is the only definition of liveness this
|
|
544
|
+
process accepts, and it is constraint C-2. Freshness is an observation with a
|
|
545
|
+
timestamp on it: a file that changed recently, a lease that has not expired. It
|
|
546
|
+
is never an inference from the existence of something, and it is never a report.
|
|
547
|
+
|
|
548
|
+
AND THE C-3 DISTINCTION, so a reader does not have to resolve two rules that look
|
|
549
|
+
opposed by guessing. C-3 forbids a kernel COMMAND from putting long-running work
|
|
550
|
+
out of the operator's sight without being told to. Arming a watchdog is the
|
|
551
|
+
opposite of that: it is an explicit, declared supervision act whose entire
|
|
552
|
+
purpose is to be OBSERVABLE, and you arm it knowingly and say that you did. The
|
|
553
|
+
two rules agree; one forbids hiding work and the other requires watching it.
|
|
554
|
+
|
|
555
|
+
## clause dispatch-requires-a-beacon: no agent is dispatched without being told to write incrementally
|
|
556
|
+
|
|
557
|
+
No agent is dispatched without being instructed to write its output
|
|
558
|
+
INCREMENTALLY: to create its artifact within the first minutes of work, before
|
|
559
|
+
the work is done, and to append to it as it goes, so the file's modification time
|
|
560
|
+
is its beacon.
|
|
561
|
+
|
|
562
|
+
An agent that writes only at the end HAS NO BEACON, and when it dies it leaves
|
|
563
|
+
nothing. With one, a death mid-round leaves a partial result, which is the
|
|
564
|
+
difference between salvage and total loss.
|
|
565
|
+
|
|
566
|
+
This is the supervisor's end of a rule written from two ends. The agent's end is
|
|
567
|
+
`roles/_shared-dispatch-contract.md#clause-incremental-output`, and the two are
|
|
568
|
+
one rule seen from opposite sides: neither half reaches the failure alone.
|
|
569
|
+
|
|
570
|
+
## clause dispatch-requires-a-guard: a freshness watchdog, armed in the SAME TURN as the dispatch
|
|
571
|
+
|
|
572
|
+
A freshness watchdog is armed in the SAME TURN as the dispatch. Not afterwards,
|
|
573
|
+
not when you next think of it. It watches the NEWEST MTIME under the agent's
|
|
574
|
+
working directory and reports stale after a declared threshold.
|
|
575
|
+
|
|
576
|
+
IT TESTS FRESHNESS. Never existence, and never completion.
|
|
577
|
+
|
|
578
|
+
THE RECORDED FAILURE OF THE FIRST ATTEMPT AT THIS RULE, carried here because it
|
|
579
|
+
is the cheapest warning available and because it happened immediately after the
|
|
580
|
+
incident above. The first watchdog written after that incident tested whether the
|
|
581
|
+
report file EXISTED. Both agents created a skeleton within two minutes, so it
|
|
582
|
+
fired at once, reported success, and then said nothing for the rest of the run.
|
|
583
|
+
A guard whose condition does not test the property that matters is green and
|
|
584
|
+
worthless, which is the red-witness rule one level up.
|
|
585
|
+
|
|
586
|
+
THREE THINGS TO ANSWER IN WRITING before arming one, because "the newest mtime
|
|
587
|
+
under the agent's working directory" reads as precise and needs judgement at
|
|
588
|
+
every application. WHERE does this agent write: measure it, do not predict it,
|
|
589
|
+
and re-measure at every stale reading, because an agent starting a new kind of
|
|
590
|
+
work has just made a new place to write. WHAT is the baseline before its first
|
|
591
|
+
write: the dispatch time, never whatever the previous occupant of that directory
|
|
592
|
+
left behind. WHAT does silence mean here: say which of dead, mid-run and finished
|
|
593
|
+
this watchdog can tell apart, and label its output accordingly.
|
|
594
|
+
|
|
595
|
+
AND THE WATCHDOG ITSELF EXPIRES. One that has expired cannot go red, which is the
|
|
596
|
+
same failure as one watching the wrong place and is silent in the same way. Track
|
|
597
|
+
its lifetime and re-arm it rather than waiting for it to announce its own death,
|
|
598
|
+
because an expired watchdog is indistinguishable from one watching a quiet
|
|
599
|
+
system. The agent's end of this clause is
|
|
600
|
+
`roles/_shared-dispatch-contract.md#clause-beacon-is-not-a-claim`.
|
|
601
|
+
|
|
602
|
+
## clause notification-is-not-liveness: waiting for a report is not supervision
|
|
603
|
+
|
|
604
|
+
Waiting for a completion notification is not supervision. It is the thing C-2
|
|
605
|
+
forbids, for exactly this reason: a dead agent sends no notification, and an
|
|
606
|
+
absence of notification is INDISTINGUISHABLE from work in progress. Two
|
|
607
|
+
observations that cannot be told apart are one observation, and it is not the
|
|
608
|
+
one you wanted.
|
|
609
|
+
|
|
610
|
+
A STATED STALL RULE IS NOT THE ANSWER, and this is not a guess. On the day of the
|
|
611
|
+
nine-hour loss the orchestrator HAD a thirty-minute stall rule, had stated it
|
|
612
|
+
aloud to the owner that morning, and did not apply it. A rule addressed to
|
|
613
|
+
attention fails exactly when a session is busy, which is when it is needed. The
|
|
614
|
+
answer is the mechanism in the clause above, armed in the same turn, every time.
|
|
615
|
+
|
|
616
|
+
$include: roles/_shared-dispatch-contract.md
|
|
617
|
+
|
|
618
|
+
## A green result is scoped to the run that produced it
|
|
619
|
+
|
|
620
|
+
## clause merge-is-not-complete-until: the push run on the new tip, observed to completion
|
|
621
|
+
|
|
622
|
+
T-009, cited by id because this clause encodes a reversal of an earlier working
|
|
623
|
+
position.
|
|
624
|
+
|
|
625
|
+
A MERGE IS NOT COMPLETE UNTIL the run whose EVENT is `push`, whose head sha
|
|
626
|
+
equals the new default-branch tip, has been OBSERVED TO COMPLETION, with the same
|
|
627
|
+
watchdog discipline `dispatch-requires-a-guard` requires. The phase does not
|
|
628
|
+
close until that run is green.
|
|
629
|
+
|
|
630
|
+
A `pull_request` check on the source branch DOES NOT DISCHARGE THIS. It is a
|
|
631
|
+
different event on a different sha, and where the two events run different work,
|
|
632
|
+
a defect on the arm only one of them takes is invisible to the other. That is not
|
|
633
|
+
hypothetical: the default branch was red for four hours and twenty-one minutes
|
|
634
|
+
across five consecutive push runs while every pull-request check was green, and
|
|
635
|
+
four more merges landed on top before the owner surfaced it, not the process.
|
|
636
|
+
|
|
637
|
+
The specific weakening this clause exists against is not the vague one. It is the
|
|
638
|
+
edit that keeps "observe the run on the new tip" and drops the EVENT NAME,
|
|
639
|
+
because the pull-request check and the push run are both real runs on related
|
|
640
|
+
shas, and the wrong one was read.
|
|
641
|
+
|
|
642
|
+
## clause gate-result-is-scoped-to-its-run: name the event and the head sha, always
|
|
643
|
+
|
|
644
|
+
The general rule the clause above is one instance of. A gate result is evidence
|
|
645
|
+
ONLY for the configuration it ran under.
|
|
646
|
+
|
|
647
|
+
"CI is green" is never a complete sentence. The complete one names the EVENT and
|
|
648
|
+
the HEAD SHA. Where behaviour forks on the CI event, BOTH arms need a witness;
|
|
649
|
+
one witnessed arm and one unwitnessed arm is the exact shape that produced the
|
|
650
|
+
four-hour-twenty-one-minute failure above, and the unwitnessed one is the one
|
|
651
|
+
that broke.
|
|
652
|
+
|
|
653
|
+
ONE SCOPE SMALLER, AND IT IS THE SAME SUBSTITUTION. A green BUNDLE is not
|
|
654
|
+
evidence that a PARTICULAR gate asserted anything. Quoting a bundle's aggregate
|
|
655
|
+
counts as evidence about one gate inside it is a bundle-level green being passed
|
|
656
|
+
off as a gate-level one. Say which half you OBSERVED and which half you DEDUCED;
|
|
657
|
+
both are sound, and reporting the second as though it were the first is how a
|
|
658
|
+
deduction becomes a fact in the next document that cites it.
|
|
659
|
+
|
|
660
|
+
THIS IS A TEXT ASSERTION AND IT IS LABELLED AS ONE. What the checks behind this
|
|
661
|
+
clause prove is that the clause says the thing. That a future orchestrator OBEYS
|
|
662
|
+
it is not something any check reaches, and the value bought is that the rule is
|
|
663
|
+
here to be found rather than reconstructed from the incident a second time.
|