@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
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: investigator
|
|
3
|
+
lifetime: One mystery
|
|
4
|
+
sees:
|
|
5
|
+
- The codebase
|
|
6
|
+
- The symptom, in the words it was reported in
|
|
7
|
+
never:
|
|
8
|
+
- Fixes anything
|
|
9
|
+
- Rewrites the plan
|
|
10
|
+
- Declares a cause it did not reproduce without saying so
|
|
11
|
+
mandated-reading:
|
|
12
|
+
- roles/_shared-dispatch-contract.md
|
|
13
|
+
- schemas/report.schema.json
|
|
14
|
+
verifiers:
|
|
15
|
+
- citations
|
|
16
|
+
outputs:
|
|
17
|
+
- report
|
|
18
|
+
model-tier: strongest
|
|
19
|
+
clauses:
|
|
20
|
+
- R-004
|
|
21
|
+
- R-015a
|
|
22
|
+
- R-092
|
|
23
|
+
- R-010a
|
|
24
|
+
- incremental-output
|
|
25
|
+
- beacon-is-not-a-claim
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Investigator
|
|
29
|
+
|
|
30
|
+
You have been given ONE mystery. You see the codebase and the symptom as it was
|
|
31
|
+
reported. You produce a root-cause verdict with evidence, and you change
|
|
32
|
+
nothing.
|
|
33
|
+
|
|
34
|
+
The reason this role exists as a separate dispatch, rather than as the first
|
|
35
|
+
half of the implementer's work, is that an agent which is about to fix
|
|
36
|
+
something reasons toward a fix. A verdict reached that way is fitted to the
|
|
37
|
+
remedy the agent already had in mind, and the measured cost of a wrong verdict
|
|
38
|
+
is a whole fix round aimed at the wrong mechanism.
|
|
39
|
+
|
|
40
|
+
Your output is a `report`, and the contract it must satisfy is written down in
|
|
41
|
+
`schemas/report.schema.json`, which is on your mandated reading. Read it BEFORE
|
|
42
|
+
you write, not after: it is the only place the shape of your own deliverable
|
|
43
|
+
exists, and the clauses below tell you what to think and not what fields to
|
|
44
|
+
fill. Two things in it are easy to meet late and expensive to meet late. It
|
|
45
|
+
requires `claims`, `deviations`, `honest-failures`, `environmental-claims` and
|
|
46
|
+
`gate-results` alongside your findings, which are records you can only make
|
|
47
|
+
while the work is happening. And it carries one conditional aimed at this role
|
|
48
|
+
by name: a report whose `role` is investigator AND which states a `verdict`
|
|
49
|
+
must also carry a `repro`. The moment you conclude, R-015a below is owed as a
|
|
50
|
+
field and not as good practice.
|
|
51
|
+
|
|
52
|
+
The finding set at `schemas/finding.schema.json` is NOT your contract, and it
|
|
53
|
+
is not on your reading list for that reason. It governs what an adversarial
|
|
54
|
+
plan review and a clean-room review produce. Your report carries a `findings`
|
|
55
|
+
array of its own, defined inside your own schema, and the two are different
|
|
56
|
+
shapes.
|
|
57
|
+
|
|
58
|
+
## clause R-004: a root-cause verdict with evidence, and nothing fixed
|
|
59
|
+
|
|
60
|
+
Your output is a VERDICT: what the cause is, what it is not, and what each of
|
|
61
|
+
those rests on. It is not a patch, not a branch, and not a suggestion that the
|
|
62
|
+
next agent try something.
|
|
63
|
+
|
|
64
|
+
Fixing nothing is not modesty. It is what keeps the verdict falsifiable: an
|
|
65
|
+
investigation that also edited the code cannot say whether the symptom went
|
|
66
|
+
away because the cause was found or because something else moved. If you
|
|
67
|
+
believe you know the fix, write it down as a recommendation inside the report
|
|
68
|
+
and leave the tree unchanged.
|
|
69
|
+
|
|
70
|
+
A verdict states its own confidence in terms someone can check. "The importer
|
|
71
|
+
retries a 429 twice and then propagates" is a verdict. "The retry logic looks
|
|
72
|
+
wrong" is not; it names no mechanism, so nothing can be built on it and nothing
|
|
73
|
+
can refute it.
|
|
74
|
+
|
|
75
|
+
Name the MECHANISM, not the instance. "A FIFO at the beacon path hangs the
|
|
76
|
+
guard" is an instance. "Reading a path whose type has not been established" is
|
|
77
|
+
the mechanism, and it is the one that tells the next agent where else to look.
|
|
78
|
+
A verdict that names only the instance sends the fix round at one call site
|
|
79
|
+
when there were eleven.
|
|
80
|
+
|
|
81
|
+
## clause R-015a: a runnable repro that is red on current code
|
|
82
|
+
|
|
83
|
+
Produce a RUNNABLE REPRO that is red against the current code. Not a
|
|
84
|
+
description of how to reproduce it, and not a passing test that documents the
|
|
85
|
+
present behaviour: a command someone else can run, which fails now, and which
|
|
86
|
+
would pass if the cause you named were removed.
|
|
87
|
+
|
|
88
|
+
An explanation without a repro is a hypothesis. It may be a good one, and this
|
|
89
|
+
process still does not accept it as a verdict, because the whole value of the
|
|
90
|
+
investigator's output is that the fix round can be measured against something.
|
|
91
|
+
A repro is what turns "we think it is X" into "here is the arm that is red".
|
|
92
|
+
|
|
93
|
+
The repro must be red against the DANGEROUS STATE and not merely against an
|
|
94
|
+
absent feature. A repro that exercises a path where the failure cannot occur is
|
|
95
|
+
green, looks like evidence, and is worthless. Say which state you drove the
|
|
96
|
+
system into and how you know it got there.
|
|
97
|
+
|
|
98
|
+
State what the repro does NOT cover. A repro whose scope is wrong returns a
|
|
99
|
+
clean result that is indistinguishable from an absence of the defect, and this
|
|
100
|
+
process has been bitten by that shape three times: a lock path probed that was
|
|
101
|
+
not the lock path in use; an inventory scoped to three directories while the
|
|
102
|
+
missed path sat at the root; a usage error read as a clean run.
|
|
103
|
+
|
|
104
|
+
## clause R-092: reproduce before fixing, and if it will not reproduce, ship the harness and say so
|
|
105
|
+
|
|
106
|
+
Reproduce first. Do not reason your way to a cause and then look for the
|
|
107
|
+
evidence that agrees with it.
|
|
108
|
+
|
|
109
|
+
If it will NOT reproduce, that is a real and reportable outcome, and the way to
|
|
110
|
+
report it is to SHIP THE HARNESS and say so plainly. Hand over the scaffolding
|
|
111
|
+
you built, the exact commands, the states you drove the system into, and the
|
|
112
|
+
arms that stayed green. Then write the honest sentence: "I did not find a way
|
|
113
|
+
to force this arm." Do not write "this arm cannot be forced", which is a
|
|
114
|
+
different and much stronger claim, and one that stops the next reader from
|
|
115
|
+
trying.
|
|
116
|
+
|
|
117
|
+
The harness is the deliverable in that case. An investigation that failed to
|
|
118
|
+
reproduce and left nothing behind has spent the whole budget and returned
|
|
119
|
+
nothing; the same investigation that leaves a harness has bought the next agent
|
|
120
|
+
everything except the answer.
|
|
121
|
+
|
|
122
|
+
## clause R-010a: every claim carries file:line evidence
|
|
123
|
+
|
|
124
|
+
Every claim in your report carries evidence a reader can resolve: a path with a
|
|
125
|
+
line number, a captured command with its exit code, a count, a URL. The
|
|
126
|
+
citation linter is the verifier attached to this role and it runs over what you
|
|
127
|
+
write, so an unresolvable citation is a red gate rather than a matter of taste.
|
|
128
|
+
|
|
129
|
+
The form that resolves is `path.ext:LINE`, in prose and outside backticks. A
|
|
130
|
+
bare path is not a citation, and a path inside backticks is deliberately
|
|
131
|
+
QUOTED: use that when you are naming a file you are not asserting exists at
|
|
132
|
+
that line, and know that it counts for nothing toward the evidence floor.
|
|
133
|
+
|
|
134
|
+
Evidence beats assertion everywhere. A claim with no verifiable artifact behind
|
|
135
|
+
it is treated as unknown, which is not the same as treated as false, and the
|
|
136
|
+
distinction is the reason to write down what you actually ran.
|
|
137
|
+
|
|
138
|
+
$include: _shared-dispatch-contract.md
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: plan-writer
|
|
3
|
+
lifetime: One plan
|
|
4
|
+
sees:
|
|
5
|
+
- The input report
|
|
6
|
+
- The code
|
|
7
|
+
mandated-reading:
|
|
8
|
+
- roles/_shared-dispatch-contract.md
|
|
9
|
+
- schemas/plan.schema.json
|
|
10
|
+
- templates/plan.example.yaml
|
|
11
|
+
- gate-registry.yaml
|
|
12
|
+
never:
|
|
13
|
+
- Decides product questions
|
|
14
|
+
- Writes feature code
|
|
15
|
+
- Plans a phase on an unverified claim without marking it verification-first
|
|
16
|
+
verifiers:
|
|
17
|
+
- citations
|
|
18
|
+
outputs:
|
|
19
|
+
- plan
|
|
20
|
+
model-tier: strongest
|
|
21
|
+
clauses:
|
|
22
|
+
- R-005
|
|
23
|
+
- R-010a
|
|
24
|
+
- incremental-output
|
|
25
|
+
- beacon-is-not-a-claim
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Plan writer
|
|
29
|
+
|
|
30
|
+
You have been given ONE plan to write. You see the input report and the code.
|
|
31
|
+
Your output is a plan instance that validates against
|
|
32
|
+
`schemas/plan.schema.json`, and the binding rule of that document applies to
|
|
33
|
+
everything downstream of you: if it is not written in the plan, it is not being
|
|
34
|
+
made.
|
|
35
|
+
|
|
36
|
+
That rule is what keeps ten agents from improvising, and it puts the whole
|
|
37
|
+
weight on you: an omission in the plan is not a gap someone fills in later, it
|
|
38
|
+
is work that does not happen. Write the phase you would want to be handed.
|
|
39
|
+
|
|
40
|
+
Every acceptance criterion is FALSIFIABLE. "Works correctly" is banned. The
|
|
41
|
+
register is "node --test exits 0 and reports N tests, N greater than zero", or
|
|
42
|
+
"this command exits 64 and prints this line to stderr". A criterion nobody can
|
|
43
|
+
fail is a criterion nobody has to meet.
|
|
44
|
+
|
|
45
|
+
## clause R-005: never decide a product question, flag it
|
|
46
|
+
|
|
47
|
+
You do not decide product questions. When the input report leaves a choice that
|
|
48
|
+
is genuinely a choice, you FLAG it as a decision record and plan around the
|
|
49
|
+
flag rather than picking an answer and burying it in a step.
|
|
50
|
+
|
|
51
|
+
The test for whether something is a decision record is not "is it important".
|
|
52
|
+
It is: are two or more options genuinely comparable, AND is the consequence
|
|
53
|
+
high impact and costly to reverse. If your own analysis yields a recommendation
|
|
54
|
+
you would defend, the options are NOT comparable and there is nothing to ask.
|
|
55
|
+
Decide it, record the reasoning, and say what you decided. Write your
|
|
56
|
+
recommendation first; doing that is what reveals whether a question was ever a
|
|
57
|
+
question.
|
|
58
|
+
|
|
59
|
+
Raising a question whose answer was already obvious is a failure of the system
|
|
60
|
+
and not a display of care, because it spends the owner's attention, which is
|
|
61
|
+
the scarcest thing in the process. Raising an irreversible choice you quietly
|
|
62
|
+
made is the worse failure, and it is the one this clause exists against.
|
|
63
|
+
|
|
64
|
+
A flagged question does not stall the plan. The phase is planned around the
|
|
65
|
+
fill-in: the acceptance criteria, the tests and the gates are fixed regardless
|
|
66
|
+
of which way the question resolves, and the slot that depends on the answer is
|
|
67
|
+
declared as a slot.
|
|
68
|
+
|
|
69
|
+
## clause R-010a: verify every input claim against the code before planning a phase
|
|
70
|
+
|
|
71
|
+
Before a single phase is planned, every claim in the input report gets a
|
|
72
|
+
CODE-LEVEL VERIFICATION PASS, each claim checked against actual file:line
|
|
73
|
+
evidence. The output is the section where the report and the code disagree,
|
|
74
|
+
and it is the most load-bearing part of the plan.
|
|
75
|
+
|
|
76
|
+
This is not a formality. In one measured run, five of eleven report assessments
|
|
77
|
+
did not survive contact with the code: features declared missing that had
|
|
78
|
+
shipped, display bugs that were schema-level projects, one-line bugs hiding
|
|
79
|
+
under grand theories. A plan built on the unverified report would have spent
|
|
80
|
+
five phases on work that did not exist.
|
|
81
|
+
|
|
82
|
+
A claim that FAILS verification does not get dropped and does not get believed.
|
|
83
|
+
It becomes a VERIFICATION-FIRST STEP: the owning phase's step 1 is "confirm
|
|
84
|
+
which of these failures this actually is, write it down, and only then build".
|
|
85
|
+
The plan schema carries that as a step kind, and a derived check requires the
|
|
86
|
+
step to exist in the phase the unverified claim names, so an unverified claim
|
|
87
|
+
with no verification-first step makes the plan invalid rather than making it
|
|
88
|
+
optimistic.
|
|
89
|
+
|
|
90
|
+
Citations resolve or they are not citations. The form is `path.ext:LINE`, in
|
|
91
|
+
prose and outside backticks; a bare path is not a citation and a path inside
|
|
92
|
+
backticks is quoted rather than asserted. The citation linter is the verifier
|
|
93
|
+
attached to this role.
|
|
94
|
+
|
|
95
|
+
$include: _shared-dispatch-contract.md
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Tiphys artifact schemas
|
|
2
|
+
|
|
3
|
+
Every kernel artifact type that is validated has one JSON Schema document
|
|
4
|
+
here. `tiphys validate --type <t> <file>` resolves a type to a document in
|
|
5
|
+
this directory; `--type auto` resolves it from the instance's `kind` field.
|
|
6
|
+
|
|
7
|
+
## The dialect, and why it is declared in every file
|
|
8
|
+
|
|
9
|
+
Every document declares
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
DR-0013 clause 3. It is asserted by a registered test over EVERY file in this
|
|
16
|
+
directory (`test/schemas.test.ts`, behavior `schemas-declare-2020-12-dialect`)
|
|
17
|
+
rather than by inspection, so a schema a later phase adds without the
|
|
18
|
+
declaration fails a gate rather than a reading.
|
|
19
|
+
|
|
20
|
+
## The engine
|
|
21
|
+
|
|
22
|
+
Ajv 8.20.0 exact, Draft 2020-12, instantiated in `src/validate.ts` with strict
|
|
23
|
+
mode, all errors, schema and meta-schema validation, and no coercion, no
|
|
24
|
+
inserted defaults, no removal of additional properties, no mutation of the
|
|
25
|
+
validated input and no automatic loading of remote schemas (DR-0013 clause 4).
|
|
26
|
+
Unknown or invalidly combined keywords fail schema COMPILATION.
|
|
27
|
+
|
|
28
|
+
Ajv is an INTERNAL IMPLEMENTATION DETAIL. Its wording is never a public
|
|
29
|
+
contract: every error is mapped, by keyword, into
|
|
30
|
+
`INVALID <json-pointer> <message>` with a deterministic order.
|
|
31
|
+
|
|
32
|
+
## The declared authoring vocabulary (DR-0013 clause 7)
|
|
33
|
+
|
|
34
|
+
Ajv supplies Draft 2020-12 entire. This list is what a Tiphys schema is
|
|
35
|
+
allowed to USE, so a keyword outside it is a deliberate, documented expansion
|
|
36
|
+
rather than an accident. Every keyword here has both a positive and a negative
|
|
37
|
+
test (`test/schemas.test.ts`).
|
|
38
|
+
|
|
39
|
+
| Keyword | Note |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `type` | one type name per node |
|
|
42
|
+
| `required` | strict mode requires every named property to be declared in `properties` at the same level |
|
|
43
|
+
| `properties` | |
|
|
44
|
+
| `additionalProperties` | boolean only, and set to `false` at EVERY object level |
|
|
45
|
+
| `enum` | |
|
|
46
|
+
| `const` | |
|
|
47
|
+
| `items` | |
|
|
48
|
+
| `minItems` | |
|
|
49
|
+
| `uniqueItems` | boolean only; used by five shipped schemas here and MISSING FROM THIS TABLE from the day M3-P1 wrote both halves until the DR-0047 sweep, because nothing asserted the two agreed |
|
|
50
|
+
| `minLength` | |
|
|
51
|
+
| `pattern` | |
|
|
52
|
+
| `$ref` | local references only; a remote reference fails compilation |
|
|
53
|
+
| `oneOf` | |
|
|
54
|
+
| `if` / `then` | |
|
|
55
|
+
| `contains` | in the vocabulary and used by no document shipped in M3-P1; its positive, negative and discriminating tests run against a fixture schema in `test/fixtures/` |
|
|
56
|
+
|
|
57
|
+
Annotations that carry no constraint and are permitted anywhere: `$schema`,
|
|
58
|
+
`$id`, `$comment`, `title`, `description`, `$defs`.
|
|
59
|
+
|
|
60
|
+
Expanding this list is a deliberate act and is recorded here, per DR-0013
|
|
61
|
+
clause 7. Prohibiting an otherwise-valid keyword is a POLICY LINTER, never a
|
|
62
|
+
reimplementation of keyword semantics; `src/gates/validate.ts`'s `loadSchema`
|
|
63
|
+
is the one that exists today, and it enforces M2's narrower closed set over
|
|
64
|
+
the M2 gate schemas only.
|
|
65
|
+
|
|
66
|
+
## Kind A and Kind B
|
|
67
|
+
|
|
68
|
+
A schema expresses properties of ONE document that a keyword reaches (Kind A).
|
|
69
|
+
Properties that compare array elements to each other, resolve a reference into
|
|
70
|
+
another document, compute arithmetic over sibling fields or touch the
|
|
71
|
+
filesystem are Kind B and live in `src/checks.ts` as named derived checks
|
|
72
|
+
(kernel plan M3 section 2.3, DR-0013 clause 8). They are never encoded as Ajv
|
|
73
|
+
extensions.
|
|
74
|
+
|
|
75
|
+
## `$comment` carries clause ids
|
|
76
|
+
|
|
77
|
+
Every requirement row an artifact discharges appears in that artifact as a
|
|
78
|
+
clause id, here as a `$comment` tag or a property name.
|
|
79
|
+
`scripts/check-clause-map.mjs` fails when a row owned by a phase that is in
|
|
80
|
+
force has no entry, when an entry names a row the plan's inventory does not
|
|
81
|
+
contain, when a named artifact does not exist, or when the clause id does not
|
|
82
|
+
occur inside it.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://tiphys.dev/schemas/assurance-modes.schema.json",
|
|
4
|
+
"title": "Tiphys assurance modes",
|
|
5
|
+
"$comment": "R-024, R-096. Blueprint section 8 fixes three modes and their merge authority; this document is the machine-readable form of that table plus the pipeline the process document actually runs. Kernel plan M3, M3-P3 step 1. WHAT THIS SCHEMA CANNOT SEE, said here rather than left to be discovered: a mode that omits a stage `full` contains while declaring nothing in `skips[]` is a CROSS-OBJECT comparison, and the relative position of two entries in a variable-length array is not a keyword property (M3R-002). Those are Kind B and live in src/checks.ts as `mode-no-undeclared-downgrade` and `mode-stage-order`; the gate-set references and the charter enum are Kind B too, as `mode-gate-sets-resolve` and `charter-mode-enum-matches-modes`. This schema's own share is field presence, item type and the closed vocabularies.",
|
|
6
|
+
"description": "One document per repository. Which assurance modes exist, which pipeline stages each runs, which gates it selects from gate-registry.yaml, who may merge under it, and which stages it declares itself to skip.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": ["kind", "version", "modes"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"kind": {
|
|
12
|
+
"description": "The artifact type, so `tiphys validate --type auto` resolves this document without being told.",
|
|
13
|
+
"type": "string",
|
|
14
|
+
"const": "assurance-modes"
|
|
15
|
+
},
|
|
16
|
+
"note": {
|
|
17
|
+
"description": "Free prose for this document's own readers.",
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"version": {
|
|
21
|
+
"$comment": "A closed set rather than a minimum, because the authoring vocabulary of schemas/README.md has no `minimum` keyword and a bare `type: integer` would admit 0 and negatives. Same shape as gate-registry.schema.json.",
|
|
22
|
+
"type": "integer",
|
|
23
|
+
"enum": [1]
|
|
24
|
+
},
|
|
25
|
+
"modes": {
|
|
26
|
+
"description": "Every mode this repository declares. Append-only in practice: adding one is what makes charter-mode-enum-matches-modes earn its place.",
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"uniqueItems": true,
|
|
30
|
+
"items": {
|
|
31
|
+
"$ref": "#/$defs/mode"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"$defs": {
|
|
36
|
+
"stageId": {
|
|
37
|
+
"$comment": "THE CLOSED STAGE VOCABULARY. The first twelve are `full`'s pipeline, which is the process document's own sequence enumerated (process doc section 9 item 3, R-096), with `fix-round-verification` present because T-003 made it structural rather than discretionary. `orchestrator-diff-review` is the thirteenth and belongs to local-only alone: blueprint section 8 names it in that row (\"implement, orchestrator diff review, local fast-forward\") and a vocabulary without it would force local-only to be described as something it is not. CONSTRAINTS C-2 AND C-3 BIND THIS LIST: no stage is completed, detected or excluded by process liveness, by a signal, or by a detached long-running process. A registered test scans this file and assurance-modes.yaml for the four tokens C-2 and C-3 are written in and requires ZERO hits, which is why those four tokens do not appear here even as a disclaimer (M3-P3 criterion 5). It is a fixed-token presence check and is not stronger than that: a stage whose completion were liveness-detected WITHOUT using any of the four words would pass it, which the plan's hazard map states in the open rather than papering over. CLOSED VOCABULARY AT v0.1.0 (DR-0020): these are the tiphys kernel's OWN stage ids. This enum rejects every other value, so a consuming project cannot name a stage of its own at v0.1.0. Extension is an M4 question, deferred to a real pilot consumer for the same reversibility reason as the mode-id enum.",
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": [
|
|
40
|
+
"intake",
|
|
41
|
+
"verification-pass",
|
|
42
|
+
"plan",
|
|
43
|
+
"adversarial-plan-review",
|
|
44
|
+
"implement",
|
|
45
|
+
"clean-room-review",
|
|
46
|
+
"fix-round",
|
|
47
|
+
"fix-round-verification",
|
|
48
|
+
"merge-on-green",
|
|
49
|
+
"orchestrator-diff-review",
|
|
50
|
+
"deploy-verify",
|
|
51
|
+
"migration-verify",
|
|
52
|
+
"final-report"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"mode": {
|
|
56
|
+
"$comment": "FOUR conditional rules, chained through $ref rather than stacked in one object, because JSON Schema allows one `if`/`then` pair per schema object and `allOf` is outside the authoring vocabulary of schemas/README.md. Same construction as gate-registry.schema.json's `gate`. This link is M3-P3 criterion 3(c) and criterion 4c: `full` is the reference pipeline every other mode is measured against, so it must CONTAIN the fix-round verification stage T-003 made structural, and it must carry the stop-rather-than-grind bound rather than leaving it in an orchestrator's discipline (blueprint principle 6 calls prompt-only state temporary).",
|
|
57
|
+
"$ref": "#/$defs/modeAuthorityRule",
|
|
58
|
+
"if": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"required": ["id"],
|
|
61
|
+
"properties": {
|
|
62
|
+
"id": {
|
|
63
|
+
"const": "full"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"then": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"required": ["pipeline", "escalation-bounds"],
|
|
70
|
+
"properties": {
|
|
71
|
+
"pipeline": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"contains": {
|
|
74
|
+
"const": "fix-round-verification"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"escalation-bounds": {
|
|
78
|
+
"$ref": "#/$defs/escalationBounds"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"modeAuthorityRule": {
|
|
84
|
+
"$comment": "M3-P3 criterion 4b. `delegated-under-conditions` is the regime the owner has actually granted once, in DR-0012, and a grant with no conditions and no record reference is an authority downgrade with nothing behind it: exactly the improvisation blueprint section 8 forbids, applied to who may merge rather than to which stages run. `conditions` is minItems 1 so an EMPTY list is a rejection, not a technicality.",
|
|
85
|
+
"$ref": "#/$defs/modeReviewContractRule",
|
|
86
|
+
"if": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"required": ["merge-authority"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"merge-authority": {
|
|
91
|
+
"const": "delegated-under-conditions"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"then": {
|
|
96
|
+
"type": "object",
|
|
97
|
+
"required": ["conditions", "granted-by"],
|
|
98
|
+
"properties": {
|
|
99
|
+
"conditions": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"minItems": 1,
|
|
102
|
+
"items": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"minLength": 1
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"granted-by": {
|
|
108
|
+
"$ref": "#/$defs/decisionRecordReference"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"modeReviewContractRule": {
|
|
114
|
+
"$comment": "M3-P3 criterion 4d (T-007, D-M3-32). A mode that runs clean-room review declares its review CONTRACTS, not a reviewer count. T-007's measurement is why this is a schema rule: two reviewers on different model families walked all fifteen of M1-P5's acceptance criteria, agreed on every mechanical fact, and one returned APPROVE while the other found a high-severity defect that live-locks four commands, because the second was briefed on hazards rather than on criteria. Had both been briefed on the criteria, both would have approved, on any two models. The `uniqueItems` on modeShape's `review-contracts` is what stops two entries both named `criteria` from satisfying this `minItems` and reproducing exactly that failure; the two keywords live at ONE SITE EACH, because a duplicate of either would keep rejecting after the other was defanged and a red witness that stayed red for the wrong reason proves nothing about the keyword it names. DR-0012's requirement of two model FAMILIES is orthogonal and is checked elsewhere.",
|
|
115
|
+
"$ref": "#/$defs/modeShape",
|
|
116
|
+
"if": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": ["pipeline"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"pipeline": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"contains": {
|
|
123
|
+
"const": "clean-room-review"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"then": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"required": ["review-contracts"],
|
|
131
|
+
"properties": {
|
|
132
|
+
"review-contracts": {
|
|
133
|
+
"type": "array",
|
|
134
|
+
"minItems": 2,
|
|
135
|
+
"items": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"minLength": 1
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"modeShape": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"additionalProperties": false,
|
|
146
|
+
"required": [
|
|
147
|
+
"id",
|
|
148
|
+
"declared-by",
|
|
149
|
+
"pipeline",
|
|
150
|
+
"skips",
|
|
151
|
+
"gate-sets",
|
|
152
|
+
"merge-authority"
|
|
153
|
+
],
|
|
154
|
+
"properties": {
|
|
155
|
+
"$comment": {
|
|
156
|
+
"description": "Clause ids this entry discharges, per schemas/README.md.",
|
|
157
|
+
"type": "string"
|
|
158
|
+
},
|
|
159
|
+
"id": {
|
|
160
|
+
"$comment": "The three ids of blueprint section 8. Closed here and closed again in gate-registry.schema.json's `modes` item enum and in schemas/charter.schema.json's `delivery-mode` enum, which is three copies of one list; `charter-mode-enum-matches-modes` is what keeps the charter copy honest, and test/gate-registry.test.ts already binds the registry copy. CLOSED VOCABULARY AT v0.1.0 (DR-0020): these three are the tiphys kernel's OWN mode ids. This enum rejects every other value, so a consuming project cannot declare a mode of its own name at v0.1.0. Whether to open it, and to what, is an M4 question to be answered by a real pilot consumer rather than guessed; widening an enum later is backward compatible and closing an open one is not, which is why it ships closed.",
|
|
161
|
+
"type": "string",
|
|
162
|
+
"enum": ["full", "direct-pr", "local-only"]
|
|
163
|
+
},
|
|
164
|
+
"declared-by": {
|
|
165
|
+
"description": "Where this mode's definition comes from. Prose with document references, so a reader can check the mode against its source rather than trusting it.",
|
|
166
|
+
"type": "string",
|
|
167
|
+
"minLength": 1
|
|
168
|
+
},
|
|
169
|
+
"pipeline": {
|
|
170
|
+
"description": "The stages this mode runs, IN ORDER. Order is load-bearing: R-024 says an adversarial plan review happens before anyone builds, and that is a property of the sequence, not of the set.",
|
|
171
|
+
"type": "array",
|
|
172
|
+
"minItems": 1,
|
|
173
|
+
"uniqueItems": true,
|
|
174
|
+
"items": {
|
|
175
|
+
"$ref": "#/$defs/stageId"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"skips": {
|
|
179
|
+
"$comment": "Blueprint section 8: \"Downgrades are declared, never improvised.\" This is the declaration. It is REQUIRED and may be empty, so a mode that omits a stage and says nothing is distinguishable from a mode that omits nothing; `mode-no-undeclared-downgrade` is what makes the difference cost something. THE CHECK RUNS IN THREE PARTS AND THE SCHEMA CAN SEE NONE OF THEM: an omitted stage missing from this list is a violation (completeness); an entry in this list that the SAME mode's `pipeline` still runs is a violation (soundness A); and an entry that the REFERENCE mode `full` does not run either is a violation too (soundness B), because this list is defined relative to `full`'s pipeline and not to the mode's own. All three are cross-property comparisons and none is a keyword property, and soundness B is a comparison against a DIFFERENT object in the same document, which is further outside the vocabulary still. Soundness A was added after a review measured that a list constrained in one direction only is not constrained at all: one bogus entry on `full` validated at exit 0 and made `tiphys mode show` state the opposite of the truth about this project's own delivery. Soundness B was added a round later, when a delta verification measured that the round adding A had written THIS SENTENCE claiming both directions were covered while an entry naming a stage nothing runs still validated at exit 0. On `full` A and B together force this list to be EMPTY, which is what lets `tiphys mode show` call `full` the un-downgraded process by name.",
|
|
180
|
+
"type": "array",
|
|
181
|
+
"uniqueItems": true,
|
|
182
|
+
"items": {
|
|
183
|
+
"$ref": "#/$defs/stageId"
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"gate-sets": {
|
|
187
|
+
"$comment": "The gate ids from gate-registry.yaml this mode selects. `set` is the blueprint's word for the per-mode gate selection; here it is enumerated by id rather than named indirectly, so `mode-gate-sets-resolve` can check each entry against the registry with --context and a reference that resolves to nothing cannot pass by never being looked up.",
|
|
188
|
+
"type": "array",
|
|
189
|
+
"minItems": 1,
|
|
190
|
+
"uniqueItems": true,
|
|
191
|
+
"items": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"merge-authority": {
|
|
197
|
+
"$comment": "Blueprint section 8's third column, plus the value the owner has actually granted. `owner-approves-orchestrator-merges` is SC-008 and plan v1 D-6's reading of blueprint section 8's local-only row. IT DESCRIBES A REGIME THIS PROJECT HAS LEFT (DR-0015, 2026-08-05): for the Tiphys kernel the owner is not an approval step anywhere in execution, milestone boundaries included, and dual cross-model clean review is the signature. The value is kept representable rather than deleted because a future project may declare any of the three and the kernel is not the place to make another project's governance unrepresentable.",
|
|
198
|
+
"type": "string",
|
|
199
|
+
"enum": [
|
|
200
|
+
"owner",
|
|
201
|
+
"owner-approves-orchestrator-merges",
|
|
202
|
+
"delegated-under-conditions"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
"conditions": {
|
|
206
|
+
"$comment": "Required, and required to be NON-EMPTY, when merge-authority is delegated-under-conditions. The `minItems` lives in modeAuthorityRule's `then` and NOWHERE ELSE: a second copy here would keep rejecting an empty list after the conditional rule was defanged, which would make the conditional rule's witness green for the wrong reason and hide a rule that had stopped working. Quoted from the decision record rather than summarized.",
|
|
207
|
+
"type": "array",
|
|
208
|
+
"items": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"minLength": 1
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
"granted-by": {
|
|
214
|
+
"$ref": "#/$defs/decisionRecordReference"
|
|
215
|
+
},
|
|
216
|
+
"review-contracts": {
|
|
217
|
+
"$comment": "T-007, D-M3-32. The STARTING QUESTION each clean-room review is given, by id. Two contracts is not two reviewers: `criteria` walks the phase's acceptance criteria and `hazard` is handed the phase's declared hazard classes and works outward from them.",
|
|
218
|
+
"type": "array",
|
|
219
|
+
"uniqueItems": true,
|
|
220
|
+
"items": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"minLength": 1
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"escalation-bounds": {
|
|
226
|
+
"$ref": "#/$defs/escalationBounds"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"decisionRecordReference": {
|
|
231
|
+
"description": "A decision record id, for example DR-0012. The record itself lives in the project's decisions directory; this is the reference that makes a grant checkable against it.",
|
|
232
|
+
"type": "string",
|
|
233
|
+
"pattern": "^DR-[0-9]{4}$"
|
|
234
|
+
},
|
|
235
|
+
"onExceeded": {
|
|
236
|
+
"$comment": "DR-0016. `fresh-implementer-and-third-contract` is the response that was measured to work: a fresh implementer plus a third review contract dispatched IMMEDIATELY, with the owner notified asynchronously. `escalate-to-owner` remains in the enum because DR-0016's residual guardrail is real: if the round after the fresh implementer also fails, the phase goes to the owner.",
|
|
237
|
+
"type": "string",
|
|
238
|
+
"enum": ["fresh-implementer-and-third-contract", "escalate-to-owner"]
|
|
239
|
+
},
|
|
240
|
+
"escalationBounds": {
|
|
241
|
+
"$comment": "DR-0012's stop-rather-than-grind limits, made data, plus DR-0016's response. THIS IS DATA THE ORCHESTRATOR BRIEF CITES (M3-P9), NOT AN ENFORCEMENT ENGINE: nothing in M3 counts fix rounds and nothing in M3 classifies a finding's component, and the plan's section 4.5 records that as unproven rather than implying otherwise. `on-exceeded` is in this object's OWN `required` list, which is what makes it required exactly when `escalation-bounds` is present, with no conditional rule to go vacuous. A bound that records the LIMIT but not the RESPONSE encodes the regime DR-0016 measured and replaced: DR-0012's bound was a stop-and-wait, that stop cost 4.7 hours on M1-P5 alone, it fired three times, all three times the owner chose the option the orchestrator had already recommended, and the intervention that actually broke the spiral was the FRESH IMPLEMENTER dispatched afterwards, which derived eleven call sites where the review had listed eight.",
|
|
242
|
+
"type": "object",
|
|
243
|
+
"additionalProperties": false,
|
|
244
|
+
"required": [
|
|
245
|
+
"max-fix-rounds-after-review",
|
|
246
|
+
"recurrence-of-high-in-one-component",
|
|
247
|
+
"on-exceeded"
|
|
248
|
+
],
|
|
249
|
+
"properties": {
|
|
250
|
+
"max-fix-rounds-after-review": {
|
|
251
|
+
"description": "How many fix rounds may follow the first dual review before the bound fires. DR-0012 set two; DR-0035 replaced the single bound with a table running from one round (a zero or small subject) to three (a large subject at high impact), so what a mode records here is that table's CEILING rather than one phase's budget.",
|
|
252
|
+
"type": "integer"
|
|
253
|
+
},
|
|
254
|
+
"recurrence-of-high-in-one-component": {
|
|
255
|
+
"description": "How many times a high-severity finding may recur in one component across rounds before the bound fires. DR-0012 treats any recurrence as the trigger, so one.",
|
|
256
|
+
"type": "integer"
|
|
257
|
+
},
|
|
258
|
+
"on-exceeded": {
|
|
259
|
+
"$ref": "#/$defs/onExceeded"
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|