@junghanacs/entwurf 0.41.1 → 0.45.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 (102) hide show
  1. package/AGENTS.md +2 -1
  2. package/BASELINE.md +7 -5
  3. package/CHANGELOG.md +344 -0
  4. package/DELIVERY.md +37 -20
  5. package/ENTWURF.json +236 -0
  6. package/README.md +75 -65
  7. package/VERIFY.md +9 -9
  8. package/docs/external-mcp-host.md +1 -1
  9. package/docs/setup-clean-host.md +59 -33
  10. package/mcp/entwurf-bridge/dist/ENTWURF.json +236 -0
  11. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +32 -190
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/agent-guidance.js +299 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +10 -0
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +23 -2
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +7 -1
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +23 -24
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +15 -11
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +21 -10
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +4 -2
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +5 -0
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +29 -24
  22. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +18 -16
  23. package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/register.js +13 -2
  24. package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +2 -2
  25. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +1 -1
  26. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-receive.js +25 -17
  27. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +101 -32
  28. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +57 -7
  29. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +23 -45
  30. package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +12 -12
  31. package/mcp/entwurf-bridge/src/index.ts +126 -321
  32. package/native/win32-x64/entwurf_win.node +0 -0
  33. package/native/win32-x64/manifest.json +2 -2
  34. package/package.json +5 -4
  35. package/pi-extensions/lib/agent-guidance.ts +341 -0
  36. package/pi-extensions/lib/entwurf-self-address.ts +13 -0
  37. package/pi-extensions/lib/entwurf-v2-contract.ts +25 -2
  38. package/pi-extensions/lib/entwurf-v2-decider.ts +7 -0
  39. package/pi-extensions/lib/entwurf-v2-surface.ts +27 -30
  40. package/pi-extensions/lib/entwurf-v2-visible-resume.ts +15 -16
  41. package/pi-extensions/lib/fresh-call-composition.ts +21 -10
  42. package/pi-extensions/lib/herdr-fresh-call.ts +4 -2
  43. package/pi-extensions/lib/meta-sender-identity.ts +4 -0
  44. package/pi-extensions/lib/mux-fresh-call.ts +29 -30
  45. package/pi-extensions/lib/mux-resume-call.ts +18 -19
  46. package/pi-extensions/lib/native-push/register.ts +17 -2
  47. package/pi-extensions/lib/omp-fresh-preflight.ts +2 -2
  48. package/pi-extensions/lib/pi-durable-fresh-preflight.ts +1 -1
  49. package/pi-extensions/lib/remote-pair-receive.ts +27 -19
  50. package/pi-extensions/lib/remote-pair-send.ts +124 -34
  51. package/pi-extensions/meta-bridge-omp.ts +69 -7
  52. package/pi-extensions/meta-bridge-pi-durable.ts +23 -64
  53. package/run.sh +182 -22
  54. package/scripts/build-bridge.sh +10 -0
  55. package/scripts/check-agy-sender-identity.ts +6 -4
  56. package/scripts/check-capability-bundle-reach.ts +86 -0
  57. package/scripts/check-entwurf-self-address.ts +37 -6
  58. package/scripts/check-entwurf-v2-contract.ts +24 -2
  59. package/scripts/check-entwurf-v2-production.ts +45 -31
  60. package/scripts/check-entwurf-v2-surface.ts +94 -98
  61. package/scripts/check-gate-qualification.ts +17 -13
  62. package/scripts/check-mux-resume-call.ts +20 -3
  63. package/scripts/check-native-push-adapter.ts +4 -0
  64. package/scripts/check-native-push-register.ts +32 -82
  65. package/scripts/check-remote-pair-installed.ts +2 -2
  66. package/scripts/dev-bin.sh +112 -1
  67. package/scripts/lib/chain-terminus-publication.ts +58 -0
  68. package/scripts/lib/codex-fresh-live-protocol.ts +30 -0
  69. package/scripts/lib/codex-fresh-source-receipts.ts +112 -3
  70. package/scripts/lib/pi-durable-fresh-live-receipts.ts +29 -1
  71. package/scripts/mutants/agent-guidance.json +160 -0
  72. package/scripts/mutants/bridge-boot-resume.json +6 -8
  73. package/scripts/mutants/capability-bundle-reach.json +124 -0
  74. package/scripts/mutants/chain-terminus-publication.json +17 -0
  75. package/scripts/mutants/codex-native.json +98 -0
  76. package/scripts/mutants/control-send-receipt.json +23 -6
  77. package/scripts/mutants/mux-fresh-call.json +30 -4
  78. package/scripts/mutants/mux-resume-call.json +28 -3
  79. package/scripts/mutants/native-push-paused.json +17 -0
  80. package/scripts/mutants/omp-fresh.json +13 -2
  81. package/scripts/mutants/pack-install.json +46 -0
  82. package/scripts/mutants/pi-durable.json +17 -5
  83. package/scripts/mutants/remote-pair-display.json +3 -3
  84. package/scripts/mutants/remote-pair-receive.json +41 -11
  85. package/scripts/mutants/remote-pair-roundtrip.json +67 -7
  86. package/scripts/mutants/remote-pair-send.json +177 -19
  87. package/scripts/mutants/remote-pair-transport.json +4 -4
  88. package/scripts/mutants/self-address.json +10 -10
  89. package/scripts/mutants/source-install.json +66 -0
  90. package/scripts/mutants/v2-surface.json +50 -64
  91. package/scripts/mutants/v2-visible-resume.json +11 -0
  92. package/scripts/remote-pair-receive.ts +12 -12
  93. package/scripts/smoke-agy-install-state.sh +121 -0
  94. package/scripts/smoke-agy-native-push-live.ts +13 -0
  95. package/scripts/smoke-codex-fresh-live.ts +50 -27
  96. package/scripts/smoke-entwurf-chain-live.ts +7 -9
  97. package/scripts/smoke-herdr-fresh-call-live.ts +4 -4
  98. package/scripts/smoke-herdr-plugin-build-live.ts +179 -50
  99. package/scripts/smoke-mux-lifecycle-live.ts +140 -8
  100. package/scripts/smoke-omp-fresh-live.ts +5 -4
  101. package/scripts/smoke-pi-durable-fresh-live.ts +29 -7
  102. package/scripts/smoke-setup-verdict.sh +27 -2
