@junghanacs/entwurf 0.13.1 → 0.14.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 +48 -15
- package/BASELINE.md +3 -3
- package/CHANGELOG.md +45 -0
- package/CONTRIBUTING.md +13 -9
- package/DELIVERY.md +7 -6
- package/README.md +27 -27
- package/VERIFY.md +22 -14
- package/demo/README.md +1 -1
- package/demo/demo-baseline.sh +1 -3
- package/demo/demo.sh +2 -5
- package/docs/acp-backend-rail.md +9 -4
- package/docs/external-mcp-host.md +4 -5
- package/docs/setup-clean-host.md +8 -7
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +148 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +8 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +7 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +13 -14
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +45 -40
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +117 -95
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +23 -57
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +16 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +5 -53
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-release.js +21 -36
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +3 -15
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send-fallback.js +12 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +2 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +30 -67
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +256 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +91 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +258 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-launch.js +202 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-placement.js +289 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +170 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +136 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/session-id.js +8 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-discovery.js +3 -3
- package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +51 -0
- package/mcp/entwurf-bridge/dist/scripts/new-session-id.js +9 -4
- package/mcp/entwurf-bridge/src/index.ts +164 -28
- package/mcp/entwurf-bridge/start.sh +2 -2
- package/mcp/entwurf-bridge/test.sh +23 -9
- package/mcp/entwurf-bridge/tsconfig.build.json +11 -2
- package/package.json +22 -11
- package/pi-extensions/entwurf-control.ts +218 -40
- package/pi-extensions/lib/acp/backend.ts +71 -12
- package/pi-extensions/lib/acp/overlay.ts +8 -6
- package/pi-extensions/lib/entwurf-control-rpc.ts +7 -5
- package/pi-extensions/lib/entwurf-core.ts +15 -15
- package/pi-extensions/lib/entwurf-resume-args.ts +41 -52
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-contract.ts +120 -99
- package/pi-extensions/lib/entwurf-v2-decider.ts +30 -91
- package/pi-extensions/lib/entwurf-v2-lock.ts +16 -7
- package/pi-extensions/lib/entwurf-v2-production.ts +4 -78
- package/pi-extensions/lib/entwurf-v2-release.ts +25 -49
- package/pi-extensions/lib/entwurf-v2-runner.ts +6 -21
- package/pi-extensions/lib/entwurf-v2-send-fallback.ts +12 -11
- package/pi-extensions/lib/entwurf-v2-send.ts +2 -7
- package/pi-extensions/lib/entwurf-v2-surface.ts +36 -76
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +370 -0
- package/pi-extensions/lib/meta-session.ts +93 -5
- package/pi-extensions/lib/mux-fresh-call.ts +328 -0
- package/pi-extensions/lib/mux-launch.ts +267 -0
- package/pi-extensions/lib/mux-placement.ts +387 -0
- package/pi-extensions/lib/mux-resume-call.ts +221 -0
- package/pi-extensions/lib/resume-launch-identity.ts +162 -0
- package/pi-extensions/lib/session-id.js +8 -5
- package/pi-extensions/lib/socket-discovery.ts +3 -3
- package/run.sh +471 -201
- package/scripts/agy-bridge-config.py +5 -1
- package/scripts/check-acp-backend-preflight.ts +1 -1
- package/scripts/check-acp-overlay.ts +13 -3
- package/scripts/check-acp-stream-hooks.ts +504 -0
- package/scripts/check-elapsed.sh +25 -0
- package/scripts/check-entwurf-bridge-boot.ts +51 -4
- package/scripts/check-entwurf-bridge-pi-free.ts +6 -5
- package/scripts/check-entwurf-control-rpc.ts +4 -3
- package/scripts/check-entwurf-resume-args.ts +72 -70
- package/scripts/check-entwurf-session-identity.ts +14 -10
- package/scripts/check-entwurf-v2-contract.ts +34 -59
- package/scripts/check-entwurf-v2-decider.ts +17 -177
- package/scripts/check-entwurf-v2-lock.ts +5 -2
- package/scripts/check-entwurf-v2-matrix.ts +3 -53
- package/scripts/check-entwurf-v2-production.ts +2 -91
- package/scripts/check-entwurf-v2-release.ts +10 -105
- package/scripts/check-entwurf-v2-runner.ts +4 -85
- package/scripts/check-entwurf-v2-send-fallback.ts +5 -6
- package/scripts/check-entwurf-v2-send.ts +0 -28
- package/scripts/check-entwurf-v2-surface.ts +157 -128
- package/scripts/check-entwurf-v2-visible-resume.ts +445 -0
- package/scripts/check-fresh-cut-gate.sh +1 -1
- package/scripts/check-gate-qualification.ts +98 -7
- package/scripts/check-install-container.sh +10 -2
- package/scripts/check-install-surface.ts +1 -1
- package/scripts/check-keyset-overlap.py +1 -1
- package/scripts/check-meta-facts.ts +249 -0
- package/scripts/check-meta-identity-consumers.ts +1 -1
- package/scripts/check-meta-session.ts +169 -0
- package/scripts/check-mux-launch-tmux.ts +316 -0
- package/scripts/check-mux-launch.ts +288 -0
- package/scripts/check-mux-launcher-fence.ts +264 -0
- package/scripts/check-mux-parent-artifact.ts +195 -0
- package/scripts/check-mux-placement-tmux.ts +322 -0
- package/scripts/check-mux-placement.ts +323 -0
- package/scripts/check-mux-resume-call.ts +282 -0
- package/scripts/check-probe-cli-shim.ts +25 -22
- package/scripts/check-probe-ordering.ts +84 -76
- package/scripts/check-release-gate-outcomes.ts +127 -7
- package/scripts/check-resume-launch-identity.ts +244 -0
- package/scripts/check-socket-discovery.ts +1 -1
- package/scripts/fixtures/mux-parent-transcript.scrubbed.jsonl +3 -0
- package/scripts/inventory-verification-surface.ts +349 -0
- package/scripts/lib/claude-launcher-fence.ts +322 -0
- package/scripts/lib/mutation-qualify.ts +109 -3
- package/scripts/meta-bridge-doctor.sh +6 -8
- package/scripts/meta-facts.ts +60 -0
- package/scripts/mutants/acp-overlay.json +17 -0
- package/scripts/mutants/acp-stream-hooks.json +158 -0
- package/scripts/mutants/bridge-boot-resume.json +45 -0
- package/scripts/mutants/meta-facts.json +50 -0
- package/scripts/mutants/meta-identity.json +36 -0
- package/scripts/mutants/mux-boundary.json +196 -0
- package/scripts/mutants/mux-fresh-call.json +185 -0
- package/scripts/mutants/mux-launcher-fence.json +123 -0
- package/scripts/mutants/mux-parent-artifact.json +39 -0
- package/scripts/mutants/mux-resume-call.json +148 -0
- package/scripts/mutants/probe-ordering.json +0 -1037
- package/scripts/mutants/release-gate.json +35 -0
- package/scripts/mutants/resume-args.json +76 -0
- package/scripts/mutants/resume-launch-identity.json +96 -0
- package/scripts/mutants/v2-surface.json +58 -18
- package/scripts/mutants/v2-visible-resume.json +215 -0
- package/scripts/new-session-id.ts +9 -4
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-agy-native-push-live.ts +6 -17
- package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
- package/scripts/smoke-meta-honesty.sh +1 -1
- package/scripts/smoke-mux-fresh-call-live.ts +365 -0
- package/scripts/smoke-mux-lifecycle-live.ts +1136 -0
- package/scripts/smoke-pi-attach.ts +1 -1
- package/scripts/smoke-user-scope-citizen.sh +1 -1
- package/scripts/tsconfig.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-preflight.js +0 -160
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +0 -273
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn.js +0 -216
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +0 -373
- package/pi-extensions/lib/entwurf-v2-spawn.ts +0 -323
- package/scripts/check-acp-sdk-surface.ts +0 -275
- package/scripts/check-entwurf-v2-spawn-production.ts +0 -551
- package/scripts/check-entwurf-v2-spawn.ts +0 -399
- package/scripts/smoke-entwurf-v2-spawn-live.ts +0 -188
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +0 -467
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "mux-boundary",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "V2-DELIVERY-EXCLUDES-MUX",
|
|
7
|
+
"title": "a mux launch handle is reintroduced as an entwurf_v2 delivery receipt transport",
|
|
8
|
+
"subject": "pi-extensions/lib/entwurf-v2-contract.ts",
|
|
9
|
+
"find": [
|
|
10
|
+
"export const ENTWURF_V2_TRANSPORTS = [\"control-socket\", \"meta-mailbox\", \"native-push\"] as const;"
|
|
11
|
+
],
|
|
12
|
+
"replace": [
|
|
13
|
+
"export const ENTWURF_V2_TRANSPORTS = [",
|
|
14
|
+
"\t\"control-socket\",",
|
|
15
|
+
"\t\"tmux-live\",",
|
|
16
|
+
"\t\"meta-mailbox\",",
|
|
17
|
+
"\t\"native-push\",",
|
|
18
|
+
"] as const;"
|
|
19
|
+
],
|
|
20
|
+
"gate": ["bash", "run.sh", "check-entwurf-v2-contract"],
|
|
21
|
+
"timeoutSeconds": 60,
|
|
22
|
+
"signature": "[QK:V2-DELIVERY-EXCLUDES-MUX]",
|
|
23
|
+
"signatureSource": "scripts/check-entwurf-v2-contract.ts"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"claim": "MUX-ANCHOR-REQUIRED",
|
|
27
|
+
"title": "TMUX is no longer required, so a caller holding only a pane id makes a bare tmux resolve to the DEFAULT server",
|
|
28
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
29
|
+
"find": [
|
|
30
|
+
"\tif (typeof server !== \"string\" || server.length === 0) return { ok: false, reason: \"no-tmux-context\" };"
|
|
31
|
+
],
|
|
32
|
+
"replace": ["\tvoid server;"],
|
|
33
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
34
|
+
"timeoutSeconds": 60,
|
|
35
|
+
"signature": "[QK:MUX-ANCHOR-REQUIRED]",
|
|
36
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"claim": "MUX-SELECTOR-NATIVE-ID",
|
|
40
|
+
"title": "selector validation is disabled, so a forged `-t` value reaches tmux's own parser",
|
|
41
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
42
|
+
"find": ["\tif (!okShape) {"],
|
|
43
|
+
"replace": ["\tif (false && !okShape) {"],
|
|
44
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
45
|
+
"timeoutSeconds": 60,
|
|
46
|
+
"signature": "[QK:MUX-SELECTOR-NATIVE-ID]",
|
|
47
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"claim": "MUX-TMUX-FAILURE-LOUD",
|
|
51
|
+
"title": "a nonzero or signalled tmux run is swallowed, so `no server running` is laundered into a fact about the pane",
|
|
52
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
53
|
+
"find": ["\tif (run.status === 0) return;"],
|
|
54
|
+
"replace": ["\tif (run.status === 0 || run.status !== 0) return;"],
|
|
55
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
56
|
+
"timeoutSeconds": 60,
|
|
57
|
+
"signature": "[QK:MUX-TMUX-FAILURE-LOUD]",
|
|
58
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"claim": "MUX-ANCHOR-ECHO-BACK",
|
|
62
|
+
"title": "the pane-id echo-back is dropped, so tmux's rc=0 answer about ANOTHER pane is accepted as the caller's placement",
|
|
63
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
64
|
+
"find": ["\tif (paneId !== anchor) return { ok: false, reason: \"anchor-mismatch\" };"],
|
|
65
|
+
"replace": ["\t// echo-back dropped"],
|
|
66
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
67
|
+
"timeoutSeconds": 60,
|
|
68
|
+
"signature": "[QK:MUX-ANCHOR-ECHO-BACK]",
|
|
69
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"claim": "MUX-APPEND-END-DETACHED",
|
|
73
|
+
"title": "append drops -a/{end} and becomes a lowest-free-index new-window, a different verb from appending at the session end",
|
|
74
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
75
|
+
"find": [
|
|
76
|
+
"\treturn [\"new-window\", \"-d\", \"-a\", \"-t\", `${sessionId}:{end}`, \"-P\", \"-F\", APPEND_FORMAT];"
|
|
77
|
+
],
|
|
78
|
+
"replace": ["\treturn [\"new-window\", \"-d\", \"-t\", `${sessionId}:`, \"-P\", \"-F\", APPEND_FORMAT];"],
|
|
79
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
80
|
+
"timeoutSeconds": 60,
|
|
81
|
+
"signature": "[QK:MUX-APPEND-END-DETACHED]",
|
|
82
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"claim": "MUX-CLOSE-BY-WINDOW-ID",
|
|
86
|
+
"title": "a failed kill-window is reported as already-gone without proving absence, so a window that is still open reads as closed",
|
|
87
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
88
|
+
"find": ["\treturn ids.includes(windowId) ? null : \"already-gone\";"],
|
|
89
|
+
"replace": ["\treturn \"already-gone\";"],
|
|
90
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
91
|
+
"timeoutSeconds": 60,
|
|
92
|
+
"signature": "[QK:MUX-CLOSE-BY-WINDOW-ID]",
|
|
93
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"claim": "MUX-CONTEXT-BOUND-MUTATION",
|
|
97
|
+
"title": "context binding matches on the session id alone, so a restarted or foreign server with the same $N is accepted",
|
|
98
|
+
"subject": "pi-extensions/lib/mux-placement.ts",
|
|
99
|
+
"find": ["\treturn origin.serverPid === now.serverPid && origin.sessionId === now.sessionId;"],
|
|
100
|
+
"replace": ["\treturn origin.sessionId === now.sessionId;"],
|
|
101
|
+
"gate": ["bash", "run.sh", "check-mux-placement"],
|
|
102
|
+
"timeoutSeconds": 60,
|
|
103
|
+
"signature": "[QK:MUX-CONTEXT-BOUND-MUTATION]",
|
|
104
|
+
"signatureSource": "scripts/check-mux-placement.ts"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"claim": "MUX-LAUNCH-PRECONDITION-FIRST",
|
|
108
|
+
"title": "the runtime precondition is skipped, so a window is opened onto a runtime that cannot start and the receipt looks identical to a good launch",
|
|
109
|
+
"subject": "pi-extensions/lib/mux-launch.ts",
|
|
110
|
+
"find": ["\tif (!isAbsolute(runtimePath)) {"],
|
|
111
|
+
"replace": ["\tif (false && !isAbsolute(runtimePath)) {"],
|
|
112
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
113
|
+
"timeoutSeconds": 60,
|
|
114
|
+
"signature": "[QK:MUX-LAUNCH-PRECONDITION-FIRST]",
|
|
115
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"claim": "MUX-LAUNCH-PATH-NO-SPLIT",
|
|
119
|
+
"title": "the whitespace guard is dropped, so tmux re-splits a spaced runtime path and launches a truncated binary with the remainder as an argument",
|
|
120
|
+
"subject": "pi-extensions/lib/mux-launch.ts",
|
|
121
|
+
"find": ["\tif (WHITESPACE.test(runtimePath)) {"],
|
|
122
|
+
"replace": ["\tif (false && WHITESPACE.test(runtimePath)) {"],
|
|
123
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
124
|
+
"timeoutSeconds": 60,
|
|
125
|
+
"signature": "[QK:MUX-LAUNCH-PATH-NO-SPLIT]",
|
|
126
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"claim": "MUX-LAUNCH-PATH-HIT-NOT-SKIPPED",
|
|
130
|
+
"title": "the launchability proof is moved inside the PATH loop's catch, so an unlaunchable FIRST hit is silently skipped and a later entry launches a different install than the operator's own `pi`",
|
|
131
|
+
"subject": "pi-extensions/lib/mux-launch.ts",
|
|
132
|
+
"find": [
|
|
133
|
+
"\t\t} catch {",
|
|
134
|
+
"\t\t\tcontinue;",
|
|
135
|
+
"\t\t}",
|
|
136
|
+
"\t\tassertLaunchTarget(candidate);",
|
|
137
|
+
"\t\treturn candidate;"
|
|
138
|
+
],
|
|
139
|
+
"replace": [
|
|
140
|
+
"\t\t\tassertLaunchTarget(candidate);",
|
|
141
|
+
"\t\t} catch {",
|
|
142
|
+
"\t\t\tcontinue;",
|
|
143
|
+
"\t\t}",
|
|
144
|
+
"\t\treturn candidate;"
|
|
145
|
+
],
|
|
146
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
147
|
+
"timeoutSeconds": 60,
|
|
148
|
+
"signature": "[QK:MUX-LAUNCH-PATH-HIT-NOT-SKIPPED]",
|
|
149
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"claim": "MUX-LAUNCH-NO-SHELL-ARGV",
|
|
153
|
+
"title": "the `--` separator is dropped, so tmux takes the runtime as a shell-command string instead of exec'ing it directly",
|
|
154
|
+
"subject": "pi-extensions/lib/mux-launch.ts",
|
|
155
|
+
"find": [
|
|
156
|
+
"\treturn [\"new-window\", \"-d\", \"-a\", \"-t\", `${sessionId}:{end}`, \"-P\", \"-F\", APPEND_FORMAT, \"--\", runtimePath];"
|
|
157
|
+
],
|
|
158
|
+
"replace": [
|
|
159
|
+
"\treturn [\"new-window\", \"-d\", \"-a\", \"-t\", `${sessionId}:{end}`, \"-P\", \"-F\", APPEND_FORMAT, runtimePath];"
|
|
160
|
+
],
|
|
161
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
162
|
+
"timeoutSeconds": 60,
|
|
163
|
+
"signature": "[QK:MUX-LAUNCH-NO-SHELL-ARGV]",
|
|
164
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"claim": "MUX-LAUNCH-NO-CARRIER",
|
|
168
|
+
"title": "a window-name carrier is reintroduced into the launch argv, handing tmux's own parser a value this rail did not author",
|
|
169
|
+
"subject": "pi-extensions/lib/mux-launch.ts",
|
|
170
|
+
"find": [
|
|
171
|
+
"\treturn [\"new-window\", \"-d\", \"-a\", \"-t\", `${sessionId}:{end}`, \"-P\", \"-F\", APPEND_FORMAT, \"--\", runtimePath];"
|
|
172
|
+
],
|
|
173
|
+
"replace": [
|
|
174
|
+
"\treturn [\"new-window\", \"-d\", \"-a\", \"-n\", PI_RUNTIME_COMMAND, \"-t\", `${sessionId}:{end}`, \"-P\", \"-F\", APPEND_FORMAT, \"--\", runtimePath];"
|
|
175
|
+
],
|
|
176
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
177
|
+
"timeoutSeconds": 60,
|
|
178
|
+
"signature": "[QK:MUX-LAUNCH-NO-CARRIER]",
|
|
179
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"claim": "MUX-LAUNCH-CORE-IMPORT-FREE",
|
|
183
|
+
"title": "the launch composition is imported by the delivery core, making fresh launch a dependency of entwurf_v2 delivery",
|
|
184
|
+
"subject": "pi-extensions/lib/entwurf-v2-production.ts",
|
|
185
|
+
"find": ["import { isOutOfSocketDomainGardenIdConflict } from \"./entwurf-facts.ts\";"],
|
|
186
|
+
"replace": [
|
|
187
|
+
"import { isOutOfSocketDomainGardenIdConflict } from \"./entwurf-facts.ts\";",
|
|
188
|
+
"import { launchPi as _launchPi } from \"./mux-launch.ts\";"
|
|
189
|
+
],
|
|
190
|
+
"gate": ["bash", "run.sh", "check-mux-launch"],
|
|
191
|
+
"timeoutSeconds": 60,
|
|
192
|
+
"signature": "[QK:MUX-LAUNCH-CORE-IMPORT-FREE]",
|
|
193
|
+
"signatureSource": "scripts/check-mux-launch.ts"
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "mux-fresh-call",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "FRESHCALL-PI-ARGV-PROMPT-FIRST",
|
|
7
|
+
"title": "pi gets the flag before the prompt again — the measured shape that opens a window whose first turn never runs",
|
|
8
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
9
|
+
"find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
|
|
10
|
+
"replace": ["\t\t\treturn [\"--entwurf-control\", prompt, \"--model\", model];"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
12
|
+
"timeoutSeconds": 120,
|
|
13
|
+
"signature": "[QK:FRESHCALL-PI-ARGV-PROMPT-FIRST]",
|
|
14
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"claim": "FRESHCALL-CLAUDE-ARGV-EQUALS-FORM",
|
|
18
|
+
"title": "claude-code goes back to the variadic space form, which swallows the prompt as an option value",
|
|
19
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
20
|
+
"find": [
|
|
21
|
+
"\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
|
|
22
|
+
],
|
|
23
|
+
"replace": [
|
|
24
|
+
"\t\t\treturn [prompt, \"--allowedTools\", FRESH_CALL_CALLBACK_TOOL[\"claude-code\"], `--model=${model}`];"
|
|
25
|
+
],
|
|
26
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
27
|
+
"timeoutSeconds": 120,
|
|
28
|
+
"signature": "[QK:FRESHCALL-CLAUDE-ARGV-EQUALS-FORM]",
|
|
29
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"claim": "FRESHCALL-PI-MODEL-ARGV",
|
|
33
|
+
"title": "pi drops its measured two-token model option and silently resolves its ambient default again",
|
|
34
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
35
|
+
"find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
|
|
36
|
+
"replace": ["\t\t\treturn [prompt, \"--entwurf-control\"];"],
|
|
37
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
38
|
+
"timeoutSeconds": 120,
|
|
39
|
+
"signature": "[QK:FRESHCALL-PI-MODEL-ARGV]",
|
|
40
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"claim": "FRESHCALL-PI-MODEL-DIALECT",
|
|
44
|
+
"title": "pi model argv is unified with Claude Code into the equals form that the real Pi parser rejects",
|
|
45
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
46
|
+
"find": ["\t\t\treturn [prompt, \"--entwurf-control\", \"--model\", model];"],
|
|
47
|
+
"replace": ["\t\t\treturn [prompt, \"--entwurf-control\", `--model=${model}`];"],
|
|
48
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
49
|
+
"timeoutSeconds": 120,
|
|
50
|
+
"signature": "[QK:FRESHCALL-PI-MODEL-DIALECT]",
|
|
51
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"claim": "FRESHCALL-CLAUDE-MODEL-ARGV",
|
|
55
|
+
"title": "Claude Code drops the explicit model token and silently resolves its ambient Opus default again",
|
|
56
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
57
|
+
"find": [
|
|
58
|
+
"\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`, `--model=${model}`];"
|
|
59
|
+
],
|
|
60
|
+
"replace": ["\t\t\treturn [prompt, `--allowedTools=${FRESH_CALL_CALLBACK_TOOL[\"claude-code\"]}`];"],
|
|
61
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
62
|
+
"timeoutSeconds": 120,
|
|
63
|
+
"signature": "[QK:FRESHCALL-CLAUDE-MODEL-ARGV]",
|
|
64
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"claim": "FRESHCALL-CALLBACK-PRECEDES-TASK",
|
|
68
|
+
"title": "the task is framed before the callback instruction, so a sibling that stalls in the task never names itself",
|
|
69
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
70
|
+
"find": ["\t\t`FIRST ACTION, before reading files or anything else: call ${tool} with ` +"],
|
|
71
|
+
"replace": ["\t\t`FINAL ACTION, after completing the task: call ${tool} with ` +"],
|
|
72
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
73
|
+
"timeoutSeconds": 120,
|
|
74
|
+
"signature": "[QK:FRESHCALL-CALLBACK-PRECEDES-TASK]",
|
|
75
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"claim": "FRESHCALL-RECEIPT-WITHOUT-CORRELATION",
|
|
79
|
+
"title": "the launch receipt grows a sibling garden-id field, making an async correlation look like a synchronous return",
|
|
80
|
+
"subject": "pi-extensions/lib/mux-fresh-call.ts",
|
|
81
|
+
"find": ["\tbackend: FreshCallBackend;\n\tmodel: string;\n\truntimePath: string;\n\tnonce: string;\n}"],
|
|
82
|
+
"replace": [
|
|
83
|
+
"\tbackend: FreshCallBackend;\n\tmodel: string;\n\truntimePath: string;\n\tnonce: string;\n\tgardenId?: string;\n}"
|
|
84
|
+
],
|
|
85
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
86
|
+
"timeoutSeconds": 120,
|
|
87
|
+
"signature": "[QK:FRESHCALL-RECEIPT-WITHOUT-CORRELATION]",
|
|
88
|
+
"signatureSource": "test/mux-fresh-call.test.ts"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"claim": "FRESHCALL-PI-SURFACE-IDENTITY",
|
|
92
|
+
"title": "native pi takes the caller garden id from the environment instead of its own resident closure — the uuidv7 confusion, reintroduced",
|
|
93
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
94
|
+
"find": ["\t\t\t\t\tcallerGardenId: residentGardenId,"],
|
|
95
|
+
"replace": ["\t\t\t\t\tcallerGardenId: process.env.PI_SESSION_ID ?? null,"],
|
|
96
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
97
|
+
"timeoutSeconds": 120,
|
|
98
|
+
"signature": "[QK:FRESHCALL-PI-SURFACE-IDENTITY]",
|
|
99
|
+
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"claim": "FRESHCALL-PI-MODEL-SCHEMA",
|
|
103
|
+
"title": "native pi drops the required model field from fresh-call while the composition still expects one",
|
|
104
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
105
|
+
"find": [
|
|
106
|
+
"\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: \"Required runtime model: canonical provider/model for pi, or a Claude Code model id/alias.\",\n\t\t\t}),\n"
|
|
107
|
+
],
|
|
108
|
+
"replace": [""],
|
|
109
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
110
|
+
"timeoutSeconds": 120,
|
|
111
|
+
"signature": "[QK:FRESHCALL-PI-MODEL-SCHEMA]",
|
|
112
|
+
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"claim": "FRESHCALL-CLAUDE-SURFACE-IDENTITY",
|
|
116
|
+
"title": "the MCP bridge reads the caller garden id straight out of env instead of its authoritative self envelope",
|
|
117
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
118
|
+
"find": [
|
|
119
|
+
"\t\t\tconst self = await buildAuthoritativeSelfEnvelope();\n\t\t\tcallerGardenId = self.envelope.sessionId;"
|
|
120
|
+
],
|
|
121
|
+
"replace": ["\t\t\tcallerGardenId = process.env.PI_SESSION_ID ?? null;"],
|
|
122
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
123
|
+
"timeoutSeconds": 120,
|
|
124
|
+
"signature": "[QK:FRESHCALL-CLAUDE-SURFACE-IDENTITY]",
|
|
125
|
+
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"claim": "FRESHCALL-CLAUDE-MODEL-SCHEMA",
|
|
129
|
+
"title": "MCP drops the required model field from fresh-call while the composition still expects one",
|
|
130
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
131
|
+
"find": [
|
|
132
|
+
"\t\tmodel: z\n\t\t\t.string()\n\t\t\t.min(1)\n\t\t\t.max(200)\n\t\t\t// The `\\[` below is USELESS TO JS AND LOAD-BEARING TO THE HOST. zod emits this source\n\t\t\t// text verbatim as the JSON Schema `pattern`, and the host's tool-schema validator is a\n\t\t\t// Rust regex engine that rejects an unescaped `[` inside a character class as \"unclosed\n\t\t\t// character class\" — a 400 on tools/list that stops EVERY Claude session from opening\n\t\t\t// (7-M-fix). Biome's safe fix removes it; do not accept that fix. The suppression must\n\t\t\t// stay on the line DIRECTLY above the expression, or it attaches to nothing and reads\n\t\t\t// as an unused suppression while the escape goes back to being fixable.\n\t\t\t// biome-ignore lint/complexity/noUselessEscapeInRegex: emitted to a Rust regex validator, see above\n\t\t\t.regex(/^[A-Za-z0-9][A-Za-z0-9._/:\\[\\]-]*$/)\n\t\t\t.describe(\"Required runtime model: canonical provider/model for pi, or a Claude Code model id/alias.\"),\n"
|
|
133
|
+
],
|
|
134
|
+
"replace": [""],
|
|
135
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
136
|
+
"timeoutSeconds": 120,
|
|
137
|
+
"signature": "[QK:FRESHCALL-CLAUDE-MODEL-SCHEMA]",
|
|
138
|
+
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"claim": "FRESHCALL-MODEL-PATTERN-HOST-VALID",
|
|
142
|
+
"title": "the #62 escape replanted: biome's safe fix unescapes the zod model pattern, JS still accepts it, and the Rust-family host validator rejects the whole tool definition",
|
|
143
|
+
"subject": "mcp/entwurf-bridge/src/index.ts",
|
|
144
|
+
"find": ["\t\t\t.regex(/^[A-Za-z0-9][A-Za-z0-9._/:\\[\\]-]*$/)"],
|
|
145
|
+
"replace": ["\t\t\t.regex(/^[A-Za-z0-9][A-Za-z0-9._/:[\\]-]*$/)"],
|
|
146
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
147
|
+
"timeoutSeconds": 120,
|
|
148
|
+
"signature": "[QK:FRESHCALL-MODEL-PATTERN-HOST-VALID]",
|
|
149
|
+
"signatureSource": "test/fresh-call-surfaces.contract.test.ts"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"claim": "FRESHCALL-MODEL-PATTERN-PROVIDER-VALID",
|
|
153
|
+
"title": "the same unescape planted on the TypeBox surface rides pi-ai's real anthropic-messages conversion into the request body as an invalid Rust-family pattern",
|
|
154
|
+
"subject": "pi-extensions/entwurf-control.ts",
|
|
155
|
+
"find": ["\t\t\t\tpattern: \"^[A-Za-z0-9][A-Za-z0-9._/:\\\\[\\\\]-]*$\","],
|
|
156
|
+
"replace": ["\t\t\t\tpattern: \"^[A-Za-z0-9][A-Za-z0-9._/:[\\\\]-]*$\","],
|
|
157
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
158
|
+
"timeoutSeconds": 120,
|
|
159
|
+
"signature": "[QK:FRESHCALL-MODEL-PATTERN-PROVIDER-VALID]",
|
|
160
|
+
"signatureSource": "test/fresh-call-provider.contract.test.ts"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"claim": "PIIMPORT-WORK-SURFACE",
|
|
164
|
+
"title": "the measured #62 escape replanted on the floor itself: check-pi-import-surface falls back to the tracked index, so a brand-new forbidden private-subpath import is invisible until it is staged",
|
|
165
|
+
"subject": "run.sh",
|
|
166
|
+
"find": [" git ls-files -z --cached --others --exclude-standard -- '*.ts' '*.js' '*.mjs' '*.cjs'"],
|
|
167
|
+
"replace": [" git ls-files -z --cached -- '*.ts' '*.js' '*.mjs' '*.cjs'"],
|
|
168
|
+
"gate": ["bash", "run.sh", "check-pi-import-surface"],
|
|
169
|
+
"timeoutSeconds": 60,
|
|
170
|
+
"signature": "[QK:PIIMPORT-WORK-SURFACE]",
|
|
171
|
+
"signatureSource": "run.sh"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"claim": "VITEST-FAILED-TITLE-ATTRIBUTION",
|
|
175
|
+
"title": "the pilot's kill attribution collects PASSING test titles instead of failed ones, recreating the code-frame false-KILLED hole this lane exists to close",
|
|
176
|
+
"subject": "scripts/lib/mutation-qualify.ts",
|
|
177
|
+
"find": ["\t\t\tif (assertion.status !== \"failed\") continue;"],
|
|
178
|
+
"replace": ["\t\t\tif (assertion.status === \"failed\") continue;"],
|
|
179
|
+
"gate": ["node", "--experimental-strip-types", "scripts/check-gate-qualification.ts", "--attribution-self-test"],
|
|
180
|
+
"timeoutSeconds": 60,
|
|
181
|
+
"signature": "[QK:VITEST-FAILED-TITLE-ATTRIBUTION]",
|
|
182
|
+
"signatureSource": "scripts/check-gate-qualification.ts"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "mux-launcher-fence",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "LAUNCHFENCE-PREFLIGHT-FAIL-CLOSED",
|
|
7
|
+
"title": "the preflight stops checking where the launcher RESOLVES to, so a launcher already pointing into the fixture is pinned and launched anyway",
|
|
8
|
+
"subject": "scripts/lib/claude-launcher-fence.ts",
|
|
9
|
+
"find": [
|
|
10
|
+
"\tif (isInside(fixtureRoot, resolvedPath)) {",
|
|
11
|
+
"\t\tthrow new Error(",
|
|
12
|
+
"\t\t\t`claude-launcher-fence: fail-closed — the launcher's resolved target ${resolvedPath} is INSIDE the fixture cleanup root ${fixtureRoot}`,",
|
|
13
|
+
"\t\t);",
|
|
14
|
+
"\t}"
|
|
15
|
+
],
|
|
16
|
+
"replace": ["\t// the launcher-path containment check above already walks the fixture axis"],
|
|
17
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
18
|
+
"timeoutSeconds": 120,
|
|
19
|
+
"signature": "[QK:LAUNCHFENCE-PREFLIGHT-FAIL-CLOSED]",
|
|
20
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"claim": "LAUNCHFENCE-RETARGET-BLOCKS-CLEANUP",
|
|
24
|
+
"title": "the cleanup guard stops naming a KNOWN symlink-hop fixture reference, so the incident's dangling retarget is demoted to a vague unproven state",
|
|
25
|
+
"subject": "scripts/lib/claude-launcher-fence.ts",
|
|
26
|
+
"find": [
|
|
27
|
+
"\t\tif (isInside(snapshot.fixtureRoot, hop)) {",
|
|
28
|
+
"\t\t\treturn {",
|
|
29
|
+
"\t\t\t\tsafeToRemove: false,",
|
|
30
|
+
"\t\t\t\tproblems: [`the launcher's link target ${hop} lies inside the fixture cleanup root`],",
|
|
31
|
+
"\t\t\t};",
|
|
32
|
+
"\t\t}"
|
|
33
|
+
],
|
|
34
|
+
"replace": ["\t\t// the realpath walk below covers the symlink hop"],
|
|
35
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
36
|
+
"timeoutSeconds": 120,
|
|
37
|
+
"signature": "[QK:LAUNCHFENCE-RETARGET-BLOCKS-CLEANUP]",
|
|
38
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"claim": "LAUNCHFENCE-CONTENT-CHANGE-DETECTED",
|
|
42
|
+
"title": "the integrity oracle drops content identity, so an in-place rewrite of the resolved target passes teardown unreported",
|
|
43
|
+
"subject": "scripts/lib/claude-launcher-fence.ts",
|
|
44
|
+
"find": [
|
|
45
|
+
"\t\t} else {",
|
|
46
|
+
"\t\t\ttry {",
|
|
47
|
+
"\t\t\t\tif (sha256File(resolvedNow) !== snapshot.sha256) {",
|
|
48
|
+
"\t\t\t\t\tproblems.push(`the launcher's resolved target ${resolvedNow} changed content (sha256 mismatch)`);",
|
|
49
|
+
"\t\t\t\t}",
|
|
50
|
+
"\t\t\t} catch (err) {",
|
|
51
|
+
"\t\t\t\tproblems.push(",
|
|
52
|
+
"\t\t\t\t\t`the launcher's resolved target ${resolvedNow} could not be hashed: ${err instanceof Error ? err.message : String(err)}`,",
|
|
53
|
+
"\t\t\t\t);",
|
|
54
|
+
"\t\t\t}",
|
|
55
|
+
"\t\t}"
|
|
56
|
+
],
|
|
57
|
+
"replace": ["\t\t}"],
|
|
58
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
59
|
+
"timeoutSeconds": 120,
|
|
60
|
+
"signature": "[QK:LAUNCHFENCE-CONTENT-CHANGE-DETECTED]",
|
|
61
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"claim": "LAUNCHFENCE-XDG-EXACT-RESTORE",
|
|
65
|
+
"title": "an originally absent XDG variable is filled with a canonical default instead of being deleted — a guess about how the runtime reads its config, not operator parity",
|
|
66
|
+
"subject": "scripts/lib/claude-launcher-fence.ts",
|
|
67
|
+
"find": [
|
|
68
|
+
"\t\tif (original === null || original === undefined) delete env[name];",
|
|
69
|
+
"\t\telse env[name] = original;"
|
|
70
|
+
],
|
|
71
|
+
"replace": [
|
|
72
|
+
"\t\tif (original === null || original === undefined) env[name] = path.join(env.HOME ?? \"\", \".local\", \"share\");",
|
|
73
|
+
"\t\telse env[name] = original;"
|
|
74
|
+
],
|
|
75
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
76
|
+
"timeoutSeconds": 120,
|
|
77
|
+
"signature": "[QK:LAUNCHFENCE-XDG-EXACT-RESTORE]",
|
|
78
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"claim": "LAUNCHFENCE-WIRED-LIFECYCLE",
|
|
82
|
+
"title": "the lifecycle smoke disconnects the integrity oracle from its teardown, so the fence exists but nothing runs it before fixture removal",
|
|
83
|
+
"subject": "scripts/smoke-mux-lifecycle-live.ts",
|
|
84
|
+
"find": ["\tconst launcherProblems = verifyClaudeLauncher(launcherSnapshot);"],
|
|
85
|
+
"replace": ["\tconst launcherProblems: string[] = [];"],
|
|
86
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
87
|
+
"timeoutSeconds": 120,
|
|
88
|
+
"signature": "[QK:LAUNCHFENCE-WIRED-LIFECYCLE]",
|
|
89
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"claim": "LAUNCHFENCE-LIFECYCLE-CELL-BRANCH",
|
|
93
|
+
"title": "lifecycle's real-HOME cell env collapses to one branch — exact parity for every cell — silently dropping the ACP pi cell's MEASURED canonical XDG requirement",
|
|
94
|
+
"subject": "scripts/smoke-mux-lifecycle-live.ts",
|
|
95
|
+
"find": [
|
|
96
|
+
"\t\t\t\tif (backend === \"pi\") {",
|
|
97
|
+
"\t\t\t\t\tserverEnv.XDG_CONFIG_HOME = REAL_XDG_CONFIG_HOME;",
|
|
98
|
+
"\t\t\t\t\tserverEnv.XDG_DATA_HOME = REAL_XDG_DATA_HOME;",
|
|
99
|
+
"\t\t\t\t\tserverEnv.XDG_STATE_HOME = REAL_XDG_STATE_HOME;",
|
|
100
|
+
"\t\t\t\t\tserverEnv.XDG_CACHE_HOME = REAL_XDG_CACHE_HOME;",
|
|
101
|
+
"\t\t\t\t} else {",
|
|
102
|
+
"\t\t\t\t\trestoreOriginalXdg(serverEnv, ORIGINAL_XDG);",
|
|
103
|
+
"\t\t\t\t}"
|
|
104
|
+
],
|
|
105
|
+
"replace": ["\t\t\t\trestoreOriginalXdg(serverEnv, ORIGINAL_XDG);"],
|
|
106
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
107
|
+
"timeoutSeconds": 120,
|
|
108
|
+
"signature": "[QK:LAUNCHFENCE-LIFECYCLE-CELL-BRANCH]",
|
|
109
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"claim": "LAUNCHFENCE-WIRED-FRESH-CALL",
|
|
113
|
+
"title": "the fresh-call smoke disconnects the integrity oracle from its teardown, so only one of the two affected smokes is actually protected",
|
|
114
|
+
"subject": "scripts/smoke-mux-fresh-call-live.ts",
|
|
115
|
+
"find": ["\t\tconst launcherProblems = verifyClaudeLauncher(launcherSnapshot);"],
|
|
116
|
+
"replace": ["\t\tconst launcherProblems: string[] = [];"],
|
|
117
|
+
"gate": ["bash", "run.sh", "check-mux-launcher-fence"],
|
|
118
|
+
"timeoutSeconds": 120,
|
|
119
|
+
"signature": "[QK:LAUNCHFENCE-WIRED-FRESH-CALL]",
|
|
120
|
+
"signatureSource": "scripts/check-mux-launcher-fence.ts"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "mux-parent-artifact",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "MUXARTIFACT-NONCE-FLOW",
|
|
7
|
+
"title": "the callback body carries a different nonce than the launch receipt, documenting a correlation rail that does not exist",
|
|
8
|
+
"subject": "scripts/fixtures/mux-parent-transcript.scrubbed.jsonl",
|
|
9
|
+
"find": ["mux-fresh-call-000000000000000000000000\\n\\n<sender_info>"],
|
|
10
|
+
"replace": ["mux-fresh-call-999999999999999999999999\\n\\n<sender_info>"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-mux-parent-artifact"],
|
|
12
|
+
"timeoutSeconds": 60,
|
|
13
|
+
"signature": "[QK:MUXARTIFACT-NONCE-FLOW]",
|
|
14
|
+
"signatureSource": "scripts/check-mux-parent-artifact.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"claim": "MUXARTIFACT-SENDER-INFO-SHAPE",
|
|
18
|
+
"title": "the envelope's sessionId field is renamed, so the fixture documents a parser that cannot read a real callback",
|
|
19
|
+
"subject": "scripts/fixtures/mux-parent-transcript.scrubbed.jsonl",
|
|
20
|
+
"find": ["<sender_info>{\\\"sessionId\\\":"],
|
|
21
|
+
"replace": ["<sender_info>{\\\"gardenId\\\":"],
|
|
22
|
+
"gate": ["bash", "run.sh", "check-mux-parent-artifact"],
|
|
23
|
+
"timeoutSeconds": 60,
|
|
24
|
+
"signature": "[QK:MUXARTIFACT-SENDER-INFO-SHAPE]",
|
|
25
|
+
"signatureSource": "scripts/check-mux-parent-artifact.ts"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"claim": "MUXARTIFACT-RECEIPT-GRAMMAR",
|
|
29
|
+
"title": "the scrubbed session id is collapsed onto the window sigil, documenting a receipt tmux never emits",
|
|
30
|
+
"subject": "scripts/fixtures/mux-parent-transcript.scrubbed.jsonl",
|
|
31
|
+
"find": ["in session $0"],
|
|
32
|
+
"replace": ["in session @0"],
|
|
33
|
+
"gate": ["bash", "run.sh", "check-mux-parent-artifact"],
|
|
34
|
+
"timeoutSeconds": 60,
|
|
35
|
+
"signature": "[QK:MUXARTIFACT-RECEIPT-GRAMMAR]",
|
|
36
|
+
"signatureSource": "scripts/check-mux-parent-artifact.ts"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|