@junghanacs/entwurf 0.30.1 → 0.32.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 +4 -2
- package/CHANGELOG.md +194 -0
- package/DELIVERY.md +1 -0
- package/README.md +64 -14
- package/VERIFY.md +36 -1
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/setup-clean-host.md +121 -4
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +7 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-deliverability.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +34 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +28 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +28 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +92 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +236 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +746 -0
- package/mcp/entwurf-bridge/src/index.ts +7 -7
- package/mcp/entwurf-bridge/tsconfig.build.json +8 -1
- package/package.json +19 -19
- package/pi/entwurf-capabilities.json +1 -0
- package/pi/pi-durable/bootstrap.mjs +404 -0
- package/pi/pi-durable/carrier/LICENSE +21 -0
- package/pi/pi-durable/carrier/harness-setup.js +123 -0
- package/pi/pi-durable/carrier/prompt.js +74 -0
- package/pi/pi-durable/carrier/runtime.js +402 -0
- package/pi/pi-durable/carrier/sessions.js +56 -0
- package/pi/pi-durable/carrier/subagent.js +55 -0
- package/pi/pi-durable/carrier/tui.js +655 -0
- package/pi/pi-durable/carrier-relocation.mjs +160 -0
- package/pi/pi-durable/carrier-resolver.mjs +38 -0
- package/pi/pi-durable/overlay/runtime-contacts.patch +91 -0
- package/pi/pi-durable/overlay/upstream-pin.json +108 -0
- package/pi-extensions/lib/entwurf-deliverability.ts +7 -1
- package/pi-extensions/lib/fresh-call-composition.ts +42 -7
- package/pi-extensions/lib/meta-sender-identity.ts +7 -1
- package/pi-extensions/lib/meta-session.ts +28 -2
- package/pi-extensions/lib/mux-fresh-call.ts +32 -2
- package/pi-extensions/lib/pi-durable-fresh-preflight.ts +113 -0
- package/pi-extensions/lib/pi-durable-runtime.ts +318 -0
- package/pi-extensions/meta-bridge-pi-durable.ts +1024 -0
- package/run.sh +624 -184
- package/scripts/check-entwurf-bridge-pi-free.ts +7 -5
- package/scripts/check-fresh-call-dispatch.ts +18 -0
- package/scripts/check-gate-qualification.ts +87 -34
- package/scripts/check-herdr-activation.ts +5 -4
- package/scripts/check-pi-durable-contact.ts +767 -0
- package/scripts/check-pi-durable-receive.ts +1079 -0
- package/scripts/check-pi-durable-send.ts +1821 -0
- package/scripts/emit-pi-durable-carrier.ts +355 -0
- package/scripts/lib/mutation-qualify.ts +21 -45
- package/scripts/lib/pi-durable-fresh-live-receipts.ts +139 -0
- package/scripts/lib/pi-durable-operator-guard.ts +89 -0
- package/scripts/lib/pi-durable-r1.ts +100 -0
- package/scripts/lib/pi-durable-reap.ts +27 -0
- package/scripts/lib/pi-durable-receive.ts +137 -0
- package/scripts/lib/qualification-receipt.ts +7 -11
- package/scripts/mutants/control-send-receipt.json +1 -1
- package/scripts/mutants/copilot-birth.json +2 -2
- package/scripts/mutants/gate-qualification.json +13 -0
- package/scripts/mutants/meta-hook-session-switch.json +4 -2
- package/scripts/mutants/mux-fresh-call.json +69 -3
- package/scripts/mutants/omp-birth.json +2 -2
- package/scripts/mutants/omp-fresh.json +6 -4
- package/scripts/mutants/pack-install.json +3 -3
- package/scripts/mutants/pi-durable.json +723 -0
- package/scripts/mutants/pi-floor.json +24 -2
- package/scripts/pi-durable-contact-host.mjs +105 -0
- package/scripts/pi-durable-receive-host.mjs +127 -0
- package/scripts/pi-durable-send-host.mjs +284 -0
- package/scripts/smoke-herdr-raw-install-live.sh +1 -1
- package/scripts/smoke-pi-durable-fresh-live.ts +624 -0
- package/scripts/smoke-setup-verdict.sh +22 -3
- package/scripts/smoke-user-scope-citizen.sh +1 -1
- package/scripts/tsconfig.json +1 -0
|
@@ -0,0 +1,723 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "pi-durable",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "PI-DURABLE-ENTRY-GUARD-FLOOR-SAFE",
|
|
7
|
+
"title": "the verifier's entry guard goes back to import.meta.main, which the floor's runner can misread as the process entry",
|
|
8
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
9
|
+
"find": ["if (invokedDirectly) {\n"],
|
|
10
|
+
"replace": ["if (import.meta.main) {\n"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
12
|
+
"timeoutSeconds": 300,
|
|
13
|
+
"signature": "[QK:PI-DURABLE-ENTRY-GUARD-FLOOR-SAFE]",
|
|
14
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
15
|
+
"build": {
|
|
16
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
17
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"claim": "PI-DURABLE-PREFLIGHT-FOUR-UNITS",
|
|
22
|
+
"title": "the receive unit stops asking whether the compiled owner join admits the durable host, so a launch proceeds to a citizen nobody can deliver to",
|
|
23
|
+
"subject": "pi-extensions/lib/pi-durable-fresh-preflight.ts",
|
|
24
|
+
"find": [
|
|
25
|
+
"\tif (!ownerJoinAdmitsDurableHost(layout.deliverability)) return \"pi-durable-receive-unit-missing\";\n"
|
|
26
|
+
],
|
|
27
|
+
"replace": [""],
|
|
28
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
29
|
+
"timeoutSeconds": 300,
|
|
30
|
+
"signature": "[QK:PI-DURABLE-PREFLIGHT-FOUR-UNITS]",
|
|
31
|
+
"signatureSource": "pi-extensions/lib/pi-durable-fresh-preflight.test.ts",
|
|
32
|
+
"build": {
|
|
33
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
34
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"claim": "PI-DURABLE-PREFLIGHT-MODEL-QUALIFIED",
|
|
39
|
+
"title": "a model without a provider part passes the preflight and reaches the durable launch",
|
|
40
|
+
"subject": "pi-extensions/lib/pi-durable-fresh-preflight.ts",
|
|
41
|
+
"find": ["\tif (at <= 0 || at === model.length - 1) return null;"],
|
|
42
|
+
"replace": ["\tif (at < 0 || at === model.length - 1) return null;"],
|
|
43
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
44
|
+
"timeoutSeconds": 300,
|
|
45
|
+
"signature": "[QK:PI-DURABLE-PREFLIGHT-MODEL-QUALIFIED]",
|
|
46
|
+
"signatureSource": "pi-extensions/lib/pi-durable-fresh-preflight.test.ts",
|
|
47
|
+
"build": {
|
|
48
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
49
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"claim": "PI-DURABLE-BOOTSTRAP-ARGV-NO-BRIDGE-ENTRY",
|
|
54
|
+
"title": "the launch argv accepts --bridge-entry, so a caller can point the contact at a bridge outside this package",
|
|
55
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
56
|
+
"find": [
|
|
57
|
+
"const VALUE_FLAGS = [\"--provider\", \"--model\", \"--width\", \"--entwurf-bootstrap\", \"--native-module\"];"
|
|
58
|
+
],
|
|
59
|
+
"replace": [
|
|
60
|
+
"const VALUE_FLAGS = [\"--bridge-entry\", \"--provider\", \"--model\", \"--width\", \"--entwurf-bootstrap\", \"--native-module\"];"
|
|
61
|
+
],
|
|
62
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
63
|
+
"timeoutSeconds": 300,
|
|
64
|
+
"signature": "[QK:PI-DURABLE-BOOTSTRAP-ARGV-NO-BRIDGE-ENTRY]",
|
|
65
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
66
|
+
"build": {
|
|
67
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
68
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"claim": "PI-DURABLE-FRESH-CALL-EXPOSED",
|
|
73
|
+
"title": "entwurf_fresh_call drops out of the durable contact's tools, so the citizen cannot open a sibling",
|
|
74
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
75
|
+
"find": ["\t\ttools: PI_DURABLE_TOOL_NAMES.map(tool),"],
|
|
76
|
+
"replace": ["\t\ttools: PI_DURABLE_TOOL_NAMES.filter((name) => name !== \"entwurf_fresh_call\").map(tool),"],
|
|
77
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
78
|
+
"timeoutSeconds": 300,
|
|
79
|
+
"signature": "[QK:PI-DURABLE-FRESH-CALL-EXPOSED]",
|
|
80
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
81
|
+
"build": {
|
|
82
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
83
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"claim": "PI-DURABLE-BRIDGE-DIRECT-SCRUBBED",
|
|
88
|
+
"title": "the identity scrub is omitted, so inherited identity carriers reach the bridge child",
|
|
89
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
90
|
+
"find": ["\t\tif (value !== undefined && !scrubbed.has(key)) env[key] = value;\n"],
|
|
91
|
+
"replace": ["\t\tif (value !== undefined) env[key] = value;\n"],
|
|
92
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
93
|
+
"timeoutSeconds": 300,
|
|
94
|
+
"signature": "[QK:PI-DURABLE-BRIDGE-DIRECT-SCRUBBED]",
|
|
95
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
96
|
+
"build": {
|
|
97
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
98
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"claim": "PI-DURABLE-CHILD-ROOTS-ARE-WRITTEN-ROOTS",
|
|
103
|
+
"title": "the root binding is omitted, so the bridge child reads whatever garden roots it inherited instead of the roots the contact wrote",
|
|
104
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
105
|
+
"find": [
|
|
106
|
+
"\tfor (const key of Object.keys(PI_DURABLE_BRIDGE_ROOT_ENV) as (keyof PiDurableRoots)[]) {\n\t\tenv[PI_DURABLE_BRIDGE_ROOT_ENV[key]] = roots[key];\n\t}\n"
|
|
107
|
+
],
|
|
108
|
+
"replace": [""],
|
|
109
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
110
|
+
"timeoutSeconds": 300,
|
|
111
|
+
"signature": "[QK:PI-DURABLE-CHILD-ROOTS-ARE-WRITTEN-ROOTS]",
|
|
112
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
113
|
+
"build": {
|
|
114
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
115
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"claim": "PDH-JOIN-FOREIGN-SENDER-REFUSED",
|
|
120
|
+
"title": "the durable host leaves the sender join, so a live durable receiver whose owner sender marker names another garden is no longer refused (ABSENT-SENDER and SCOPE also go red)",
|
|
121
|
+
"subject": "pi-extensions/lib/entwurf-deliverability.ts",
|
|
122
|
+
"find": [
|
|
123
|
+
"export const SENDER_JOINED_RECEIVER_OWNER_KINDS: readonly string[] = [\"claude-code-cli\", \"pi-durable-host\"];"
|
|
124
|
+
],
|
|
125
|
+
"replace": ["export const SENDER_JOINED_RECEIVER_OWNER_KINDS: readonly string[] = [\"claude-code-cli\"];"],
|
|
126
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
127
|
+
"timeoutSeconds": 300,
|
|
128
|
+
"signature": "[QK:PDH-JOIN-FOREIGN-SENDER-REFUSED]",
|
|
129
|
+
"signatureSource": "pi-extensions/lib/entwurf-deliverability.owner-join.test.ts",
|
|
130
|
+
"build": {
|
|
131
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
132
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"claim": "PI-DURABLE-SCHEMA-DRIFT-REFUSED",
|
|
137
|
+
"title": "schema drift is never reported, so a bridge whose tool schemas differ from the exposed copies is accepted at birth",
|
|
138
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
139
|
+
"find": ["\treturn problems.length === 0 ? undefined : problems.join(\"; \");"],
|
|
140
|
+
"replace": ["\treturn undefined;"],
|
|
141
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
142
|
+
"timeoutSeconds": 300,
|
|
143
|
+
"signature": "[QK:PI-DURABLE-SCHEMA-DRIFT-REFUSED]",
|
|
144
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
145
|
+
"build": {
|
|
146
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
147
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"claim": "PI-DURABLE-RECEIVER-REFUSES-UNVERIFIED-IDENTITY",
|
|
152
|
+
"title": "the receiver arms against any live sender marker, even one naming another garden or session",
|
|
153
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
154
|
+
"find": [
|
|
155
|
+
"\t\t\tif (sender === null || sender.gardenId !== gardenId || sender.nativeSessionId !== nativeSessionId) {"
|
|
156
|
+
],
|
|
157
|
+
"replace": [
|
|
158
|
+
"\t\t\tif (sender === null || (sender.gardenId !== gardenId && sender.nativeSessionId !== nativeSessionId)) {"
|
|
159
|
+
],
|
|
160
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
161
|
+
"timeoutSeconds": 300,
|
|
162
|
+
"signature": "[QK:PI-DURABLE-RECEIVER-REFUSES-UNVERIFIED-IDENTITY]",
|
|
163
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
164
|
+
"build": {
|
|
165
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
166
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"claim": "PI-DURABLE-ONE-BIRTH",
|
|
171
|
+
"title": "a born contact can attach again, minting a second birth on the same contact",
|
|
172
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
173
|
+
"find": [
|
|
174
|
+
"\t\t\tif (state.kind !== \"pending\") {\n\t\t\t\tthrow new Error(`pi-durable contact: attach is a one-time birth"
|
|
175
|
+
],
|
|
176
|
+
"replace": [
|
|
177
|
+
"\t\t\tif (state.kind === \"attaching\") {\n\t\t\t\tthrow new Error(`pi-durable contact: attach is a one-time birth"
|
|
178
|
+
],
|
|
179
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
180
|
+
"timeoutSeconds": 300,
|
|
181
|
+
"signature": "[QK:PI-DURABLE-ONE-BIRTH]",
|
|
182
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
183
|
+
"build": {
|
|
184
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
185
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"claim": "PI-DURABLE-FIRST-INPUT-ONCE",
|
|
190
|
+
"title": "the launcher's first input loses its fixed request id, so a reopen can admit the same task again",
|
|
191
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
192
|
+
"find": ["\t\t\t\trequestId: `entwurf-first-input:${attachment.gardenId}`,\n"],
|
|
193
|
+
"replace": [""],
|
|
194
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
195
|
+
"timeoutSeconds": 300,
|
|
196
|
+
"signature": "[QK:PI-DURABLE-FIRST-INPUT-ONCE]",
|
|
197
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
198
|
+
"build": {
|
|
199
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
200
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"claim": "PI-DURABLE-GATE-SEND-OWNS-QUALIFIED-START",
|
|
205
|
+
"title": "the send gate registers a bridge under a fresh start read instead of the start that qualified it, so a pid recycled after qualification is owned and signalled",
|
|
206
|
+
"subject": "scripts/check-pi-durable-send.ts",
|
|
207
|
+
"find": ["own(child.pid, \"bridge\", child.start)"],
|
|
208
|
+
"replace": ["own(child.pid, \"bridge\")"],
|
|
209
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
210
|
+
"timeoutSeconds": 300,
|
|
211
|
+
"signature": "[QK:PI-DURABLE-GATE-SEND-OWNS-QUALIFIED-START]",
|
|
212
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
213
|
+
"build": {
|
|
214
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
215
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"claim": "PI-DURABLE-GATE-SEND-OBSERVED-BY-IDENTITY",
|
|
220
|
+
"title": "the send gate looks complete observation up by pid, so a host whose pid was reused inherits its predecessor's observed children",
|
|
221
|
+
"subject": "scripts/check-pi-durable-send.ts",
|
|
222
|
+
"find": ["childrenObserved.has(host)"],
|
|
223
|
+
"replace": ["[...childrenObserved].some((h) => h.pid === host.pid)"],
|
|
224
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
225
|
+
"timeoutSeconds": 300,
|
|
226
|
+
"signature": "[QK:PI-DURABLE-GATE-SEND-OBSERVED-BY-IDENTITY]",
|
|
227
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
228
|
+
"build": {
|
|
229
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
230
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"claim": "PI-DURABLE-GATE-SEND-S3-START-RECHECKED",
|
|
235
|
+
"title": "the send gate's SIGKILL of the paused bridge loses its start-key re-check, so a process that replaced it after the IO and state reads is killed",
|
|
236
|
+
"subject": "scripts/check-pi-durable-send.ts",
|
|
237
|
+
"find": [
|
|
238
|
+
"\tif (procStat(bridge1.pid)?.start !== bridge1.start)\n\t\tthrow new Error(`GAP: bridge1 ${bridge1.pid} is not the observed process immediately before its SIGKILL`);\n"
|
|
239
|
+
],
|
|
240
|
+
"replace": [""],
|
|
241
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
242
|
+
"timeoutSeconds": 300,
|
|
243
|
+
"signature": "[QK:PI-DURABLE-GATE-SEND-S3-START-RECHECKED]",
|
|
244
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
245
|
+
"build": {
|
|
246
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
247
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"claim": "PI-DURABLE-GATE-RECEIVE-CONNECT-CLOSES",
|
|
252
|
+
"title": "the receive gate's failed connect no longer closes the transport, so a bridge spawned inside connect is left neither owned nor closed",
|
|
253
|
+
"subject": "scripts/check-pi-durable-receive.ts",
|
|
254
|
+
"find": [
|
|
255
|
+
"\ttry {\n\t\tawait client.connect(transport);\n\t} catch (error) {\n\t\t// A failed connect may already have spawned the bridge, which is not owned yet: close the\n\t\t// transport (it ends the child it spawned) before rethrowing, and keep the cause first.\n\t\ttry {\n\t\t\tawait transport.close();\n\t\t} catch (closeError) {\n\t\t\tthrow new AggregateError(\n\t\t\t\t[error, closeError],\n\t\t\t\t`the sending bridge did not connect (${(error as Error).message}); closing it also failed`,\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n"
|
|
256
|
+
],
|
|
257
|
+
"replace": ["\tawait client.connect(transport);\n"],
|
|
258
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
259
|
+
"timeoutSeconds": 300,
|
|
260
|
+
"signature": "[QK:PI-DURABLE-GATE-RECEIVE-CONNECT-CLOSES]",
|
|
261
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
262
|
+
"build": {
|
|
263
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
264
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"claim": "PI-DURABLE-RECEIVER-DIAGNOSTIC-LATEST-ONLY",
|
|
269
|
+
"title": "the receiver diagnostic appends every successful admission instead of keeping the latest one, so it grows with the host's lifetime (RING-COALESCES, whose two-pass expectation is latest-only, also goes red)",
|
|
270
|
+
"subject": "pi-extensions/meta-bridge-pi-durable.ts",
|
|
271
|
+
"find": [
|
|
272
|
+
"\t\t\t\tadmissions.splice(0, admissions.length, { why, requestId, submissionId: submission.id, fresh, unread });"
|
|
273
|
+
],
|
|
274
|
+
"replace": ["\t\t\t\tadmissions.push({ why, requestId, submissionId: submission.id, fresh, unread });"],
|
|
275
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
276
|
+
"timeoutSeconds": 300,
|
|
277
|
+
"signature": "[QK:PI-DURABLE-RECEIVER-DIAGNOSTIC-LATEST-ONLY]",
|
|
278
|
+
"signatureSource": "pi-extensions/meta-bridge-pi-durable.test.ts",
|
|
279
|
+
"build": {
|
|
280
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
281
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"claim": "PI-DURABLE-CARRIER-RELOCATION-TWO-RULES",
|
|
286
|
+
"title": "a carrier file's import of a sibling keeps its .ts specifier, so the installed carrier asks Node for a file that was never emitted",
|
|
287
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
288
|
+
"find": ["return `./${name}`;"],
|
|
289
|
+
"replace": ["return spec;"],
|
|
290
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
291
|
+
"timeoutSeconds": 300,
|
|
292
|
+
"signature": "[QK:PI-DURABLE-CARRIER-RELOCATION-TWO-RULES]",
|
|
293
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
294
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"claim": "PI-DURABLE-CARRIER-RELOCATION-REFUSES",
|
|
298
|
+
"title": "the emitter stops counting specifier openings against recognized statements, so a dynamic or single-quoted import escapes the relocation unrewritten",
|
|
299
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
300
|
+
"find": ["if (begun !== statements) {"],
|
|
301
|
+
"replace": ["if (false) {"],
|
|
302
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
303
|
+
"timeoutSeconds": 300,
|
|
304
|
+
"signature": "[QK:PI-DURABLE-CARRIER-RELOCATION-REFUSES]",
|
|
305
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
306
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"claim": "PI-DURABLE-CARRIER-RESOLVE-DECLARED",
|
|
310
|
+
"title": "the resolver maps a declared target one directory above the package's dist, so every carrier internal import binds a file the pin never named",
|
|
311
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
312
|
+
"find": ["return pathToFileURL(file).href;"],
|
|
313
|
+
"replace": ["return pathToFileURL(path.join(dist(), \"..\", target)).href;"],
|
|
314
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
315
|
+
"timeoutSeconds": 300,
|
|
316
|
+
"signature": "[QK:PI-DURABLE-CARRIER-RESOLVE-DECLARED]",
|
|
317
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
318
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"claim": "PI-DURABLE-CARRIER-RESOLVE-REFUSES",
|
|
322
|
+
"title": "the resolver only asks that a parent be somewhere under the carrier directory, so an undeclared or nested file there may reach pi-coding-agent internals",
|
|
323
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
324
|
+
"find": ["if (!files.includes(parent)) {"],
|
|
325
|
+
"replace": ["if (parent === \"\") {"],
|
|
326
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
327
|
+
"timeoutSeconds": 300,
|
|
328
|
+
"signature": "[QK:PI-DURABLE-CARRIER-RESOLVE-REFUSES]",
|
|
329
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
330
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"claim": "PI-DURABLE-CARRIER-HOST-ROOT",
|
|
334
|
+
"title": "the coding-agent root is taken from any package directory above the root export, so a different package named in that place becomes the dist the carrier binds",
|
|
335
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
336
|
+
"find": ["if (name !== CODING_AGENT) {"],
|
|
337
|
+
"replace": ["if (false) {"],
|
|
338
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
339
|
+
"timeoutSeconds": 300,
|
|
340
|
+
"signature": "[QK:PI-DURABLE-CARRIER-HOST-ROOT]",
|
|
341
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
342
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"claim": "PI-DURABLE-CARRIER-PIN-MATCHES",
|
|
346
|
+
"title": "the pin records a digest the committed carrier file does not carry, so a carrier edited after emission would still be the declared one",
|
|
347
|
+
"subject": "pi/pi-durable/overlay/upstream-pin.json",
|
|
348
|
+
"find": ["\"sha256\": \"ca0ee10dc904a57d46bb33b37fcc4efe48dfa08b2f0d10e79e7bc22136871f0a\""],
|
|
349
|
+
"replace": ["\"sha256\": \"0000000000000000000000000000000000000000000000000000000000000000\""],
|
|
350
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
351
|
+
"timeoutSeconds": 300,
|
|
352
|
+
"signature": "[QK:PI-DURABLE-CARRIER-PIN-MATCHES]",
|
|
353
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
354
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"claim": "PI-DURABLE-CARRIER-PIN-MALFORMED",
|
|
358
|
+
"title": "the carrier declaration no longer requires plain file names, so a pin naming ../escape.js is accepted and the resolver answers a path outside the carrier",
|
|
359
|
+
"subject": "pi/pi-durable/carrier-relocation.mjs",
|
|
360
|
+
"find": ["if (!names?.every(plain) || names.length === 0"],
|
|
361
|
+
"replace": ["if (!names || names.length === 0"],
|
|
362
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
363
|
+
"timeoutSeconds": 300,
|
|
364
|
+
"signature": "[QK:PI-DURABLE-CARRIER-PIN-MALFORMED]",
|
|
365
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
366
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"claim": "PI-DURABLE-CARRIER-EMIT-NO-REPLACE",
|
|
370
|
+
"title": "the emitter reads source objects without --no-replace-objects, so a refs/replace entry in the maintainer's repository stands in for a pinned file",
|
|
371
|
+
"subject": "scripts/emit-pi-durable-carrier.ts",
|
|
372
|
+
"find": ["return [\"--no-replace-objects\", \"-C\", source, ...args];"],
|
|
373
|
+
"replace": ["return [\"-C\", source, ...args];"],
|
|
374
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
375
|
+
"timeoutSeconds": 300,
|
|
376
|
+
"signature": "[QK:PI-DURABLE-CARRIER-EMIT-NO-REPLACE]",
|
|
377
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
378
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"claim": "PI-DURABLE-RUNTIME-VERIFIED",
|
|
382
|
+
"title": "the verifier stops walking from each member to its own member dependencies, so only the carrier's direct edges are ever compared",
|
|
383
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
384
|
+
"find": ["\t\tif (name in pin.members && edge.at !== null) pending.push({ name, at: edge.at });\n"],
|
|
385
|
+
"replace": [""],
|
|
386
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
387
|
+
"timeoutSeconds": 300,
|
|
388
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-VERIFIED]",
|
|
389
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
390
|
+
"build": {
|
|
391
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
392
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"claim": "PI-DURABLE-RUNTIME-PACKAGE-INCOMPLETE",
|
|
397
|
+
"title": "a missing carrier resolver or relocation grammar is no longer an incomplete package, so the launcher prints a resolver path that does not exist",
|
|
398
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
399
|
+
"find": ["for (const at of [layout.resolver, layout.relocation]) {"],
|
|
400
|
+
"replace": ["for (const at of [] as string[]) {"],
|
|
401
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
402
|
+
"timeoutSeconds": 300,
|
|
403
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-PACKAGE-INCOMPLETE]",
|
|
404
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
405
|
+
"build": {
|
|
406
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
407
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"claim": "PI-DURABLE-RUNTIME-CARRIER-DRIFT",
|
|
412
|
+
"title": "a carrier file whose bytes are not the pinned ones verifies, so an edited app runs as the emitted one",
|
|
413
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
414
|
+
"find": ["else if (sha256(fs.readFileSync(at)) !== file.sha256) drifted.push("],
|
|
415
|
+
"replace": ["else if (false) drifted.push("],
|
|
416
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
417
|
+
"timeoutSeconds": 300,
|
|
418
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-CARRIER-DRIFT]",
|
|
419
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
420
|
+
"build": {
|
|
421
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
422
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"claim": "PI-DURABLE-RUNTIME-SDK-ABSENT",
|
|
427
|
+
"title": "a declared package that resolves nothing is no longer named absent and reads as a version mismatch",
|
|
428
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
429
|
+
"find": ["if (absent !== undefined) return { reason: \"pi-durable-sdk-absent\", detail: edgeText(absent) };"],
|
|
430
|
+
"replace": [""],
|
|
431
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
432
|
+
"timeoutSeconds": 300,
|
|
433
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-SDK-ABSENT]",
|
|
434
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
435
|
+
"build": {
|
|
436
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
437
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"claim": "PI-DURABLE-RUNTIME-SDK-MISMATCH",
|
|
442
|
+
"title": "only the carrier's own edges are compared, so a member binding another version of a member through its nested copy verifies",
|
|
443
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
444
|
+
"find": ["const mismatch = facts.edges.find((e) => e.got !== e.want || e.name !== e.to);"],
|
|
445
|
+
"replace": [
|
|
446
|
+
"const mismatch = facts.edges.find((e) => e.from === \"carrier\" && (e.got !== e.want || e.name !== e.to));"
|
|
447
|
+
],
|
|
448
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
449
|
+
"timeoutSeconds": 300,
|
|
450
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-SDK-MISMATCH]",
|
|
451
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
452
|
+
"build": {
|
|
453
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
454
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"claim": "PI-DURABLE-RUNTIME-SHARED-COPY-PASSES",
|
|
459
|
+
"title": "a same-version copy shared from above the package is treated as absent, so an ordinary hoisted install of the pinned set is refused",
|
|
460
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
461
|
+
"find": ["\t\tconst edge = resolveEdge(\"carrier\", name, want, base);\n"],
|
|
462
|
+
"replace": [
|
|
463
|
+
"\t\tconst edge = ((e) => (e.at !== null && !e.at.startsWith(layout.root) ? { ...e, got: null } : e))(resolveEdge(\"carrier\", name, want, base));\n"
|
|
464
|
+
],
|
|
465
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
466
|
+
"timeoutSeconds": 300,
|
|
467
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-SHARED-COPY-PASSES]",
|
|
468
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
469
|
+
"build": {
|
|
470
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
471
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"claim": "PI-DURABLE-RUNTIME-READ-ONLY",
|
|
476
|
+
"title": "verifying leaves a marker in the installed carrier directory, so a read-only check mutates the package it certifies",
|
|
477
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
478
|
+
"find": ["\tconst facts = inspectPiDurableRuntime(layout);\n\tconst verdict = piDurableRuntimeVerdict(facts);"],
|
|
479
|
+
"replace": [
|
|
480
|
+
"\tfs.writeFileSync(path.join(layout.carrierDir, \".verified\"), \"\");\n\tconst facts = inspectPiDurableRuntime(layout);\n\tconst verdict = piDurableRuntimeVerdict(facts);"
|
|
481
|
+
],
|
|
482
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
483
|
+
"timeoutSeconds": 300,
|
|
484
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-READ-ONLY]",
|
|
485
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
486
|
+
"build": {
|
|
487
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
488
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"claim": "PI-DURABLE-RUNTIME-CHECKOUT-CARRIER",
|
|
493
|
+
"title": "a committed carrier file is edited by hand after emission, so the checkout ships app bytes its pin does not record",
|
|
494
|
+
"subject": "pi/pi-durable/carrier/sessions.js",
|
|
495
|
+
"find": ["import lockfile from \"proper-lockfile\";"],
|
|
496
|
+
"replace": ["import lockfile from \"proper-lockfile\"; // edited"],
|
|
497
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
498
|
+
"timeoutSeconds": 300,
|
|
499
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-CHECKOUT-CARRIER]",
|
|
500
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
501
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"claim": "PI-DURABLE-RUNTIME-CLI-EXITS",
|
|
505
|
+
"title": "a refused carrier exits 0 from resolve, so the launcher execs node under whatever the refusal printed",
|
|
506
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
507
|
+
"find": ["\treturn PI_DURABLE_RUNTIME_EXIT.refused;\n}"],
|
|
508
|
+
"replace": ["\treturn PI_DURABLE_RUNTIME_EXIT.verified;\n}"],
|
|
509
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
510
|
+
"timeoutSeconds": 300,
|
|
511
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-CLI-EXITS]",
|
|
512
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
513
|
+
"build": {
|
|
514
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
515
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"claim": "PI-DURABLE-RUNTIME-REACHABLE-CLOSURE",
|
|
520
|
+
"title": "the walk stops at the members the carrier finds itself, so a same-version nested copy's own wrong-version dependency verifies",
|
|
521
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
522
|
+
"find": ["\t\t\tif (edge.at !== null) pending.push({ name: dep, at: edge.at });\n"],
|
|
523
|
+
"replace": [""],
|
|
524
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
525
|
+
"timeoutSeconds": 300,
|
|
526
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-REACHABLE-CLOSURE]",
|
|
527
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
528
|
+
"build": {
|
|
529
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
530
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"claim": "PI-DURABLE-RUNTIME-PACKAGE-IDENTITY",
|
|
535
|
+
"title": "an edge is judged by version alone, so a different package that happens to carry the pinned version stands in for the member",
|
|
536
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
537
|
+
"find": [" || e.name !== e.to);"],
|
|
538
|
+
"replace": [");"],
|
|
539
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
540
|
+
"timeoutSeconds": 300,
|
|
541
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-PACKAGE-IDENTITY]",
|
|
542
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
543
|
+
"build": {
|
|
544
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
545
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"claim": "PI-DURABLE-RUNTIME-SHARED-WALKED-ONCE",
|
|
550
|
+
"title": "a copy reached by two paths is walked twice, so its edges are reported twice and a member cycle never ends",
|
|
551
|
+
"subject": "pi-extensions/lib/pi-durable-runtime.ts",
|
|
552
|
+
"find": ["\t\tif (walked.has(next.at)) continue;\n"],
|
|
553
|
+
"replace": [""],
|
|
554
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
555
|
+
"timeoutSeconds": 300,
|
|
556
|
+
"signature": "[QK:PI-DURABLE-RUNTIME-SHARED-WALKED-ONCE]",
|
|
557
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
558
|
+
"build": {
|
|
559
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
560
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
"claim": "PI-DURABLE-GATE-OPERATOR-GUARD-INVARIANT",
|
|
565
|
+
"title": "the registration snapshot keeps names but not bytes, so an edit to an existing pi-durable record under the same filename passes the guard",
|
|
566
|
+
"subject": "scripts/lib/pi-durable-operator-guard.ts",
|
|
567
|
+
"find": ["if (fs.lstatSync(file).isFile() && keep(name)) out[name] = sha256(file);"],
|
|
568
|
+
"replace": ["if (fs.lstatSync(file).isFile() && keep(name)) out[name] = \"\";"],
|
|
569
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
570
|
+
"timeoutSeconds": 300,
|
|
571
|
+
"signature": "[QK:PI-DURABLE-GATE-OPERATOR-GUARD-INVARIANT]",
|
|
572
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
573
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"claim": "PI-DURABLE-GATE-OPERATOR-GUARD-WIRED",
|
|
577
|
+
"title": "the contact gate compares the operator snapshot with itself, so a run that changed the operator's registrations still passes its guard",
|
|
578
|
+
"subject": "scripts/check-pi-durable-contact.ts",
|
|
579
|
+
"find": ["operatorSnapshotUnchanged(operatorBefore, operatorPiDurableSnapshot(operatorAgent)),"],
|
|
580
|
+
"replace": ["operatorSnapshotUnchanged(operatorBefore, operatorBefore),"],
|
|
581
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
582
|
+
"timeoutSeconds": 300,
|
|
583
|
+
"signature": "[QK:PI-DURABLE-GATE-OPERATOR-GUARD-WIRED]",
|
|
584
|
+
"signatureSource": "pi-extensions/lib/pi-durable-runtime.test.ts",
|
|
585
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
"claim": "PI-DURABLE-MODULE-ABSENT-UNCHANGED",
|
|
589
|
+
"title": "the module phase runs without a --native-module, so a launch that names no module still tries to import one",
|
|
590
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
591
|
+
"find": ["\tconst extensions = nativeModule === undefined ? [] : [await loadNativeModule(nativeModule)];"],
|
|
592
|
+
"replace": ["\tconst extensions = false ? [] : [await loadNativeModule(nativeModule)];"],
|
|
593
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
594
|
+
"timeoutSeconds": 300,
|
|
595
|
+
"signature": "[QK:PI-DURABLE-MODULE-ABSENT-UNCHANGED]",
|
|
596
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
597
|
+
"build": {
|
|
598
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
599
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
600
|
+
}
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"claim": "PI-DURABLE-MODULE-PATH-REFUSED",
|
|
604
|
+
"title": "a relative --native-module is resolved against whatever directory the launch happens to be in",
|
|
605
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
606
|
+
"find": ["\tif (!isAbsolute(value))"],
|
|
607
|
+
"replace": ["\tif (false)"],
|
|
608
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
609
|
+
"timeoutSeconds": 300,
|
|
610
|
+
"signature": "[QK:PI-DURABLE-MODULE-PATH-REFUSED]",
|
|
611
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
612
|
+
"build": {
|
|
613
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
614
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
"claim": "PI-DURABLE-MODULE-INIT-BEFORE-RUNTIME",
|
|
619
|
+
"title": "the module initializes after the TUI is imported, so its environment arrives after the SDK modules have evaluated",
|
|
620
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
621
|
+
"find": [
|
|
622
|
+
"\tconst extensions = nativeModule === undefined ? [] : [await loadNativeModule(nativeModule)];",
|
|
623
|
+
"\t// Loaded before anything opens, as upstream main.ts imports it statically: a TUI that cannot",
|
|
624
|
+
"\t// load opens no session, mints no citizen and leaves nothing to clean up.",
|
|
625
|
+
"\tconst { runDurableTui } = await loadTui();"
|
|
626
|
+
],
|
|
627
|
+
"replace": [
|
|
628
|
+
"\t// Loaded before anything opens, as upstream main.ts imports it statically: a TUI that cannot",
|
|
629
|
+
"\t// load opens no session, mints no citizen and leaves nothing to clean up.",
|
|
630
|
+
"\tconst { runDurableTui } = await loadTui();",
|
|
631
|
+
"\tconst extensions = nativeModule === undefined ? [] : [await loadNativeModule(nativeModule)];"
|
|
632
|
+
],
|
|
633
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
634
|
+
"timeoutSeconds": 300,
|
|
635
|
+
"signature": "[QK:PI-DURABLE-MODULE-INIT-BEFORE-RUNTIME]",
|
|
636
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
637
|
+
"build": {
|
|
638
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
639
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
640
|
+
}
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"claim": "PI-DURABLE-MODULE-IMPORT-FAILED",
|
|
644
|
+
"title": "a module that throws during initialization is treated as no module and the app opens anyway",
|
|
645
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
646
|
+
"find": ["\t} catch (error) {", "\t\tthrow Object.assign(", "\t\t\trefuse(\"native-module-import-failed\","],
|
|
647
|
+
"replace": [
|
|
648
|
+
"\t} catch (error) {",
|
|
649
|
+
"\t\treturn undefined;",
|
|
650
|
+
"\t\tthrow Object.assign(",
|
|
651
|
+
"\t\t\trefuse(\"native-module-import-failed\","
|
|
652
|
+
],
|
|
653
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
654
|
+
"timeoutSeconds": 300,
|
|
655
|
+
"signature": "[QK:PI-DURABLE-MODULE-IMPORT-FAILED]",
|
|
656
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
657
|
+
"build": {
|
|
658
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
659
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"claim": "PI-DURABLE-MODULE-IDENTITY-GUARD",
|
|
664
|
+
"title": "the identity carriers are compared only after the module ran, so a change its initialization made is never seen",
|
|
665
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
666
|
+
"find": ["\tconst changed = identityChanges(before, identitySnapshot());"],
|
|
667
|
+
"replace": ["\tconst changed = identityChanges(identitySnapshot(), identitySnapshot());"],
|
|
668
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
669
|
+
"timeoutSeconds": 300,
|
|
670
|
+
"signature": "[QK:PI-DURABLE-MODULE-IDENTITY-GUARD]",
|
|
671
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
672
|
+
"build": {
|
|
673
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
674
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
"claim": "PI-DURABLE-MODULE-CWD-PINNED",
|
|
679
|
+
"title": "the app is opened wherever the process is at open time, not in the caller's directory fixed before the module ran",
|
|
680
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
681
|
+
"find": ["\tconst citizen = await openDurableCitizen({ ...args, cwd, extensions, bridgeEntry, open, contact });"],
|
|
682
|
+
"replace": ["\tconst citizen = await openDurableCitizen({ ...args, extensions, bridgeEntry, open, contact });"],
|
|
683
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
684
|
+
"timeoutSeconds": 300,
|
|
685
|
+
"signature": "[QK:PI-DURABLE-MODULE-CWD-PINNED]",
|
|
686
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
687
|
+
"build": {
|
|
688
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
689
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
690
|
+
}
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
"claim": "PI-DURABLE-MODULE-EXPORT-NAME",
|
|
694
|
+
"title": "a module may name its extension entwurf, coding-tools, pi-prompt or subagent, and the native registry silently replaces that extension",
|
|
695
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
696
|
+
"find": ["\tif (RESERVED_EXTENSION_NAMES.includes(extension.name)) {"],
|
|
697
|
+
"replace": ["\tif (false) {"],
|
|
698
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
699
|
+
"timeoutSeconds": 300,
|
|
700
|
+
"signature": "[QK:PI-DURABLE-MODULE-EXPORT-NAME]",
|
|
701
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
702
|
+
"build": {
|
|
703
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
704
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
"claim": "PI-DURABLE-MODULE-EXTENSION-ORDER",
|
|
709
|
+
"title": "the module's extension is installed before the contact",
|
|
710
|
+
"subject": "pi/pi-durable/bootstrap.mjs",
|
|
711
|
+
"find": ["\t\t\textensions: [contact.extension, ...extensions],"],
|
|
712
|
+
"replace": ["\t\t\textensions: [...extensions, contact.extension],"],
|
|
713
|
+
"gate": ["bash", "run.sh", "check-pi-durable-beside"],
|
|
714
|
+
"timeoutSeconds": 300,
|
|
715
|
+
"signature": "[QK:PI-DURABLE-MODULE-EXTENSION-ORDER]",
|
|
716
|
+
"signatureSource": "pi-extensions/lib/pi-durable-native-module.test.ts",
|
|
717
|
+
"build": {
|
|
718
|
+
"argv": ["bash", "scripts/build-bridge.sh"],
|
|
719
|
+
"output": "mcp/entwurf-bridge/dist"
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
]
|
|
723
|
+
}
|