@@ -6,9 +6,9 @@
6
6
  "claim": "REMOTE-ROUTE-UNDECLARED-LOCAL-UNCHANGED",
7
7
  "title": "a declared route captures every target, so a gid the declaration never named is sent to the other host instead of the local decider",
8
8
  "subject": "pi-extensions/lib/remote-pair-send.ts",
9
- "find": ["\tif (route === null || params.target !== route.remoteGardenId) {"],
10
- "replace": ["\tif (route === null) {"],
11
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
9
+ "find": ["\tconst declared = (opts.optIn?.routes ?? []).filter((r) => r.remoteGardenId === params.target);"],
10
+ "replace": ["\tconst declared = opts.optIn?.routes ?? [];"],
11
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
12
12
  "timeoutSeconds": 600,
13
13
  "signature": "[QK:REMOTE-ROUTE-UNDECLARED-LOCAL-UNCHANGED]",
14
14
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -21,9 +21,9 @@
21
21
  "claim": "REMOTE-ROUTE-LOCAL-CONFLICT-FAILS-CLOSED",
22
22
  "title": "a declared remote gid that this host also answers to is sent away anyway, so two hosts' citizens share one address and the sender silently picks the remote",
23
23
  "subject": "pi-extensions/lib/remote-pair-send.ts",
24
- "find": ["\tif (await opts.localTrace(route.remoteGardenId)) {"],
24
+ "find": ["\tif (await opts.localTrace(params.target)) {"],
25
25
  "replace": ["\tif (Boolean(0)) {"],
26
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
26
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
27
27
  "timeoutSeconds": 600,
28
28
  "signature": "[QK:REMOTE-ROUTE-LOCAL-CONFLICT-FAILS-CLOSED]",
