@junghanacs/entwurf 0.15.0 → 0.16.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 (90) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +299 -0
  3. package/DELIVERY.md +4 -3
  4. package/README.md +99 -67
  5. package/VERIFY.md +13 -7
  6. package/docs/acp-backend-rail.md +1 -1
  7. package/docs/external-mcp-host.md +147 -9
  8. package/docs/setup-clean-host.md +221 -16
  9. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +65 -20
  10. package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +17 -6
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +1 -1
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +172 -5
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +152 -17
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +271 -0
  16. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +988 -0
  17. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-receive-omp.js +574 -0
  18. package/mcp/entwurf-bridge/dist/scripts/omp-receive-facts.js +84 -0
  19. package/mcp/entwurf-bridge/src/index.ts +65 -19
  20. package/mcp/entwurf-bridge/tsconfig.build.json +19 -3
  21. package/mcp/tsconfig.json +10 -0
  22. package/package.json +14 -4
  23. package/pi/entwurf-capabilities.json +1 -0
  24. package/pi/meta-bridge-omp/entwurf-meta-omp/package.json +7 -0
  25. package/pi/omp-receive/entwurf-receive-omp/package.json +7 -0
  26. package/pi-extensions/entwurf-control.ts +12 -9
  27. package/pi-extensions/lib/entwurf-self-address.ts +18 -7
  28. package/pi-extensions/lib/meta-sender-identity.ts +1 -1
  29. package/pi-extensions/lib/meta-session.ts +219 -5
  30. package/pi-extensions/lib/mux-fresh-call.ts +171 -17
  31. package/pi-extensions/lib/omp-fresh-preflight.ts +275 -0
  32. package/pi-extensions/meta-bridge-omp.ts +1244 -0
  33. package/pi-extensions/meta-bridge-receive-omp.ts +666 -0
  34. package/run.sh +1041 -174
  35. package/scripts/agy-bridge.sh +4 -2
  36. package/scripts/check-copilot-birth-hook.ts +700 -23
  37. package/scripts/check-entwurf-self-address.ts +31 -0
  38. package/scripts/check-fresh-cut-gate.sh +12 -4
  39. package/scripts/check-gate-qualification.ts +8 -2
  40. package/scripts/check-harness-admission-parity.ts +143 -0
  41. package/scripts/check-meta-doctor-oracle.sh +20 -0
  42. package/scripts/check-omp-birth-hook.ts +1049 -0
  43. package/scripts/check-omp-fresh-preflight.ts +181 -0
  44. package/scripts/check-omp-receive-arm.ts +516 -0
  45. package/scripts/check-setup-qualification.sh +126 -0
  46. package/scripts/copilot-bridge-doctor.sh +104 -71
  47. package/scripts/copilot-bridge-install.sh +180 -20
  48. package/scripts/copilot-bridge-oracle.sh +223 -0
  49. package/scripts/copilot-bridge-uninstall.sh +137 -0
  50. package/scripts/dev-bin.sh +50 -9
  51. package/scripts/fake-copilot-vendor.sh +67 -0
  52. package/scripts/inventory-verification-surface.ts +1 -1
  53. package/scripts/meta-bridge-hook-log.sh +9 -1
  54. package/scripts/mutants/copilot-birth.json +96 -5
  55. package/scripts/mutants/mux-fresh-call.json +22 -22
  56. package/scripts/mutants/omp-birth.json +173 -0
  57. package/scripts/mutants/omp-fresh.json +300 -0
  58. package/scripts/mutants/omp-receive.json +135 -0
  59. package/scripts/mutants/pi-package-ownership.json +92 -0
  60. package/scripts/mutants/self-address.json +34 -0
  61. package/scripts/mutants/setup-verdict.json +148 -0
  62. package/scripts/mutants/source-install.json +32 -0
  63. package/scripts/omp-bridge-doctor.sh +315 -0
  64. package/scripts/omp-bridge-install.sh +221 -0
  65. package/scripts/omp-bridge-oracle.sh +154 -0
  66. package/scripts/omp-bridge-uninstall.sh +57 -0
  67. package/scripts/omp-mcp-bridge.sh +320 -0
  68. package/scripts/omp-mcp-config.py +392 -0
  69. package/scripts/omp-receive-doctor.sh +246 -0
  70. package/scripts/omp-receive-facts.ts +106 -0
  71. package/scripts/omp-receive-install.sh +228 -0
  72. package/scripts/omp-receive-uninstall.sh +60 -0
  73. package/scripts/omp-tool-surface.py +349 -0
  74. package/scripts/pi_settings_io.py +22 -0
  75. package/scripts/raw-omp-measure/README.md +420 -0
  76. package/scripts/raw-omp-measure/probe-extension.ts +76 -0
  77. package/scripts/raw-omp-measure/probe-receive-surface.ts +250 -0
  78. package/scripts/raw-omp-measure/source-audit.md +414 -0
  79. package/scripts/register-pi-package.py +525 -7
  80. package/scripts/register-pi-provider.py +162 -12
  81. package/scripts/smoke-agy-install-state.sh +86 -30
  82. package/scripts/smoke-agy-statusline-state.sh +9 -6
  83. package/scripts/smoke-omp-bridge-state.sh +221 -0
  84. package/scripts/smoke-omp-fresh-live.ts +497 -0
  85. package/scripts/smoke-omp-mcp-state.sh +327 -0
  86. package/scripts/smoke-omp-receive-live.ts +340 -0
  87. package/scripts/smoke-omp-receive-state.sh +196 -0
  88. package/scripts/smoke-setup-verdict.sh +291 -0
  89. package/scripts/smoke-user-scope-citizen.sh +388 -1
  90. package/scripts/tsconfig.json +2 -0
