@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.
Files changed (59) hide show
  1. package/AGENTS.md +1 -1
  2. package/BASELINE.md +23 -5
  3. package/CHANGELOG.md +236 -0
  4. package/DELIVERY.md +59 -6
  5. package/README.md +40 -9
  6. package/VERIFY.md +9 -1
  7. package/docs/acp-backend-rail.md +9 -1
  8. package/docs/external-mcp-host.md +6 -3
  9. package/docs/setup-clean-host.md +93 -7
  10. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +3 -3
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +6 -2
  12. package/package.json +2 -2
  13. package/pi-extensions/acp-provider.ts +1 -1
  14. package/pi-extensions/lib/acp/models.ts +3 -3
  15. package/pi-extensions/lib/acp/overlay.ts +6 -2
  16. package/pi-extensions/lib/meta-session.ts +25 -0
  17. package/run.sh +71 -26
  18. package/scripts/agy-bridge.sh +1 -1
  19. package/scripts/agy-imprint.sh +10 -7
  20. package/scripts/check-acp-carrier-augment.ts +6 -5
  21. package/scripts/check-acp-cortex.ts +41 -0
  22. package/scripts/check-acp-provider-surface.ts +9 -6
  23. package/scripts/check-copilot-birth-hook.ts +3 -1
  24. package/scripts/check-copilot-receive-arm.ts +169 -21
  25. package/scripts/check-copilot-statusline.ts +3 -1
  26. package/scripts/check-gate-qualification.ts +10 -9
  27. package/scripts/check-hook-launch-topology.ts +6 -5
  28. package/scripts/check-install-surface.ts +2 -1
  29. package/scripts/check-meta-facts.ts +6 -4
  30. package/scripts/check-meta-hook-session-switch.ts +4 -3
  31. package/scripts/check-meta-identity-consumers.ts +8 -7
  32. package/scripts/check-meta-receiver-marker.ts +2 -1
  33. package/scripts/check-omp-birth-hook.ts +3 -2
  34. package/scripts/check-probe-bridge-command.ts +3 -1
  35. package/scripts/check-setup-qualification.sh +21 -0
  36. package/scripts/copilot-bridge-doctor.sh +15 -5
  37. package/scripts/copilot-bridge-install.sh +6 -2
  38. package/scripts/copilot-launch.sh +16 -2
  39. package/scripts/copilot-receive-bridge.sh +80 -13
  40. package/scripts/lib/reclaim-on-exit.ts +86 -0
  41. package/scripts/meta-bridge-doctor.sh +56 -15
  42. package/scripts/meta-bridge-install.sh +13 -7
  43. package/scripts/meta-bridge-uninstall.sh +6 -4
  44. package/scripts/mutants/acp-cortex.json +26 -2
  45. package/scripts/mutants/copilot-receive.json +26 -0
  46. package/scripts/mutants/omp-birth.json +23 -6
  47. package/scripts/mutants/setup-verdict.json +13 -0
  48. package/scripts/omp-bridge-doctor.sh +110 -41
  49. package/scripts/omp-bridge-install.sh +6 -2
  50. package/scripts/omp-receive-install.sh +7 -2
  51. package/scripts/raw-async-delivery/README.md +10 -1
  52. package/scripts/raw-codex-measure/README.md +689 -0
  53. package/scripts/raw-codex-measure/source-audit.md +243 -0
  54. package/scripts/raw-macos-measure/README.md +148 -0
  55. package/scripts/raw-macos-measure/probe.sh +389 -0
  56. package/scripts/smoke-meta-async-drift.sh +7 -5
  57. package/scripts/smoke-meta-install-state.sh +70 -19
  58. package/scripts/smoke-omp-bridge-state.sh +38 -0
  59. 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-SIX-ROW-SURFACE",
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-SIX-ROW-SURFACE]",
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 moved from an early-exiting `grep -q` to `grep -c` (the SIGPIPE/pipefail repair); the replanted defect is unchanged only the line it attaches to moved",
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
- " HITS=\"$(tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=.*[^[:space:]]' || true)\""
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
- " HITS=\"$(tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=' || true)\""
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": [" if [ \"${HITS:-0}\" -gt 0 ]; then"],
179
- "replace": [" if [ \"${HITS:-0}\" -gt 99 ]; then"],
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="$(sha256sum "$UNIT_DIR/$rel" 2>/dev/null | cut -c1-12)"
91
- SRC_SHA="$(sha256sum "$src" 2>/dev/null | cut -c1-12)"
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
- MINT_ERRORS=' ERROR \[omp\] (?!sender-marker-)'
184
- LAST_ERROR_LINE="$(grep -nP "$MINT_ERRORS" "$HOOK_LOG" 2>/dev/null | tail -1 | cut -d: -f1)"
185
- LAST_OK_LINE="$(grep -n ' INFO \[omp\] \(create\|attach\) ' "$HOOK_LOG" 2>/dev/null | tail -1 | cut -d: -f1)"
186
- TOTAL_ERRORS="$(grep -cP "$MINT_ERRORS" "$HOOK_LOG" 2>/dev/null | head -1)"; TOTAL_ERRORS="${TOTAL_ERRORS:-0}"
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
- grep -P "$MINT_ERRORS" "$HOOK_LOG" | tail -3 | sed 's/^/ /'
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
- if [ -d /proc ]; then
255
- CONTAMINATED=""
256
- # Candidate set. Production scans every `omp` pid. `ENTWURF_OMP_CARRIER_PIDS` (set, even
257
- # to empty) narrows it so a hermetic smoke can hand this branch REAL processes it launched
258
- # and read their real `/proc/<pid>/environ`. It narrows candidates ONLY — the nonblank
259
- # predicate below is the same production code either way.
260
- if [ -n "${ENTWURF_OMP_CARRIER_PIDS+x}" ]; then
261
- CARRIER_CANDIDATES="$ENTWURF_OMP_CARRIER_PIDS"
262
- else
263
- CARRIER_CANDIDATES="$(pgrep -x omp 2>/dev/null || true)"
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
- for pid in $CARRIER_CANDIDATES; do
266
- case "$pid" in *[!0-9]*) continue ;; esac
267
- ENVIRON="/proc/$pid/environ"
268
- [ -r "$ENVIRON" ] || continue
269
- # `grep -c`, never `grep -q`. This file runs under `set -o pipefail` (line 26), and a
270
- # `-q` grep EXITS AT THE FIRST MATCH, closing the pipe while `tr` is still writing the
271
- # rest of an ~12KB environ. `tr` dies of SIGPIPE (141), pipefail promotes that to the
272
- # pipeline's status, and the `if` takes the CLEAN branch so a genuinely contaminated
273
- # process was reported as clean, and the doctor printed PASS. It is a RACE on how far
274
- # `tr` got, which is why it read as flakiness: measured on this host, 6 misses in 40
275
- # reads of one live fixture carrying PI_SESSION_ID=foreign-garden. `-c` consumes all of
276
- # stdin, so there is no early close and nothing to race. The same lesson is already
277
- # written at smoke-omp-mcp-state.sh:91 it had not reached this reader.
278
- HITS="$(tr '\0' '\n' < "$ENVIRON" 2>/dev/null | grep -cE '^(PI_SESSION_ID|PI_AGENT_ID)=.*[^[:space:]]' || true)"
279
- if [ "${HITS:-0}" -gt 0 ]; then
280
- CONTAMINATED="$CONTAMINATED $pid"
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
- else
289
- note "/proc is unavailable, so live omp environments could not be read on this platform"
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 only, same fence as the Claude and Copilot installers.
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
- [ "$(uname -s)" = "Linux" ] || die "Linux only; $(uname -s) is not a certified axis for this install."
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 only, same fence as the Claude, Copilot and omp-birth installers.
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
- [ "$(uname -s)" = "Linux" ] || die "Linux only; $(uname -s) is not a certified axis for this install."
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.**