@junghanacs/entwurf 0.19.0 → 0.20.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 +1 -1
- package/BASELINE.md +23 -5
- package/CHANGELOG.md +236 -0
- package/DELIVERY.md +59 -6
- package/README.md +40 -9
- package/VERIFY.md +9 -1
- package/docs/acp-backend-rail.md +9 -1
- package/docs/external-mcp-host.md +6 -3
- package/docs/setup-clean-host.md +93 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +3 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +6 -2
- package/package.json +2 -2
- package/pi-extensions/acp-provider.ts +1 -1
- package/pi-extensions/lib/acp/models.ts +3 -3
- package/pi-extensions/lib/acp/overlay.ts +6 -2
- package/pi-extensions/lib/meta-session.ts +25 -0
- package/run.sh +71 -26
- package/scripts/agy-bridge.sh +1 -1
- package/scripts/agy-imprint.sh +10 -7
- package/scripts/check-acp-carrier-augment.ts +6 -5
- package/scripts/check-acp-cortex.ts +41 -0
- package/scripts/check-acp-provider-surface.ts +9 -6
- package/scripts/check-copilot-birth-hook.ts +3 -1
- package/scripts/check-copilot-receive-arm.ts +169 -21
- package/scripts/check-copilot-statusline.ts +3 -1
- package/scripts/check-gate-qualification.ts +10 -9
- package/scripts/check-hook-launch-topology.ts +6 -5
- package/scripts/check-install-surface.ts +2 -1
- package/scripts/check-meta-facts.ts +6 -4
- package/scripts/check-meta-hook-session-switch.ts +4 -3
- package/scripts/check-meta-identity-consumers.ts +8 -7
- package/scripts/check-meta-receiver-marker.ts +2 -1
- package/scripts/check-omp-birth-hook.ts +3 -2
- package/scripts/check-probe-bridge-command.ts +3 -1
- package/scripts/check-setup-qualification.sh +21 -0
- package/scripts/copilot-bridge-doctor.sh +15 -5
- package/scripts/copilot-bridge-install.sh +6 -2
- package/scripts/copilot-launch.sh +16 -2
- package/scripts/copilot-receive-bridge.sh +80 -13
- package/scripts/lib/reclaim-on-exit.ts +86 -0
- package/scripts/meta-bridge-doctor.sh +56 -15
- package/scripts/meta-bridge-install.sh +13 -7
- package/scripts/meta-bridge-uninstall.sh +6 -4
- package/scripts/mutants/acp-cortex.json +26 -2
- package/scripts/mutants/copilot-receive.json +26 -0
- package/scripts/mutants/omp-birth.json +23 -6
- package/scripts/mutants/setup-verdict.json +13 -0
- package/scripts/omp-bridge-doctor.sh +110 -41
- package/scripts/omp-bridge-install.sh +6 -2
- package/scripts/omp-receive-install.sh +7 -2
- package/scripts/raw-async-delivery/README.md +10 -1
- package/scripts/raw-codex-measure/README.md +689 -0
- package/scripts/raw-codex-measure/source-audit.md +243 -0
- package/scripts/raw-macos-measure/README.md +148 -0
- package/scripts/raw-macos-measure/probe.sh +389 -0
- package/scripts/smoke-meta-async-drift.sh +7 -5
- package/scripts/smoke-meta-install-state.sh +70 -19
- package/scripts/smoke-omp-bridge-state.sh +38 -0
- package/scripts/smoke-setup-verdict.sh +100 -0
|
@@ -26,6 +26,19 @@
|
|
|
26
26
|
"signature": "[QK:CORTEX-CURATED-FOUR-ROWS]",
|
|
27
27
|
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
28
28
|
},
|
|
29
|
+
{
|
|
30
|
+
"claim": "CLAUDE-CURATED-THREE-ROWS",
|
|
31
|
+
"title": "dropping a curated CLAUDE row shrinks the operator's model list while the exact-set comparison stays green — expected derives from the same constant, so only the independent count catches it",
|
|
32
|
+
"subject": "pi-extensions/lib/acp/models.ts",
|
|
33
|
+
"find": [
|
|
34
|
+
"export const SUPPORTED_ANTHROPIC_MODEL_IDS = [\"claude-sonnet-5\", \"claude-opus-5\", \"claude-fable-5-1\"] as const;"
|
|
35
|
+
],
|
|
36
|
+
"replace": ["export const SUPPORTED_ANTHROPIC_MODEL_IDS = [\"claude-sonnet-5\", \"claude-opus-5\"] as const;"],
|
|
37
|
+
"gate": ["bash", "run.sh", "check-acp-provider-surface"],
|
|
38
|
+
"timeoutSeconds": 300,
|
|
39
|
+
"signature": "[QK:CLAUDE-CURATED-THREE-ROWS]",
|
|
40
|
+
"signatureSource": "scripts/check-acp-provider-surface.ts"
|
|
41
|
+
},
|
|
29
42
|
{
|
|
30
43
|
"claim": "CORTEX-AUTH-NARROW-CREDENTIAL-CACHE",
|
|
31
44
|
"title": "widening the auth passthrough to the whole cortex/cache leaks operator tool_outputs/tip_history into the child",
|
|
@@ -56,6 +69,17 @@
|
|
|
56
69
|
"signature": "[QK:CORTEX-AUTOUPDATE-OFF]",
|
|
57
70
|
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
58
71
|
},
|
|
72
|
+
{
|
|
73
|
+
"claim": "CORTEX-REALHOME-PLATFORM-NEUTRAL",
|
|
74
|
+
"title": "re-deriving realHome absoluteness from the POSIX flavor alone makes a drive/UNC HOME read as relative — the guard would state the host it runs on instead of the contract (PR #77, @yizixu)",
|
|
75
|
+
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
76
|
+
"find": ["\tif (!params.realHome || !(isAbsolute(params.realHome) || win32.isAbsolute(params.realHome))) {"],
|
|
77
|
+
"replace": ["\tif (!params.realHome || !params.realHome.startsWith(\"/\")) {"],
|
|
78
|
+
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
79
|
+
"timeoutSeconds": 300,
|
|
80
|
+
"signature": "[QK:CORTEX-REALHOME-PLATFORM-NEUTRAL]",
|
|
81
|
+
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
82
|
+
},
|
|
59
83
|
{
|
|
60
84
|
"claim": "CORTEX-BRIDGE-DUAL-HOME",
|
|
61
85
|
"title": "dropping the bridge-only real-HOME restore leaves the garden store cut off — tools reach the model but see an empty garden (D10)",
|
|
@@ -182,14 +206,14 @@
|
|
|
182
206
|
"signatureSource": "scripts/check-acp-session-reuse.ts"
|
|
183
207
|
},
|
|
184
208
|
{
|
|
185
|
-
"claim": "CORTEX-PROVIDER-
|
|
209
|
+
"claim": "CORTEX-PROVIDER-EXACT-ROW-SURFACE",
|
|
186
210
|
"title": "filtering the cortex rows out of the REAL provider entry drops the whole backend from the operator's model list while models.ts and check-acp-cortex stay green",
|
|
187
211
|
"subject": "pi-extensions/acp-provider.ts",
|
|
188
212
|
"find": ["\t\tmodels: allCuratedModels(),"],
|
|
189
213
|
"replace": ["\t\tmodels: allCuratedModels().filter((m) => !m.id.startsWith(\"cortex-\")),"],
|
|
190
214
|
"gate": ["bash", "run.sh", "check-acp-provider-surface"],
|
|
191
215
|
"timeoutSeconds": 300,
|
|
192
|
-
"signature": "[QK:CORTEX-PROVIDER-
|
|
216
|
+
"signature": "[QK:CORTEX-PROVIDER-EXACT-ROW-SURFACE]",
|
|
193
217
|
"signatureSource": "scripts/check-acp-provider-surface.ts"
|
|
194
218
|
}
|
|
195
219
|
]
|
|
@@ -233,6 +233,17 @@
|
|
|
233
233
|
"signature": "[QK:COPILOT-RECEIVE-DOCTOR-UNREADABLE-ENVIRON-IS-RED]",
|
|
234
234
|
"signatureSource": "scripts/check-copilot-receive-arm.ts"
|
|
235
235
|
},
|
|
236
|
+
{
|
|
237
|
+
"claim": "COPILOT-RECEIVE-DOCTOR-UNREADABLE-ARGV-IS-UNVERIFIABLE",
|
|
238
|
+
"title": "collapsing every OSError on `/proc/<pid>/cmdline` back to None makes a REFUSED identity read indistinguishable from a process that left: the candidate is skipped before identity is decided, all counters stay zero, and the doctor prints the benign `no live GitHub Copilot CLI process` note — claiming ABSENCE while a live CLI it was never allowed to identify may be sitting there inert. The environ claim above cannot cover this one: that branch is reachable only AFTER a successful argv match",
|
|
239
|
+
"subject": "scripts/copilot-receive-bridge.sh",
|
|
240
|
+
"find": ["\t\tif exc.errno in (errno.ENOENT, errno.ESRCH):", "\t\t\treturn None", "\t\treturn UNREADABLE"],
|
|
241
|
+
"replace": ["\t\treturn None"],
|
|
242
|
+
"gate": ["bash", "run.sh", "check-copilot-receive-arm"],
|
|
243
|
+
"timeoutSeconds": 300,
|
|
244
|
+
"signature": "[QK:COPILOT-RECEIVE-DOCTOR-UNREADABLE-ARGV-IS-UNVERIFIABLE]",
|
|
245
|
+
"signatureSource": "scripts/check-copilot-receive-arm.ts"
|
|
246
|
+
},
|
|
236
247
|
{
|
|
237
248
|
"claim": "COPILOT-RECEIVE-DOCTOR-OWNS-SCANNER-FAILURE",
|
|
238
249
|
"title": "letting the scanner's exit status reach the assignment under `set -e` kills the doctor mid-section: no verdict line is printed at all, so the operator cannot tell a healthy host from a broken doctor — the same silent-death shape this lane already fixed once in the log grep",
|
|
@@ -258,6 +269,21 @@
|
|
|
258
269
|
"timeoutSeconds": 300,
|
|
259
270
|
"signature": "[QK:COPILOT-RECEIVE-DOCTOR-PI-CARRIER-IS-RED]",
|
|
260
271
|
"signatureSource": "scripts/check-copilot-receive-arm.ts"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"claim": "COPILOT-RECEIVE-STUB-CHILD-DIES-WITH-PARENT",
|
|
275
|
+
"title": "a stub child with no parent-death watchdog outlives the gate forever — measured on `oracle` as 360 reparented Node receivers, because a red gate exits by THROWING and never reaches any teardown written below it",
|
|
276
|
+
"subject": "scripts/check-copilot-receive-arm.ts",
|
|
277
|
+
"find": [
|
|
278
|
+
"if (parentAtStart === 1) process.exit(0);",
|
|
279
|
+
"setInterval(() => {",
|
|
280
|
+
"\tif (process.ppid !== parentAtStart) process.exit(0);"
|
|
281
|
+
],
|
|
282
|
+
"replace": ["void parentAtStart;", "setInterval(() => {", "\t/* the vendor bootstrap's parent check, removed */"],
|
|
283
|
+
"gate": ["bash", "run.sh", "check-copilot-receive-arm"],
|
|
284
|
+
"timeoutSeconds": 300,
|
|
285
|
+
"signature": "[QK:COPILOT-RECEIVE-STUB-CHILD-DIES-WITH-PARENT]",
|
|
286
|
+
"signatureSource": "scripts/check-copilot-receive-arm.ts"
|
|
261
287
|
}
|
|
262
288
|
]
|
|
263
289
|
}
|
|
@@ -158,13 +158,13 @@
|
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
"claim": "OMP-DOCTOR-CARRIER-TRIMS",
|
|
161
|
-
"title": "treating an empty or whitespace-only PI carrier as an inherited identity makes Bundle C's deliberate tmux `-e NAME=` scrub fail the deterministic floor whenever a visible fresh omp citizen is alive. Re-anchored when the carrier scan
|
|
161
|
+
"title": "treating an empty or whitespace-only PI carrier as an inherited identity makes Bundle C's deliberate tmux `-e NAME=` scrub fail the deterministic floor whenever a visible fresh omp citizen is alive. Re-anchored twice, and the replanted defect is unchanged both times — only the line it attaches to moved: first when the carrier scan went from an early-exiting `grep -q` to `grep -c` (the SIGPIPE/pipefail repair), then when the scan lost an indentation level because the `[ -d /proc ]` wrapper whose `else` arm was a fail-open `note` was removed (#78 D1)",
|
|
162
162
|
"subject": "scripts/omp-bridge-doctor.sh",
|
|
163
163
|
"find": [
|
|
164
|
-
"
|
|
164
|
+
" HITS=\"$(tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=.*[^[:space:]]' || true)\""
|
|
165
165
|
],
|
|
166
166
|
"replace": [
|
|
167
|
-
"
|
|
167
|
+
" HITS=\"$(tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=' || true)\""
|
|
168
168
|
],
|
|
169
169
|
"gate": ["bash", "run.sh", "smoke-omp-bridge-state"],
|
|
170
170
|
"timeoutSeconds": 300,
|
|
@@ -173,14 +173,31 @@
|
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
"claim": "OMP-DOCTOR-CARRIER-NONBLANK-IS-RED",
|
|
176
|
-
"title": "the doctor stops flagging a live omp process that carries a NONBLANK inherited PI_SESSION_ID/PI_AGENT_ID, so a session whose MCP children would speak under the parent pi garden id reads as clean and the doctor prints PASS. The real defect was subtler than this replant, which is why the replant is written this way: `grep -q` exited at the first match, SIGPIPEd `tr` mid-environ, and pipefail turned a MATCH into a failed pipeline — a race on how far `tr` got, misreading ~15% of runs, so a `-q` replant would SURVIVE most of the time and prove nothing. This one makes the same false-clean deterministic",
|
|
176
|
+
"title": "the doctor stops flagging a live omp process that carries a NONBLANK inherited PI_SESSION_ID/PI_AGENT_ID, so a session whose MCP children would speak under the parent pi garden id reads as clean and the doctor prints PASS. The real defect was subtler than this replant, which is why the replant is written this way: `grep -q` exited at the first match, SIGPIPEd `tr` mid-environ, and pipefail turned a MATCH into a failed pipeline — a race on how far `tr` got, misreading ~15% of runs, so a `-q` replant would SURVIVE most of the time and prove nothing. This one makes the same false-clean deterministic. Re-anchored at one indentation level less when the `[ -d /proc ]` wrapper was removed (#78 D1)",
|
|
177
177
|
"subject": "scripts/omp-bridge-doctor.sh",
|
|
178
|
-
"find": ["
|
|
179
|
-
"replace": ["
|
|
178
|
+
"find": [" if [ \"${HITS:-0}\" -gt 0 ]; then"],
|
|
179
|
+
"replace": [" if [ \"${HITS:-0}\" -gt 99 ]; then"],
|
|
180
180
|
"gate": ["bash", "run.sh", "smoke-omp-bridge-state"],
|
|
181
181
|
"timeoutSeconds": 180,
|
|
182
182
|
"signature": "[QK:OMP-DOCTOR-CARRIER-NONBLANK-IS-RED]",
|
|
183
183
|
"signatureSource": "scripts/smoke-omp-bridge-state.sh"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"claim": "OMP-DOCTOR-UNENUMERATED-IS-UNVERIFIABLE",
|
|
187
|
+
"title": "restoring `|| true` on the candidate-discovery `pgrep` folds a FAILED enumeration (exit 2, or a `pgrep` that is not on PATH at all) into `nothing matched` (exit 1): the loop receives an empty candidate set, the doctor prints the clean carrier line and PASSes, and a live omp session carrying a foreign pi garden id reads as CLEAN because the tool that would have found it never ran. The documented `ENTWURF_OMP_CARRIER_PIDS` seam cannot substitute for this — it narrows candidates and short-circuits the very enumeration that failed",
|
|
188
|
+
"subject": "scripts/omp-bridge-doctor.sh",
|
|
189
|
+
"find": [
|
|
190
|
+
" ENUM_RC=0",
|
|
191
|
+
" CARRIER_CANDIDATES=\"$(pgrep -x omp 2>/dev/null)\" || ENUM_RC=$?",
|
|
192
|
+
" if [ \"$ENUM_RC\" -gt 1 ]; then",
|
|
193
|
+
" ENUM_FAILED=\"$ENUM_RC\"",
|
|
194
|
+
" fi"
|
|
195
|
+
],
|
|
196
|
+
"replace": [" CARRIER_CANDIDATES=\"$(pgrep -x omp 2>/dev/null || true)\""],
|
|
197
|
+
"gate": ["bash", "run.sh", "smoke-omp-bridge-state"],
|
|
198
|
+
"timeoutSeconds": 300,
|
|
199
|
+
"signature": "[QK:OMP-DOCTOR-UNENUMERATED-IS-UNVERIFIABLE]",
|
|
200
|
+
"signatureSource": "scripts/smoke-omp-bridge-state.sh"
|
|
184
201
|
}
|
|
185
202
|
]
|
|
186
203
|
}
|
|
@@ -178,6 +178,19 @@
|
|
|
178
178
|
"timeoutSeconds": 180,
|
|
179
179
|
"signature": "[QK:SETUP-OMP-CONFIG-NO-OVERWRITE]",
|
|
180
180
|
"signatureSource": "scripts/check-setup-qualification.sh"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"claim": "SETUP-DARWIN-RAIL-COSMETIC-PASS",
|
|
184
|
+
"title": "the platform rail check is dropped, so a harness whose install completes on a platform with no rail receipt reads PASS and the whole setup reads green again — the 0.20.0 hole the installer's retired Darwin refusal used to cover",
|
|
185
|
+
"subject": "run.sh",
|
|
186
|
+
"find": [
|
|
187
|
+
" if harness_rail_certified_platform; then\n setup_result \"$1\" PASS \"$2 — verify: $3\"\n return 0\n fi"
|
|
188
|
+
],
|
|
189
|
+
"replace": [" setup_result \"$1\" PASS \"$2 — verify: $3\"\n return 0"],
|
|
190
|
+
"gate": ["bash", "scripts/check-setup-qualification.sh"],
|
|
191
|
+
"timeoutSeconds": 180,
|
|
192
|
+
"signature": "[QK:SETUP-DARWIN-RAIL-COSMETIC-PASS]",
|
|
193
|
+
"signatureSource": "scripts/check-setup-qualification.sh"
|
|
181
194
|
}
|
|
182
195
|
]
|
|
183
196
|
}
|
|
@@ -40,6 +40,16 @@ note() { echo " note $*"; }
|
|
|
40
40
|
bad() { echo " FAIL $*"; fail=1; }
|
|
41
41
|
own_bad() { echo " FAIL $*"; own_fail=1; }
|
|
42
42
|
|
|
43
|
+
# 12-hex digest, portable. NOT `sha256sum`: that is coreutils and absent on macOS.
|
|
44
|
+
# NOT `shasum -a 256` either (byte-identical layout though it is) — that would be a
|
|
45
|
+
# second digest convention in this tree, and python3 is already a HARD prerequisite
|
|
46
|
+
# on every path that reaches a digest here: the structural oracle below runs python3
|
|
47
|
+
# before this loop is entered. So the digest reuses the python3 hashlib form
|
|
48
|
+
# omp-receive-doctor.sh:99 and copilot-receive-bridge.sh:174 already ship. Empty on
|
|
49
|
+
# any failure, exactly like the old `2>/dev/null` form — the caller reads an empty
|
|
50
|
+
# digest as STALE, which is the fail-closed side.
|
|
51
|
+
sha12() { python3 -c 'import hashlib,sys;print(hashlib.sha256(open(sys.argv[1],"rb").read()).hexdigest()[:12])' "$1" 2>/dev/null || true; }
|
|
52
|
+
|
|
43
53
|
# shellcheck source=scripts/omp-bridge-oracle.sh
|
|
44
54
|
. "$HERE/omp-bridge-oracle.sh"
|
|
45
55
|
|
|
@@ -87,8 +97,8 @@ if [ -n "$UNIT_DIR" ]; then
|
|
|
87
97
|
note "$label source is absent in this checkout ($src) — parity not measurable here"
|
|
88
98
|
continue
|
|
89
99
|
fi
|
|
90
|
-
INST_SHA="$(
|
|
91
|
-
SRC_SHA="$(
|
|
100
|
+
INST_SHA="$(sha12 "$UNIT_DIR/$rel")"
|
|
101
|
+
SRC_SHA="$(sha12 "$src")"
|
|
92
102
|
if [ -n "$INST_SHA" ] && [ "$INST_SHA" = "$SRC_SHA" ]; then
|
|
93
103
|
ok "installed $label matches source ($INST_SHA)"
|
|
94
104
|
else
|
|
@@ -180,17 +190,25 @@ fi
|
|
|
180
190
|
echo
|
|
181
191
|
echo "[what the extension did — ${HOOK_LOG:-<unresolved>}]"
|
|
182
192
|
if [ -n "$HOOK_LOG" ] && [ -f "$HOOK_LOG" ]; then
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
193
|
+
# PORTABLE SELECTOR, SAME CONTRACT. The separation above is a negative lookahead,
|
|
194
|
+
# and BSD grep (macOS) has no `-P` at all — so the selector is awk, where two
|
|
195
|
+
# conditions ARE `(?!…)`. It is also the pipefail-safe form: `grep -c` exits 1 on a
|
|
196
|
+
# zero-match file, which under this file's `set -o pipefail` (line 26) is exactly
|
|
197
|
+
# what the old `| head -1` was laundering; awk exits 0 and prints 0.
|
|
198
|
+
# The success selector moves from GNU BRE `\(a\|b\)` to ERE `(a|b)` for the same
|
|
199
|
+
# reason: BRE alternation is a GNU extension, so on BSD grep that pattern matches
|
|
200
|
+
# nothing and a RECOVERED host would be reported as unrecovered — a false RED.
|
|
201
|
+
MINT_ERRORS='/ ERROR \[omp\] / && !/ ERROR \[omp\] sender-marker-/'
|
|
202
|
+
LAST_ERROR_LINE="$(awk "$MINT_ERRORS{print NR}" "$HOOK_LOG" 2>/dev/null | tail -1)"
|
|
203
|
+
LAST_OK_LINE="$(grep -nE ' INFO \[omp\] (create|attach) ' "$HOOK_LOG" 2>/dev/null | tail -1 | cut -d: -f1)"
|
|
204
|
+
TOTAL_ERRORS="$(awk "$MINT_ERRORS{n++} END{print n+0}" "$HOOK_LOG" 2>/dev/null)"; TOTAL_ERRORS="${TOTAL_ERRORS:-0}"
|
|
187
205
|
if [ -z "$LAST_ERROR_LINE" ]; then
|
|
188
206
|
ok "no omp mint ERROR lines in $HOOK_LOG"
|
|
189
207
|
elif [ -n "$LAST_OK_LINE" ] && [ "$LAST_OK_LINE" -gt "$LAST_ERROR_LINE" ]; then
|
|
190
208
|
note "$TOTAL_ERRORS historical omp mint ERROR line(s), all followed by a successful mint (line $LAST_OK_LINE > $LAST_ERROR_LINE) — recovered, not red"
|
|
191
209
|
else
|
|
192
210
|
bad "the newest omp mint line in $HOOK_LOG is an unrecovered ERROR — the extension RAN and did not mint:"
|
|
193
|
-
|
|
211
|
+
awk "$MINT_ERRORS" "$HOOK_LOG" | tail -3 | sed 's/^/ /'
|
|
194
212
|
fi
|
|
195
213
|
|
|
196
214
|
MARKER_FAILED="$(grep -c ' ERROR \[omp\] sender-marker-failed ' "$HOOK_LOG" 2>/dev/null | head -1)"
|
|
@@ -251,42 +269,93 @@ fi
|
|
|
251
269
|
# than absorbing it into any other verdict.
|
|
252
270
|
echo
|
|
253
271
|
echo "[inherited pi identity carriers on live omp processes]"
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
272
|
+
# THE CANDIDATE HALF IS PORTABLE; THE PREDICATE INPUT IS NOT. `pgrep -x omp` is POSIX
|
|
273
|
+
# and answers on every platform; reading another process's environment is what needs
|
|
274
|
+
# `/proc`. Those two facts used to be fused into one `[ -d /proc ]` branch whose else
|
|
275
|
+
# arm was a `note`, and a note lets this doctor end in PASS while the contamination
|
|
276
|
+
# detector is blind — the same fail-OPEN shape copilot-receive-bridge.sh:376-380
|
|
277
|
+
# refuses on Linux ("A note would let the doctor end in PASS while a session that can
|
|
278
|
+
# never arm is running, which is the exact false-success the section was written to
|
|
279
|
+
# break"). The epistemic state is identical, so the verdict is now identical: an axis
|
|
280
|
+
# whose predicate INPUT cannot be obtained is UNVERIFIABLE and non-green, never clean.
|
|
281
|
+
#
|
|
282
|
+
# Candidate set. Production scans every `omp` pid. `ENTWURF_OMP_CARRIER_PIDS` (set, even
|
|
283
|
+
# to empty) narrows it so a hermetic smoke can hand this branch REAL processes it launched
|
|
284
|
+
# and read their real `/proc/<pid>/environ`. It narrows candidates ONLY — the nonblank
|
|
285
|
+
# predicate below is the same production code either way. It is a TEST SEAM, never
|
|
286
|
+
# production proof: the branch below is what a real host runs, so it owes its own honesty.
|
|
287
|
+
ENUM_FAILED=""
|
|
288
|
+
if [ -n "${ENTWURF_OMP_CARRIER_PIDS+x}" ]; then
|
|
289
|
+
CARRIER_CANDIDATES="$ENTWURF_OMP_CARRIER_PIDS"
|
|
290
|
+
else
|
|
291
|
+
# `pgrep` HAS THREE ANSWERS AND ONLY TWO OF THEM ARE FACTS ABOUT omp. 0 = it enumerated
|
|
292
|
+
# and matched. 1 = it enumerated and NOTHING matched — a real, positive absence, which
|
|
293
|
+
# is evidence. ANYTHING ELSE (2 usage/syntax, 3 fatal, 127 not on PATH) means the
|
|
294
|
+
# enumeration itself did not happen, so the candidate set is UNKNOWN — not empty.
|
|
295
|
+
# This used to be `|| true`, which folded that third answer into the second: an empty
|
|
296
|
+
# candidate set, a loop that never runs, and the clean `ok` below. A live contaminated
|
|
297
|
+
# omp session then read as CLEAN because the tool that would have found it never ran
|
|
298
|
+
# (reproduced on an isolated install with a PATH-preceding `pgrep` shim exiting 2:
|
|
299
|
+
# rc=0, runtime PASS, ownership PASS). Same class as the missing-/proc branches below,
|
|
300
|
+
# so it gets the same verdict: an axis whose predicate INPUT cannot be obtained is
|
|
301
|
+
# UNVERIFIABLE and non-green, never clean.
|
|
302
|
+
ENUM_RC=0
|
|
303
|
+
CARRIER_CANDIDATES="$(pgrep -x omp 2>/dev/null)" || ENUM_RC=$?
|
|
304
|
+
if [ "$ENUM_RC" -gt 1 ]; then
|
|
305
|
+
ENUM_FAILED="$ENUM_RC"
|
|
264
306
|
fi
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
#
|
|
275
|
-
#
|
|
276
|
-
#
|
|
277
|
-
#
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
fi
|
|
282
|
-
done
|
|
283
|
-
if [ -n "$CONTAMINATED" ]; then
|
|
284
|
-
bad "live omp process(es)$CONTAMINATED carry a non-empty PI_SESSION_ID/PI_AGENT_ID inherited from a pi citizen's shell. Their MCP children would speak under the PARENT pi garden id, not their own — close them and relaunch omp from a shell without those variables"
|
|
285
|
-
else
|
|
286
|
-
ok "no live omp process carries a non-empty PI_SESSION_ID/PI_AGENT_ID (empty carrier values are the managed tmux scrub and are nonauthoritative; omp mints neither itself — the danger is pure inheritance passthrough, ledger M6)"
|
|
307
|
+
fi
|
|
308
|
+
CONTAMINATED=""
|
|
309
|
+
UNVERIFIABLE=""
|
|
310
|
+
for pid in $CARRIER_CANDIDATES; do
|
|
311
|
+
case "$pid" in *[!0-9]*) continue ;; esac
|
|
312
|
+
ENVIRON="/proc/$pid/environ"
|
|
313
|
+
if [ ! -d "/proc/$pid" ]; then
|
|
314
|
+
# TWO DIFFERENT FACTS SHARE THIS SHAPE AND ONLY ONE IS EVIDENCE. Where /proc
|
|
315
|
+
# exists, a missing /proc/<pid> means the process vanished between `pgrep` and
|
|
316
|
+
# this read — nothing to judge, so it is skipped. Where /proc ITSELF does not
|
|
317
|
+
# exist (Darwin), the process is still there and it is the INTERFACE that is
|
|
318
|
+
# missing: the verdict input is gone while the subject is not, which is the
|
|
319
|
+
# UNVERIFIABLE state and is reported, never skipped.
|
|
320
|
+
[ -d /proc ] && continue
|
|
321
|
+
UNVERIFIABLE="$UNVERIFIABLE $pid"
|
|
322
|
+
continue
|
|
287
323
|
fi
|
|
288
|
-
|
|
289
|
-
|
|
324
|
+
# STILL THERE, STILL UNREADABLE (hidepid, or an omp owned by another user that
|
|
325
|
+
# `pgrep` legitimately found) — same missing input, same state. This used to be a
|
|
326
|
+
# silent `continue`, which reported such a process as clean.
|
|
327
|
+
if [ ! -r "$ENVIRON" ]; then
|
|
328
|
+
UNVERIFIABLE="$UNVERIFIABLE $pid"
|
|
329
|
+
continue
|
|
330
|
+
fi
|
|
331
|
+
# `grep -c`, never `grep -q`. This file runs under `set -o pipefail` (line 26), and a
|
|
332
|
+
# `-q` grep EXITS AT THE FIRST MATCH, closing the pipe while `tr` is still writing the
|
|
333
|
+
# rest of an ~12KB environ. `tr` dies of SIGPIPE (141), pipefail promotes that to the
|
|
334
|
+
# pipeline's status, and the `if` takes the CLEAN branch — so a genuinely contaminated
|
|
335
|
+
# process was reported as clean, and the doctor printed PASS. It is a RACE on how far
|
|
336
|
+
# `tr` got, which is why it read as flakiness: measured on this host, 6 misses in 40
|
|
337
|
+
# reads of one live fixture carrying PI_SESSION_ID=foreign-garden. `-c` consumes all of
|
|
338
|
+
# stdin, so there is no early close and nothing to race. The same lesson is already
|
|
339
|
+
# written at smoke-omp-mcp-state.sh:91 — it had not reached this reader.
|
|
340
|
+
HITS="$(tr '\0' '\n' < "$ENVIRON" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=.*[^[:space:]]' || true)"
|
|
341
|
+
if [ "${HITS:-0}" -gt 0 ]; then
|
|
342
|
+
CONTAMINATED="$CONTAMINATED $pid"
|
|
343
|
+
fi
|
|
344
|
+
done
|
|
345
|
+
# Reported on their own lines, never folded: "contaminated", "cannot be judged" and "the
|
|
346
|
+
# candidate set is unknown" send an operator to three different places, and absence is a
|
|
347
|
+
# fourth answer that is none of them.
|
|
348
|
+
if [ -n "$CONTAMINATED" ]; then
|
|
349
|
+
bad "live omp process(es)$CONTAMINATED carry a non-empty PI_SESSION_ID/PI_AGENT_ID inherited from a pi citizen's shell. Their MCP children would speak under the PARENT pi garden id, not their own — close them and relaunch omp from a shell without those variables"
|
|
350
|
+
fi
|
|
351
|
+
if [ -n "$UNVERIFIABLE" ]; then
|
|
352
|
+
bad "UNVERIFIABLE — the environment of live omp process(es)$UNVERIFIABLE could not be read, so their PI_SESSION_ID/PI_AGENT_ID state is UNKNOWN and is NOT assumed clean. On this platform there may be no per-process environment interface at all; \`ps -E\`/\`ps eww\` is deliberately NOT used as a substitute, because on Darwin it succeeds only for unrestricted targets and the measurement that would say which side omp falls on has not been run (scripts/raw-macos-measure/probe.sh cell M6). Otherwise, re-run this doctor as the user that owns those sessions."
|
|
353
|
+
fi
|
|
354
|
+
if [ -n "$ENUM_FAILED" ]; then
|
|
355
|
+
bad "UNVERIFIABLE — 'pgrep -x omp' FAILED (exit $ENUM_FAILED), so the SET of live omp processes is UNKNOWN and is NOT assumed empty. Nothing was enumerated, so this doctor can neither name a contaminated session nor claim there is none. Repair the process-enumeration tool on PATH (a \`pgrep\` that exits 1 is the honest 'nothing matched' and stays green) and re-run."
|
|
356
|
+
fi
|
|
357
|
+
if [ -z "$CONTAMINATED" ] && [ -z "$UNVERIFIABLE" ] && [ -z "$ENUM_FAILED" ]; then
|
|
358
|
+
ok "no live omp process carries a non-empty PI_SESSION_ID/PI_AGENT_ID (empty carrier values are the managed tmux scrub and are nonauthoritative; omp mints neither itself — the danger is pure inheritance passthrough, ledger M6)"
|
|
290
359
|
fi
|
|
291
360
|
|
|
292
361
|
# ── ownership axis ───────────────────────────────────────────────────────────
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
# install shape. The agent dir is resolved by the shared oracle, which REFUSES rather
|
|
22
22
|
# than guesses when an inherited `PI_*` knob makes it ambiguous (ledger M6).
|
|
23
23
|
#
|
|
24
|
-
# Platform: Linux
|
|
24
|
+
# Platform: Linux and Darwin, same fence as the Claude and Copilot installers. Its own
|
|
25
|
+
# platform dependency is python3 (checked below); no /proc, no GNU-only tool.
|
|
25
26
|
set -euo pipefail
|
|
26
27
|
|
|
27
28
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -45,7 +46,10 @@ for arg in "$@"; do
|
|
|
45
46
|
esac
|
|
46
47
|
done
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
case "$(uname -s)" in
|
|
50
|
+
Linux | Darwin) ;;
|
|
51
|
+
*) die "unsupported platform '$(uname -s)'. This installer requires Linux or Darwin." ;;
|
|
52
|
+
esac
|
|
49
53
|
command -v python3 >/dev/null 2>&1 || die "python3 is required and is not on PATH."
|
|
50
54
|
|
|
51
55
|
# shellcheck source=scripts/omp-bridge-oracle.sh
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
# resolved by the shared oracle, which REFUSES rather than guesses when an inherited
|
|
25
25
|
# `PI_*` knob makes it ambiguous (ledger M6).
|
|
26
26
|
#
|
|
27
|
-
# Platform: Linux
|
|
27
|
+
# Platform: Linux and Darwin, same fence as the Claude, Copilot and omp-birth
|
|
28
|
+
# installers. Its own platform dependency is python3 (checked below); no /proc,
|
|
29
|
+
# no GNU-only tool.
|
|
28
30
|
set -euo pipefail
|
|
29
31
|
|
|
30
32
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -48,7 +50,10 @@ for arg in "$@"; do
|
|
|
48
50
|
esac
|
|
49
51
|
done
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
case "$(uname -s)" in
|
|
54
|
+
Linux | Darwin) ;;
|
|
55
|
+
*) die "unsupported platform '$(uname -s)'. This installer requires Linux or Darwin." ;;
|
|
56
|
+
esac
|
|
52
57
|
command -v python3 >/dev/null 2>&1 || die "python3 is required and is not on PATH."
|
|
53
58
|
|
|
54
59
|
# shellcheck source=scripts/omp-bridge-oracle.sh
|
|
@@ -457,7 +457,16 @@ Still true and documented rather than fixed: a hard link produces `CREATE` with
|
|
|
457
457
|
no `CLOSE_WRITE` and is not reported (nothing writes mailbox messages that way),
|
|
458
458
|
and `IN_IGNORED` for a deleted garden directory is not handled (harmless).
|
|
459
459
|
|
|
460
|
-
## Codex raw delivery status (0.136.0)
|
|
460
|
+
## Codex raw delivery status (0.136.0 — re-verified at 0.153.4)
|
|
461
|
+
|
|
462
|
+
> **0.153.4 pointer (2026-09-08, lane #95).** Everything in this section still holds; the two
|
|
463
|
+
> shipped scripts were re-run AS SHIPPED at codex-cli 0.153.4 and went green (`ok: true`,
|
|
464
|
+
> `status_seen: ["active","active","idle"]`, model reply in the visible TUI with zero typing).
|
|
465
|
+
> The current coordinates, the six step-1 vendor measurements, and the source receipts live in
|
|
466
|
+
> [`../raw-codex-measure/README.md`](../raw-codex-measure/README.md) and its `source-audit.md`.
|
|
467
|
+
> One method correction belongs here: at 0.153.4 the rollout JSONL is materialized LAZILY, so
|
|
468
|
+
> the "newest rollout's session_meta id" recipe below can hand you a thread from weeks ago.
|
|
469
|
+
> Ask the app-server instead — `thread/loaded/list` returns the live thread ids.
|
|
461
470
|
|
|
462
471
|
Measured against `@openai/codex` 0.136.0 (source: `~/repos/3rd/codex`). **Codex IS
|
|
463
472
|
breakable for local raw idle-wake — without managed standalone and without cloud.**
|