@@ -94,10 +94,10 @@
94
94
  },
95
95
  {
96
96
  "claim": "HOOK-LOG-RAIL-SCOPED",
97
- "title": "an untagged ERROR grep lets a Copilot fail-closed refusal redden the CLAUDE doctor forever copilot's recovery token cannot exist on that rail",
97
+ "title": "dropping the copilot tag from the shared-hook-log filter lets a Copilot fail-closed refusal redden the CLAUDE doctor forever \u2014 copilot's recovery token cannot exist on that rail",
98
98
  "subject": "scripts/meta-bridge-hook-log.sh",
99
- "find": [" own=\"$(grep -v ' \\[copilot\\] ' \"$log\" 2>/dev/null || true)\""],
100
- "replace": [" own=\"$(cat \"$log\" 2>/dev/null || true)\""],
99
+ "find": [" own=\"$(grep -v -e ' \\[copilot\\] ' -e ' \\[omp\\] ' \"$log\" 2>/dev/null || true)\""],
100
+ "replace": [" own=\"$(grep -v ' \\[omp\\] ' \"$log\" 2>/dev/null || true)\""],
101
101
  "gate": ["bash", "run.sh", "check-meta-doctor-oracle"],
102
102
  "timeoutSeconds": 600,
103
103
  "signature": "[QK:HOOK-LOG-RAIL-SCOPED]",
@@ -132,9 +132,11 @@
132
132
  "title": "closing the reader half leaves the writer talking to nobody — the hook writes a copilot marker, the bridge never looks in that directory, and the citizen's sends are refused as anonymous (the #46 shape, which is why writer and reader open in one change)",
133
133
  "subject": "pi-extensions/lib/meta-sender-identity.ts",
134
134
  "find": [
135
- "export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\", \"copilot\"];"
135
+ "export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\", \"copilot\", \"omp\"];"
136
+ ],
137
+ "replace": [
138
+ "export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\", \"omp\"];"
136
139
  ],
137
- "replace": ["export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\"];"],
138
140
  "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
139
141
  "timeoutSeconds": 300,
140
142
  "signature": "[QK:COPILOT-SENDER-READER-OPEN]",
@@ -150,6 +152,95 @@
150
152
  "timeoutSeconds": 300,
151
153
  "signature": "[QK:COPILOT-INSTALL-LIST-FAILURE-IS-FATAL]",
152
154
  "signatureSource": "scripts/check-copilot-birth-hook.ts"
155
+ },
156
+ {
157
+ "claim": "COPILOT-BIRTH-INVERSE-NO-STATE",
158
+ "title": "the inverse runs as a blind best-effort remove with NO ownership state, deleting vendor registrations this package cannot prove it owns",
159
+ "subject": "scripts/copilot-bridge-uninstall.sh",
160
+ "find": [
161
+ "[ -f \"$STATE_FILE\" ] || die \"no ownership state at $STATE_FILE — nothing this package provably owns to remove. A legacy no-state installation is adopted by './run.sh install-copilot-bridge' first, then removed.\""
162
+ ],
163
+ "replace": [
164
+ "[ -f \"$STATE_FILE\" ] || { copilot plugin uninstall \"$QUALIFIED\" >/dev/null 2>&1 || true; copilot plugin marketplace remove \"$MKT_NAME\" >/dev/null 2>&1 || true; rm -rf \"$ASM\"; exit 0; }"
165
+ ],
166
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
167
+ "timeoutSeconds": 300,
168
+ "signature": "[QK:COPILOT-BIRTH-INVERSE-NO-STATE]",
169
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
170
+ },
171
+ {
172
+ "claim": "COPILOT-BIRTH-INVERSE-FOREIGN",
173
+ "title": "the inverse removes a marketplace that carries our name but is registered at ANOTHER path — someone else's registration deleted by our uninstall",
174
+ "subject": "scripts/copilot-bridge-uninstall.sh",
175
+ "find": [
176
+ " if [ \"$MKT_PATH\" != \"$ASM\" ]; then\n die \"a marketplace named '$MKT_NAME' is registered at '$MKT_PATH', not at the recorded assembly ($ASM). That registration is not provably ours — refusing with zero vendor/filesystem writes; inspect 'copilot plugin marketplace list' manually.\"\n fi"
177
+ ],
178
+ "replace": [" :"],
179
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
180
+ "timeoutSeconds": 300,
181
+ "signature": "[QK:COPILOT-BIRTH-INVERSE-FOREIGN]",
182
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
183
+ },
184
+ {
185
+ "claim": "COPILOT-MKT-DUPLICATE-REFUSED",
186
+ "title": "the marketplace-row parser silently returns the FIRST of several same-named rows instead of refusing the ambiguity — the retired grep|head -1 behavior, re-planted: a second marketplace with our name steers every path check at whichever row happens to print first (#86 C3a corrective amendment, B defect 2)",
187
+ "subject": "scripts/copilot-bridge-oracle.sh",
188
+ "find": [
189
+ "if len(paths) > 1:\n print(f\"multiple marketplace rows named {name}: paths {paths} — duplicates are ambiguity nobody may act on\", file=sys.stderr)\n sys.exit(1)\nprint(f\"one {paths[0]}\" if paths else \"absent\")"
190
+ ],
191
+ "replace": ["print(f\"one {paths[0]}\" if paths else \"absent\")"],
192
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
193
+ "timeoutSeconds": 300,
194
+ "signature": "[QK:COPILOT-MKT-DUPLICATE-REFUSED]",
195
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
196
+ },
197
+ {
198
+ "claim": "COPILOT-MALFORMED-ROW-NOT-ABSENT",
199
+ "title": "a truncated/garbled exact plugin row falls through the parser and rounds to ABSENT, which the inverse reads as retry-safe absence and continues past — the exact fall-through B reproduced (`(v0.1` with no closing paren) against 47a5ae3 (#86 C3a corrective amendment, B defect 3)",
200
+ "subject": "scripts/copilot-bridge-oracle.sh",
201
+ "find": [
202
+ " if not (rest.startswith(\"(v\") and rest.endswith(\")\")):\n print(f\"malformed exact row for {qualified}: {row!r} does not parse as '<qualified> (v<version>)'\", file=sys.stderr)\n sys.exit(1)"
203
+ ],
204
+ "replace": [" if not (rest.startswith(\"(v\") and rest.endswith(\")\")):\n continue"],
205
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
206
+ "timeoutSeconds": 300,
207
+ "signature": "[QK:COPILOT-MALFORMED-ROW-NOT-ABSENT]",
208
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
209
+ },
210
+ {
211
+ "claim": "COPILOT-STATE-VERSION-WHITESPACE",
212
+ "title": "the state validator accepts a pluginVersion carrying whitespace, so the space-separated fact transport (`cut -d' ' -f3`) truncates it into a FABRICATED version and consumers act on a value the state never recorded (#86 C3a corrective amendment, B defect 4)",
213
+ "subject": "scripts/copilot-bridge-oracle.sh",
214
+ "find": ["if any(ord(c) < 0x21 or ord(c) == 0x7f for c in state[\"pluginVersion\"]):"],
215
+ "replace": ["if False and state[\"pluginVersion\"]:"],
216
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
217
+ "timeoutSeconds": 300,
218
+ "signature": "[QK:COPILOT-STATE-VERSION-WHITESPACE]",
219
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
220
+ },
221
+ {
222
+ "claim": "COPILOT-DOCTOR-ORACLE-CONSUMED",
223
+ "title": "the doctor's structural verdict stops consulting the shared oracle and reads every assembly as green, so a unit install/adopt would refuse (broken hooks.json, unbaked launcher) doctors as healthy — the second-parser drift B flagged, taken to its end state (#86 C3a corrective amendment, B defect 1)",
224
+ "subject": "scripts/copilot-bridge-doctor.sh",
225
+ "find": ["if ORACLE_REASON=\"$(copilot_assembly_valid \"$ASM\" \"$PLUGIN\" 2>&1)\"; then"],
226
+ "replace": ["if ORACLE_REASON=\"\"; then"],
227
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
228
+ "timeoutSeconds": 300,
229
+ "signature": "[QK:COPILOT-DOCTOR-ORACLE-CONSUMED]",
230
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
231
+ },
232
+ {
233
+ "claim": "COPILOT-BIRTH-NO-FALSE-ABSENCE",
234
+ "title": "the inverse reads a FAILING `copilot plugin list` as an empty host and reports a clean removal over a host whose real contents nobody read",
235
+ "subject": "scripts/copilot-bridge-uninstall.sh",
236
+ "find": [
237
+ "if ! INSTALLED_LIST=\"$(copilot plugin list 2>/dev/null)\"; then\n die \"'copilot plugin list' failed, so this host's installed plugins are UNKNOWN — refusing with zero writes. Fix the Copilot CLI error and re-run.\"\nfi"
238
+ ],
239
+ "replace": ["INSTALLED_LIST=\"$(copilot plugin list 2>/dev/null)\" || INSTALLED_LIST=\"\""],
240
+ "gate": ["bash", "run.sh", "check-copilot-birth-hook"],
241
+ "timeoutSeconds": 300,
242
+ "signature": "[QK:COPILOT-BIRTH-NO-FALSE-ABSENCE]",
243
+ "signatureSource": "scripts/check-copilot-birth-hook.ts"
153
244
  }