29
29
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -36,9 +36,9 @@
36
36
  "claim": "REMOTE-ROUTE-SENDER-MUST-BE-DECLARED",
37
37
  "title": "any present envelope may use the route, so an anonymous caller or another citizen on this host speaks to the other host as the declared sender",
38
38
  "subject": "pi-extensions/lib/remote-pair-send.ts",
39
- "find": ["\tif (!sender || sender.origin === \"external-mcp\" || sender.sessionId !== route.localGardenId) {"],
40
- "replace": ["\tif (!sender || Boolean(0)) {"],
41
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
39
+ "find": ["\t\tsender && sender.origin !== \"external-mcp\""],
40
+ "replace": ["\t\tsender"],
41
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
42
42
  "timeoutSeconds": 600,
43
43
  "signature": "[QK:REMOTE-ROUTE-SENDER-MUST-BE-DECLARED]",
44
44
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -53,7 +53,7 @@
53
53
  "subject": "pi-extensions/lib/remote-pair-send.ts",
54
54
  "find": ["\t\t\"BatchMode=yes\","],
55
55
  "replace": ["\t\t\"BatchMode=no\","],
56
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
56
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
57
57
  "timeoutSeconds": 600,
58
58
  "signature": "[QK:REMOTE-ROUTE-EXACT-ARGV-ONCE]",
59
59
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -70,7 +70,7 @@
70
70
  "replace": [
71
71
  "\tawait opts.transport.run(remoteReceiveArgv(route), JSON.stringify(claim), 1);\n\tconst result = await opts.transport.run("
72
72
  ],
73
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
73
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
74
74
  "timeoutSeconds": 600,
75
75
  "signature": "[QK:REMOTE-ROUTE-NO-RETRY]",
76
76
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -87,7 +87,7 @@
87
87
  "\tif (r.exitCode === 0 && keys === \"isError,kind,text\" && o.kind === \"dispatched\" && o.isError === false) {"
88
88
  ],
89
89
  "replace": ["\tif (keys === \"isError,kind,text\" && o.kind === \"dispatched\" && o.isError === false) {"],
90
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
90
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
91
91
  "timeoutSeconds": 600,
92
92
  "signature": "[QK:REMOTE-RECEIPT-EXIT-AND-KIND-AGREE]",
93
93
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -102,7 +102,7 @@
102
102
  "subject": "pi-extensions/lib/remote-pair-send.ts",
103
103
  "find": ["const REMOTE_PATH = /^\\/[A-Za-z0-9._/-]+$/;"],
104
104
  "replace": ["const REMOTE_PATH = /^\\/.+$/;"],
105
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
105
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
106
106
  "timeoutSeconds": 600,
107
107
  "signature": "[QK:REMOTE-ROUTE-DECL-NO-QUOTING-NEEDED]",
108
108
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -117,7 +117,7 @@
117
117
  "subject": "pi-extensions/lib/remote-pair-send.ts",
118
118
  "find": ["\t\t\tif (inspection.kind !== \"absent\") return true;"],
119
119
  "replace": ["\t\t\tif (false) return true;"],
120
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
120
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
121
121
  "timeoutSeconds": 600,
122
122
  "signature": "[QK:REMOTE-ROUTE-LOCAL-TRACE-ANY-STATE]",
123
123
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -129,10 +129,10 @@
129
129
  {
130
130
  "claim": "REMOTE-ROUTE-RECEIPT-PATHS-OTHER-HOST",
131
131
  "title": "the accepted receipt drops the note that its paths are on the other host, so the other host's messagePath reads as a file the sender could open",
132
- "subject": "pi-extensions/lib/remote-pair-send.ts",
132
+ "subject": "ENTWURF.json",
133
133
  "find": ["read/answer unknown until a reply arrives; paths below are on the other host)"],
134
134
  "replace": ["read/answer unknown until a reply arrives)"],
135
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
135
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
136
136
  "timeoutSeconds": 600,
137
137
  "signature": "[QK:REMOTE-ROUTE-RECEIPT-PATHS-OTHER-HOST]",
138
138
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -141,13 +141,32 @@
141
141
  "output": "mcp/entwurf-bridge/dist"
142
142
  }
