@junghanacs/entwurf 0.25.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/BASELINE.md +1 -1
- package/CHANGELOG.md +73 -0
- package/DELIVERY.md +1 -1
- package/README.md +178 -674
- package/VERIFY.md +16 -15
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +6 -2
- package/docs/external-mcp-host.md +1 -1
- package/docs/setup-clean-host.md +346 -10
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +27 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +12 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-peers-render.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-mailbox.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +3 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +3 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +13 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-mailbox-body.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +3 -3
- package/mcp/entwurf-bridge/src/index.ts +30 -3
- package/package.json +11 -11
- package/pi-extensions/entwurf-control.ts +50 -637
- package/pi-extensions/lib/acp/backend-adapter.ts +13 -1
- package/pi-extensions/lib/entwurf-fact-provider.ts +2 -2
- package/pi-extensions/lib/entwurf-mcp-server.ts +74 -0
- package/pi-extensions/lib/entwurf-peers-render.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-decider.ts +2 -2
- package/pi-extensions/lib/entwurf-v2-mailbox.ts +2 -2
- package/pi-extensions/lib/entwurf-v2-production.ts +3 -3
- package/pi-extensions/lib/entwurf-v2-surface.ts +3 -5
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +3 -3
- package/pi-extensions/lib/fresh-call-composition.ts +13 -6
- package/pi-extensions/lib/meta-mailbox-body.ts +1 -1
- package/pi-extensions/lib/mux-fresh-call.ts +3 -3
- package/run.sh +163 -50
- package/scripts/check-entwurf-peers-surface.ts +8 -15
- package/scripts/check-entwurf-self-address.ts +7 -11
- package/scripts/check-entwurf-v2-surface.ts +20 -112
- package/scripts/check-fresh-call-dispatch.ts +12 -13
- package/scripts/check-gate-qualification.ts +248 -4
- package/scripts/check-install-surface.ts +3 -2
- package/scripts/check-mux-resume-call.ts +24 -35
- package/scripts/check-pi-bridge-sender.ts +130 -0
- package/scripts/check-pi-mcp-bridge.ts +251 -0
- package/scripts/lib/codex-fresh-live-protocol.ts +17 -5
- package/scripts/lib/codex-fresh-source-receipts.ts +21 -2
- package/scripts/lib/mutation-qualify.ts +269 -44
- package/scripts/lib/pi-mcp-bridge-probe.mjs +170 -0
- package/scripts/meta-bridge-doctor.sh +16 -5
- package/scripts/mutants/acp-foreground-only.json +17 -0
- package/scripts/mutants/codex-native.json +11 -11
- package/scripts/mutants/control-send-receipt.json +6 -4
- package/scripts/mutants/copilot-birth.json +2 -1
- package/scripts/mutants/fresh-call-dispatch.json +3 -14
- package/scripts/mutants/gate-qualification.json +59 -0
- package/scripts/mutants/mux-fresh-call.json +43 -45
- package/scripts/mutants/mux-resume-call.json +11 -35
- package/scripts/mutants/pack-install.json +15 -4
- package/scripts/mutants/pi-bridge-sender.json +54 -0
- package/scripts/mutants/pi-floor.json +6 -2
- package/scripts/mutants/pi-mcp-bridge.json +36 -0
- package/scripts/mutants/pi-mcp-register.json +51 -0
- package/scripts/mutants/v2-surface.json +6 -6
- package/scripts/resident-rpc-drive.ts +5 -1
- package/scripts/smoke-acp-bundled-mcp-live.ts +3 -1
- package/scripts/smoke-acp-cortex-live.ts +3 -1
- package/scripts/smoke-acp-session-reuse-live.ts +29 -12
- package/scripts/smoke-acp-socket-citizen-live.ts +3 -1
- package/scripts/smoke-acp-v2-send-live.ts +3 -1
- package/scripts/smoke-codex-fresh-live.ts +20 -1
- package/scripts/smoke-entwurf-chain-live.ts +6 -2
- package/scripts/smoke-entwurf-v2-matrix-live.ts +3 -1
- package/scripts/smoke-herdr-raw-install-live.sh +1 -1
- package/scripts/smoke-mux-lifecycle-live.ts +1 -1
- package/scripts/smoke-resident-garden-guard.sh +3 -1
|
@@ -393,17 +393,6 @@
|
|
|
393
393
|
"signature": "[QK:FRESHCALL-CODEX-PREMUTATION-MCP]",
|
|
394
394
|
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
395
395
|
},
|
|
396
|
-
{
|
|
397
|
-
"claim": "FRESHCALL-CODEX-PREMUTATION-PI",
|
|
398
|
-
"title": "the native pi public surface relabels a Codex request as pi at the shared dispatcher seam, bypassing the same central preflight from the other public door",
|
|
399
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
400
|
-
"find": ["\t\t\t\t\tbackend: params.backend,"],
|
|
401
|
-
"replace": ["\t\t\t\t\tbackend: \"pi\","],
|
|
402
|
-
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
403
|
-
"timeoutSeconds": 180,
|
|
404
|
-
"signature": "[QK:FRESHCALL-CODEX-PREMUTATION-PI]",
|
|
405
|
-
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
406
|
-
},
|
|
407
396
|
{
|
|
408
397
|
"claim": "CODEX-BIRTH-DOCTOR-REQUIRES-TRUST",
|
|
409
398
|
"title": "the doctor treats the vendor trust receipt as optional, so a declared hook the vendor will never run reports green",
|
|
@@ -648,6 +637,17 @@
|
|
|
648
637
|
"signature": "[QK:CODEX-LIVE-REPORT-TOKEN-EXACT]",
|
|
649
638
|
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
650
639
|
},
|
|
640
|
+
{
|
|
641
|
+
"claim": "CODEX-LIVE-PI-MCP-SOURCE-DIALECT",
|
|
642
|
+
"title": "Pi's current qualified fresh-call receipt no longer reaches semantic launch and cleanup authority, recreating the Pi 1.0 timeout",
|
|
643
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
644
|
+
"find": ["\t[\"mcp__entwurf_bridge__entwurf_fresh_call\", \"entwurf_fresh_call\"],"],
|
|
645
|
+
"replace": ["\t[\"mcp__entwurf_bridge__entwurf_fresh_call\", \"unrecognized_pi_fresh_call\"],"],
|
|
646
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
647
|
+
"timeoutSeconds": 180,
|
|
648
|
+
"signature": "[QK:CODEX-LIVE-PI-MCP-SOURCE-DIALECT]",
|
|
649
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
650
|
+
},
|
|
651
651
|
{
|
|
652
652
|
"claim": "CODEX-LIVE-SOURCE-JOIN",
|
|
653
653
|
"title": "a Pi tool result can be joined to a call whose tool name differs, turning an unrelated result body into launch authority",
|
|
@@ -174,14 +174,15 @@
|
|
|
174
174
|
"gate": ["bash", "run.sh", "check-tests-beside-behavior"],
|
|
175
175
|
"timeoutSeconds": 600,
|
|
176
176
|
"signature": "[QK:VITEST-TEST-DIR-ON-THE-FLOOR]",
|
|
177
|
-
"signatureSource": "run.sh"
|
|
177
|
+
"signatureSource": "run.sh",
|
|
178
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
178
179
|
},
|
|
179
180
|
{
|
|
180
181
|
"claim": "PI-CORE-PIN-TRACKS-FLOOR",
|
|
181
182
|
"title": "the queue oracle's pi-agent-core pin drifts off the floor the rest of the pi runtime is pinned to, so the oracle keeps answering honestly — about a pi nobody in this repo runs",
|
|
182
183
|
"subject": "package.json",
|
|
183
|
-
"find": ["\"@earendil-works/pi-agent-core\": \"0.
|
|
184
|
-
"replace": ["\"@earendil-works/pi-agent-core\": \"0.
|
|
184
|
+
"find": ["\"@earendil-works/pi-agent-core\": \"1.0.0\","],
|
|
185
|
+
"replace": ["\"@earendil-works/pi-agent-core\": \"0.87.1\","],
|
|
185
186
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
186
187
|
"timeoutSeconds": 300,
|
|
187
188
|
"signature": "[QK:PI-CORE-PIN-TRACKS-FLOOR]",
|
|
@@ -218,7 +219,8 @@
|
|
|
218
219
|
"gate": ["bash", "run.sh", "check-tests-beside-behavior"],
|
|
219
220
|
"timeoutSeconds": 600,
|
|
220
221
|
"signature": "[QK:VITEST-TEST-DIR-HAS-COORDINATE]",
|
|
221
|
-
"signatureSource": "run.sh"
|
|
222
|
+
"signatureSource": "run.sh",
|
|
223
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
222
224
|
},
|
|
223
225
|
{
|
|
224
226
|
"claim": "SEND-OUTCOME-LIST-NAMES-EVERY-RAIL",
|
|
@@ -101,7 +101,8 @@
|
|
|
101
101
|
"gate": ["bash", "run.sh", "check-meta-doctor-oracle"],
|
|
102
102
|
"timeoutSeconds": 600,
|
|
103
103
|
"signature": "[QK:HOOK-LOG-RAIL-SCOPED]",
|
|
104
|
-
"signatureSource": "scripts/check-meta-doctor-oracle.sh"
|
|
104
|
+
"signatureSource": "scripts/check-meta-doctor-oracle.sh",
|
|
105
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
105
106
|
},
|
|
106
107
|
{
|
|
107
108
|
"claim": "COPILOT-BIRTH-DOES-NOT-ARM-RECEIVER",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"signatureSource": "scripts/check-fresh-call-dispatch.ts"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
|
-
"claim": "FCD-SURFACE-
|
|
79
|
-
"title": "the
|
|
78
|
+
"claim": "FCD-SURFACE-ROOT-ONLY",
|
|
79
|
+
"title": "the one public fresh-call surface goes back to choosing a rail itself instead of reaching the composition root, so rail choice lives outside the root again",
|
|
80
80
|
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
81
81
|
"find": [
|
|
82
82
|
"\t\t\tconst dispatched = await dispatchFreshCall({\n\t\t\t\tbackend,\n\t\t\t\tmodel,\n\t\t\t\ttask,\n\t\t\t\tcwd,\n\t\t\t\tplacement,\n\t\t\t\tcallerGardenId,\n\t\t\t\tcallerNativeSessionId,\n\t\t\t\tcallerCwd,\n\t\t\t});"
|
|
@@ -86,18 +86,7 @@
|
|
|
86
86
|
],
|
|
87
87
|
"gate": ["bash", "run.sh", "check-fresh-call-dispatch"],
|
|
88
88
|
"timeoutSeconds": 120,
|
|
89
|
-
"signature": "[QK:FCD-SURFACE-
|
|
90
|
-
"signatureSource": "scripts/check-fresh-call-dispatch.ts"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"claim": "FCD-PI-DYNAMIC-IMPORT",
|
|
94
|
-
"title": "pi reaches the composition root by a literal path again, which is how the lazy import fence erodes",
|
|
95
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
96
|
-
"find": ["const FRESH_CALL_DISPATCH_MODULE = \"./lib/fresh-call-dispatch.ts\";"],
|
|
97
|
-
"replace": ["const FRESH_CALL_DISPATCH_MODULE = \"./lib/fresh-call-dispatch-renamed.ts\";"],
|
|
98
|
-
"gate": ["bash", "run.sh", "check-fresh-call-dispatch"],
|
|
99
|
-
"timeoutSeconds": 120,
|
|
100
|
-
"signature": "[QK:FCD-PI-DYNAMIC-IMPORT]",
|
|
89
|
+
"signature": "[QK:FCD-SURFACE-ROOT-ONLY]",
|
|
101
90
|
"signatureSource": "scripts/check-fresh-call-dispatch.ts"
|
|
102
91
|
},
|
|
103
92
|
{
|
|
@@ -23,6 +23,65 @@
|
|
|
23
23
|
"timeoutSeconds": 120,
|
|
24
24
|
"signature": "[QK:LANE-INVENTORY-DECLARED]",
|
|
25
25
|
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"claim": "QUALIFY-BUILD-TRACKS-MUTATION",
|
|
29
|
+
"title": "the runner keeps the baseline build output across a mutation instead of rebuilding it from the mutated bytes — a gate that reads only the compiled output judges source it was never handed, and every mutant planted in the build's source survives (#125: the compiled entwurf-bridge a pi citizen registers)",
|
|
30
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
31
|
+
"find": ["\t\t\t\t\tconst b = await buildOutput(build, outputAbs, m.timeoutSeconds);"],
|
|
32
|
+
"replace": ["\t\t\t\t\tconst b = { run: pre, digest: baseline };"],
|
|
33
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
34
|
+
"timeoutSeconds": 120,
|
|
35
|
+
"signature": "[QK:QUALIFY-BUILD-TRACKS-MUTATION]",
|
|
36
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"claim": "QUALIFY-BUILD-RED-NOT-A-KILL",
|
|
40
|
+
"title": "a mutation that breaks the declared build is attributed like a gate run — the build's own failure output is read for the claim token, so a broken build is certified as the gate killing the defect",
|
|
41
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
42
|
+
"find": [
|
|
43
|
+
"\t\t\t\tsignatureOnFailureLine: !buildRed && signatureAttributedToFailure(run.output, m.signature, run.failedTitles),"
|
|
44
|
+
],
|
|
45
|
+
"replace": [
|
|
46
|
+
"\t\t\t\tsignatureOnFailureLine: signatureAttributedToFailure(run.output, m.signature, run.failedTitles),"
|
|
47
|
+
],
|
|
48
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
49
|
+
"timeoutSeconds": 120,
|
|
50
|
+
"signature": "[QK:QUALIFY-BUILD-RED-NOT-A-KILL]",
|
|
51
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"claim": "QUALIFY-BUILD-SCOPED-TO-GROUP",
|
|
55
|
+
"title": "the declared build output outlives its group — a later group runs against an input it never declared, and the ignored output is left in the snapshot",
|
|
56
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
57
|
+
"find": ["\t\t\tif (outputAbs) fs.rmSync(outputAbs, { recursive: true, force: true });"],
|
|
58
|
+
"replace": ["\t\t\tif (outputAbs) void 0;"],
|
|
59
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
60
|
+
"timeoutSeconds": 120,
|
|
61
|
+
"signature": "[QK:QUALIFY-BUILD-SCOPED-TO-GROUP]",
|
|
62
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"claim": "QUALIFY-BUILD-OUTPUT-GUARDED",
|
|
66
|
+
"title": "a gate that writes into its declared build output keeps its KILLED verdict — the next run is judged against bytes no build produced",
|
|
67
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
68
|
+
"find": ["\t\t\t\t\t\toutputWritten = wroteOutput(b.digest);"],
|
|
69
|
+
"replace": ["\t\t\t\t\t\toutputWritten = false;"],
|
|
70
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
71
|
+
"timeoutSeconds": 120,
|
|
72
|
+
"signature": "[QK:QUALIFY-BUILD-OUTPUT-GUARDED]",
|
|
73
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"claim": "QUALIFY-BUILD-GROUP-CONSISTENT",
|
|
77
|
+
"title": "mutants of one gate may declare different builds (or one none) — the same gate is handed different inputs depending on run order, and a group's control no longer describes all of its mutants",
|
|
78
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
79
|
+
"find": ["\t\tif (mine !== first) {"],
|
|
80
|
+
"replace": ["\t\tif (mine !== first && false) {"],
|
|
81
|
+
"gate": ["bash", "run.sh", "check-gate-manifests"],
|
|
82
|
+
"timeoutSeconds": 120,
|
|
83
|
+
"signature": "[QK:QUALIFY-BUILD-GROUP-CONSISTENT]",
|
|
84
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
26
85
|
}
|
|
27
86
|
]
|
|
28
87
|
}
|
|
@@ -121,8 +121,8 @@
|
|
|
121
121
|
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
|
-
"claim": "FRESHCALL-CWD-SURFACE
|
|
125
|
-
"title": "
|
|
124
|
+
"claim": "FRESHCALL-CWD-SURFACE",
|
|
125
|
+
"title": "the fresh-call surface drops the optional cwd from its schema, so cross-repo fresh silently cannot exist from any caller — pi included, which reaches this bridge since #125",
|
|
126
126
|
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
127
127
|
"find": [
|
|
128
128
|
"\t\tcwd: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional literal ABSOLUTE path of an existing directory to start the sibling in (cross-repo fresh). Omit or pass \\\"\\\" to start where the CALLER is — this agent's own cwd on BOTH rails, or for a Codex caller its own record directory, because this bridge is the app-server's child and that process's directory is not the caller's. Taken exactly as given: no trim, no realpath, no project-name resolution. '#' is refused on the tmux rail only, because tmux format-expands a start directory; inside herdr it is an ordinary path character. The receipt echoes the directory that was REQUESTED or the caller record it came from, never an observation of where the pane landed.\",\n\t\t\t),\n"
|
|
@@ -130,31 +130,7 @@
|
|
|
130
130
|
"replace": [""],
|
|
131
131
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
132
132
|
"timeoutSeconds": 120,
|
|
133
|
-
"signature": "[QK:FRESHCALL-CWD-SURFACE
|
|
134
|
-
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
"claim": "FRESHCALL-PI-SURFACE-IDENTITY",
|
|
138
|
-
"title": "native pi takes the caller garden id from the environment instead of its own resident closure — the uuidv7 confusion, reintroduced",
|
|
139
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
140
|
-
"find": ["\t\t\t\t\tcallerGardenId: residentGardenId,"],
|
|
141
|
-
"replace": ["\t\t\t\t\tcallerGardenId: process.env.PI_SESSION_ID ?? null,"],
|
|
142
|
-
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
143
|
-
"timeoutSeconds": 120,
|
|
144
|
-
"signature": "[QK:FRESHCALL-PI-SURFACE-IDENTITY]",
|
|
145
|
-
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
"claim": "FRESHCALL-PI-MODEL-SCHEMA",
|
|
149
|
-
"title": "native pi drops the required model field from fresh-call while the composition still expects one",
|
|
150
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
151
|
-
"find": [
|
|
152
|
-
"\t\t\tmodel: Type.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tmaxLength: 200,\n\t\t\t\tpattern: \"^[A-Za-z0-9][A-Za-z0-9._/:\\\\[\\\\]-]*$\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"Required runtime model: canonical provider/model for pi, a Claude Code model id/alias, or a Copilot/OMP/Codex model name.\",\n\t\t\t}),\n"
|
|
153
|
-
],
|
|
154
|
-
"replace": [""],
|
|
155
|
-
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
156
|
-
"timeoutSeconds": 120,
|
|
157
|
-
"signature": "[QK:FRESHCALL-PI-MODEL-SCHEMA]",
|
|
133
|
+
"signature": "[QK:FRESHCALL-CWD-SURFACE]",
|
|
158
134
|
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
159
135
|
},
|
|
160
136
|
{
|
|
@@ -196,10 +172,10 @@
|
|
|
196
172
|
},
|
|
197
173
|
{
|
|
198
174
|
"claim": "FRESHCALL-MODEL-PATTERN-PROVIDER-VALID",
|
|
199
|
-
"title": "the
|
|
200
|
-
"subject": "
|
|
201
|
-
"find": ["\t\t\t
|
|
202
|
-
"replace": ["\t\t\t
|
|
175
|
+
"title": "the #62 unescape planted on the bridge's zod pattern rides Pi's built-in MCP spread and pi-ai's real anthropic-messages conversion into the request body as an invalid Rust-family pattern",
|
|
176
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
177
|
+
"find": ["\t\t\t.regex(/^[A-Za-z0-9][A-Za-z0-9._/:\\[\\]-]*$/)"],
|
|
178
|
+
"replace": ["\t\t\t.regex(/^[A-Za-z0-9][A-Za-z0-9._/:[\\]-]*$/)"],
|
|
203
179
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
204
180
|
"timeoutSeconds": 120,
|
|
205
181
|
"signature": "[QK:FRESHCALL-MODEL-PATTERN-PROVIDER-VALID]",
|
|
@@ -284,6 +260,39 @@
|
|
|
284
260
|
"signature": "[QK:FRESHCALL-COPILOT-CALLBACK-TOOL]",
|
|
285
261
|
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
286
262
|
},
|
|
263
|
+
{
|
|
264
|
+
"claim": "FRESHCALL-PI-CALLBACK-DIALECT",
|
|
265
|
+
"title": "pi callback rolls back to the 0.99.1 hyphen spelling, which a 0.99.2 host no longer declares — the first turn is spent on a tool that is not there",
|
|
266
|
+
"subject": "pi-extensions/lib/fresh-call-composition.ts",
|
|
267
|
+
"find": ["\tpi: \"mcp__entwurf_bridge__entwurf_callback\","],
|
|
268
|
+
"replace": ["\tpi: \"mcp__entwurf-bridge__entwurf_callback\","],
|
|
269
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
270
|
+
"timeoutSeconds": 180,
|
|
271
|
+
"signature": "[QK:FRESHCALL-PI-CALLBACK-DIALECT]",
|
|
272
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"claim": "FRESHCALL-PI-DELIVERY-DIALECT",
|
|
276
|
+
"title": "pi delivery rolls back to the 0.99.1 hyphen spelling — the result is sent to a tool a 0.99.2 host does not declare",
|
|
277
|
+
"subject": "pi-extensions/lib/fresh-call-composition.ts",
|
|
278
|
+
"find": ["\tpi: \"mcp__entwurf_bridge__entwurf_v2\","],
|
|
279
|
+
"replace": ["\tpi: \"mcp__entwurf-bridge__entwurf_v2\","],
|
|
280
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
281
|
+
"timeoutSeconds": 180,
|
|
282
|
+
"signature": "[QK:FRESHCALL-PI-DELIVERY-DIALECT]",
|
|
283
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"claim": "FRESHCALL-PI-PEERS-DIALECT",
|
|
287
|
+
"title": "pi peers offer rolls back to the 0.99.1 hyphen spelling — the corroboration tool is named in a spelling the sibling cannot reach",
|
|
288
|
+
"subject": "pi-extensions/lib/fresh-call-composition.ts",
|
|
289
|
+
"find": ["\tpi: \"mcp__entwurf_bridge__entwurf_peers\","],
|
|
290
|
+
"replace": ["\tpi: \"mcp__entwurf-bridge__entwurf_peers\","],
|
|
291
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
292
|
+
"timeoutSeconds": 180,
|
|
293
|
+
"signature": "[QK:FRESHCALL-PI-PEERS-DIALECT]",
|
|
294
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
295
|
+
},
|
|
287
296
|
{
|
|
288
297
|
"claim": "FRESHCALL-COPILOT-PREFLIGHT-PREMUTATION",
|
|
289
298
|
"title": "the capability preflight is removed — a host missing the birth, MCP, receiver or footer unit gets a real window and a launch receipt for a sibling that can never call home",
|
|
@@ -430,17 +439,6 @@
|
|
|
430
439
|
"signature": "[QK:FRESHCALL-COPILOT-EXPLICIT-POLICY]",
|
|
431
440
|
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
432
441
|
},
|
|
433
|
-
{
|
|
434
|
-
"claim": "FRESHCALL-BACKEND-SET-SURFACE-PARITY-PI",
|
|
435
|
-
"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",
|
|
436
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
437
|
-
"find": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\", \"copilot\", \"omp\", \"codex\"], {"],
|
|
438
|
-
"replace": ["\t\t\tbackend: StringEnum([\"pi\", \"claude-code\", \"copilot\", \"omp\"], {"],
|
|
439
|
-
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
440
|
-
"timeoutSeconds": 180,
|
|
441
|
-
"signature": "[QK:FRESHCALL-BACKEND-SET-SURFACE-PARITY-PI]",
|
|
442
|
-
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
443
|
-
},
|
|
444
442
|
{
|
|
445
443
|
"claim": "TMUXSESSION-LOOKUP-ENGINE",
|
|
446
444
|
"title": "the seat lookup goes back to the `-f` filter engine, which was measured to match EVERY session when the name contains a '}' — a fresh sibling then opens in whichever session tmux listed first",
|
|
@@ -510,8 +508,8 @@
|
|
|
510
508
|
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
511
509
|
},
|
|
512
510
|
{
|
|
513
|
-
"claim": "FRESHCALL-PLACEMENT-SURFACE
|
|
514
|
-
"title": "
|
|
511
|
+
"claim": "FRESHCALL-PLACEMENT-SURFACE",
|
|
512
|
+
"title": "the fresh-call surface drops the optional seat from its schema, so opening a sibling in the operator's project session silently cannot exist from any caller",
|
|
515
513
|
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
516
514
|
"find": [
|
|
517
515
|
"\t\tplacement: z\n\t\t\t.object({\n\t\t\t\ttmuxSession: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"EXACT name of an EXISTING session on this agent's own tmux server. Nothing is created: an absent session is refused as tmux-session-missing, and a name outside [A-Za-z0-9][A-Za-z0-9_-]* as tmux-session-name-invalid.\",\n\t\t\t\t\t),\n\t\t\t})\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional expert seat override, TMUX ONLY: open the sibling in ONE EXISTING tmux session of this agent's own server, and it always wins. When omitted the seat follows the CALLER, never the backend being opened: a Codex CALLER opens beside its own TUI pane, matched by thread-id in that pane's terminal title (0 or 2+ matching panes refuse, never fall back); every other caller opens in its own session. A pane title is a placement input only — never an address, liveness or delivery fact. Nothing is ever created. Inside herdr this field is refused by name — placement there belongs to herdr, and a tmux session name would silently place the sibling somewhere else. Independent of cwd; neither is inferred from the other. The receipt reports the selected name (absent for the caller-pane rule, which observed a session rather than requesting a name), its source, and resolved target session id.\",\n\t\t\t),\n"
|
|
@@ -519,7 +517,7 @@
|
|
|
519
517
|
"replace": [""],
|
|
520
518
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
521
519
|
"timeoutSeconds": 180,
|
|
522
|
-
"signature": "[QK:FRESHCALL-PLACEMENT-SURFACE
|
|
520
|
+
"signature": "[QK:FRESHCALL-PLACEMENT-SURFACE]",
|
|
523
521
|
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
524
522
|
},
|
|
525
523
|
{
|
|
@@ -93,55 +93,31 @@
|
|
|
93
93
|
"signatureSource": "scripts/check-mux-resume-call.ts"
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
|
-
"claim": "MUXRESUME-
|
|
97
|
-
"title": "the
|
|
98
|
-
"subject": "
|
|
99
|
-
"find": ["\t\tregisterResumeCallTool(pi);"],
|
|
100
|
-
"replace": ["\t\tvoid registerResumeCallTool;"],
|
|
101
|
-
"gate": ["bash", "run.sh", "check-mux-resume-call"],
|
|
102
|
-
"timeoutSeconds": 60,
|
|
103
|
-
"signature": "[QK:MUXRESUME-PI-SURFACE-REGISTERED]",
|
|
104
|
-
"signatureSource": "scripts/check-mux-resume-call.ts"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"claim": "MUXRESUME-PI-SURFACE-TARGET-ONLY",
|
|
108
|
-
"title": "a task knob is added to the native schema, re-opening the prompt axis a resume deliberately does not have",
|
|
109
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
96
|
+
"claim": "MUXRESUME-DESC-CONTRACT-MCP",
|
|
97
|
+
"title": "the MCP description drops the dormant-only scope, inviting callers to aim the verb at live citizens it will refuse",
|
|
98
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
110
99
|
"find": [
|
|
111
|
-
"\t\
|
|
100
|
+
"\t\"Reopen ONE DORMANT pi citizen under its OWN garden id, in a visible window in the operator's own tmux \""
|
|
112
101
|
],
|
|
113
102
|
"replace": [
|
|
114
|
-
"\t\
|
|
103
|
+
"\t\"Reopen ONE pi citizen under its OWN garden id, in a visible window in the operator's own tmux \""
|
|
115
104
|
],
|
|
116
105
|
"gate": ["bash", "run.sh", "check-mux-resume-call"],
|
|
117
106
|
"timeoutSeconds": 60,
|
|
118
|
-
"signature": "[QK:MUXRESUME-
|
|
119
|
-
"signatureSource": "scripts/check-mux-resume-call.ts"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
"claim": "MUXRESUME-DESC-CONTRACT-PI",
|
|
123
|
-
"title": "the native description stops saying a resume runs no turn, so a caller reasonably expects the citizen to act on being reopened",
|
|
124
|
-
"subject": "pi-extensions/entwurf-control.ts",
|
|
125
|
-
"find": ["This runs NO turn: the window comes\nback with the conversation and waits"],
|
|
126
|
-
"replace": ["The window comes\nback with the conversation and waits"],
|
|
127
|
-
"gate": ["bash", "run.sh", "check-mux-resume-call"],
|
|
128
|
-
"timeoutSeconds": 60,
|
|
129
|
-
"signature": "[QK:MUXRESUME-DESC-CONTRACT-PI]",
|
|
107
|
+
"signature": "[QK:MUXRESUME-DESC-CONTRACT-MCP]",
|
|
130
108
|
"signatureSource": "scripts/check-mux-resume-call.ts"
|
|
131
109
|
},
|
|
132
110
|
{
|
|
133
|
-
"claim": "MUXRESUME-
|
|
134
|
-
"title": "the
|
|
111
|
+
"claim": "MUXRESUME-MCP-TARGET-PASSTHROUGH",
|
|
112
|
+
"title": "the bridge resume handler substitutes a constant id for the caller's target, so the record lookup reopens a citizen nobody named while the target-only schema stays green",
|
|
135
113
|
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
136
|
-
"find": [
|
|
137
|
-
"\t\"Reopen ONE DORMANT pi citizen under its OWN garden id, in a visible window in the operator's own tmux \""
|
|
138
|
-
],
|
|
114
|
+
"find": ["\t\t\tconst result = await visibleResume(target, makeVisibleResumeDeps(visibleResumeLaunch));"],
|
|
139
115
|
"replace": [
|
|
140
|
-
"\t\
|
|
116
|
+
"\t\t\tconst result = await visibleResume(\"20260101T000000-feed00\", makeVisibleResumeDeps(visibleResumeLaunch));"
|
|
141
117
|
],
|
|
142
118
|
"gate": ["bash", "run.sh", "check-mux-resume-call"],
|
|
143
119
|
"timeoutSeconds": 60,
|
|
144
|
-
"signature": "[QK:MUXRESUME-
|
|
120
|
+
"signature": "[QK:MUXRESUME-MCP-TARGET-PASSTHROUGH]",
|
|
145
121
|
"signatureSource": "scripts/check-mux-resume-call.ts"
|
|
146
122
|
}
|
|
147
123
|
]
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"claim": "PACK-INSTALL-PIN-MATCHER-BOUNDED",
|
|
7
7
|
"title": "the pin-leak matcher loses its version boundary and blesses substring lookalikes — @0.85.10 reads as the pinned 0.85.1 and the gate announces a verified tree it never verified (independent review, 2026-08-25)",
|
|
8
8
|
"subject": "run.sh",
|
|
9
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@0\\.
|
|
10
|
-
"replace": [" grep '^@earendil-works+' | grep -v '@0\\.87\\.
|
|
9
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.0\\.0(_|$)' || true"],
|
|
10
|
+
"replace": [" grep '^@earendil-works+' | grep -v '@0\\.87\\.1' || true"],
|
|
11
11
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
12
12
|
"timeoutSeconds": 120,
|
|
13
13
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED]",
|
|
@@ -17,12 +17,23 @@
|
|
|
17
17
|
"claim": "PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE",
|
|
18
18
|
"title": "the pin-leak matcher narrows back to the pi-* families and goes blind to a non-pi member of the same runtime closure — @earendil-works/chord (new in pi 0.85.0, a runtime dependency of pi-coding-agent/pi-agent-core/pi-client/pi-protocol) floats unpinned while the gate prints a verified pin (measured 2026-09-06 on a real 0.85.1 install tree)",
|
|
19
19
|
"subject": "run.sh",
|
|
20
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@0\\.
|
|
21
|
-
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@0\\.
|
|
20
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.0\\.0(_|$)' || true"],
|
|
21
|
+
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.0\\.0(_|$)' || true"],
|
|
22
22
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
23
23
|
"timeoutSeconds": 120,
|
|
24
24
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE]",
|
|
25
25
|
"signatureSource": "run.sh"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"claim": "PACK-INSTALL-CONSUMER-ROOTS-CONTAINED",
|
|
29
|
+
"title": "a consumer subcall stops naming its own PI_CODING_AGENT_DIR, so an inherited agent dir wins over the sandbox HOME and the consumer's user-scope registration lands outside it (measured 2026-10-01, #125)",
|
|
30
|
+
"subject": "run.sh",
|
|
31
|
+
"find": [" \"XDG_CACHE_HOME=$h/.cache\" \\\n \"PI_CODING_AGENT_DIR=$h/.pi/agent\""],
|
|
32
|
+
"replace": [" \"XDG_CACHE_HOME=$h/.cache\""],
|
|
33
|
+
"gate": ["bash", "run.sh", "check-pack-consumer-roots"],
|
|
34
|
+
"timeoutSeconds": 120,
|
|
35
|
+
"signature": "[QK:PACK-INSTALL-CONSUMER-ROOTS-CONTAINED]",
|
|
36
|
+
"signatureSource": "run.sh"
|
|
26
37
|
}
|
|
27
38
|
]
|
|
28
39
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "pi-bridge-sender",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "PI-BRIDGE-SENDER-RECORD-BACKED",
|
|
7
|
+
"title": "the backing check starts treating a missing control socket as inadmissible, so a dormant pi citizen loses its own identity instead of answering replyable:false",
|
|
8
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
9
|
+
"find": ["\tif (identity.backend !== \"pi\") {"],
|
|
10
|
+
"replace": [
|
|
11
|
+
"\tif (identity.backend !== \"pi\" || !existsSync(controlSocketPathIn(ENTWURF_DIR, envelope.sessionId))) {"
|
|
12
|
+
],
|
|
13
|
+
"gate": ["bash", "run.sh", "check-pi-bridge-sender"],
|
|
14
|
+
"timeoutSeconds": 60,
|
|
15
|
+
"signature": "[QK:PI-BRIDGE-SENDER-RECORD-BACKED]",
|
|
16
|
+
"signatureSource": "scripts/check-pi-bridge-sender.ts"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"claim": "PI-BRIDGE-SENDER-MISSING-REFUSED",
|
|
20
|
+
"title": "the pi branch returns the raw carrier again, so any well-formed PI_SESSION_ID is served as a sender whether or not a record exists",
|
|
21
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
22
|
+
"find": ["\tif (pi && pi.sessionId === selected.id) return { envelope: requirePiSenderRecord(pi) };"],
|
|
23
|
+
"replace": ["\tif (pi && pi.sessionId === selected.id) return { envelope: pi };"],
|
|
24
|
+
"gate": ["bash", "run.sh", "check-pi-bridge-sender"],
|
|
25
|
+
"timeoutSeconds": 60,
|
|
26
|
+
"signature": "[QK:PI-BRIDGE-SENDER-MISSING-REFUSED]",
|
|
27
|
+
"signatureSource": "scripts/check-pi-bridge-sender.ts"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"claim": "PI-BRIDGE-SENDER-BACKEND-REFUSED",
|
|
31
|
+
"title": "the backend check is dropped, so a PI_SESSION_ID naming another harness's record is served as a pi sender",
|
|
32
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
33
|
+
"find": ["\tif (identity.backend !== \"pi\") {"],
|
|
34
|
+
"replace": ["\tif (identity.backend === undefined) {"],
|
|
35
|
+
"gate": ["bash", "run.sh", "check-pi-bridge-sender"],
|
|
36
|
+
"timeoutSeconds": 60,
|
|
37
|
+
"signature": "[QK:PI-BRIDGE-SENDER-BACKEND-REFUSED]",
|
|
38
|
+
"signatureSource": "scripts/check-pi-bridge-sender.ts"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"claim": "PI-BRIDGE-SENDER-UNREADABLE-CAUSE",
|
|
42
|
+
"title": "reader failures are flattened into the absent-record refusal, so a corrupt store reads as a citizen that simply does not exist",
|
|
43
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
44
|
+
"find": ["\tconst identity = readMetaIdentityByGardenId(envelope.sessionId);"],
|
|
45
|
+
"replace": [
|
|
46
|
+
"\tconst identity = (() => {\n\t\ttry {\n\t\t\treturn readMetaIdentityByGardenId(envelope.sessionId);\n\t\t} catch {\n\t\t\tthrow new Error(`no meta-record for garden id \"${envelope.sessionId}\"`);\n\t\t}\n\t})();"
|
|
47
|
+
],
|
|
48
|
+
"gate": ["bash", "run.sh", "check-pi-bridge-sender"],
|
|
49
|
+
"timeoutSeconds": 60,
|
|
50
|
+
"signature": "[QK:PI-BRIDGE-SENDER-UNREADABLE-CAUSE]",
|
|
51
|
+
"signatureSource": "scripts/check-pi-bridge-sender.ts"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
"claim": "PI-FLOOR-SINGLE-SOURCE",
|
|
7
7
|
"title": "one row of the pnpm workspace closure is left on the previous floor while every other surface moved — the shape a version bump actually fails in. Nothing else reads that file, so the stranded row surfaces only at install time, in a different command, far from the change that stranded it",
|
|
8
8
|
"subject": "pnpm-workspace.yaml",
|
|
9
|
-
"find": [
|
|
10
|
-
|
|
9
|
+
"find": [
|
|
10
|
+
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2 || 1.0.0'"
|
|
11
|
+
],
|
|
12
|
+
"replace": [
|
|
13
|
+
" - '@earendil-works/pi-telemetry@0.85.0 || 0.85.1 || 0.86.0 || 0.87.0 || 0.87.1 || 0.99.1 || 0.99.2'"
|
|
14
|
+
],
|
|
11
15
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
12
16
|
"timeoutSeconds": 300,
|
|
13
17
|
"signature": "[QK:PI-FLOOR-SINGLE-SOURCE]",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "pi-mcp-bridge",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "PI-MCP-BRIDGE-DECLARED-SURFACE",
|
|
7
|
+
"title": "entwurf_self joins the hidden list, so a pi model is no longer declared the verb that tells it who it is",
|
|
8
|
+
"subject": "pi-extensions/lib/entwurf-mcp-server.ts",
|
|
9
|
+
"find": [
|
|
10
|
+
"export const ENTWURF_MCP_HIDDEN_TOOLS = [\"entwurf_inbox_read\", \"entwurf_register_native\"] as const;"
|
|
11
|
+
],
|
|
12
|
+
"replace": [
|
|
13
|
+
"export const ENTWURF_MCP_HIDDEN_TOOLS = [\"entwurf_inbox_read\", \"entwurf_register_native\", \"entwurf_self\"] as const;"
|
|
14
|
+
],
|
|
15
|
+
"gate": ["bash", "run.sh", "check-pi-mcp-bridge"],
|
|
16
|
+
"timeoutSeconds": 120,
|
|
17
|
+
"signature": "[QK:PI-MCP-BRIDGE-DECLARED-SURFACE]",
|
|
18
|
+
"signatureSource": "scripts/check-pi-mcp-bridge.ts",
|
|
19
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"claim": "PI-MCP-BRIDGE-SAME-CHILD-IDENTITY",
|
|
23
|
+
"title": "the explicit carrier is built from the model label when one is known, so the spawned child claims an identity no record holds",
|
|
24
|
+
"subject": "pi-extensions/lib/entwurf-mcp-server.ts",
|
|
25
|
+
"find": ["\t\tenv: { PI_SESSION_ID: input.gardenId, ...(input.agentId ? { PI_AGENT_ID: input.agentId } : {}) },"],
|
|
26
|
+
"replace": [
|
|
27
|
+
"\t\tenv: { PI_SESSION_ID: input.agentId ?? input.gardenId, ...(input.agentId ? { PI_AGENT_ID: input.agentId } : {}) },"
|
|
28
|
+
],
|
|
29
|
+
"gate": ["bash", "run.sh", "check-pi-mcp-bridge"],
|
|
30
|
+
"timeoutSeconds": 120,
|
|
31
|
+
"signature": "[QK:PI-MCP-BRIDGE-SAME-CHILD-IDENTITY]",
|
|
32
|
+
"signatureSource": "scripts/check-pi-mcp-bridge.ts",
|
|
33
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "pi-mcp-register",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "PI-MCP-REGISTER-AFTER-BIRTH",
|
|
7
|
+
"title": "the extension factory registers the bridge at load, before any record exists — the server is on Pi's registry with no born identity to carry",
|
|
8
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
9
|
+
"find": ["\tpi.registerMessageRenderer(SESSION_MESSAGE_TYPE, renderSessionMessage);"],
|
|
10
|
+
"replace": [
|
|
11
|
+
"\tpi.registerMessageRenderer(SESSION_MESSAGE_TYPE, renderSessionMessage);",
|
|
12
|
+
"\tpi.registerMcpServer(ENTWURF_MCP_SERVER_NAME, { command: process.execPath, args: [] });"
|
|
13
|
+
],
|
|
14
|
+
"gate": ["bash", "run.sh", "check-pi-mcp-register"],
|
|
15
|
+
"timeoutSeconds": 60,
|
|
16
|
+
"signature": "[QK:PI-MCP-REGISTER-AFTER-BIRTH]",
|
|
17
|
+
"signatureSource": "pi-extensions/entwurf-control.test.ts",
|
|
18
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"claim": "PI-MCP-IDENTITY-BEFORE-UI",
|
|
22
|
+
"title": "the status line is rendered before the registration, so a UI failure leaves a born citizen without its verbs",
|
|
23
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
24
|
+
"find": [
|
|
25
|
+
"\t\tregisterEntwurfMcpServer(pi, ctx, birth.gardenId);",
|
|
26
|
+
"\t\tupdateStatus(ctx, true, birth.gardenId);"
|
|
27
|
+
],
|
|
28
|
+
"replace": [
|
|
29
|
+
"\t\tupdateStatus(ctx, true, birth.gardenId);",
|
|
30
|
+
"\t\tregisterEntwurfMcpServer(pi, ctx, birth.gardenId);"
|
|
31
|
+
],
|
|
32
|
+
"gate": ["bash", "run.sh", "check-pi-mcp-register"],
|
|
33
|
+
"timeoutSeconds": 60,
|
|
34
|
+
"signature": "[QK:PI-MCP-IDENTITY-BEFORE-UI]",
|
|
35
|
+
"signatureSource": "pi-extensions/entwurf-control.test.ts",
|
|
36
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"claim": "PI-MCP-EXPOSURE",
|
|
40
|
+
"title": "the verbs are registered behind codemode instead of declared directly, so the model is handed a different surface than every other host",
|
|
41
|
+
"subject": "pi-extensions/lib/entwurf-mcp-server.ts",
|
|
42
|
+
"find": ["\t\texposure: \"direct\","],
|
|
43
|
+
"replace": ["\t\texposure: \"codemode\","],
|
|
44
|
+
"gate": ["bash", "run.sh", "check-pi-mcp-register"],
|
|
45
|
+
"timeoutSeconds": 60,
|
|
46
|
+
"signature": "[QK:PI-MCP-EXPOSURE]",
|
|
47
|
+
"signatureSource": "pi-extensions/entwurf-control.test.ts",
|
|
48
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
@@ -39,20 +39,20 @@
|
|
|
39
39
|
"signatureSource": "scripts/check-entwurf-v2-production.ts"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
"claim": "V2SURF-
|
|
43
|
-
"title": "
|
|
44
|
-
"subject": "
|
|
42
|
+
"claim": "V2SURF-MODE-SCOPE",
|
|
43
|
+
"title": "the bridge mode param (the one every caller reads, pi included since #125) reverts to \"Delivery mode for a live send\" (false for native-push) (#120 P2: the description was rewritten to stop claiming an interrupt, so the mutation now strips the rail scope from the corrected sentence)",
|
|
44
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
45
45
|
"find": [
|
|
46
|
-
"\t\t\t\t\
|
|
46
|
+
"\t\t\t\t\"Injection style for a CONTROL-SOCKET send only: steer (ask the receiver's steering queue) or follow_up (ask its follow-up queue). NEITHER is an interrupt: a busy receiver drains steering after each turn and follow-ups only when its inner loop ends, so a later steer overtakes every earlier follow_up and there is no order between the two. Both queues are volatile process memory — an abort drops what is in them. The receipt names which queue accepted the message (`queued-steer` / `queued-follow-up`); an idle receiver answers `sent`, meaning the turn was TRIGGERED, not that the model has seen the text. \" +",
|
|
47
47
|
"\t\t\t\t\t\"The mailbox and native-push plans carry no mode, so it has no effect on those rails.\","
|
|
48
48
|
],
|
|
49
49
|
"replace": [
|
|
50
|
-
"\t\t\t\t\
|
|
50
|
+
"\t\t\t\t\"Delivery mode for a live send: steer (ask the steering queue) or follow_up (ask the follow-up queue). \" +",
|
|
51
51
|
"\t\t\t\t\t\"Both queues are volatile process memory.\","
|
|
52
52
|
],
|
|
53
53
|
"gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
|
|
54
54
|
"timeoutSeconds": 60,
|
|
55
|
-
"signature": "[QK:V2SURF-
|
|
55
|
+
"signature": "[QK:V2SURF-MODE-SCOPE]",
|
|
56
56
|
"signatureSource": "scripts/check-entwurf-v2-surface.ts"
|
|
57
57
|
},
|
|
58
58
|
{
|