154
245
  ]
155
246
  }
@@ -6,8 +6,8 @@
6
6
  "claim": "FRESHCALL-PI-ARGV-PROMPT-FIRST",
7
7
  "title": "pi gets the flag before the prompt again — the measured shape that opens a window whose first turn never runs",
8
8
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
9
- "find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
10
- "replace": ["\t\t\treturn [\"--entwurf-control\", prompt, \"--model\", model];"],
9
+ "find": ["\t\t\treturn [composition.prompt, \"--entwurf-control\", \"--model\", model];"],
10
+ "replace": ["\t\t\treturn [\"--entwurf-control\", composition.prompt, \"--model\", model];"],
11
11
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
12
12
  "timeoutSeconds": 120,
13
13
  "signature": "[QK:FRESHCALL-PI-ARGV-PROMPT-FIRST]",
@@ -18,10 +18,10 @@
18
18
  "title": "claude-code goes back to the variadic space form, which swallows the prompt as an option value",
19
19
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
20
20
  "find": [
21
- "\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
21
+ "\t\t\treturn [composition.prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
22
22
  ],
23
23
  "replace": [
24
- "\t\t\treturn [prompt, \"--allowedTools\", FRESH_CALL_CALLBACK_TOOL[\"claude-code\"], `--model=${model}`];"
24
+ "\t\t\treturn [composition.prompt, \"--allowedTools\", FRESH_CALL_CALLBACK_TOOL[\"claude-code\"], `--model=${model}`];"
25
25
  ],