143
143
  },
144
+ {
145
+ "claim": "REMOTE-DELIVERY-RESULT-CLAUSES-FROM-ROOT",
146
+ "title": "the accepted receipt reads a hand-kept copy of its clause, one byte off the Root text, instead of the Root lookup: it still names acceptance and still says its paths are on the other host, so only the byte comparison against Root can see the drift",
147
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
148
+ "find": [
149
+ "\t\t\t\ttext: `entwurf_v2 remote ${via} → ${ENTWURF_DELIVERY_RESULT_CLAUSES[\"remote-accepted\"]}\\n${o.text}`,"
150
+ ],
151
+ "replace": [
152
+ "\t\t\t\ttext: `entwurf_v2 remote ${via} → accepted by the other host (its fact; read/answer unknown until a reply arrives; paths below are on the other host)\\n${o.text}`,"
153
+ ],
154
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
155
+ "timeoutSeconds": 600,
156
+ "signature": "[QK:REMOTE-DELIVERY-RESULT-CLAUSES-FROM-ROOT]",
157
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
158
+ "build": {
159
+ "argv": ["bash", "scripts/build-bridge.sh"],
160
+ "output": "mcp/entwurf-bridge/dist"
161
+ }
162
+ },
144
163
  {
145
164
  "claim": "REMOTE-PAIR-OPT-IN-ABSENT-IS-OFF",
146
165
  "title": "an absent opt-in file throws instead of meaning off, so every local send on a host that never opted in fails",
147
166
  "subject": "pi-extensions/lib/remote-pair-send.ts",
148
167
  "find": ["\t\tif ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;"],
149
168
  "replace": ["\t\tif (false) return null;"],
150
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
169
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
151
170
  "timeoutSeconds": 600,
152
171
  "signature": "[QK:REMOTE-PAIR-OPT-IN-ABSENT-IS-OFF]",
153
172
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -162,7 +181,7 @@
162
181
  "subject": "pi-extensions/lib/remote-pair-send.ts",
163
182
  "find": ["\tif (!st.isFile()) {\n\t\tthrow new RemoteRouteDeclarationError(`remote pair opt-in"],
164
183
  "replace": ["\tif (false) {\n\t\tthrow new RemoteRouteDeclarationError(`remote pair opt-in"],
165
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
184
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
166
185
  "timeoutSeconds": 600,
167
186
  "signature": "[QK:REMOTE-PAIR-OPT-IN-BROKEN-REFUSED]",
168
187
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -176,12 +195,12 @@
176
195
  "title": "an error the other host reports after a possible write is headed as a non-delivery, inviting a resend that would deliver twice",
177
196
  "subject": "pi-extensions/lib/remote-pair-send.ts",
178
197
  "find": [
179
- "\t\t\t\ttext: `entwurf_v2 remote ${via} → the other host reported an error while processing; read its receipt below, delivery is not inferred from this line; not retried (paths below are on the other host)\\n${o.text}`,"
198
+ "\t\t\t\ttext: `entwurf_v2 remote ${via} → ${ENTWURF_DELIVERY_RESULT_CLAUSES[\"remote-reported-error\"]}\\n${o.text}`,"
180
199
  ],
181
200
  "replace": [
182
201
  "\t\t\t\ttext: `entwurf_v2 remote ${via} → the other host did not deliver (paths below are on the other host)\\n${o.text}`,"
183
202
  ],
184
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
203
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
185
204
  "timeoutSeconds": 600,
186
205
  "signature": "[QK:REMOTE-REPORTED-ERROR-NO-DELIVERY-INFERENCE]",
187
206
  "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
@@ -189,6 +208,145 @@
189
208
  "argv": ["bash", "scripts/build-bridge.sh"],
190
209
  "output": "mcp/entwurf-bridge/dist"
191
210
  }
