@junghanacs/entwurf 0.24.0 → 0.25.1
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/CHANGELOG.md +564 -0
- package/CONTRIBUTING.md +1 -1
- package/DELIVERY.md +24 -1
- package/README.md +2 -2
- package/VERIFY.md +20 -2
- package/demo/README.md +5 -2
- package/docs/acp-backend-rail.md +49 -2
- package/docs/setup-clean-host.md +4 -4
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +5 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/control-send-receipt.js +101 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +6 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +17 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +4 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +53 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +38 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +13 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-placement.js +11 -0
- package/mcp/entwurf-bridge/dist/protocol.js +0 -7
- package/mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js +40 -3
- package/mcp/entwurf-bridge/dist/scripts/herdr-rails.mjs +72 -0
- package/mcp/entwurf-bridge/src/index.ts +5 -4
- package/package.json +10 -9
- package/pi-extensions/entwurf-control.ts +27 -154
- package/pi-extensions/lib/compaction-send-guard.ts +5 -3
- package/pi-extensions/lib/control-send-receipt.ts +108 -0
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-contract.ts +6 -2
- package/pi-extensions/lib/entwurf-v2-production.ts +19 -1
- package/pi-extensions/lib/entwurf-v2-runner.ts +23 -1
- package/pi-extensions/lib/entwurf-v2-send.ts +82 -6
- package/pi-extensions/lib/entwurf-v2-surface.ts +42 -3
- package/pi-extensions/lib/herdr-fresh-call.ts +13 -3
- package/pi-extensions/lib/herdr-placement.ts +11 -0
- package/protocol.js +0 -8
- package/run.sh +202 -33
- package/scripts/check-entwurf-v2-surface.ts +289 -10
- package/scripts/check-gate-qualification.ts +2354 -11
- package/scripts/check-herdr-fresh-call.ts +10 -2
- package/scripts/check-herdr-placement.ts +51 -0
- package/scripts/check-herdr-plugin-build.ts +11 -4
- package/scripts/check-herdr-plugin.ts +745 -38
- package/scripts/check-mux-launcher-fence.ts +37 -0
- package/scripts/check-pi-launch.ts +7 -4
- package/scripts/check-release-gate-outcomes.ts +165 -0
- package/scripts/doctor-pi-provider.ts +44 -4
- package/scripts/herdr-rails.mjs +75 -0
- package/scripts/lib/qualification-acceptance.ts +146 -0
- package/scripts/lib/qualification-artifact.ts +359 -0
- package/scripts/lib/qualification-collection.ts +384 -0
- package/scripts/lib/qualification-gh.ts +231 -0
- package/scripts/lib/qualification-ledger.ts +669 -0
- package/scripts/lib/qualification-oracle-core.ts +279 -0
- package/scripts/lib/qualification-receipt.ts +561 -0
- package/scripts/lib/qualification-release.ts +271 -0
- package/scripts/meta-bridge-state.py +18 -1
- package/scripts/mutants/bridge-command-boot.json +38 -0
- package/scripts/mutants/control-send-receipt.json +235 -0
- package/scripts/mutants/herdr-fresh-call.json +4 -4
- package/scripts/mutants/herdr-plugin-build.json +7 -11
- package/scripts/mutants/herdr-plugin.json +177 -9
- package/scripts/mutants/meta-retire.json +22 -0
- package/scripts/mutants/pack-install.json +4 -4
- package/scripts/mutants/pi-floor.json +17 -0
- package/scripts/mutants/qualification-ledger.json +489 -0
- package/scripts/mutants/release-gate.json +48 -0
- package/scripts/mutants/retired-sent-surface.json +32 -0
- package/scripts/mutants/v2-surface.json +7 -7
- package/scripts/qualification-oracle.ts +124 -0
- package/scripts/smoke-codex-fresh-live.ts +94 -13
- package/scripts/smoke-herdr-fresh-call-live.ts +15 -8
- package/scripts/smoke-herdr-raw-install-live.sh +66 -4
- package/scripts/smoke-meta-install-state.sh +107 -1
- package/scripts/smoke-mux-lifecycle-live.ts +9 -2
- package/scripts/smoke-pi-provider-state.sh +106 -0
- package/scripts/smoke-setup-verdict.sh +18 -2
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "qualification-ledger",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "LEDGER-DIGEST-CHECKED",
|
|
7
|
+
"title": "the composer stops re-deriving receiptSha256 — a receipt whose verdict was edited after it was written would count as the measurement it no longer is (#124 P2)",
|
|
8
|
+
"subject": "scripts/lib/qualification-ledger.ts",
|
|
9
|
+
"find": ["\tif (sha256(canonicalJson(body)) !== receiptSha256) {"],
|
|
10
|
+
"replace": ["\tif (false) {"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
12
|
+
"timeoutSeconds": 120,
|
|
13
|
+
"signature": "[QK:LEDGER-DIGEST-CHECKED]",
|
|
14
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"claim": "LEDGER-FLAG-BLOCKS-GREEN",
|
|
18
|
+
"title": "the verdict ignores group flags — content-identical provenance, a red-then-green on identical bytes or observed cache drift would read COMPOSITE-GREEN instead of RISK-PENDING (#124 P2)",
|
|
19
|
+
"subject": "scripts/lib/qualification-ledger.ts",
|
|
20
|
+
"find": ["\t\t\t\t: gCounts.MEASURED === gCounts.total && gCounts.total > 0 && flagged.length === 0"],
|
|
21
|
+
"replace": ["\t\t\t\t: gCounts.MEASURED === gCounts.total && gCounts.total > 0"],
|
|
22
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
23
|
+
"timeoutSeconds": 120,
|
|
24
|
+
"signature": "[QK:LEDGER-FLAG-BLOCKS-GREEN]",
|
|
25
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"claim": "LEDGER-SEAL-IN-PASS-RECOMPUTE",
|
|
29
|
+
"title": "the composer's pass recompute forgets the seal — a receipt whose candidate moved during the run could still claim passed and count as MEASURED (#124 P2)",
|
|
30
|
+
"subject": "scripts/lib/qualification-ledger.ts",
|
|
31
|
+
"find": ["\t\tr.result.porcelainClean &&", "\t\tr.seal.stable;"],
|
|
32
|
+
"replace": ["\t\tr.result.porcelainClean;"],
|
|
33
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
34
|
+
"timeoutSeconds": 120,
|
|
35
|
+
"signature": "[QK:LEDGER-SEAL-IN-PASS-RECOMPUTE]",
|
|
36
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"claim": "LEDGER-INVALID-BLOCKS-GREEN",
|
|
40
|
+
"title": "the verdict stops failing closed on invalid receipts — a broken or duplicated receipt beside all-MEASURED groups would read COMPOSITE-GREEN instead of RED (#124 P2 review D2)",
|
|
41
|
+
"subject": "scripts/lib/qualification-ledger.ts",
|
|
42
|
+
"find": ["\t\tgCounts.FAIL > 0 || invalid.length > 0 || inputErrors.length > 0"],
|
|
43
|
+
"replace": ["\t\tgCounts.FAIL > 0 || inputErrors.length > 0"],
|
|
44
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
45
|
+
"timeoutSeconds": 120,
|
|
46
|
+
"signature": "[QK:LEDGER-INVALID-BLOCKS-GREEN]",
|
|
47
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"claim": "RECEIPT-SEAL-MOVED-IS-RED",
|
|
51
|
+
"title": "the group receipt producer drops the seal from `passed` — a run during which the origin candidate changed would be written green (#124 P1)",
|
|
52
|
+
"subject": "scripts/lib/qualification-receipt.ts",
|
|
53
|
+
"find": ["\tconst passed = reportPassed(report) && sealStable;"],
|
|
54
|
+
"replace": ["\tconst passed = reportPassed(report);"],
|
|
55
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
56
|
+
"timeoutSeconds": 120,
|
|
57
|
+
"signature": "[QK:RECEIPT-SEAL-MOVED-IS-RED]",
|
|
58
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"claim": "RECEIPT-PARENT-REALPATH-CONTAINED",
|
|
62
|
+
"title": "fingerprints lose the parent-realpath containment — a declared input reached through an intermediate directory symlink would hash bytes outside the repo as if they were the candidate's (#124 P1 review)",
|
|
63
|
+
"subject": "scripts/lib/qualification-receipt.ts",
|
|
64
|
+
"find": [
|
|
65
|
+
"\t\tif (parentReal !== repoReal && !parentReal.startsWith(repoReal + path.sep)) {",
|
|
66
|
+
"\t\t\tout[rel] = \"outside-repo\";",
|
|
67
|
+
"\t\t\tcontinue;",
|
|
68
|
+
"\t\t}"
|
|
69
|
+
],
|
|
70
|
+
"replace": ["\t\t// containment removed"],
|
|
71
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
72
|
+
"timeoutSeconds": 120,
|
|
73
|
+
"signature": "[QK:RECEIPT-PARENT-REALPATH-CONTAINED]",
|
|
74
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"claim": "COLLECT-RED-DOES-NOT-STOP",
|
|
78
|
+
"title": "the collector stops at the first red group — the tail after a late failure is never measured, which is exactly the serial-body gap #124 exists to close",
|
|
79
|
+
"subject": "scripts/lib/qualification-collection.ts",
|
|
80
|
+
"find": ["\t\t\tif (!r.sealStable) c.stoppedBy = \"seal-moved\";"],
|
|
81
|
+
"replace": ["\t\t\tif (!r.sealStable || !r.passed) c.stoppedBy = \"seal-moved\";"],
|
|
82
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
83
|
+
"timeoutSeconds": 120,
|
|
84
|
+
"signature": "[QK:COLLECT-RED-DOES-NOT-STOP]",
|
|
85
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"claim": "COLLECT-SEAL-MOVED-STOPS",
|
|
89
|
+
"title": "the collector ignores a moved origin seal — groups after a candidate change would still be collected as if they measured the same bytes",
|
|
90
|
+
"subject": "scripts/lib/qualification-collection.ts",
|
|
91
|
+
"find": ["\t\t\tif (!r.sealStable) c.stoppedBy = \"seal-moved\";"],
|
|
92
|
+
"replace": ["\t\t\tif (false) c.stoppedBy = \"seal-moved\";"],
|
|
93
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
94
|
+
"timeoutSeconds": 120,
|
|
95
|
+
"signature": "[QK:COLLECT-SEAL-MOVED-STOPS]",
|
|
96
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"claim": "COLLECT-UNDECLARED-FILE-NAMED",
|
|
100
|
+
"title": "checkCollection stops listing undeclared files — a stray receipt dropped into a collection would ride along unnamed",
|
|
101
|
+
"subject": "scripts/lib/qualification-collection.ts",
|
|
102
|
+
"find": ["\tfor (const f of names) if (!declared.has(f)) errors.push(`collection-extra: ${f}`);"],
|
|
103
|
+
"replace": ["\tvoid names;"],
|
|
104
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
105
|
+
"timeoutSeconds": 120,
|
|
106
|
+
"signature": "[QK:COLLECT-UNDECLARED-FILE-NAMED]",
|
|
107
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"claim": "COLLECT-CANDIDATE-DRIFT-STOPS",
|
|
111
|
+
"title": "the collector does not compare each receipt with the candidate it started on — bytes moved BETWEEN seal-stable groups would yield a COMPLETE collection of two candidates (#124 step-1 review D1)",
|
|
112
|
+
"subject": "scripts/lib/qualification-collection.ts",
|
|
113
|
+
"find": ["\t\t\t\tif (drift.length > 0) {"],
|
|
114
|
+
"replace": ["\t\t\t\tif (false) {"],
|
|
115
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
116
|
+
"timeoutSeconds": 120,
|
|
117
|
+
"signature": "[QK:COLLECT-CANDIDATE-DRIFT-STOPS]",
|
|
118
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"claim": "COLLECT-FILE-NAME-CONFINED",
|
|
122
|
+
"title": "checkCollection trusts the file name collection.json declares — a `../` or absolute name would steer the read outside the collection (#124 step-1 review D2)",
|
|
123
|
+
"subject": "scripts/lib/qualification-collection.ts",
|
|
124
|
+
"find": ["\t\tif (a.file !== receiptFileName(i)) {"],
|
|
125
|
+
"replace": ["\t\tif (false) {"],
|
|
126
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
127
|
+
"timeoutSeconds": 120,
|
|
128
|
+
"signature": "[QK:COLLECT-FILE-NAME-CONFINED]",
|
|
129
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"claim": "RELEASE-RED-REMEASURED-CLEARS",
|
|
133
|
+
"title": "the release composer forgets which groups were red on the ancestor chain — the section that broke would no longer be required on the final SHA, so an unre-measured late failure could hide behind older greens (#124 step 2)",
|
|
134
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
135
|
+
"find": ["\tfor (const [k, passed] of newestPassed) if (!passed) requiredKeys.add(k);"],
|
|
136
|
+
"replace": ["\tvoid newestPassed;"],
|
|
137
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
138
|
+
"timeoutSeconds": 120,
|
|
139
|
+
"signature": "[QK:RELEASE-RED-REMEASURED-CLEARS]",
|
|
140
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"claim": "RELEASE-UNRUN-BLOCKS",
|
|
144
|
+
"title": "release mode stops blocking UNRUN — a group with no pass receipt anywhere in the chain could ride into a RISK proposal as if it had ever been measured (#124 step 2)",
|
|
145
|
+
"subject": "scripts/lib/qualification-ledger.ts",
|
|
146
|
+
"find": ["\t\tif (opts.mode === \"release\" && g.state === \"UNRUN\") {"],
|
|
147
|
+
"replace": ["\t\tif (false) {"],
|
|
148
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
149
|
+
"timeoutSeconds": 120,
|
|
150
|
+
"signature": "[QK:RELEASE-UNRUN-BLOCKS]",
|
|
151
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"claim": "RELEASE-CANDIDATE-CROSS-CHECKED",
|
|
155
|
+
"title": "the release composer ignores a CI-claimed candidate the final tree contradicts — receipts measured on other bytes would be composed as the final SHA's (#124 step 2)",
|
|
156
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
157
|
+
"find": ["\tconst red = contractErrors.length > 0 || crossCheck.length > 0;"],
|
|
158
|
+
"replace": ["\tconst red = contractErrors.length > 0;"],
|
|
159
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
160
|
+
"timeoutSeconds": 120,
|
|
161
|
+
"signature": "[QK:RELEASE-CANDIDATE-CROSS-CHECKED]",
|
|
162
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"claim": "RELEASE-NEWEST-ATTEMPT-WINS",
|
|
166
|
+
"title": "the per-SHA run choice keeps whichever attempt came first in the input — an older, more favorable attempt could be selected over the newest one (#124 step 2)",
|
|
167
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
168
|
+
"find": ["\t\tif (!cur || newer(a.run, cur.run)) {"],
|
|
169
|
+
"replace": ["\t\tif (!cur) {"],
|
|
170
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
171
|
+
"timeoutSeconds": 120,
|
|
172
|
+
"signature": "[QK:RELEASE-NEWEST-ATTEMPT-WINS]",
|
|
173
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"claim": "RELEASE-INPUT-CONTRACT",
|
|
177
|
+
"title": "the release composer admits a run whose headSha is off the first-parent chain — a side branch's or an unrelated SHA's receipts could count toward this release (#124 step 2)",
|
|
178
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
179
|
+
"find": ["\t\tif (!chainPos.has(run.headSha)) {"],
|
|
180
|
+
"replace": ["\t\tif (false) {"],
|
|
181
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
182
|
+
"timeoutSeconds": 120,
|
|
183
|
+
"signature": "[QK:RELEASE-INPUT-CONTRACT]",
|
|
184
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"claim": "RELEASE-FINAL-COLLECTION-REQUIRED",
|
|
188
|
+
"title": "the release composer accepts an INCOMPLETE final-SHA collection — a final run that crashed or stopped midway would be composed as if every requested group had been measured (#124 step 2)",
|
|
189
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
190
|
+
"find": [
|
|
191
|
+
"\telse if (!finalEntry.complete)",
|
|
192
|
+
"\t\tcontractErrors.push(`final-SHA collection incomplete: ${finalEntry.errors.join(\"; \")}`);"
|
|
193
|
+
],
|
|
194
|
+
"replace": [
|
|
195
|
+
"\telse if (false)",
|
|
196
|
+
"\t\tcontractErrors.push(`final-SHA collection incomplete: ${finalEntry.errors.join(\"; \")}`);"
|
|
197
|
+
],
|
|
198
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
199
|
+
"timeoutSeconds": 120,
|
|
200
|
+
"signature": "[QK:RELEASE-FINAL-COLLECTION-REQUIRED]",
|
|
201
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"claim": "ARTIFACT-SELECT-EXACTLY-ONE",
|
|
205
|
+
"title": "artifact selection only refuses zero hits — with two artifacts of the run's name the first would be taken silently (#124 stage 3a)",
|
|
206
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
207
|
+
"find": ["\tif (hits.length !== 1)"],
|
|
208
|
+
"replace": ["\tif (hits.length === 0)"],
|
|
209
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
210
|
+
"timeoutSeconds": 120,
|
|
211
|
+
"signature": "[QK:ARTIFACT-SELECT-EXACTLY-ONE]",
|
|
212
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"claim": "ARTIFACT-DIGEST-CHECKED",
|
|
216
|
+
"title": "artifact admission stops comparing GitHub's recorded digest with the zip bytes' own sha256 — any bytes could be admitted as that artifact (#124 stage 3a)",
|
|
217
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
218
|
+
"find": ["\tif (a.digest !== `sha256:${zipSha}`)"],
|
|
219
|
+
"replace": ["\tif (false)"],
|
|
220
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
221
|
+
"timeoutSeconds": 120,
|
|
222
|
+
"signature": "[QK:ARTIFACT-DIGEST-CHECKED]",
|
|
223
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"claim": "ARTIFACT-ZIP-CONFINED",
|
|
227
|
+
"title": "the zip reader stops refusing symlink entries — a link named like a receipt would be read as one (#124 stage 3a)",
|
|
228
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
229
|
+
"find": ["\t\tif ((unixMode & 0o170000) === 0o120000) {"],
|
|
230
|
+
"replace": ["\t\tif (false) {"],
|
|
231
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
232
|
+
"timeoutSeconds": 120,
|
|
233
|
+
"signature": "[QK:ARTIFACT-ZIP-CONFINED]",
|
|
234
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"claim": "ARTIFACT-ZIP-STRUCTURE",
|
|
238
|
+
"title": "the zip reader stops requiring its entry count to consume the whole central directory — a lowered EOCD count hides a listed entry (#124 stage 3a review)",
|
|
239
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
240
|
+
"find": ["\tif (p !== cdOff + cdSize) {"],
|
|
241
|
+
"replace": ["\tif (false) {"],
|
|
242
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
243
|
+
"timeoutSeconds": 120,
|
|
244
|
+
"signature": "[QK:ARTIFACT-ZIP-STRUCTURE]",
|
|
245
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"claim": "ARTIFACT-CORE-RECOMPUTED",
|
|
249
|
+
"title": "admission stops recomputing core.sha256 from the receipt's own parts — a C0 witness could be edited while keeping its hash (#124 stage 3a)",
|
|
250
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
251
|
+
"find": ["\t\tif (recomputed !== core.sha256)"],
|
|
252
|
+
"replace": ["\t\tif (false)"],
|
|
253
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
254
|
+
"timeoutSeconds": 120,
|
|
255
|
+
"signature": "[QK:ARTIFACT-CORE-RECOMPUTED]",
|
|
256
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"claim": "ARTIFACT-CORE-SHAPE",
|
|
260
|
+
"title": "admission stops checking the core's fields — a receipt without node identity could be labelled a CI witness (#124 stage 3a review)",
|
|
261
|
+
"subject": "scripts/lib/qualification-artifact.ts",
|
|
262
|
+
"find": ["\t\tconst shapeErr = coreShapeError(core);"],
|
|
263
|
+
"replace": ["\t\tconst shapeErr = null as string | null;"],
|
|
264
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
265
|
+
"timeoutSeconds": 120,
|
|
266
|
+
"signature": "[QK:ARTIFACT-CORE-SHAPE]",
|
|
267
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"claim": "GH-PROVENANCE-BOUNDARY",
|
|
271
|
+
"title": "the GitHub boundary stops checking a run's head repository — a fork's run could supply this repository's release evidence (#124 stage 3b)",
|
|
272
|
+
"subject": "scripts/lib/qualification-gh.ts",
|
|
273
|
+
"find": ["\tif (run.head_repository?.full_name !== repo) {"],
|
|
274
|
+
"replace": ["\tif (false) {"],
|
|
275
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
276
|
+
"timeoutSeconds": 120,
|
|
277
|
+
"signature": "[QK:GH-PROVENANCE-BOUNDARY]",
|
|
278
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"claim": "GH-NEWEST-RUN-ONLY",
|
|
282
|
+
"title": "the GitHub boundary judges the OLDEST ci.yml run at the SHA — an older, friendlier collection would be chosen over the newest run (#124 stage 3b)",
|
|
283
|
+
"subject": "scripts/lib/qualification-gh.ts",
|
|
284
|
+
"find": ["\tconst run = runs.reduce((a, b) => (b.id > a.id ? b : a));"],
|
|
285
|
+
"replace": ["\tconst run = runs.reduce((a, b) => (b.id < a.id ? b : a));"],
|
|
286
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
287
|
+
"timeoutSeconds": 120,
|
|
288
|
+
"signature": "[QK:GH-NEWEST-RUN-ONLY]",
|
|
289
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"claim": "GH-NEWER-FAILED-COLLECTION-NOT-PAPERED",
|
|
293
|
+
"title": "an ancestor run is admitted although a newer run at that SHA attempted a collection and failed — the new failure would be papered over by the old green (#124 stage 3b review)",
|
|
294
|
+
"subject": "scripts/lib/qualification-gh.ts",
|
|
295
|
+
"find": ["\t\tif (compositeSucceeded(jobs).length > 0 || r.conclusion !== \"success\") {"],
|
|
296
|
+
"replace": ["\t\tif (false) {"],
|
|
297
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
298
|
+
"timeoutSeconds": 120,
|
|
299
|
+
"signature": "[QK:GH-NEWER-FAILED-COLLECTION-NOT-PAPERED]",
|
|
300
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"claim": "GH-COLLECT-STEPS-REQUIRED",
|
|
304
|
+
"title": "the GitHub boundary stops requiring the collect and upload steps to have succeeded — a run whose collection failed could still be read (#124 stage 3b)",
|
|
305
|
+
"subject": "scripts/lib/qualification-gh.ts",
|
|
306
|
+
"find": ["\tfor (const name of [COMPOSITE_STEP, COMPOSITE_UPLOAD_STEP]) {"],
|
|
307
|
+
"replace": ["\tfor (const name of [] as string[]) {"],
|
|
308
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
309
|
+
"timeoutSeconds": 120,
|
|
310
|
+
"signature": "[QK:GH-COLLECT-STEPS-REQUIRED]",
|
|
311
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"claim": "RELEASE-DIRTY-NOT-INVENTED",
|
|
315
|
+
"title": "the release composer asserts a clean final candidate instead of keeping the independent one's porcelain — a dirty tree could compose to COMPOSITE-GREEN (#124 Grok review F1)",
|
|
316
|
+
"subject": "scripts/lib/qualification-release.ts",
|
|
317
|
+
"find": ["\t\thead: input.finalSha,"],
|
|
318
|
+
"replace": ["\t\thead: input.finalSha,", "\t\tporcelainClean: true,"],
|
|
319
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
320
|
+
"timeoutSeconds": 120,
|
|
321
|
+
"signature": "[QK:RELEASE-DIRTY-NOT-INVENTED]",
|
|
322
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"claim": "ORACLE-SELF-CHECK",
|
|
326
|
+
"title": "the oracle core's self-check stops refusing a dirty checkout — run in place, an operator's uncommitted bytes could be judged as the SHA they are not (#124 P1)",
|
|
327
|
+
"subject": "scripts/lib/qualification-oracle-core.ts",
|
|
328
|
+
"find": ["\tif (st.status !== 0 || st.stdout !== \"\") errors.push(\"self-check: this checkout is not clean\");"],
|
|
329
|
+
"replace": ["\tif (st.status !== 0) errors.push(\"self-check: this checkout is not clean\");"],
|
|
330
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
331
|
+
"timeoutSeconds": 120,
|
|
332
|
+
"signature": "[QK:ORACLE-SELF-CHECK]",
|
|
333
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"claim": "ORACLE-FINAL-RUN-PINNED",
|
|
337
|
+
"title": "the oracle core stops comparing the newest run at the SHA with the pinned final run — evidence from a run the exact-CI oracle did not choose would be composed (#124 P1)",
|
|
338
|
+
"subject": "scripts/lib/qualification-oracle-core.ts",
|
|
339
|
+
"find": ["\tif (final.runId !== null && final.runId !== input.finalRunId) {"],
|
|
340
|
+
"replace": ["\tif (false) {"],
|
|
341
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
342
|
+
"timeoutSeconds": 120,
|
|
343
|
+
"signature": "[QK:ORACLE-FINAL-RUN-PINNED]",
|
|
344
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"claim": "ORACLE-DIGEST-MACHINE-INDEPENDENT",
|
|
348
|
+
"title": "a non-deterministic input leaks into the decision digest — two runs over identical inputs would name different ledgers; this negative covers the REPEAT axis of the claim only, not the clone-location axis (#124 P1)",
|
|
349
|
+
"subject": "scripts/lib/qualification-oracle-core.ts",
|
|
350
|
+
"find": ["\treturn sha256(canonicalJson(ledger));"],
|
|
351
|
+
"replace": ["\treturn sha256(canonicalJson(ledger) + process.hrtime.bigint());"],
|
|
352
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
353
|
+
"timeoutSeconds": 120,
|
|
354
|
+
"signature": "[QK:ORACLE-DIGEST-MACHINE-INDEPENDENT]",
|
|
355
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"claim": "ORACLE-SOURCE-MISSING",
|
|
359
|
+
"title": "the launcher stops refusing a SHA that does not carry the oracle core — the 8d508d3 shape would fail as a node error instead of ABORT oracle-source-missing (#124 P1)",
|
|
360
|
+
"subject": "scripts/qualification-oracle.ts",
|
|
361
|
+
"find": ["\t\tif (!fs.existsSync(path.join(clone, ORACLE_CORE_PATH))) {"],
|
|
362
|
+
"replace": ["\t\tif (false) {"],
|
|
363
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
364
|
+
"timeoutSeconds": 120,
|
|
365
|
+
"signature": "[QK:ORACLE-SOURCE-MISSING]",
|
|
366
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"claim": "ORACLE-RUNS-TARGET-BYTES",
|
|
370
|
+
"title": "the launcher runs the ORIGIN checkout's oracle core instead of the target SHA's — the operator's working-tree bytes would judge a SHA (#124 P1)",
|
|
371
|
+
"subject": "scripts/qualification-oracle.ts",
|
|
372
|
+
"find": [
|
|
373
|
+
"\t\tconst child = spawnSync(process.execPath, [\"--experimental-strip-types\", ORACLE_CORE_PATH, ...passArgs], {"
|
|
374
|
+
],
|
|
375
|
+
"replace": [
|
|
376
|
+
"\t\tconst child = spawnSync(process.execPath, [\"--experimental-strip-types\", path.join(origin, ORACLE_CORE_PATH), ...passArgs], {"
|
|
377
|
+
],
|
|
378
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
379
|
+
"timeoutSeconds": 120,
|
|
380
|
+
"signature": "[QK:ORACLE-RUNS-TARGET-BYTES]",
|
|
381
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"claim": "ORACLE-ORIGIN-TRIPWIRE",
|
|
385
|
+
"title": "the launcher stops re-reading the origin tripwire — a core that wrote the operator's checkout while it ran would keep its own exit 0 (#124 P1)",
|
|
386
|
+
"subject": "scripts/qualification-oracle.ts",
|
|
387
|
+
"find": ["\t\tif (after !== before) {"],
|
|
388
|
+
"replace": ["\t\tif (false) {"],
|
|
389
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
390
|
+
"timeoutSeconds": 120,
|
|
391
|
+
"signature": "[QK:ORACLE-ORIGIN-TRIPWIRE]",
|
|
392
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"claim": "ACCEPT-ONLY-RISK-PENDING",
|
|
396
|
+
"title": "the acceptance-record check stops requiring a RISK-PENDING ledger — a record against a NOT-QUALIFIED (or RED/GREEN) ledger would read RECORD-CONSISTENT (#124 P2)",
|
|
397
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
398
|
+
"find": [
|
|
399
|
+
"\tif (ledger.verdict !== \"RISK-PENDING\") errors.push(`ledger: verdict is ${ledger.verdict}, not RISK-PENDING`);"
|
|
400
|
+
],
|
|
401
|
+
"replace": ["\tif (false) errors.push(`ledger: verdict is ${ledger.verdict}, not RISK-PENDING`);"],
|
|
402
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
403
|
+
"timeoutSeconds": 120,
|
|
404
|
+
"signature": "[QK:ACCEPT-ONLY-RISK-PENDING]",
|
|
405
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"claim": "ACCEPT-DIGEST-RECOMPUTED",
|
|
409
|
+
"title": "the acceptance-record check stops recomputing the ledger digest — a ledger edited after the record named it would still read RECORD-CONSISTENT (#124 P2)",
|
|
410
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
411
|
+
"find": ["\tif (sha256(canonicalJson(ledger)) !== rec.ledgerSha256)"],
|
|
412
|
+
"replace": ["\tif (false)"],
|
|
413
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
414
|
+
"timeoutSeconds": 120,
|
|
415
|
+
"signature": "[QK:ACCEPT-DIGEST-RECOMPUTED]",
|
|
416
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"claim": "ACCEPT-RISKS-EXACT",
|
|
420
|
+
"title": "the acceptance-record check compares risks as a multiset — a record listing the risks in another order would read RECORD-CONSISTENT (#124 P2)",
|
|
421
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
422
|
+
"find": ["\tif (canonicalJson(rec.risks) !== canonicalJson(ledger.risks))"],
|
|
423
|
+
"replace": ["\tif (multiset(rec.risks) !== multiset(ledger.risks))"],
|
|
424
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
425
|
+
"timeoutSeconds": 120,
|
|
426
|
+
"signature": "[QK:ACCEPT-RISKS-EXACT]",
|
|
427
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"claim": "ACCEPT-RISKS-REDERIVED",
|
|
431
|
+
"title": "the acceptance-record check trusts the ledger's own risk list — a composer that dropped a risk its groups imply would go unnoticed behind a consistent digest (#124 P2)",
|
|
432
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
433
|
+
"find": ["\tif (multiset(rederiveRisks(ledger.groups)) !== multiset(ledger.risks))"],
|
|
434
|
+
"replace": ["\tif (false)"],
|
|
435
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
436
|
+
"timeoutSeconds": 120,
|
|
437
|
+
"signature": "[QK:ACCEPT-RISKS-REDERIVED]",
|
|
438
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"claim": "ACCEPT-DATE-REAL",
|
|
442
|
+
"title": "the acceptance-record check accepts any date-shaped acceptedOn — 2026-02-30 would read RECORD-CONSISTENT (#124 P2)",
|
|
443
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
444
|
+
"find": ["\t} else if (!isRealDate(r.acceptedOn)) {"],
|
|
445
|
+
"replace": ["\t} else if (false) {"],
|
|
446
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
447
|
+
"timeoutSeconds": 120,
|
|
448
|
+
"signature": "[QK:ACCEPT-DATE-REAL]",
|
|
449
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"claim": "ORACLE-DECLARED-REQUIRED",
|
|
453
|
+
"title": "the oracle core drops --require-group before the release composer — a group GLG required on the final SHA would never be required (#124 P2)",
|
|
454
|
+
"subject": "scripts/lib/qualification-oracle-core.ts",
|
|
455
|
+
"find": ["\t\toperatorDeclared: input.operatorDeclared,"],
|
|
456
|
+
"replace": ["\t\toperatorDeclared: [],"],
|
|
457
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
458
|
+
"timeoutSeconds": 120,
|
|
459
|
+
"signature": "[QK:ORACLE-DECLARED-REQUIRED]",
|
|
460
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"claim": "CORE-FILES-COVER-QUALIFICATION",
|
|
464
|
+
"title": "CORE_FILES forgets a qualification source — acceptance.ts bytes could change without moving the receipt core seal, the c-core decision or the CI core witness (#124 D1)",
|
|
465
|
+
"subject": "scripts/lib/qualification-receipt.ts",
|
|
466
|
+
"find": ["\t\"scripts/lib/qualification-acceptance.ts\","],
|
|
467
|
+
"replace": ["\t// (qualification-acceptance.ts not listed)"],
|
|
468
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
469
|
+
"timeoutSeconds": 120,
|
|
470
|
+
"signature": "[QK:CORE-FILES-COVER-QUALIFICATION]",
|
|
471
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"claim": "ACCEPT-REFUSAL-REDERIVED",
|
|
475
|
+
"title": "the acceptance-record check trusts the ledger's own blockers — a RISK-PENDING ledger with an UNRUN group or a dirty candidate and its blockers stripped would read RECORD-CONSISTENT (#124 D2)",
|
|
476
|
+
"subject": "scripts/lib/qualification-acceptance.ts",
|
|
477
|
+
"find": [
|
|
478
|
+
"\tif (refusals.length > 0) errors.push(`ledger: refusal state in its own groups/candidate: ${refusals.join(\"; \")}`);"
|
|
479
|
+
],
|
|
480
|
+
"replace": [
|
|
481
|
+
"\tif (false) errors.push(`ledger: refusal state in its own groups/candidate: ${refusals.join(\"; \")}`);"
|
|
482
|
+
],
|
|
483
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
484
|
+
"timeoutSeconds": 120,
|
|
485
|
+
"signature": "[QK:ACCEPT-REFUSAL-REDERIVED]",
|
|
486
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
487
|
+
}
|
|
488
|
+
]
|
|
489
|
+
}
|
|
@@ -227,6 +227,54 @@
|
|
|
227
227
|
"timeoutSeconds": 180,
|
|
228
228
|
"signature": "[QK:CODEX-FIRST-ADMISSION-IS-RELEASE-MUST]",
|
|
229
229
|
"signatureSource": "scripts/check-release-gate-outcomes.ts"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"claim": "CODEX-OPERATOR-PREREQ-ABSENT-SKIPS",
|
|
233
|
+
"title": "a constant-false guard leaves the decline arm as dead code, so every absent operator input falls through to the assertions and exits FAIL again — the shape that made this MUST step red inside every cut and would require a per-cut exception",
|
|
234
|
+
"subject": "scripts/smoke-codex-fresh-live.ts",
|
|
235
|
+
"find": [
|
|
236
|
+
"\tconst absentInputs = OPERATOR_INPUTS.filter(([name]) => (process.env[name]?.trim() ?? \"\") === \"\");",
|
|
237
|
+
"\tif (absentInputs.length > 0) {"
|
|
238
|
+
],
|
|
239
|
+
"replace": [
|
|
240
|
+
"\tconst absentInputs = OPERATOR_INPUTS.filter(([name]) => (process.env[name]?.trim() ?? \"\") === \"\");",
|
|
241
|
+
"\tif (absentInputs.length > 0 && process.env.ENTWURF_NEVER_SET === \"1\") {"
|
|
242
|
+
],
|
|
243
|
+
"gate": ["bash", "run.sh", "check-release-gate-outcomes"],
|
|
244
|
+
"timeoutSeconds": 300,
|
|
245
|
+
"signature": "[QK:CODEX-OPERATOR-PREREQ-ABSENT-SKIPS]",
|
|
246
|
+
"signatureSource": "scripts/check-release-gate-outcomes.ts"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"claim": "CODEX-OPERATOR-PREREQ-WRONG-FAILS",
|
|
250
|
+
"title": "turning the pid grammar into a decline means a malformed, dead or non-Codex app-server pid the operator DID supply reports as a missing prerequisite, so a broken answer buys silence where a cut reads silence as an unmet precondition rather than a defect",
|
|
251
|
+
"subject": "scripts/smoke-codex-fresh-live.ts",
|
|
252
|
+
"find": [
|
|
253
|
+
"\tok(",
|
|
254
|
+
"\t\t\"ENTWURF_CODEX_APP_SERVER_PID explicitly names the existing operator-owned app-server\",",
|
|
255
|
+
"\t\t/^[1-9]\\d*$/.test(pidText),"
|
|
256
|
+
],
|
|
257
|
+
"replace": [
|
|
258
|
+
"\tif (!/^[1-9]\\d*$/.test(pidText)) skipLive(LABEL, \"no usable app-server pid was supplied\");",
|
|
259
|
+
"\tok(",
|
|
260
|
+
"\t\t\"an app-server pid was supplied\",",
|
|
261
|
+
"\t\ttrue,"
|
|
262
|
+
],
|
|
263
|
+
"gate": ["bash", "run.sh", "check-release-gate-outcomes"],
|
|
264
|
+
"timeoutSeconds": 300,
|
|
265
|
+
"signature": "[QK:CODEX-OPERATOR-PREREQ-WRONG-FAILS]",
|
|
266
|
+
"signatureSource": "scripts/check-release-gate-outcomes.ts"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"claim": "CODEX-OPERATOR-PREREQ-STATED-NOT-SEARCHED",
|
|
270
|
+
"title": "deriving the app-server pid by process search in the release instructions teaches the exact inference the MUST step refuses, and on a host running several app-servers it hands the gate an arbitrary process to verify as the operator's answer",
|
|
271
|
+
"subject": ".claude/skills/entwurf-release/SKILL.md",
|
|
272
|
+
"find": [": \"${CODEX_APP_SERVER_PID:?state the app-server pid you started; never search for it}\""],
|
|
273
|
+
"replace": ["CODEX_APP_SERVER_PID=$(pgrep -f 'codex.*app-server' | head -1)"],
|
|
274
|
+
"gate": ["bash", "run.sh", "check-release-gate-outcomes"],
|
|
275
|
+
"timeoutSeconds": 300,
|
|
276
|
+
"signature": "[QK:CODEX-OPERATOR-PREREQ-STATED-NOT-SEARCHED]",
|
|
277
|
+
"signatureSource": "scripts/check-release-gate-outcomes.ts"
|
|
230
278
|
}
|
|
231
279
|
]
|
|
232
280
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "retired-sent-surface",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "NO-RENDERER-WITHOUT-PRODUCER",
|
|
7
|
+
"title": "a renderer is registered for a customType nothing in this extension emits — a producer-less orphan box no operator can ever reach, the same shape that shipped for two releases behind comments naming producers that did not exist",
|
|
8
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
9
|
+
"find": ["\tpi.registerMessageRenderer(SESSION_MESSAGE_TYPE, renderSessionMessage);"],
|
|
10
|
+
"replace": [
|
|
11
|
+
"\tpi.registerMessageRenderer(SESSION_MESSAGE_TYPE, renderSessionMessage);\n\tpi.registerMessageRenderer(\"entwurf-orphan\", renderSessionMessage);"
|
|
12
|
+
],
|
|
13
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
14
|
+
"timeoutSeconds": 300,
|
|
15
|
+
"signature": "[QK:NO-RENDERER-WITHOUT-PRODUCER]",
|
|
16
|
+
"signatureSource": "scripts/check-entwurf-v2-surface.ts"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"claim": "RETIRED-SENT-SURFACE-ABSENT",
|
|
20
|
+
"title": "the retired sender-side echo constant comes back as a public export of a SHIPPED file — a name an npm consumer can import and nothing in the repo can ever produce, which is the promise #120 P3 removed rather than renamed",
|
|
21
|
+
"subject": "protocol.js",
|
|
22
|
+
"find": ["export const ENTWURF_PROJECT_CONTEXT_OPEN_TAG = \"<project-context\";"],
|
|
23
|
+
"replace": [
|
|
24
|
+
"export const ENTWURF_PROJECT_CONTEXT_OPEN_TAG = \"<project-context\";\nexport const ENTWURF_SENT_MESSAGE_TYPE = \"entwurf-sent\";"
|
|
25
|
+
],
|
|
26
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
27
|
+
"timeoutSeconds": 300,
|
|
28
|
+
"signature": "[QK:RETIRED-SENT-SURFACE-ABSENT]",
|
|
29
|
+
"signatureSource": "scripts/check-entwurf-v2-surface.ts"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"claim": "V2PROD-INBAND-ERROR-WIRED",
|
|
32
|
-
"title": "the production sendOverSocket closure stops copying response.error onto the RpcSendResult, so a receiver's named in-band refusal is stranded one hop before driveSend and the caller sees a reasonless rejected",
|
|
32
|
+
"title": "the production sendOverSocket closure stops copying response.error onto the RpcSendResult, so a receiver's named in-band refusal is stranded one hop before driveSend and the caller sees a reasonless rejected (#120 P2: the wire seam now also classifies the acceptance boundary, so the same line carries one more field — the mutation still drops the receiver's own error)",
|
|
33
33
|
"subject": "pi-extensions/lib/entwurf-v2-production.ts",
|
|
34
|
-
"find": ["\t\t\treturn { success: response.success, error: response.error };"],
|
|
35
|
-
"replace": ["\t\t\treturn { success: response.success };"],
|
|
34
|
+
"find": ["\t\t\treturn { success: response.success, error: response.error, boundary };"],
|
|
35
|
+
"replace": ["\t\t\treturn { success: response.success, boundary };"],
|
|
36
36
|
"gate": ["bash", "run.sh", "check-entwurf-v2-production"],
|
|
37
37
|
"timeoutSeconds": 60,
|
|
38
38
|
"signature": "[QK:V2PROD-INBAND-ERROR-WIRED]",
|
|
@@ -40,15 +40,15 @@
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"claim": "V2SURF-PI-MODE-SCOPE",
|
|
43
|
-
"title": "pi-native mode param reverts to \"Delivery mode for a live send\" (false for native-push)",
|
|
43
|
+
"title": "pi-native mode param reverts to \"Delivery mode for a live send\" (false for native-push) (#120 P2: the description was rewritten to stop claiming an interrupt, so the mutation now strips the rail scope from the corrected sentence)",
|
|
44
44
|
"subject": "pi-extensions/entwurf-control.ts",
|
|
45
45
|
"find": [
|
|
46
|
-
"\t\t\t\t\t\"Injection style for a CONTROL-SOCKET send only: steer (
|
|
46
|
+
"\t\t\t\t\t\"Injection style for a CONTROL-SOCKET send only: steer (ask the receiver's steering queue) or follow_up (ask its follow-up queue). NEITHER is an interrupt: a busy receiver drains steering after each turn and follow-ups only when its inner loop ends, so a later steer overtakes every earlier follow_up and there is no order between the two. Both queues are volatile process memory — an abort drops what is in them. The receipt names which queue accepted the message (`queued-steer` / `queued-follow-up`); an idle receiver answers `sent`, meaning the turn was TRIGGERED, not that the model has seen the text. \" +",
|
|
47
47
|
"\t\t\t\t\t\"The mailbox and native-push plans carry no mode, so it has no effect on those rails.\","
|
|
48
48
|
],
|
|
49
49
|
"replace": [
|
|
50
|
-
"\t\t\t\t\t\"Delivery mode for a live send: steer (
|
|
51
|
-
"\t\t\t\t\t\"
|
|
50
|
+
"\t\t\t\t\t\"Delivery mode for a live send: steer (ask the steering queue) or follow_up (ask the follow-up queue). \" +",
|
|
51
|
+
"\t\t\t\t\t\"Both queues are volatile process memory.\","
|
|
52
52
|
],
|
|
53
53
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
54
54
|
"timeoutSeconds": 60,
|