26
26
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
27
27
  "timeoutSeconds": 120,
@@ -32,8 +32,8 @@
32
32
  "claim": "FRESHCALL-PI-MODEL-ARGV",
33
33
  "title": "pi drops its measured two-token model option and silently resolves its ambient default again",
34
34
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
35
- "find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
36
- "replace": ["\t\t\treturn [prompt, \"--entwurf-control\"];"],
35
+ "find": ["\t\t\treturn [composition.prompt, \"--entwurf-control\", \"--model\", model];"],
36
+ "replace": ["\t\t\treturn [composition.prompt, \"--entwurf-control\"];"],
37
37
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
38
38
  "timeoutSeconds": 120,
39
39
  "signature": "[QK:FRESHCALL-PI-MODEL-ARGV]",
@@ -43,8 +43,8 @@
43
43
  "claim": "FRESHCALL-PI-MODEL-DIALECT",
44
44
  "title": "pi model argv is unified with Claude Code into the equals form that the real Pi parser rejects",
45
45
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
46
- "find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
47
- "replace": ["\t\t\treturn [prompt, \"--entwurf-control\", `--model=${model}`];"],
46
+ "find": ["\t\t\treturn [composition.prompt, \"--entwurf-control\", \"--model\", model];"],
47
+ "replace": ["\t\t\treturn [composition.prompt, \"--entwurf-control\", `--model=${model}`];"],
48
48
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
49
49
  "timeoutSeconds": 120,