211
+ },
212
+ {
213
+ "claim": "REMOTE-ROUTES-V2-EXACT-SHAPE",
214
+ "title": "an empty routes array is read as a declaration with no route, so a file meant to switch the pair off silently keeps the bridge reading an opt-in instead of being refused",
215
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
216
+ "find": ["\tif (!Array.isArray(obj.routes) || obj.routes.length === 0) {"],
217
+ "replace": ["\tif (!Array.isArray(obj.routes)) {"],
218
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
219
+ "timeoutSeconds": 600,
220
+ "signature": "[QK:REMOTE-ROUTES-V2-EXACT-SHAPE]",
221
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
222
+ "build": {
223
+ "argv": ["bash", "scripts/build-bridge.sh"],
224
+ "output": "mcp/entwurf-bridge/dist"
225
+ }
226
+ },
227
+ {
228
+ "claim": "REMOTE-ROUTES-LEGACY-NAMED-REFUSAL",
229
+ "title": "the versionless single-pair file is quietly read as one route, so a host keeps a pre-#149 declaration through the hard cut with no named transition",
230
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
231
+ "find": ["\tif (!Object.hasOwn(obj, \"version\")) {"],
232
+ "replace": [
233
+ "\tif (!Object.hasOwn(obj, \"version\")) return { routes: [parseRoute(obj, what)] };\n\tif (Boolean(0)) {"
234
+ ],
235
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
236
+ "timeoutSeconds": 600,
237
+ "signature": "[QK:REMOTE-ROUTES-LEGACY-NAMED-REFUSAL]",
238
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
239
+ "build": {
240
+ "argv": ["bash", "scripts/build-bridge.sh"],
241
+ "output": "mcp/entwurf-bridge/dist"
242
+ }
243
+ },
244
+ {
245
+ "claim": "REMOTE-ROUTES-LEGAL-REPEATS-ACCEPTED",
246
+ "title": "one alias may carry only one route, so a host with two citizens on the same other host cannot declare both pairs",
247
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
248
+ "find": ["\t\tif (file !== undefined && file !== r.remotePairFile) {"],
249
+ "replace": ["\t\tif (file !== undefined) {"],
250
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
251
+ "timeoutSeconds": 600,
252
+ "signature": "[QK:REMOTE-ROUTES-LEGAL-REPEATS-ACCEPTED]",
253
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
254
+ "build": {
255
+ "argv": ["bash", "scripts/build-bridge.sh"],
256
+ "output": "mcp/entwurf-bridge/dist"
257
+ }
258
+ },
259
+ {
260
+ "claim": "REMOTE-ROUTES-DUPLICATE-PAIR-REFUSED",
261
+ "title": "the same exact pair may be declared twice, so the file carries two entries for one route and the reader keeps whichever it meets first",
262
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
263
+ "find": ["\t\tif (pairs.has(pair)) {"],
264
+ "replace": ["\t\tif (Boolean(0)) {"],
265
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
266
+ "timeoutSeconds": 600,
267
+ "signature": "[QK:REMOTE-ROUTES-DUPLICATE-PAIR-REFUSED]",
268
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
269
+ "build": {
270
+ "argv": ["bash", "scripts/build-bridge.sh"],
271
+ "output": "mcp/entwurf-bridge/dist"
272
+ }
273
+ },
274
+ {
275
+ "claim": "REMOTE-ROUTES-LOCAL-REMOTE-OVERLAP-REFUSED",
276
+ "title": "a gid may be local in one route and remote in another, so one citizen is claimed to live on this host and on another at once",
277
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
278
+ "find": ["\t\tif (locals.has(r.remoteGardenId)) {"],
279
+ "replace": ["\t\tif (Boolean(0)) {"],
280
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
281
+ "timeoutSeconds": 600,
282
+ "signature": "[QK:REMOTE-ROUTES-LOCAL-REMOTE-OVERLAP-REFUSED]",
283
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
284
+ "build": {
285
+ "argv": ["bash", "scripts/build-bridge.sh"],
286
+ "output": "mcp/entwurf-bridge/dist"
287
+ }
288
+ },
289
+ {
290
+ "claim": "REMOTE-ROUTES-REMOTE-HOST-CONFLICT-REFUSED",
291
+ "title": "one remote gid may be reached through two aliases, so which host a message to it goes to depends on which sender sends it",
292
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
293
+ "find": ["\t\tif (host && (host.ssh !== r.ssh || host.remotePairFile !== r.remotePairFile)) {"],
294
+ "replace": ["\t\tif (host && host.remotePairFile !== r.remotePairFile) {"],
295
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
296
+ "timeoutSeconds": 600,
297
+ "signature": "[QK:REMOTE-ROUTES-REMOTE-HOST-CONFLICT-REFUSED]",
298
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
299
+ "build": {
300
+ "argv": ["bash", "scripts/build-bridge.sh"],
301
+ "output": "mcp/entwurf-bridge/dist"
302
+ }
303
+ },
304
+ {
305
+ "claim": "REMOTE-ROUTES-ALIAS-FILE-CONFLICT-REFUSED",
306
+ "title": "one alias may name two remote files, though the host behind it accepts only its one canonical file, so one of those routes can never be received",
307
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
308
+ "find": ["\t\tif (file !== undefined && file !== r.remotePairFile) {"],
309
+ "replace": ["\t\tif (Boolean(0)) {"],
310
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
311
+ "timeoutSeconds": 600,
312
+ "signature": "[QK:REMOTE-ROUTES-ALIAS-FILE-CONFLICT-REFUSED]",
313
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
314
+ "build": {
315
+ "argv": ["bash", "scripts/build-bridge.sh"],
316
+ "output": "mcp/entwurf-bridge/dist"
317
+ }
318
+ },
319
+ {
320
+ "claim": "REMOTE-ROUTE-SELECT-EXACT-PAIR",
321
+ "title": "the route is chosen by target alone, so a citizen paired with another remote speaks over a route declared for a different sender",
322
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
323
+ "find": ["? declared.find((r) => r.localGardenId === sender.sessionId) :"],
324
+ "replace": ["? declared.find(() => true) :"],
325
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
326
+ "timeoutSeconds": 600,
327
+ "signature": "[QK:REMOTE-ROUTE-SELECT-EXACT-PAIR]",
328
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
329
+ "build": {
330
+ "argv": ["bash", "scripts/build-bridge.sh"],
331
+ "output": "mcp/entwurf-bridge/dist"
332
+ }
333
+ },
334
+ {
335
+ "claim": "REMOTE-ROUTE-NO-LOCAL-FALLBACK",
336
+ "title": "a declared remote target with no route for this sender falls through to the local path, so a gid the operator said lives elsewhere is resolved on this host",
337
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
338
+ "find": ["\tif (!sender || !route) {"],
339
+ "replace": [
340
+ "\tif (!sender || !route) return opts.runLocal(params, { senderProvider: opts.senderProvider });\n\tif (!sender || !route) {"
341
+ ],
342
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
343
+ "timeoutSeconds": 600,
344
+ "signature": "[QK:REMOTE-ROUTE-NO-LOCAL-FALLBACK]",
345
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
346
+ "build": {
347
+ "argv": ["bash", "scripts/build-bridge.sh"],
348
+ "output": "mcp/entwurf-bridge/dist"
349
+ }
192
350
  }
