@junghanacs/entwurf 0.22.0 → 0.23.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/AGENTS.md +4 -1
- package/BASELINE.md +1 -0
- package/CHANGELOG.md +514 -0
- package/DELIVERY.md +10 -2
- package/README.md +43 -4
- package/VERIFY.md +47 -0
- package/docs/acp-backend-rail.md +96 -17
- package/docs/setup-clean-host.md +11 -1
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +39 -40
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +2 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/codex-declaration.js +609 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/codex-fresh-preflight.js +95 -56
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +40 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-fact-provider.js +6 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-facts.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-peer-observe.js +67 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-peers-render.js +9 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +24 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +423 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-dispatch.js +98 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +1018 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-placement.js +213 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +46 -273
- package/mcp/entwurf-bridge/dist/scripts/peer-facts.js +109 -0
- package/mcp/entwurf-bridge/src/index.ts +41 -41
- package/mcp/entwurf-bridge/tsconfig.build.json +1 -0
- package/package.json +9 -8
- package/pi-extensions/entwurf-control.ts +91 -52
- package/pi-extensions/lib/acp/acp-client.ts +3 -3
- package/pi-extensions/lib/acp/backend-adapter.ts +3 -3
- package/pi-extensions/lib/acp/backend.ts +4 -4
- package/pi-extensions/lib/acp/event-mapper.ts +5 -5
- package/pi-extensions/lib/acp/tool-surface.ts +2 -1
- package/pi-extensions/lib/codex-declaration.js +612 -0
- package/pi-extensions/lib/codex-fresh-preflight.ts +107 -51
- package/pi-extensions/lib/entwurf-control-rpc.ts +46 -0
- package/pi-extensions/lib/entwurf-fact-provider.ts +13 -2
- package/pi-extensions/lib/entwurf-facts.ts +14 -1
- package/pi-extensions/lib/entwurf-peer-observe.ts +72 -2
- package/pi-extensions/lib/entwurf-peers-render.ts +9 -1
- package/pi-extensions/lib/entwurf-self-address.ts +33 -0
- package/pi-extensions/lib/entwurf-v2-contract.ts +2 -2
- package/pi-extensions/lib/entwurf-v2-lock.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-runner.ts +1 -1
- package/pi-extensions/lib/fresh-call-composition.ts +493 -0
- package/pi-extensions/lib/fresh-call-dispatch.ts +142 -0
- package/pi-extensions/lib/herdr-fresh-call.ts +1378 -0
- package/pi-extensions/lib/herdr-placement.ts +276 -0
- package/pi-extensions/lib/mux-fresh-call.ts +95 -301
- package/run.sh +588 -204
- package/scripts/check-acp-usage-accounting.ts +9 -9
- package/scripts/check-codex-birth-hook.ts +187 -0
- package/scripts/check-entwurf-control-rpc.ts +138 -0
- package/scripts/check-entwurf-fact-provider.ts +4 -2
- package/scripts/check-entwurf-peers-surface.ts +3 -1
- package/scripts/check-entwurf-self-address.ts +68 -0
- package/scripts/check-fresh-call-dispatch.ts +301 -0
- package/scripts/check-gate-qualification.ts +17 -4
- package/scripts/check-herdr-activation.ts +1293 -0
- package/scripts/check-herdr-fresh-call.ts +1250 -0
- package/scripts/check-herdr-placement.ts +383 -0
- package/scripts/check-herdr-plugin-build.ts +842 -0
- package/scripts/check-herdr-plugin-profile.ts +371 -0
- package/scripts/check-herdr-plugin.ts +523 -0
- package/scripts/check-herdr-runtime-bootstrap.ts +1264 -0
- package/scripts/check-herdr-sandbox.ts +456 -0
- package/scripts/check-herdr-supply.ts +184 -0
- package/scripts/check-mux-launcher-fence.ts +138 -0
- package/scripts/check-peer-facts.ts +331 -0
- package/scripts/check-pi-launch.ts +358 -0
- package/scripts/check-release-gate-outcomes.ts +19 -0
- package/scripts/check-typing-call-fence.ts +296 -0
- package/scripts/codex-birth-doctor.sh +159 -16
- package/scripts/codex-birth-install.sh +178 -72
- package/scripts/codex-birth-uninstall.sh +162 -7
- package/scripts/fixtures/herdr-supply.json +29 -0
- package/scripts/herdr-activation.mjs +536 -0
- package/scripts/herdr-plugin-activate.mjs +270 -0
- package/scripts/herdr-plugin-deactivate.mjs +193 -0
- package/scripts/herdr-runtime.mjs +1203 -0
- package/scripts/install-herdr-ci.sh +96 -0
- package/scripts/inventory-verification-surface.ts +86 -10
- package/scripts/lib/codex-fresh-live-protocol.ts +2 -2
- package/scripts/lib/tree-digest.ts +97 -0
- package/scripts/meta-bridge-install.sh +19 -2
- package/scripts/meta-bridge-state.py +167 -11
- package/scripts/mutants/codex-caller-seat.json +6 -8
- package/scripts/mutants/codex-native.json +195 -29
- package/scripts/mutants/control-socket-disconnect.json +57 -0
- package/scripts/mutants/fresh-call-dispatch.json +154 -0
- package/scripts/mutants/herdr-activation.json +305 -0
- package/scripts/mutants/herdr-fresh-call.json +448 -0
- package/scripts/mutants/herdr-placement.json +161 -0
- package/scripts/mutants/herdr-plugin-build.json +160 -0
- package/scripts/mutants/herdr-plugin-profile.json +202 -0
- package/scripts/mutants/herdr-plugin.json +133 -0
- package/scripts/mutants/herdr-runtime-bootstrap.json +411 -0
- package/scripts/mutants/herdr-supply.json +133 -0
- package/scripts/mutants/meta-hook-session-switch.json +2 -2
- package/scripts/mutants/mux-fresh-call.json +104 -17
- package/scripts/mutants/mux-launcher-fence.json +13 -0
- package/scripts/mutants/omp-fresh.json +4 -4
- package/scripts/mutants/peer-facts.json +98 -0
- package/scripts/mutants/pi-launch.json +113 -0
- package/scripts/mutants/resume-args.json +6 -6
- package/scripts/mutants/self-address.json +33 -0
- package/scripts/mutants/typing-call-fence.json +17 -0
- package/scripts/mutants/v2-surface.json +2 -2
- package/scripts/mutants/v2-visible-resume.json +17 -17
- package/scripts/peer-facts.ts +120 -0
- package/scripts/register-pi-package.py +8 -0
- package/scripts/register-pi-provider.py +88 -12
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-codex-birth.sh +281 -12
- package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
- package/scripts/smoke-herdr-fresh-call-live.ts +1027 -0
- package/scripts/smoke-herdr-plugin-build-live.ts +543 -0
- package/scripts/smoke-herdr-raw-install-live.sh +849 -0
- package/scripts/tsconfig.json +5 -0
- package/scripts/check-entwurf-facts.ts +0 -385
- package/scripts/check-entwurf-resume-args.ts +0 -122
- package/scripts/check-entwurf-v2-decider.ts +0 -657
- package/scripts/check-entwurf-v2-lock.ts +0 -371
- package/scripts/check-entwurf-v2-mailbox.ts +0 -261
- package/scripts/check-entwurf-v2-matrix.ts +0 -401
- package/scripts/check-entwurf-v2-native-push.ts +0 -221
- package/scripts/check-entwurf-v2-release.ts +0 -151
- package/scripts/check-entwurf-v2-runner.ts +0 -448
- package/scripts/check-entwurf-v2-send-fallback.ts +0 -350
- package/scripts/check-entwurf-v2-send.ts +0 -458
- package/scripts/check-entwurf-v2-visible-resume.ts +0 -445
- package/scripts/check-socket-discovery.ts +0 -401
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
# 1. the published declaration is the EXACT trust identity (matcher-less, type/command/
|
|
8
8
|
# timeout, quoted fixed launcher path) — because that identity is what an operator
|
|
9
9
|
# approves once, and any drift in it costs a second approval;
|
|
10
|
+
# 1b. entwurf owns ONLY that declaration inside a file it SHARES (#117): a neighbouring
|
|
11
|
+
# integration's `SessionStart` group in either ordering leaves install/doctor green, is
|
|
12
|
+
# reported as foreign, is never certified, survives install and inverse byte-for-byte, and
|
|
13
|
+
# moves no verdict of ours when it is edited;
|
|
10
14
|
# 2. config.toml is neither read nor written, so the vendor's [hooks.state] and entwurf's
|
|
11
15
|
# own two user atoms survive install AND inverse byte-for-byte;
|
|
12
16
|
# 3. a foreign or edited hooks.json is a ZERO-WRITE refusal, never an adoption — this unit
|
|
@@ -76,9 +80,13 @@ want "the launcher is published and executable" "[ -f '$LAUNCHER' ] && [ -x '$LA
|
|
|
76
80
|
want "the closure is published whole" "[ -f '$HELPER/meta-bridge-hook-codex.ts' ] && [ -f '$HELPER/lib/meta-session.ts' ] && [ -f '$HELPER/lib/native-push/codex-ws-client.ts' ] && [ -f '$HELPER/lib/session-id.js' ] && [ -f '$HELPER/entwurf-capabilities.json' ]"
|
|
77
81
|
want "the state is a regular non-symlink file" "[ -f '$STATE' ] && [ ! -L '$STATE' ]"
|
|
78
82
|
want "the state is bound to the fixed paths and finished publishing" \
|
|
79
|
-
"node -e 'const s=require(process.argv[1]); if(s.schema!==\"codex-birth-install-state/
|
|
83
|
+
"node -e 'const s=require(process.argv[1]); if(s.schema!==\"codex-birth-install-state/v2\")throw 0; if(s.status!==\"installed\")throw 0; if(s.hooksFile!==process.argv[2])throw 0; if(s.helperDir!==process.argv[3])throw 0;' '$STATE' '$HOOKS' '$HELPER'"
|
|
84
|
+
# The receipt is a DECLARATION digest, not a file digest. A state carrying a whole-file
|
|
85
|
+
# `hooksSha256` would be claiming authority over bytes a neighbour owns — the #117 defect itself.
|
|
86
|
+
want "[QK:CODEX-BIRTH-STATE-CERTIFIES-DECLARATION] the state records a declaration receipt and NO whole-file digest" \
|
|
87
|
+
"node -e 'const s=require(process.argv[1]); const hex=v=>/^[0-9a-f]{64}\$/.test(v); if(\"hooksSha256\" in s)throw new Error(\"the state still claims the whole file\"); if(s.declaration.event!==\"SessionStart\")throw 0; if(typeof s.declaration.command!==\"string\")throw 0; if(!hex(s.declaration.sha256))throw 0;' '$STATE'"
|
|
80
88
|
want "the state records a digest for every published byte" \
|
|
81
|
-
"node -e 'const s=require(process.argv[1]); const hex=v=>/^[0-9a-f]{64}\$/.test(v); if(
|
|
89
|
+
"node -e 'const s=require(process.argv[1]); const hex=v=>/^[0-9a-f]{64}\$/.test(v); if(s.helperFiles.length!==6)throw 0; for(const f of s.helperFiles){if(!hex(f.sha256))throw 0;}' '$STATE'"
|
|
82
90
|
|
|
83
91
|
# The trust identity, asserted field by field. This is the cell that costs a second operator
|
|
84
92
|
# approval if it ever drifts, so it is checked literally rather than by shape.
|
|
@@ -153,7 +161,7 @@ MT1="$(stat -c %Y "$HOOKS")"; sleep 1.1
|
|
|
153
161
|
"$INSTALL" >"$SB/out" 2>&1 || die "reinstall failed: $(cat "$SB/out")"
|
|
154
162
|
MT2="$(stat -c %Y "$HOOKS")"
|
|
155
163
|
want "reinstall does not rewrite the declaration" "[ '$MT1' = '$MT2' ]"
|
|
156
|
-
want "reinstall
|
|
164
|
+
want "reinstall recognises its own declaration by normalized digest and rewrites nothing" "grep -q 'NOT REWRITTEN, not one byte' '$SB/out'"
|
|
157
165
|
cmp -s "$SB/config.before.toml" "$CFG" && ok "reinstall still left config.toml byte-identical" || die "reinstall modified config.toml"
|
|
158
166
|
|
|
159
167
|
###############################################################################
|
|
@@ -198,31 +206,180 @@ ok "the unit axis is green again after the absent member was republished"
|
|
|
198
206
|
# refusals — a foreign file, an edited file, a symlink; each ZERO-WRITE
|
|
199
207
|
###############################################################################
|
|
200
208
|
"$UNINSTALL" >/dev/null 2>&1 || die "clean uninstall before the refusal cells failed"
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
209
|
+
|
|
210
|
+
###############################################################################
|
|
211
|
+
# COEXISTENCE (#117) — the neighbour is joined, never adopted and never refused
|
|
212
|
+
#
|
|
213
|
+
# Until 0.22.0 this unit owned hooks.json WHOLE: a file it had not written was a zero-write
|
|
214
|
+
# refusal, and its whole-file digest went red the moment anyone else appended. That is exactly
|
|
215
|
+
# what Herdr's official Codex integration does, and the vendor keeps running both declarations
|
|
216
|
+
# because `[source]` discovery.rs:664-665 keys trust per `<path>:<event>:<group>:<handler>`.
|
|
217
|
+
# These cells are the new contract: one group is ours, everything else is foreign bytes we read
|
|
218
|
+
# and never write.
|
|
219
|
+
###############################################################################
|
|
220
|
+
FOREIGN_GROUP=' {
|
|
221
|
+
"hooks": [
|
|
222
|
+
{
|
|
223
|
+
"command": "bash '"'"'/sandbox/.codex/herdr-agent-state.sh'"'"' session",
|
|
224
|
+
"timeout": 10,
|
|
225
|
+
"type": "command"
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
}'
|
|
229
|
+
neighbour_survives() { # <label>
|
|
230
|
+
printf '%s' "$FOREIGN_GROUP" > "$SB/foreign-block.txt"
|
|
231
|
+
grep -qF -f "$SB/foreign-block.txt" "$HOOKS" && ok "$1" || die "$1 (the foreign group's bytes changed)"
|
|
232
|
+
}
|
|
233
|
+
foreign_file() { # writes a hooks.json declaring ONLY the neighbour, in its own formatting AND
|
|
234
|
+
# its own mode — both are things this unit must carry over rather than normalise.
|
|
235
|
+
printf '{\n "hooks": {\n "SessionStart": [\n%s\n ]\n }\n}\n' "$FOREIGN_GROUP" > "$HOOKS"
|
|
236
|
+
chmod 0600 "$HOOKS"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# ORDER A — the neighbour is there first and entwurf joins it.
|
|
240
|
+
foreign_file
|
|
241
|
+
cp "$HOOKS" "$SB/foreign-only.json"
|
|
242
|
+
want "[QK:CODEX-BIRTH-JOINS-FOREIGN-FILE] a foreign hooks.json is JOINED by text splice, never adopted and never refused" \
|
|
243
|
+
"'$INSTALL' >'$SB/out' 2>&1 && grep -q 'appended entwurf' '$SB/out' && grep -q 'byte-for-byte' '$SB/out'"
|
|
244
|
+
neighbour_survives "the neighbour's declaration survives the install byte-for-byte"
|
|
245
|
+
want "[QK:CODEX-BIRTH-SHARED-FILE-MODE-KEPT] the shared file keeps the mode it was found with — a file we only add a group to is not one whose permissions are ours to reset" \
|
|
246
|
+
"[ \"\$(stat -c %a '$HOOKS')\" = '0600' ] || [ \"\$(stat -c %a '$HOOKS')\" = '600' ]"
|
|
247
|
+
want "entwurf's declaration was APPENDED, so the neighbour keeps index 0 and the trust receipt it already has" \
|
|
248
|
+
"node -e 'const s=JSON.parse(require(\"node:fs\").readFileSync(process.argv[1],\"utf8\")); const g=s.hooks.SessionStart; if(g.length!==2)throw new Error(\"groups \"+g.length); if(g[0].hooks[0].command.includes(\"entwurf\"))throw new Error(\"entwurf took index 0\"); if(g[1].hooks[0].command!==\"'\''\"+process.argv[2]+\"'\''\")throw new Error(\"ours is not at index 1\");' '$HOOKS' '$LAUNCHER'"
|
|
249
|
+
want "[QK:CODEX-BIRTH-DOCTOR-COEXISTS] the doctor certifies entwurf's own declaration at its MEASURED index and stays green beside a neighbour" \
|
|
250
|
+
"'$DOCTOR' --unit-only >'$SB/out' 2>&1 && grep -q \"entwurf's declaration is certified at .* group 1 handler 0\" '$SB/out'"
|
|
251
|
+
want "[QK:CODEX-BIRTH-DOCTOR-REPORTS-FOREIGN] the neighbour is reported as present-but-foreign, in its own section, and certified by nothing" \
|
|
252
|
+
"grep -q 'FOREIGN (what else declares' '$SB/out' && grep -q 'SessionStart group 0: bash' '$SB/out' && grep -q 'present-but-foreign' '$SB/out' && grep -q 'never overwritten, never absorbed' '$SB/out'"
|
|
253
|
+
|
|
254
|
+
# THE VENDOR RECEIPT IS READ AT OUR MEASURED INDEX, and this is the cell that would have caught
|
|
255
|
+
# the #117 false green: with the neighbour at index 0, a constant `:0:0` reads THEIR approval and
|
|
256
|
+
# reports a birth hook the vendor was never asked to run.
|
|
257
|
+
trust_receipt "$HOOKS:session_start:1:0"
|
|
258
|
+
want "[QK:CODEX-BIRTH-TRUST-INDEX-MEASURED] the full doctor reads the vendor receipt at entwurf's MEASURED index (1:0 here), never at the constant :0:0" \
|
|
259
|
+
"'$DOCTOR' >'$SB/out' 2>&1"
|
|
260
|
+
trust_receipt "$HOOKS:session_start:0:0"
|
|
261
|
+
"$DOCTOR" >"$SB/out" 2>&1 && die "the doctor read the NEIGHBOUR's receipt at :0:0 as entwurf's own approval"
|
|
262
|
+
want "a receipt at the neighbour's index is named as somebody else's approval, and the key looked for is ours" \
|
|
263
|
+
"grep -q \"NONE at this unit's key $HOOKS:session_start:1:0\" '$SB/out'"
|
|
264
|
+
cp "$SB/config.before.toml" "$CFG"
|
|
265
|
+
|
|
266
|
+
# A neighbour EDITED after our install moves nothing of ours — it is not ours to certify.
|
|
267
|
+
python3 -c 'import json,sys
|
|
268
|
+
p=sys.argv[1]; d=json.load(open(p))
|
|
269
|
+
d["hooks"]["SessionStart"][0]["hooks"][0]["timeout"]=99
|
|
270
|
+
open(p,"w").write(json.dumps(d,indent=2))' "$HOOKS"
|
|
271
|
+
want "[QK:CODEX-BIRTH-FOREIGN-EDIT-NEUTRAL] a neighbour's declaration edited after our install is still reported and still certified by nothing — our verdict is unmoved" \
|
|
272
|
+
"'$DOCTOR' --unit-only >'$SB/out' 2>&1 && grep -q \"entwurf's declaration is certified\" '$SB/out' && grep -q 'SessionStart group 0: bash' '$SB/out'"
|
|
273
|
+
"$INSTALL" >"$SB/out" 2>&1 || die "reinstall beside an edited neighbour failed: $(cat "$SB/out")"
|
|
274
|
+
want "a reinstall beside an edited neighbour does not rewrite hooks.json at all" "grep -q 'NOT REWRITTEN, not one byte' '$SB/out'"
|
|
275
|
+
|
|
276
|
+
# The inverse takes our group out and leaves the neighbour's bytes exactly where they were.
|
|
277
|
+
cp "$HOOKS" "$SB/before-inverse.json"
|
|
278
|
+
# The exit status rides INSIDE the claim: a splice aimed at the wrong group is caught by the
|
|
279
|
+
# post-condition and comes back as DRIFT, which is a nonzero exit — and a separate `|| die` above
|
|
280
|
+
# would swallow that with a line that cannot carry this claim's token.
|
|
281
|
+
INVERSE_RC=0
|
|
282
|
+
"$UNINSTALL" >"$SB/out" 2>&1 || INVERSE_RC=$?
|
|
283
|
+
want "[QK:CODEX-BIRTH-INVERSE-KEEPS-FOREIGN] the inverse removes ONLY entwurf's group, by splice, and keeps the shared file — a splice that landed anywhere else would be refused by its own post-condition and reported as drift instead" \
|
|
284
|
+
"[ \"$INVERSE_RC\" -eq 0 ] && [ -f '$HOOKS' ] && grep -q 'by text splice' '$SB/out' && ! grep -q 'codex-birth-launch.sh' '$HOOKS'"
|
|
285
|
+
want "the inverse left the neighbour as the file's only declaration" \
|
|
286
|
+
"node -e 'const s=JSON.parse(require(\"node:fs\").readFileSync(process.argv[1],\"utf8\")); if(s.hooks.SessionStart.length!==1)throw 0; if(!s.hooks.SessionStart[0].hooks[0].command.includes(\"herdr\"))throw 0;' '$HOOKS'"
|
|
287
|
+
want "the inverse removed entwurf's own description and left no entwurf prose behind" "! grep -q 'entwurf codex-birth' '$HOOKS'"
|
|
288
|
+
# The neighbour was re-indented by its own editor above; what must survive the SPLICE is every
|
|
289
|
+
# byte of the group as it stood immediately before the inverse ran.
|
|
290
|
+
node -e '
|
|
291
|
+
const fs = require("node:fs");
|
|
292
|
+
const before = JSON.parse(fs.readFileSync(process.argv[1], "utf8")).hooks.SessionStart.filter((g) => !JSON.stringify(g).includes("codex-birth-launch"));
|
|
293
|
+
const after = JSON.parse(fs.readFileSync(process.argv[2], "utf8")).hooks.SessionStart;
|
|
294
|
+
if (JSON.stringify(before) !== JSON.stringify(after)) throw new Error("foreign groups changed across the inverse");
|
|
295
|
+
' "$SB/before-inverse.json" "$HOOKS" && ok "[QK:CODEX-BIRTH-INVERSE-FOREIGN-EXACT] every foreign group is value-identical across the inverse" || die "the inverse changed a foreign group"
|
|
206
296
|
rm -f "$HOOKS"
|
|
207
297
|
|
|
298
|
+
# ORDER B — entwurf is there first and the neighbour appends afterwards, re-serializing the
|
|
299
|
+
# WHOLE document on its way past (measured: Herdr does exactly this, oracle 2026-09-17).
|
|
300
|
+
"$INSTALL" >/dev/null 2>&1 || die "install before the order-B cell failed"
|
|
301
|
+
python3 -c 'import json,sys
|
|
302
|
+
p=sys.argv[1]; d=json.load(open(p))
|
|
303
|
+
g=d["hooks"]["SessionStart"][0]["hooks"][0]
|
|
304
|
+
d["hooks"]["SessionStart"][0]["hooks"][0]={"command":g["command"],"timeout":g["timeout"],"type":g["type"]}
|
|
305
|
+
d["hooks"]["SessionStart"].append({"hooks":[{"command":"bash \x27/sandbox/.codex/herdr-agent-state.sh\x27 session","timeout":10,"type":"command"}]})
|
|
306
|
+
open(p,"w").write(json.dumps(d,indent=2))' "$HOOKS"
|
|
307
|
+
BEFORE_SHA="$(sha256sum "$HOOKS" | cut -d" " -f1)"
|
|
308
|
+
want "[QK:CODEX-BIRTH-NORMALIZED-DIGEST] the certification is blind to key order and indentation a neighbour imposed — bytes changed, our declaration did not" \
|
|
309
|
+
"'$DOCTOR' --unit-only >'$SB/out' 2>&1 && grep -q \"entwurf's declaration is certified at .* group 0 handler 0\" '$SB/out' && grep -q 'NORMALIZED digest, not by file bytes' '$SB/out'"
|
|
310
|
+
"$INSTALL" >"$SB/out" 2>&1 || die "reinstall after a neighbour re-serialized the file failed: $(cat "$SB/out")"
|
|
311
|
+
want "that reinstall rewrote NOT ONE BYTE of the shared file" \
|
|
312
|
+
"grep -q 'NOT REWRITTEN, not one byte' '$SB/out' && [ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = '$BEFORE_SHA' ]"
|
|
313
|
+
|
|
314
|
+
# OUR OWN declaration edited is still a named refusal — the narrowing is about WHOSE bytes, not
|
|
315
|
+
# about being lenient with ours. SHAPE catches it first: `timeout` is part of the identity the
|
|
316
|
+
# operator approved, so a value the installer never writes is not a digest question at all.
|
|
317
|
+
python3 -c 'import json,sys
|
|
318
|
+
p=sys.argv[1]; d=json.load(open(p))
|
|
319
|
+
d["hooks"]["SessionStart"][0]["hooks"][0]["timeout"]=31
|
|
320
|
+
open(p,"w").write(json.dumps(d,indent=2))' "$HOOKS"
|
|
321
|
+
refuses "[QK:CODEX-BIRTH-OWN-DECLARATION-DRIFT] an edit to entwurf's OWN handler is refused by name" "declaration-shape-drifted" "$INSTALL"
|
|
322
|
+
"$DOCTOR" --unit-only >"$SB/out" 2>&1 && die "the doctor was green over an edited entwurf declaration"
|
|
323
|
+
want "the doctor names our own drifted declaration and what about it drifted" "grep -q 'declaration is not certifiable' '$SB/out' && grep -q 'timeout must be 30' '$SB/out'"
|
|
324
|
+
"$UNINSTALL" >"$SB/out" 2>&1 && die "the inverse removed an edited entwurf declaration"
|
|
325
|
+
want "the inverse leaves our own drifted declaration in place" "grep -q 'DRIFT' '$SB/out' && grep -q 'declaration-shape-drifted' '$SB/out' && [ -f '$HOOKS' ]"
|
|
326
|
+
|
|
327
|
+
# SHAPE and DIGEST are two different authorities and only one of them is the recorded receipt.
|
|
328
|
+
# Shape asks "is this the declaration these fixed paths produce"; the digest asks "is this the
|
|
329
|
+
# declaration the STATE recorded". Tampering with the receipt alone is the only way to separate
|
|
330
|
+
# them, and it must be red: a receipt anyone can retune certifies nothing.
|
|
331
|
+
rm -rf "$HOOKS" "$UNIT_ROOT"
|
|
332
|
+
"$INSTALL" >/dev/null 2>&1 || die "install before the receipt-binding cell failed"
|
|
333
|
+
python3 -c 'import json,sys
|
|
334
|
+
p=sys.argv[1]; s=json.load(open(p))
|
|
335
|
+
s["declaration"]["sha256"]="0"*64
|
|
336
|
+
open(p,"w").write(json.dumps(s,indent=2))' "$STATE"
|
|
337
|
+
want "[QK:CODEX-BIRTH-DECLARATION-RECEIPT-BINDS] the live declaration is compared to the RECORDED normalized digest, and a receipt that no longer names it is red" \
|
|
338
|
+
"! '$DOCTOR' --unit-only >'$SB/out' 2>&1 && grep -q 'declaration was EDITED after install' '$SB/out' && grep -q 'live normalized' '$SB/out' && grep -q 'recorded 0000' '$SB/out'"
|
|
339
|
+
"$INSTALL" >/dev/null 2>&1 || die "install should re-record the receipt over a tampered one"
|
|
340
|
+
"$DOCTOR" --unit-only >/dev/null 2>&1 || die "the unit axis should be green once the receipt is republished"
|
|
341
|
+
ok "install re-records the declaration receipt, and the unit axis is green again"
|
|
342
|
+
|
|
343
|
+
# ...and a SECOND copy of our declaration is a refusal too: the vendor would run the birth hook
|
|
344
|
+
# twice per session, and only one of those positions can carry the operator's receipt.
|
|
345
|
+
python3 -c 'import json,sys
|
|
346
|
+
p=sys.argv[1]; d=json.load(open(p)); g=d["hooks"]["SessionStart"]
|
|
347
|
+
g[0]["hooks"][0]["timeout"]=30
|
|
348
|
+
g.append(json.loads(json.dumps(g[0])))
|
|
349
|
+
open(p,"w").write(json.dumps(d,indent=2))' "$HOOKS"
|
|
350
|
+
refuses "[QK:CODEX-BIRTH-DECLARATION-DUPLICATED] our declaration present twice is refused by name, never first-match accepted" "declaration-duplicated" "$INSTALL"
|
|
351
|
+
"$DOCTOR" --unit-only >"$SB/out" 2>&1 && die "the doctor accepted a duplicated entwurf declaration"
|
|
352
|
+
want "the doctor names the duplication and both positions" "grep -q 'declaration-duplicated' '$SB/out' && grep -qE 'group [0-9]+ handler [0-9]+, group [0-9]+ handler [0-9]+' '$SB/out'"
|
|
353
|
+
rm -rf "$HOOKS" "$UNIT_ROOT"
|
|
354
|
+
|
|
355
|
+
|
|
208
356
|
ln -s "$SB/foreign-hooks.json" "$HOOKS"
|
|
209
357
|
refuses "a symlinked hooks.json is refused" "is a SYMLINK" "$INSTALL"
|
|
210
358
|
want "the symlink refusal wrote no state" "[ ! -e '$STATE' ] && [ -L '$HOOKS' ]"
|
|
211
359
|
rm -f "$HOOKS"
|
|
212
360
|
|
|
213
361
|
"$INSTALL" >/dev/null 2>&1 || die "install before the edited-declaration cell failed"
|
|
362
|
+
# WHITESPACE IS NOT DRIFT ANY MORE, and that is a contract change worth pinning: a normalized
|
|
363
|
+
# digest is blind to formatting precisely so a neighbour's re-serialize cannot fake an edit.
|
|
214
364
|
printf '\n' >> "$HOOKS"
|
|
365
|
+
want "[QK:CODEX-BIRTH-WHITESPACE-NOT-DRIFT] reformatting alone is not drift — the digest is over the declaration, not the bytes" \
|
|
366
|
+
"'$DOCTOR' --unit-only >/dev/null 2>&1"
|
|
367
|
+
# An edit to a FIELD of our handler still is.
|
|
368
|
+
python3 -c 'import json,sys
|
|
369
|
+
p=sys.argv[1]; d=json.load(open(p))
|
|
370
|
+
d["hooks"]["SessionStart"][0]["hooks"][0]["timeout"]=7
|
|
371
|
+
open(p,"w").write(json.dumps(d,indent=2))' "$HOOKS"
|
|
215
372
|
cp "$HOOKS" "$SB/edited-hooks.json"
|
|
216
|
-
refuses "an edited declaration is refused instead of republished" "
|
|
373
|
+
refuses "an edited declaration is refused instead of republished" "declaration-shape-drifted" "$INSTALL"
|
|
217
374
|
cmp -s "$SB/edited-hooks.json" "$HOOKS" && ok "the edited declaration survives the refusal byte-for-byte" || die "the edited hooks.json was overwritten"
|
|
218
375
|
"$DOCTOR" --unit-only >"$SB/out" 2>&1 && die "the unit axis should be red while the declaration is edited"
|
|
219
|
-
want "the doctor names the edited declaration" "grep -q '
|
|
376
|
+
want "the doctor names the edited declaration" "grep -q 'declaration is not certifiable' '$SB/out'"
|
|
220
377
|
|
|
221
378
|
###############################################################################
|
|
222
379
|
# inverse — exact removal, and a refusal that leaves drift in place
|
|
223
380
|
###############################################################################
|
|
224
381
|
"$UNINSTALL" >"$SB/out" 2>&1 && die "the inverse should refuse while the declaration is drifted"
|
|
225
|
-
want "the inverse refuses the drifted declaration" "grep -q 'DRIFT
|
|
382
|
+
want "the inverse refuses the drifted declaration" "grep -q 'DRIFT' '$SB/out' && grep -q 'declaration-shape-drifted' '$SB/out'"
|
|
226
383
|
want "the drifted declaration is LEFT IN PLACE" "[ -f '$HOOKS' ]"
|
|
227
384
|
want "the inverse keeps the state so a later run can still license the path" "[ -f '$STATE' ]"
|
|
228
385
|
cmp -s "$SB/edited-hooks.json" "$HOOKS" && ok "the drifted declaration is byte-identical after the refused inverse" || die "the refused inverse changed the drifted file"
|
|
@@ -234,7 +391,7 @@ printf '# operator edit\n' >> "$LAUNCHER"
|
|
|
234
391
|
"$UNINSTALL" >"$SB/out" 2>&1 && die "the inverse should refuse while the launcher is drifted"
|
|
235
392
|
want "the inverse refuses a drifted helper member by digest" "grep -q 'DRIFT: helper member was edited after install' '$SB/out'"
|
|
236
393
|
want "the drifted launcher is LEFT IN PLACE" "[ -f '$LAUNCHER' ]"
|
|
237
|
-
want "the declaration it already removed is
|
|
394
|
+
want "[QK:CODEX-BIRTH-INVERSE-SOLE-OWNER] the declaration it already removed is GONE — the FILE arm deletes the file it was the sole declaration in — and the state remains, because a drifted helper is still owed a licence" "[ ! -e '$HOOKS' ] && [ -f '$STATE' ]"
|
|
238
395
|
|
|
239
396
|
rm -f "$LAUNCHER"
|
|
240
397
|
"$INSTALL" >/dev/null 2>&1 || die "reinstall before the exact-inverse cell failed"
|
|
@@ -249,6 +406,11 @@ cmp -s "$SB/config.before.toml" "$CFG" && ok "the full install/inverse cycle lef
|
|
|
249
406
|
# empty unit on the strength of somebody else's approval — measured exactly that way once.
|
|
250
407
|
"$DOCTOR" --unit-only >"$SB/out" 2>&1 && die "[QK:CODEX-BIRTH-DOCTOR-ABSENT-IS-RED] the unit axis was green with NOTHING installed"
|
|
251
408
|
want "an absent unit is named as red, not as an informational note" "grep -q 'no Codex birth unit is installed here' '$SB/out'"
|
|
409
|
+
# ...and with nothing installed the FOREIGN axis says NOT READ, never "none": the UNIT axis never
|
|
410
|
+
# opened that file, and "none" would be this doctor asserting something about the operator's
|
|
411
|
+
# hooks.json it never looked at.
|
|
412
|
+
want "[QK:CODEX-BIRTH-FOREIGN-UNREAD-NOT-NONE] an unscanned FOREIGN axis reports NOT READ rather than claiming there are no neighbours" \
|
|
413
|
+
"grep -q 'NOT READ' '$SB/out' && ! grep -q 'none — entwurf is the only' '$SB/out'"
|
|
252
414
|
trust_receipt "$HOOKS:session_start:0:0"
|
|
253
415
|
"$DOCTOR" >"$SB/out" 2>&1 && die "a stale vendor receipt made an ABSENT unit green"
|
|
254
416
|
want "a stale receipt cannot carry an absent unit" "grep -q 'no Codex birth unit is installed here' '$SB/out'"
|
|
@@ -314,6 +476,29 @@ python3 -c 'import json,sys; s=json.load(open(sys.argv[1])); s["status"]="publis
|
|
|
314
476
|
"$INSTALL" >/dev/null 2>&1 || die "an interrupted `publishing` state should be finishable, not refused"
|
|
315
477
|
want "the finished publish records installed" "grep -q '\"status\": \"installed\"' '$STATE'"
|
|
316
478
|
|
|
479
|
+
# A v1 ownership receipt recorded a digest of the WHOLE hooks.json. Reading it leniently would
|
|
480
|
+
# certify bytes a neighbour owns, so every reader refuses it by name — and the installer is the
|
|
481
|
+
# one forward path, superseding it without removing anything or rewriting a foreign byte.
|
|
482
|
+
rm -rf "$HOOKS" "$UNIT_ROOT"
|
|
483
|
+
"$INSTALL" >/dev/null 2>&1 || die "install before the v1-supersede cell failed"
|
|
484
|
+
python3 -c 'import json,sys
|
|
485
|
+
p=sys.argv[1]; s=json.load(open(p))
|
|
486
|
+
s["schema"]="codex-birth-install-state/v1"
|
|
487
|
+
s["hooksSha256"]="1"*64
|
|
488
|
+
del s["declaration"]
|
|
489
|
+
open(p,"w").write(json.dumps(s,indent=2))' "$STATE"
|
|
490
|
+
want "[QK:CODEX-BIRTH-STATE-V1-REFUSED] the doctor refuses a v1 receipt by name and names the one forward path" \
|
|
491
|
+
"! '$DOCTOR' --unit-only >'$SB/out' 2>&1 && grep -q 'codex-birth-install-state/v1' '$SB/out' && grep -q 'WHOLE hooks.json' '$SB/out' && grep -q 'install-codex-birth' '$SB/out'"
|
|
492
|
+
"$UNINSTALL" >"$SB/out" 2>&1 && die "the inverse removed things on the word of a v1 receipt"
|
|
493
|
+
want "the inverse refuses a v1 receipt and removes NOTHING" \
|
|
494
|
+
"grep -q 'codex-birth-install-state/v2' '$SB/out' && [ -f '$HOOKS' ] && [ -f '$LAUNCHER' ] && [ -f '$STATE' ]"
|
|
495
|
+
HOOKS_BEFORE_V1="$(sha256sum "$HOOKS" | cut -d' ' -f1)"
|
|
496
|
+
"$INSTALL" >"$SB/out" 2>&1 || die "the installer should supersede a v1 receipt: $(cat "$SB/out")"
|
|
497
|
+
want "the installer supersedes v1 forward, says so, and rewrites not one byte of hooks.json" \
|
|
498
|
+
"grep -q 'superseding a v1 ownership receipt' '$SB/out' && grep -q 'NOT REWRITTEN, not one byte' '$SB/out' && [ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = \"$HOOKS_BEFORE_V1\" ]"
|
|
499
|
+
"$DOCTOR" --unit-only >/dev/null 2>&1 || die "the unit axis should be green once the receipt is v2"
|
|
500
|
+
ok "the unit axis is green once the receipt has been superseded to v2"
|
|
501
|
+
|
|
317
502
|
# The directory holding the receipt carries the receipt's authority. Children untouched: what
|
|
318
503
|
# changed is only who may replace the inventory every digest is compared against.
|
|
319
504
|
chmod 0777 "$UNIT_ROOT"
|
|
@@ -330,6 +515,90 @@ chmod 0755 "$UNIT_ROOT"
|
|
|
330
515
|
ok "the unit axis is green again once the root is no longer writable"
|
|
331
516
|
"$UNINSTALL" >/dev/null 2>&1 || die "cleanup uninstall after the parent-authority cell failed"
|
|
332
517
|
|
|
518
|
+
# ── the FILE verdict has to EARN its delete (sol B2, 2026-09-18) ─────────────────────────────
|
|
519
|
+
# The counterexample, derived from the source rather than imagined: a hooks.json that existed
|
|
520
|
+
# BEFORE this unit, carrying a foreign top-level `description` and an EMPTY SessionStart array.
|
|
521
|
+
# Our install appends one group, so afterwards there is no foreign GROUP, one event, and one
|
|
522
|
+
# declaration — which is exactly what the old FILE test asked. It deleted the whole file, and the
|
|
523
|
+
# neighbour's description with it, while the receipt had recorded `hooksExistedBefore: true` the
|
|
524
|
+
# entire time and nothing read it.
|
|
525
|
+
"$UNINSTALL" >/dev/null 2>&1 || true
|
|
526
|
+
printf '{\n "description": "a neighbour wrote this",\n "note": "and this",\n "hooks": {\n "SessionStart": []\n }\n}\n' > "$HOOKS"
|
|
527
|
+
chmod 0600 "$HOOKS"
|
|
528
|
+
PRE_EXISTING_SHA="$(sha256sum "$HOOKS" | cut -d' ' -f1)"
|
|
529
|
+
"$INSTALL" >/dev/null 2>&1 || die "install into a pre-existing empty-declaration file failed"
|
|
530
|
+
"$UNINSTALL" >"$SB/out" 2>&1 || die "uninstall after that install failed: $(cat "$SB/out")"
|
|
531
|
+
want "[QK:CODEX-BIRTH-INVERSE-KEEPS-PRE-EXISTING-FILE] a file that existed BEFORE this unit survives the inverse whole — our group comes out by splice and the neighbour's top-level bytes come back byte-for-byte, because hooksExistedBefore is a removal authority and not a decoration" \
|
|
532
|
+
"[ -f '$HOOKS' ] && [ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = \"$PRE_EXISTING_SHA\" ] && grep -q 'by text splice' '$SB/out'"
|
|
533
|
+
# And the delete arm still exists for the case it was written for: a file this unit created,
|
|
534
|
+
# holding nothing but its own description and its own group.
|
|
535
|
+
rm -f "$HOOKS"
|
|
536
|
+
"$INSTALL" >/dev/null 2>&1 || die "install into a host with no hooks.json failed"
|
|
537
|
+
"$UNINSTALL" >"$SB/out" 2>&1 || die "uninstall of a file we created failed: $(cat "$SB/out")"
|
|
538
|
+
want "a hooks.json this unit CREATED, holding only its own description and group, is still removed whole — the narrowing above added proofs to that delete, it did not retire it" \
|
|
539
|
+
"[ ! -e '$HOOKS' ] && grep -q 'entwurf was its only declaration' '$SB/out'"
|
|
540
|
+
|
|
541
|
+
# ── the SHARED file's own ownership, decided ONCE for four surfaces (sol B3, 2026-09-18) ─────
|
|
542
|
+
# The split this closes: install and uninstall asked only symlink-and-regular, the doctor asked
|
|
543
|
+
# NOTHING about who owned hooks.json, and only the fresh-call preflight refused a foreign uid or a
|
|
544
|
+
# group-writable mode. So a host could install clean, read GREEN, and have every Codex launch
|
|
545
|
+
# refuse it as `codex-birth-unit-missing` — three surfaces saying yes about bytes the fourth said
|
|
546
|
+
# no about. All four now decide with `classifyOwnedPath` in the shared declaration leaf.
|
|
547
|
+
#
|
|
548
|
+
# We still never chmod what we share. The cells below prove the mode we found is the mode left
|
|
549
|
+
# behind: an unsafe shared file is a zero-write REFUSAL, not a file we normalise on the way past.
|
|
550
|
+
"$INSTALL" >/dev/null 2>&1 || die "install before the shared-ownership cells failed"
|
|
551
|
+
HOOKS_BEFORE_UNSAFE="$(sha256sum "$HOOKS" | cut -d' ' -f1)"
|
|
552
|
+
chmod 0666 "$HOOKS"
|
|
553
|
+
refuses "[QK:CODEX-BIRTH-SHARED-FILE-OWNERSHIP] install refuses a hooks.json anyone else can rewrite — a receipt cannot bind bytes somebody else controls" \
|
|
554
|
+
"group/world-writable" "$INSTALL"
|
|
555
|
+
want "the refused install neither repaired the mode nor wrote a byte" \
|
|
556
|
+
"[ \"\$(stat -c %a '$HOOKS')\" = '666' ] && [ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = \"$HOOKS_BEFORE_UNSAFE\" ]"
|
|
557
|
+
# ONE assertion, because the exit code and the wording are one claim: a doctor that stayed green
|
|
558
|
+
# would fail a separate negative line first, and that line could not carry the token (a manifest
|
|
559
|
+
# may name its QK exactly once per gate source), so the mutant would die unattributable.
|
|
560
|
+
DOCTOR_RC=0
|
|
561
|
+
"$DOCTOR" --unit-only >"$SB/out" 2>&1 || DOCTOR_RC=$?
|
|
562
|
+
want "[QK:CODEX-BIRTH-DOCTOR-SHARED-OWNERSHIP] the doctor asks the same ownership question BEFORE it measures any digest — a digest taken in a file somebody else can rewrite certifies nothing, and a green here would contradict the launcher" \
|
|
563
|
+
"[ \"$DOCTOR_RC\" -ne 0 ] && grep -q 'group/world-writable' '$SB/out' && grep -q 'every Codex fresh call refuses this host' '$SB/out'"
|
|
564
|
+
"$UNINSTALL" >"$SB/out" 2>&1 || true # drift is a nonzero exit; the WORDS and the bytes are the claim
|
|
565
|
+
want "[QK:CODEX-BIRTH-INVERSE-SHARED-OWNERSHIP] the inverse asks it too and leaves an unsafe shared file exactly as found, counted as DRIFT — it used to rewrite a file it could not bind" \
|
|
566
|
+
"grep -q 'DRIFT: the declaration file writable-by-others' '$SB/out' && [ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = \"$HOOKS_BEFORE_UNSAFE\" ]"
|
|
567
|
+
chmod 0600 "$HOOKS"
|
|
568
|
+
# That inverse removed the closure it COULD account for and left the shared file alone, so the
|
|
569
|
+
# way back to green is an install — which is itself the claim: the refusal was about this file's
|
|
570
|
+
# ownership and nothing else, and it lifts the moment the ownership does.
|
|
571
|
+
"$INSTALL" >/dev/null 2>&1 || die "install should succeed again once the shared file is no longer writable by others"
|
|
572
|
+
"$DOCTOR" --unit-only >/dev/null 2>&1 || die "the unit axis should be green again once the shared file is no longer writable by others"
|
|
573
|
+
ok "all four surfaces agree again once the shared file is safe"
|
|
574
|
+
ln -sf "$SB/foreign-only.json" "$SB/hooks-link.json"
|
|
575
|
+
refuses "a symlinked hooks.json is refused with its OWN word — the repair is not a mode change, it is a different file" \
|
|
576
|
+
"SYMLINK" env CODEX_HOME="$CODEX_HOME" HOOKS_LINK=1 bash -c "cp '$HOOKS' '$SB/hooks-real.json'; rm '$HOOKS'; ln -s '$SB/hooks-real.json' '$HOOKS'; '$INSTALL'"
|
|
577
|
+
rm -f "$HOOKS"; cp "$SB/hooks-real.json" "$HOOKS"; chmod 0600 "$HOOKS"
|
|
578
|
+
"$UNINSTALL" >/dev/null 2>&1 || die "cleanup uninstall after the shared-ownership cells failed"
|
|
579
|
+
|
|
580
|
+
# ── the ORPHAN verdict: our bytes with no receipt behind them (glm #2) ────────────────────────
|
|
581
|
+
# `[glm 감사 2026-09-18]` this branch had no assertion and no mutant at all. It is the half-removed
|
|
582
|
+
# state — a declaration commanding OUR launcher, or a closure directory, with the receipt that
|
|
583
|
+
# licenses removing them gone — and the doctor must go RED rather than fall through to the
|
|
584
|
+
# "nothing is installed here" arm, which reads as a clean host and invites a reinstall over bytes
|
|
585
|
+
# the inverse will then refuse.
|
|
586
|
+
"$INSTALL" >/dev/null 2>&1 || die "install before the orphan cell failed"
|
|
587
|
+
ORPHAN_HOOKS_SHA="$(sha256sum "$HOOKS" | cut -d' ' -f1)"
|
|
588
|
+
mv "$STATE" "$SB/state-parked.json"
|
|
589
|
+
# ONE assertion, because red-for-the-wrong-reason is the failure mode here: with the orphan test
|
|
590
|
+
# removed the doctor still exits nonzero, down the "nothing is installed here" arm, and a cell that
|
|
591
|
+
# only checked the exit code would call that a kill. The WORDS are the claim.
|
|
592
|
+
ORPHAN_RC=0
|
|
593
|
+
"$DOCTOR" --unit-only >"$SB/out" 2>&1 || ORPHAN_RC=$?
|
|
594
|
+
want "[QK:CODEX-BIRTH-DOCTOR-ORPHAN-RED] a declaration or closure with no receipt behind it is RED and NAMED as not provably ours — never the clean-host arm, which reads as nothing installed and invites a reinstall over bytes the inverse will then refuse" \
|
|
595
|
+
"[ \"$ORPHAN_RC\" -ne 0 ] && grep -q 'not provably ours' '$SB/out' && ! grep -q 'no Codex birth unit is installed here' '$SB/out'"
|
|
596
|
+
want "the orphan doctor is READ-ONLY — it names those bytes and repairs nothing" \
|
|
597
|
+
"[ \"\$(sha256sum '$HOOKS' | cut -d' ' -f1)\" = \"$ORPHAN_HOOKS_SHA\" ] && [ ! -e '$STATE' ]"
|
|
598
|
+
mv "$SB/state-parked.json" "$STATE"
|
|
599
|
+
"$DOCTOR" --unit-only >/dev/null 2>&1 || die "the unit axis should be green again once the receipt is back"
|
|
600
|
+
"$UNINSTALL" >/dev/null 2>&1 || die "cleanup uninstall after the orphan cell failed"
|
|
601
|
+
|
|
333
602
|
# A relative root would make "the fixed launcher path" depend on the caller's cwd — and that
|
|
334
603
|
# path is exactly what the vendor keys its trust receipt to.
|
|
335
604
|
( cd "$SB" && CODEX_HOME="relative/.codex" "$INSTALL" >"$SB/out" 2>&1 ) && die "[QK:CODEX-BIRTH-REFUSES-RELATIVE-ROOT] a relative CODEX_HOME was accepted"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* smoke-entwurf-v2-matrix-live — the 5d-5 D4-b LIVE sentinel for the release-gate matrix.
|
|
3
3
|
*
|
|
4
|
-
* The deterministic sibling (
|
|
4
|
+
* The deterministic sibling (pi-extensions/lib/entwurf-v2-decider.matrix.test.ts) drives the REAL decider over fakes with
|
|
5
5
|
* ZERO IO — it fixes every (target kind → transport → lock) cell as a table. This LIVE sentinel
|
|
6
6
|
* drives the REAL production `runEntwurfV2` deps against REAL OS objects on the substrate's
|
|
7
7
|
* happy path, to catch what fakes cannot: a real `pi --entwurf-control` control socket + RPC,
|