50
50
  "signature": "[QK:FRESHCALL-PI-MODEL-DIALECT]",
@@ -55,9 +55,9 @@
55
55
  "title": "Claude Code drops the explicit model token and silently resolves its ambient Opus default again",
56
56
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
57
57
  "find": [
58
- "\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
58
+ "\t\t\treturn [composition.prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
59
59
  ],
60
- "replace": ["\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`];"],
60
+ "replace": ["\t\t\treturn [composition.prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`];"],
61
61
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
62
62
  "timeoutSeconds": 120,
63
63
  "signature": "[QK:FRESHCALL-CLAUDE-MODEL-ARGV]",
@@ -240,8 +240,8 @@
240
240
  "claim": "FRESHCALL-COPILOT-ARGV-INTERACTIVE",
241
241
  "title": "the Copilot prompt rides -p instead of --interactive — the turn runs and the CLI EXITS, closing the window on a sibling that was supposed to stay open",
242
242
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
243
- "find": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model, \"--yolo\"];"],
244
- "replace": ["\t\t\treturn [\"copilot\", \"-p\", prompt, \"--model\", model, \"--yolo\"];"],
243
+ "find": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model, \"--yolo\"];"],
244
+ "replace": ["\t\t\treturn [\"copilot\", \"-p\", composition.prompt, \"--model\", model, \"--yolo\"];"],
245
245
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
246
246
  "timeoutSeconds": 180,
247
247
  "signature": "[QK:FRESHCALL-COPILOT-ARGV-INTERACTIVE]",
@@ -251,8 +251,8 @@
251
251
  "claim": "FRESHCALL-COPILOT-MODEL-ARGV",
252
252
  "title": "the Copilot argv drops the explicit model — the managed launcher then injects `--model auto` and the caller's model choice is silently discarded",
253
253
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
254
- "find": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model, \"--yolo\"];"],
255
- "replace": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--yolo\"];"],
254
+ "find": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model, \"--yolo\"];"],
255
+ "replace": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--yolo\"];"],
256
256
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
257
257
  "timeoutSeconds": 180,
258
258
  "signature": "[QK:FRESHCALL-COPILOT-MODEL-ARGV]",
@@ -262,9 +262,9 @@
262
262
  "claim": "FRESHCALL-COPILOT-YOLO-POLICY",
263
263
  "title": "the policy token narrows back to the callback-only --allow-tool grant — the exact regression GLG measured on 2026-08-25: no YOLO in the footer, a confirmation prompt at every task tool, an impractical sibling",
264
264
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
265
- "find": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model, \"--yolo\"];"],
265
+ "find": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model, \"--yolo\"];"],
266
266
  "replace": [
267
- "\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model, \"--allow-tool=entwurf-bridge(entwurf_v2)\"];"
267
+ "\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model, \"--allow-tool=entwurf-bridge(entwurf_v2)\"];"
268
268
  ],
269
269
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
270
270
  "timeoutSeconds": 180,
@@ -312,8 +312,8 @@
312
312
  "claim": "FRESHCALL-BACKEND-SET-SURFACE-PARITY",
313
313
  "title": "a backend the composition can open is missing from the MCP surface enum — the capability exists and no external host can reach it",
314
314
  "subject": "mcp/entwurf-bridge/src/index.ts",
315
- "find": ["\t\t\t.enum([\"pi\", \"claude-code\", \"copilot\"])"],
316
- "replace": ["\t\t\t.enum([\"pi\", \"claude-code\"])"],
315
+ "find": ["\t\t\t.enum([\"pi\", \"claude-code\", \"copilot\", \"omp\"])"],
316
+ "replace": ["\t\t\t.enum([\"pi\", \"claude-code\", \"copilot\"])"],
317
317
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
318
318
  "timeoutSeconds": 180,