193
351
  ]
194
352
  }
@@ -8,7 +8,7 @@
8
8
  "subject": "pi-extensions/lib/remote-pair-transport.ts",
9
9
  "find": ["{ shell: false, stdio: [\"pipe\", \"pipe\", \"pipe\"] }"],
10
10
  "replace": ["{ shell: true, stdio: [\"pipe\", \"pipe\", \"pipe\"] }"],
11
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
11
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
12
12
  "timeoutSeconds": 600,
13
13
  "signature": "[QK:REMOTE-TRANSPORT-NO-SHELL-SEPARATE-STREAMS]",
14
14
  "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
@@ -23,7 +23,7 @@
23
23
  "subject": "pi-extensions/lib/remote-pair-transport.ts",
24
24
  "find": ["\t\t\t\t\tchild.kill(\"SIGKILL\");"],
25
25
  "replace": ["\t\t\t\t\tvoid 0;"],
26
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
26
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
27
27
  "timeoutSeconds": 600,
28
28
  "signature": "[QK:REMOTE-TRANSPORT-TIMEOUT-REAPS-OWN-CHILD]",
29
29
  "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
@@ -38,7 +38,7 @@
38
38
  "subject": "pi-extensions/lib/remote-pair-transport.ts",
39
39
  "find": ["\t\t\t\t\texitCode: spawnError ? null : code,"],
40
40
  "replace": ["\t\t\t\t\texitCode: spawnError ? 0 : code,"],
41
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
41
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
42
42
  "timeoutSeconds": 600,
43
43
  "signature": "[QK:REMOTE-TRANSPORT-SPAWN-FAILURE-INDETERMINATE]",
44
44
  "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
@@ -53,7 +53,7 @@
53
53
  "subject": "pi-extensions/lib/remote-pair-transport.ts",
54
54
  "find": ["\t\t\t\t\tfinalTimer = setTimeout(() => {"],
55
55
  "replace": ["\t\t\t\t\tfinalTimer = setTimeout(() => {\n\t\t\t\t\t\treturn;"],
56
- "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
56
+ "gate": ["bash", "run.sh", "check-remote-pair-beside"],
57
57
  "timeoutSeconds": 600,
58
58
  "signature": "[QK:REMOTE-TRANSPORT-HELD-PIPES-STILL-SETTLE]",
59
59
  "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
@@ -7,19 +7,19 @@
7
7
  "title": "entwurf_self reverts to an empty self-fetch guard + unconditional mailbox render (ordering-not-containment)",
8
8
  "subject": "mcp/entwurf-bridge/src/index.ts",
9
9
  "find": [
10
- "\t\t\t\tif (rail === \"self-fetch\") {",
11
- "\t\t\t\t\tconst mailboxPath = path.join(defaultMetaMailboxDir(), sender.sessionId);",
12
- "\t\t\t\t\textra.mailboxPath = mailboxPath;",
13
- "\t\t\t\t\tlines.push(`mailboxPath: ${mailboxPath}`);",
14
- "\t\t\t\t} else if (rail === \"native-push\") {"
15
- ],
16
- "replace": [
17
- "\t\t\t\tif (rail === \"self-fetch\") {",
18
- "\t\t\t\t}",
10
+ "\t\t\tif (rail === \"self-fetch\") {",
19
11
  "\t\t\t\tconst mailboxPath = path.join(defaultMetaMailboxDir(), sender.sessionId);",
20
12
  "\t\t\t\textra.mailboxPath = mailboxPath;",
21
13
  "\t\t\t\tlines.push(`mailboxPath: ${mailboxPath}`);",
22
- "\t\t\t\tif (rail === \"native-push\") {"
14
+ "\t\t\t} else if (rail === \"native-push\") {"
15
+ ],
16
+ "replace": [
17
+ "\t\t\tif (rail === \"self-fetch\") {",
18
+ "\t\t\t}",
19
+ "\t\t\tconst mailboxPath = path.join(defaultMetaMailboxDir(), sender.sessionId);",
20
+ "\t\t\textra.mailboxPath = mailboxPath;",
21
+ "\t\t\tlines.push(`mailboxPath: ${mailboxPath}`);",
22
+ "\t\t\tif (rail === \"native-push\") {"
23
23
  ],
24
24
  "gate": ["bash", "run.sh", "check-entwurf-self-address"],
25
25
  "timeoutSeconds": 60,
@@ -27,6 +27,72 @@
27
27
  "timeoutSeconds": 300,
28
28
  "signature": "[QK:SOURCE-OPERATOR-FAILS-LOUD]",
29
29
  "signatureSource": "scripts/smoke-agy-install-state.sh"