319
319
  "signature": "[QK:FRESHCALL-BACKEND-SET-SURFACE-PARITY]",
@@ -421,8 +421,8 @@
421
421
  "claim": "FRESHCALL-COPILOT-EXPLICIT-POLICY",
422
422
  "title": "the composition stops stating its policy and silently leans on the launcher to inject --yolo — the effective profile survives but the fresh contract loses its explicit permission statement",
423
423
  "subject": "pi-extensions/lib/mux-fresh-call.ts",
424
- "find": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model, \"--yolo\"];"],
425
- "replace": ["\t\t\treturn [\"copilot\", \"--interactive\", prompt, \"--model\", model];"],
424
+ "find": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model, \"--yolo\"];"],
425
+ "replace": ["\t\t\treturn [\"copilot\", \"--interactive\", composition.prompt, \"--model\", model];"],
426
426
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
427
427
  "timeoutSeconds": 180,
428
428
  "signature": "[QK:FRESHCALL-COPILOT-EXPLICIT-POLICY]",
@@ -432,8 +432,8 @@
432
432
  "claim": "FRESHCALL-BACKEND-SET-SURFACE-PARITY-PI",
433
433
  "title": "a backend the composition can open is missing from the native pi surface enum — an in-process pi session cannot name a capability the module already opens",
434
434
  "subject": "pi-extensions/entwurf-control.ts",
435
- "find": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\", \"copilot\"], {"],
436
- "replace": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\"], {"],
435
+ "find": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\", \"copilot\", \"omp\"], {"],
436
+ "replace": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\", \"copilot\"], {"],
437
437
  "gate": ["bash", "run.sh", "check-mux-fresh-call"],
438
438
  "timeoutSeconds": 180,
439
439
  "signature": "[QK:FRESHCALL-BACKEND-SET-SURFACE-PARITY-PI]",