30
+ },
31
+ {
32
+ "claim": "SOURCE-SAME-TARGET-PASSES",
33
+ "title": "the exclusivity check compares the unresolved entry path again, so a duplicate PATH entry or a second link to this very checkout reads as another root and blocks a correct developer install",
34
+ "subject": "scripts/dev-bin.sh",
35
+ "find": [" if os.path.lexists(path) and os.path.realpath(path) != target:"],
36
+ "replace": [" if os.path.lexists(path) and os.path.abspath(path) != target:"],
37
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
38
+ "timeoutSeconds": 300,
39
+ "signature": "[QK:SOURCE-SAME-TARGET-PASSES]",
40
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
41
+ },
42
+ {
43
+ "claim": "SOURCE-LATER-ROOT-FAILS",
44
+ "title": "the exclusivity check reads only the head of PATH again, so an old global shim later in PATH stays selectable by a shell with another PATH order while setup reports a developer install",
45
+ "subject": "scripts/dev-bin.sh",
46
+ "find": ["for d in os.environ.get(\"PATH\", \"\").split(\":\"):"],
47
+ "replace": ["for d in os.environ.get(\"PATH\", \"\").split(\":\")[:1]:"],
48
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
49
+ "timeoutSeconds": 300,
50
+ "signature": "[QK:SOURCE-LATER-ROOT-FAILS]",
51
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
52
+ },
53
+ {
54
+ "claim": "SOURCE-GLOBAL-BIN-OTHER-ROOT",
55
+ "title": "the package manager's reported global bin dir is queried but never searched, so another root there passes whenever that dir is absent from this PATH",
56
+ "subject": "scripts/dev-bin.sh",
57
+ "find": [" add(to_bin(value), label)\n"],
58
+ "replace": [" pass\n"],
59
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
60
+ "timeoutSeconds": 300,
61
+ "signature": "[QK:SOURCE-GLOBAL-BIN-OTHER-ROOT]",
62
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
63
+ },
64
+ {
65
+ "claim": "SOURCE-GLOBAL-QUERY-REFUSED",
66
+ "title": "a package manager that fails or hangs is read as not installed again, so an uninspectable global bin dir yields a clean developer-install verdict",
67
+ "subject": "scripts/dev-bin.sh",
68
+ "find": [" errors.append(value)\n"],
69
+ "replace": [" skipped.append(value)\n"],
70
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
71
+ "timeoutSeconds": 300,
72
+ "signature": "[QK:SOURCE-GLOBAL-QUERY-REFUSED]",
73
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
74
+ },
75
+ {
76
+ "claim": "SOURCE-EXCLUSIVE-WIRED",
77
+ "title": "source setup's bins step drops the exclusivity verdict again and returns its pre-repair success, so another selectable root is reported as a developer install",
78
+ "subject": "run.sh",
79
+ "find": [" [ \"$rc\" -eq 0 ] && return \"$ex_rc\"\n"],
80
+ "replace": [" [ \"$rc\" -eq 0 ] && return 0\n"],
81
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
82
+ "timeoutSeconds": 300,
83
+ "signature": "[QK:SOURCE-EXCLUSIVE-WIRED]",
84
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
85
+ },
86
+ {
87
+ "claim": "SOURCE-MANIFEST-UNREADABLE-REFUSED",
88
+ "title": "an unreadable or wrong-shaped package manifest is read as zero bin names again, so the exclusivity check finds no other root by checking nothing and source setup reports a developer install",
89
+ "subject": "scripts/dev-bin.sh",
90
+ "find": [" sys.exit(6) # an unreadable manifest is never \"0 names, no other root\"\n"],
91
+ "replace": [" bins = {} # regressed: an unreadable manifest read as zero names\n"],
92
+ "gate": ["bash", "run.sh", "smoke-agy-install-state"],
93
+ "timeoutSeconds": 300,
94
+ "signature": "[QK:SOURCE-MANIFEST-UNREADABLE-REFUSED]",
95
+ "signatureSource": "scripts/smoke-agy-install-state.sh"
30
96
  }
31
97
  ]
32
98
  }