@@ -0,0 +1,173 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "omp-birth",
4
+ "mutants": [
5
+ {
6
+ "claim": "OMP-BIRTH-TUI-MINTS",
7
+ "title": "a birth unit whose host predicate is not the vendor's tui mode mints nothing for the operator's own session — the visible sibling never becomes a citizen",
8
+ "subject": "pi-extensions/meta-bridge-omp.ts",
9
+ "find": ["const HOST_MODE = \"tui\";"],
10
+ "replace": ["const HOST_MODE = \"print\";"],
11
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
12
+ "timeoutSeconds": 300,
13
+ "signature": "[QK:OMP-BIRTH-TUI-MINTS]",
14
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
15
+ },
16
+ {
17
+ "claim": "OMP-BIRTH-SCOPE-FENCE",
18
+ "title": "a fence that admits `print` gives every task subagent its own garden id — each visible omp session would mint a citizen per internal agent, which is the exact thing #87 exists to prevent",
19
+ "subject": "pi-extensions/meta-bridge-omp.ts",
20
+ "find": ["\tif (ctx.mode !== HOST_MODE) {"],
21
+ "replace": ["\tif (ctx.mode !== HOST_MODE && ctx.mode !== \"print\") {"],
22
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
23
+ "timeoutSeconds": 300,
24
+ "signature": "[QK:OMP-BIRTH-SCOPE-FENCE]",
25
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
26
+ },
27
+ {
28
+ "claim": "OMP-BIRTH-BINDS-BOTH-EDGES",
29
+ "title": "binding only session_start leaves every post-/new, forked and in-TUI-resumed session unminted while its status line still shows the previous citizen's id (the switch edge is where those re-fire, audit C2)",
30
+ "subject": "pi-extensions/meta-bridge-omp.ts",
31
+ "find": [
32
+ "\tpi.on(\"session_switch\", (event, ctx) =>",
33
+ "\t\tonBirthEdge(`session_switch(${asNonEmptyString(event?.reason) || \"unlabeled\"})`, ctx, pi),",
34
+ "\t);"
35
+ ],
36
+ "replace": ["\t// session_switch left unbound"],
37
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
38
+ "timeoutSeconds": 300,
39
+ "signature": "[QK:OMP-BIRTH-BINDS-BOTH-EDGES]",
40
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
41
+ },
42
+ {
43
+ "claim": "OMP-BIRTH-SHOWS-GARDEN-ID",
44
+ "title": "a citizen whose garden id never reaches the vendor's own status surface has an address visible only by scraping records — not lifecycle parity (adding-a-harness.md step 4)",
45
+ "subject": "pi-extensions/meta-bridge-omp.ts",
46
+ "find": ["\t\tshowGardenId(ctx, result.record.gardenId);"],
47
+ "replace": ["\t\t// visible identity dropped"],
48
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
49
+ "timeoutSeconds": 300,
50
+ "signature": "[QK:OMP-BIRTH-SHOWS-GARDEN-ID]",
51
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
52
+ },
53
+ {
54
+ "claim": "OMP-SENDER-MARKER-OWN-PID",
55
+ "title": "keying the marker to process.ppid copies the exec'd backends' parent join into a runtime that has no launcher — the marker names the shell that started omp, and no bridge child ever looks there",
56
+ "subject": "pi-extensions/meta-bridge-omp.ts",
57
+ "find": ["\tconst ownerPid = process.pid;"],
58
+ "replace": ["\tconst ownerPid = process.ppid;"],
59
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
60
+ "timeoutSeconds": 300,
61
+ "signature": "[QK:OMP-SENDER-MARKER-OWN-PID]",
62
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
63
+ },
64
+ {
65
+ "claim": "OMP-SENDER-READER-OPEN",
66
+ "title": "a backend whose hook writes a marker but is absent from the reader list is INVISIBLE — the bridge holds the owner pid, never looks in that directory, and every send is refused as anonymous for a reason nothing logs (the #46 defect)",
67
+ "subject": "pi-extensions/lib/meta-sender-identity.ts",
68
+ "find": [
69
+ "export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\", \"copilot\", \"omp\"];"
70
+ ],
71
+ "replace": [
72
+ "export const META_SENDER_BACKENDS: readonly MetaBackend[] = [\"claude-code\", \"antigravity\", \"copilot\"];"
73
+ ],
74
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
75
+ "timeoutSeconds": 300,
76
+ "signature": "[QK:OMP-SENDER-READER-OPEN]",
77
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
78
+ },
79
+ {
80
+ "claim": "OMP-BIRTH-DOES-NOT-ARM-RECEIVER",
81
+ "title": "birth arming a receiver claims a live process holds a watch that nothing holds — the citizen reads DELIVERABLE, wired to nothing, for as long as the TUI stays open. This plants a REAL record-bound marker the certified reader accepts (an empty meta-receivers/ directory arms nothing and would be killed for the wrong reason)",
82
+ "subject": "pi-extensions/meta-bridge-omp.ts",
83
+ "find": ["\t\twriteOmpSenderMarker(result.record.gardenId, envelope);"],
84
+ "replace": [
85
+ "\t\twriteOmpSenderMarker(result.record.gardenId, envelope);",
86
+ "\t\tconst receiversDir = roots().receiversDir;",
87
+ "\t\tfs.mkdirSync(receiversDir, { recursive: true });",
88
+ "\t\tfs.writeFileSync(",
89
+ "\t\t\tpath.join(receiversDir, `${result.record.gardenId}.json`),",
90
+ "\t\t\t`${JSON.stringify({",
91
+ "\t\t\t\tgardenId: result.record.gardenId,",
92
+ "\t\t\t\tbackend: BACKEND,",
93
+ "\t\t\t\tnativeSessionId: envelope.nativeSessionId,",
94
+ "\t\t\t\townerPid: process.pid,",
95
+ "\t\t\t\townerStartKey: \"planted-by-mutant\",",
96
+ "\t\t\t\townerKind: \"omp-tui\",",
97
+ "\t\t\t\tarmProvenance: \"session-start\",",
98
+ "\t\t\t\tupdatedAt: new Date().toISOString(),",
99
+ "\t\t\t})}\\n`,",
100
+ "\t\t);"
101
+ ],
102
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
103
+ "timeoutSeconds": 300,
104
+ "signature": "[QK:OMP-BIRTH-DOES-NOT-ARM-RECEIVER]",
105
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
106
+ },
107
+ {
108
+ "claim": "OMP-BIRTH-CWD-DISAGREEMENT",
109
+ "title": "preferring one cwd when the two vendor-authoritative sources disagree mints a record keyed to a directory the session is not in — a guess exactly where the disagreement was the interesting fact",
110
+ "subject": "pi-extensions/meta-bridge-omp.ts",
111
+ "find": [
112
+ "\tif (ctxCwd && managerCwd && ctxCwd !== managerCwd) {",
113
+ "\t\treturn { refusal: `ctx.cwd and sessionManager.getCwd() disagree (${ctxCwd} vs ${managerCwd})` };",
114
+ "\t}"
115
+ ],
116
+ "replace": ["\t// disagreement tolerated: ctx.cwd simply wins"],
117
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
118
+ "timeoutSeconds": 300,
119
+ "signature": "[QK:OMP-BIRTH-CWD-DISAGREEMENT]",
120
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
121
+ },
122
+ {
123
+ "claim": "OMP-META-ROOT-JOINT-BINDING",
124
+ "title": "restoring the legacy PI_CODING_AGENT_DIR fallback inside the SHARED omp root base splits the garden store on an ordinary `omp --profile work`: the birth extension mints its record and sender marker under the vendor's profile agent dir — a pi sandbox, if that is where the value came from — and the omp-labeled bridge child pins its four roots to the same wrong bundle. Mutating the shared base replants the defect in BOTH consumers at once, which is why the subject is the common policy rather than either call site",
125
+ "subject": "pi-extensions/lib/meta-session.ts",
126
+ "find": [
127
+ "\t// NEVER `piAgentDir()` here: for backend omp that variable is the VENDOR's agent dir.",
128
+ "\treturn path.join(home, \".pi\", \"agent\");"
129
+ ],
130
+ "replace": [
131
+ "\treturn env.PI_CODING_AGENT_DIR",
132
+ "\t\t? path.resolve(expandTildeIn(env.PI_CODING_AGENT_DIR, home))",
133
+ "\t\t: path.join(home, \".pi\", \"agent\");"
134
+ ],
135
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
136
+ "timeoutSeconds": 300,
137
+ "signature": "[QK:OMP-META-ROOT-JOINT-BINDING]",
138
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
139
+ },
140
+ {
141
+ "claim": "OMP-META-ROOT-ABSOLUTE-ONLY",
142
+ "title": "resolving a relative ENTWURF_META_* override instead of refusing it makes each process's working directory a garden-root authority: the omp extension resolves it against wherever the operator launched omp while the doctor resolves it against the repository (run_ts cd's there), so the doctor reports NOT-YET off an empty directory while the extension's real store holds records. Both halves read this one leaf, so removing the fail-closed branch splits them at the same instant",
143
+ "subject": "pi-extensions/lib/meta-session.ts",
144
+ "find": [
145
+ "\t\tif (override === \"~\" || override.startsWith(\"~/\")) return path.resolve(expandTildeIn(override, home));",
146
+ "\t\tif (path.isAbsolute(override)) return path.resolve(override);",
147
+ "\t\tthrow new MetaRootPolicyError(",
148
+ "\t\t\t`omp meta-root policy refuses ${key}=${JSON.stringify(override)}: a garden root must be absolute or ~-rooted ` +",
149
+ "\t\t\t\t\"(`~` or `~/…`). A relative value would resolve against each process's own working directory, and the omp \" +",
150
+ "\t\t\t\t\"extension and its doctor do not share one — set an absolute path, or unset it to use the default under HOME.\",",
151
+ "\t\t);"
152
+ ],
153
+ "replace": ["\t\treturn path.resolve(expandTildeIn(override, home));"],
154
+ "gate": ["bash", "run.sh", "check-omp-birth-hook"],
155
+ "timeoutSeconds": 300,
156
+ "signature": "[QK:OMP-META-ROOT-ABSOLUTE-ONLY]",
157
+ "signatureSource": "scripts/check-omp-birth-hook.ts"
158
+ },
159
+ {
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",
162
+ "subject": "scripts/omp-bridge-doctor.sh",
163
+ "find": [
164
+ " if tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -qE '^(PI_SESSION_ID|PI_AGENT_ID)=.*[^[:space:]]'; then"
165
+ ],
166
+ "replace": [" if tr '\\0' '\\n' < \"$ENVIRON\" 2>/dev/null | grep -qE '^(PI_SESSION_ID|PI_AGENT_ID)='; then"],
167
+ "gate": ["bash", "run.sh", "smoke-omp-bridge-state"],
168
+ "timeoutSeconds": 300,
169
+ "signature": "[QK:OMP-DOCTOR-CARRIER-TRIMS]",
170
+ "signatureSource": "scripts/smoke-omp-bridge-state.sh"
171
+ }
172
+ ]
173
+ }