@junghanacs/entwurf 0.38.1 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/BASELINE.md +11 -4
  2. package/CHANGELOG.md +323 -0
  3. package/DELIVERY.md +34 -0
  4. package/LICENSES/node-gyp.txt +24 -0
  5. package/README.md +20 -6
  6. package/VERIFY.md +23 -4
  7. package/docs/setup-clean-host.md +43 -2
  8. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +32 -9
  9. package/mcp/entwurf-bridge/dist/pi-extensions/lib/control-socket-path.js +56 -1
  10. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +25 -0
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-mailbox-body.js +10 -4
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +14 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-receive.js +123 -0
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +259 -0
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-transport.js +80 -0
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-discovery.js +14 -2
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-probe.js +21 -0
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/win32-native.js +182 -0
  19. package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +65 -0
  20. package/mcp/entwurf-bridge/src/index.ts +38 -9
  21. package/mcp/entwurf-bridge/tsconfig.build.json +7 -0
  22. package/native/win32-x64/entwurf_win.node +0 -0
  23. package/native/win32-x64/manifest.json +45 -0
  24. package/package.json +5 -3
  25. package/pi-extensions/entwurf-control.ts +6 -1
  26. package/pi-extensions/lib/control-socket-path.js +56 -1
  27. package/pi-extensions/lib/entwurf-control-rpc.ts +32 -0
  28. package/pi-extensions/lib/meta-mailbox-body.ts +13 -4
  29. package/pi-extensions/lib/meta-session.ts +14 -0
  30. package/pi-extensions/lib/remote-pair-receive.ts +184 -0
  31. package/pi-extensions/lib/remote-pair-send.ts +325 -0
  32. package/pi-extensions/lib/remote-pair-transport.ts +81 -0
  33. package/pi-extensions/lib/socket-discovery.ts +12 -1
  34. package/pi-extensions/lib/socket-probe.ts +20 -0
  35. package/pi-extensions/lib/win32-native.js +198 -0
  36. package/run.sh +149 -1
  37. package/scripts/check-entwurf-self-address.ts +15 -4
  38. package/scripts/check-gate-qualification.ts +8 -1
  39. package/scripts/check-remote-pair-installed.ts +242 -0
  40. package/scripts/lib/remote-pair-installed-audit.ts +25 -0
  41. package/scripts/mutants/control-send-receipt.json +2 -2
  42. package/scripts/mutants/pack-install.json +28 -2
  43. package/scripts/mutants/remote-pair-display.json +53 -0
  44. package/scripts/mutants/remote-pair-installed-audit.json +28 -0
  45. package/scripts/mutants/remote-pair-receive.json +126 -0
  46. package/scripts/mutants/remote-pair-roundtrip.json +83 -0
  47. package/scripts/mutants/remote-pair-send.json +194 -0
  48. package/scripts/mutants/remote-pair-transport.json +66 -0
  49. package/scripts/mutants/win32-preview.json +215 -0
  50. package/scripts/remote-pair-receive.ts +73 -0
@@ -0,0 +1,53 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-display",
4
+ "mutants": [
5
+ {
6
+ "claim": "REMOTE-DISPLAY-LOCAL-UNCHANGED",
7
+ "title": "the remote branch is taken for every non-replyable sender, so an ordinary external or meta-session header turns into a remote line naming a route that does not exist",
8
+ "subject": "pi-extensions/lib/meta-mailbox-body.ts",
9
+ "find": ["\tconst remote = !replyable ? sender.remote : undefined;"],
10
+ "replace": [
11
+ "\tconst remote = !replyable ? (sender.remote ?? { via: \"?\", replyRoute: \"none\" as const }) : undefined;"
12
+ ],
13
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
14
+ "timeoutSeconds": 600,
15
+ "signature": "[QK:REMOTE-DISPLAY-LOCAL-UNCHANGED]",
16
+ "signatureSource": "pi-extensions/lib/meta-mailbox-body.test.ts",
17
+ "build": {
18
+ "argv": ["bash", "scripts/build-bridge.sh"],
19
+ "output": "mcp/entwurf-bridge/dist"
20
+ }
21
+ },
22
+ {
23
+ "claim": "REMOTE-DISPLAY-SESSIONLINE",
24
+ "title": "a remote sender with a declared route back is told to reply via entwurf_v2 as if that route had been probed",
25
+ "subject": "pi-extensions/lib/meta-mailbox-body.ts",
26
+ "find": ["\"reply route declared, not probed\""],
27
+ "replace": ["\"reply via entwurf_v2 to this sessionId\""],
28
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
29
+ "timeoutSeconds": 600,
30
+ "signature": "[QK:REMOTE-DISPLAY-SESSIONLINE]",
31
+ "signatureSource": "pi-extensions/lib/meta-mailbox-body.test.ts",
32
+ "build": {
33
+ "argv": ["bash", "scripts/build-bridge.sh"],
34
+ "output": "mcp/entwurf-bridge/dist"
35
+ }
36
+ },
37
+ {
38
+ "claim": "REMOTE-DISPLAY-SENDER-HOST-CWD",
39
+ "title": "a remote sender's cwd is abbreviated against this host's HOME, so a path on the other machine reads as a local one",
40
+ "subject": "pi-extensions/lib/meta-mailbox-body.ts",
41
+ "find": ["\tconst where = remote ? `${sender.cwd} (sender-host path)` : abbreviateHome(sender.cwd);"],
42
+ "replace": ["\tconst where = abbreviateHome(sender.cwd);"],
43
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
44
+ "timeoutSeconds": 600,
45
+ "signature": "[QK:REMOTE-DISPLAY-SENDER-HOST-CWD]",
46
+ "signatureSource": "pi-extensions/lib/meta-mailbox-body.test.ts",
47
+ "build": {
48
+ "argv": ["bash", "scripts/build-bridge.sh"],
49
+ "output": "mcp/entwurf-bridge/dist"
50
+ }
51
+ }
52
+ ]
53
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-installed-audit",
4
+ "mutants": [
5
+ {
6
+ "claim": "RPI-AUDIT-REAL-PATH",
7
+ "title": "the installed-closure audit judges a resolved file by its link path, so an installed file that is a symlink into a checkout passes as inside the consumer",
8
+ "subject": "scripts/lib/remote-pair-installed-audit.ts",
9
+ "find": ["\t\t\tconst real = fs.realpathSync(fileURLToPath(url));"],
10
+ "replace": ["\t\t\tconst real = fileURLToPath(url);"],
11
+ "gate": ["bash", "run.sh", "check-remote-pair-installed-audit"],
12
+ "timeoutSeconds": 120,
13
+ "signature": "[QK:RPI-AUDIT-REAL-PATH]",
14
+ "signatureSource": "test/remote-pair-installed-audit.test.ts"
15
+ },
16
+ {
17
+ "claim": "RPI-AUDIT-ROOT-BOUNDARY",
18
+ "title": "the installed-closure audit treats any path that merely starts with the consumer prefix as inside it, so a sibling directory such as <prefix>-x passes",
19
+ "subject": "scripts/lib/remote-pair-installed-audit.ts",
20
+ "find": ["\t\t\tif (real !== realRoot && !real.startsWith(`${realRoot}${path.sep}`)) out.add(real);"],
21
+ "replace": ["\t\t\tif (real !== realRoot && !real.startsWith(realRoot)) out.add(real);"],
22
+ "gate": ["bash", "run.sh", "check-remote-pair-installed-audit"],
23
+ "timeoutSeconds": 120,
24
+ "signature": "[QK:RPI-AUDIT-ROOT-BOUNDARY]",
25
+ "signatureSource": "test/remote-pair-installed-audit.test.ts"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-receive",
4
+ "mutants": [
5
+ {
6
+ "claim": "REMOTE-PAIR-FROM-OUTSIDE-NO-MUTATION",
7
+ "title": "the receiving entry stops checking the claimed sender against the declared pair, so any gid the SSH account writes is dispatched into the declared target's mailbox",
8
+ "subject": "pi-extensions/lib/remote-pair-receive.ts",
9
+ "find": ["\tif (claim.from !== decl.remoteGardenId) {"],
10
+ "replace": ["\tif (false) {"],
11
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
12
+ "timeoutSeconds": 600,
13
+ "signature": "[QK:REMOTE-PAIR-FROM-OUTSIDE-NO-MUTATION]",
14
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
15
+ "build": {
16
+ "argv": ["bash", "scripts/build-bridge.sh"],
17
+ "output": "mcp/entwurf-bridge/dist"
18
+ }
19
+ },
20
+ {
21
+ "claim": "REMOTE-PAIR-TARGET-OUTSIDE-NO-MUTATION",
22
+ "title": "the receiving entry stops checking the claimed target against the declared pair, so a declared remote can reach every deliverable citizen on this host",
23
+ "subject": "pi-extensions/lib/remote-pair-receive.ts",
24
+ "find": ["\tif (claim.target !== decl.localGardenId) {"],
25
+ "replace": ["\tif (false) {"],
26
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
27
+ "timeoutSeconds": 600,
28
+ "signature": "[QK:REMOTE-PAIR-TARGET-OUTSIDE-NO-MUTATION]",
29
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
30
+ "build": {
31
+ "argv": ["bash", "scripts/build-bridge.sh"],
32
+ "output": "mcp/entwurf-bridge/dist"
33
+ }
34
+ },
35
+ {
36
+ "claim": "REMOTE-PAIR-IGNORES-AMBIENT-SENDER",
37
+ "title": "the receiving entry lets an ambient PI_SESSION_ID in the SSH environment stand in for the sender, so the header names whoever's carrier leaked instead of the claim",
38
+ "subject": "pi-extensions/lib/remote-pair-receive.ts",
39
+ "find": ["\t\tsessionId: claim.from,"],
40
+ "replace": ["\t\tsessionId: process.env.PI_SESSION_ID ?? claim.from,"],
41
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
42
+ "timeoutSeconds": 600,
43
+ "signature": "[QK:REMOTE-PAIR-IGNORES-AMBIENT-SENDER]",
44
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
45
+ "build": {
46
+ "argv": ["bash", "scripts/build-bridge.sh"],
47
+ "output": "mcp/entwurf-bridge/dist"
48
+ }
49
+ },
50
+ {
51
+ "claim": "REMOTE-PAIR-MATCH-DISPATCHES-ONCE",
52
+ "title": "the receiving entry marks a remote sender replyable, so the body tells the receiver to reply via entwurf_v2 as if a live local reply route had been probed — none was",
53
+ "subject": "pi-extensions/lib/remote-pair-receive.ts",
54
+ "find": ["\t\treplyable: false,"],
55
+ "replace": ["\t\treplyable: true,"],
56
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
57
+ "timeoutSeconds": 600,
58
+ "signature": "[QK:REMOTE-PAIR-MATCH-DISPATCHES-ONCE]",
59
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
60
+ "build": {
61
+ "argv": ["bash", "scripts/build-bridge.sh"],
62
+ "output": "mcp/entwurf-bridge/dist"
63
+ }
64
+ },
65
+ {
66
+ "claim": "REMOTE-PAIR-CLAIM-EXACT-SHAPE",
67
+ "title": "the claim parser accepts extra or missing fields, so a sender-side field the receiver never reads can ride in and a partial claim is dispatched",
68
+ "subject": "pi-extensions/lib/remote-pair-receive.ts",
69
+ "find": ["\tif (got.length !== want.length || got.some((k, i) => k !== want[i])) {"],
70
+ "replace": ["\tif (false) {"],
71
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
72
+ "timeoutSeconds": 600,
73
+ "signature": "[QK:REMOTE-PAIR-CLAIM-EXACT-SHAPE]",
74
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
75
+ "build": {
76
+ "argv": ["bash", "scripts/build-bridge.sh"],
77
+ "output": "mcp/entwurf-bridge/dist"
78
+ }
79
+ },
80
+ {
81
+ "claim": "REMOTE-PAIR-ENTRY-REFUSES-OUTSIDE",
82
+ "title": "the entry reports a pair refusal as exit 0, so the sending host cannot tell a refused claim from a dispatched one without parsing prose",
83
+ "subject": "scripts/remote-pair-receive.ts",
84
+ "find": ["emit(receipt, receipt.kind === \"rejected\" ? 3 : receipt.isError ? 4 : 0);"],
85
+ "replace": ["emit(receipt, receipt.kind === \"rejected\" ? 0 : receipt.isError ? 4 : 0);"],
86
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
87
+ "timeoutSeconds": 600,
88
+ "signature": "[QK:REMOTE-PAIR-ENTRY-REFUSES-OUTSIDE]",
89
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
90
+ "build": {
91
+ "argv": ["bash", "scripts/build-bridge.sh"],
92
+ "output": "mcp/entwurf-bridge/dist"
93
+ }
94
+ },
95
+ {
96
+ "claim": "REMOTE-PAIR-ENTRY-USAGE",
97
+ "title": "the entry accepts any --pair it is given, so the sender picks which declaration scopes the claim on the receiving host",
98
+ "subject": "scripts/remote-pair-receive.ts",
99
+ "find": ["\tif (!path.isAbsolute(pairFile) || path.normalize(pairFile) !== own) {"],
100
+ "replace": ["\tif (false) {"],
101
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
102
+ "timeoutSeconds": 600,
103
+ "signature": "[QK:REMOTE-PAIR-ENTRY-USAGE]",
104
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
105
+ "build": {
106
+ "argv": ["bash", "scripts/build-bridge.sh"],
107
+ "output": "mcp/entwurf-bridge/dist"
108
+ }
109
+ },
110
+ {
111
+ "claim": "REMOTE-PAIR-ENTRY-REPLY-ROUTE-DECLARED",
112
+ "title": "the entry reports no route back for a claim its own opt-in pairs with, so the receiver is told it cannot answer a sender it has declared",
113
+ "subject": "scripts/remote-pair-receive.ts",
114
+ "find": ["\treplyRoute: \"declared\","],
115
+ "replace": ["\treplyRoute: \"none\","],
116
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
117
+ "timeoutSeconds": 600,
118
+ "signature": "[QK:REMOTE-PAIR-ENTRY-REPLY-ROUTE-DECLARED]",
119
+ "signatureSource": "pi-extensions/lib/remote-pair-receive.test.ts",
120
+ "build": {
121
+ "argv": ["bash", "scripts/build-bridge.sh"],
122
+ "output": "mcp/entwurf-bridge/dist"
123
+ }
124
+ }
125
+ ]
126
+ }
@@ -0,0 +1,83 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-roundtrip",
4
+ "mutants": [
5
+ {
6
+ "claim": "REMOTE-ROUNDTRIP-A-TO-B",
7
+ "title": "the bridge never reads the opt-in, so a declared remote target falls through to the local decider as bad-target",
8
+ "subject": "mcp/entwurf-bridge/src/index.ts",
9
+ "find": ["\t\t\t\t\troute: readRemotePairOptIn(remotePairOptInPath()),"],
10
+ "replace": ["\t\t\t\t\troute: null,"],
11
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
12
+ "timeoutSeconds": 600,
13
+ "signature": "[QK:REMOTE-ROUNDTRIP-A-TO-B]",
14
+ "signatureSource": "pi-extensions/lib/remote-pair-roundtrip.test.ts",
15
+ "build": {
16
+ "argv": ["bash", "scripts/build-bridge.sh"],
17
+ "output": "mcp/entwurf-bridge/dist"
18
+ }
19
+ },
20
+ {
21
+ "claim": "REMOTE-ROUNDTRIP-REVERSE-DISPATCH",
22
+ "title": "the bridge's transport never reaches the other host and always answers exit 1, so every declared remote send in either direction becomes indeterminate",
23
+ "subject": "mcp/entwurf-bridge/src/index.ts",
24
+ "find": ["\t\t\t\t\ttransport: processTransport,"],
25
+ "replace": [
26
+ "\t\t\t\t\ttransport: { run: async () => ({ exitCode: 1, signal: null, timedOut: false, stdout: \"\", stderr: \"\" }) },"
27
+ ],
28
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
29
+ "timeoutSeconds": 600,
30
+ "signature": "[QK:REMOTE-ROUNDTRIP-REVERSE-DISPATCH]",
31
+ "signatureSource": "pi-extensions/lib/remote-pair-roundtrip.test.ts",
32
+ "build": {
33
+ "argv": ["bash", "scripts/build-bridge.sh"],
34
+ "output": "mcp/entwurf-bridge/dist"
35
+ }
36
+ },
37
+ {
38
+ "claim": "REMOTE-ROUNDTRIP-OPT-IN-ABSENT-OFF",
39
+ "title": "the bridge replaces the local surface on the remote path's behalf, so a host with no opt-in stops running the existing local decider",
40
+ "subject": "mcp/entwurf-bridge/src/index.ts",
41
+ "find": ["\t\t\t\t\trunLocal: (params, opts) => runAndRenderEntwurfV2FromSurface(params, opts),"],
42
+ "replace": ["\t\t\t\t\trunLocal: async () => ({ isError: false, text: \"local skipped\" }),"],
43
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
44
+ "timeoutSeconds": 600,
45
+ "signature": "[QK:REMOTE-ROUNDTRIP-OPT-IN-ABSENT-OFF]",
46
+ "signatureSource": "pi-extensions/lib/remote-pair-roundtrip.test.ts",
47
+ "build": {
48
+ "argv": ["bash", "scripts/build-bridge.sh"],
49
+ "output": "mcp/entwurf-bridge/dist"
50
+ }
51
+ },
52
+ {
53
+ "claim": "REMOTE-ROUNDTRIP-OTHER-HOST-REFUSES",
54
+ "title": "the sender renders the other host's pair refusal without naming it, so A cannot tell B refused the pair from any other failure",
55
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
56
+ "find": ["refused by the other host's pair: ${o.reason} (${o.detail})"],
57
+ "replace": ["failed"],
58
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
59
+ "timeoutSeconds": 600,
60
+ "signature": "[QK:REMOTE-ROUNDTRIP-OTHER-HOST-REFUSES]",
61
+ "signatureSource": "pi-extensions/lib/remote-pair-roundtrip.test.ts",
62
+ "build": {
63
+ "argv": ["bash", "scripts/build-bridge.sh"],
64
+ "output": "mcp/entwurf-bridge/dist"
65
+ }
66
+ },
67
+ {
68
+ "claim": "REMOTE-ROUNDTRIP-LOCAL-TRACE-BOTH-SOCKET-DIRS",
69
+ "title": "the bridge checks only its own ENTWURF_DIR, so a live local socket in the decider's canonical dir is bypassed and the gid is sent away",
70
+ "subject": "mcp/entwurf-bridge/src/index.ts",
71
+ "find": ["\t\t\t\t\t\tcontrolSocketDirs: [CONTROL_SOCKET_DIR, ENTWURF_DIR],"],
72
+ "replace": ["\t\t\t\t\t\tcontrolSocketDirs: [ENTWURF_DIR],"],
73
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
74
+ "timeoutSeconds": 600,
75
+ "signature": "[QK:REMOTE-ROUNDTRIP-LOCAL-TRACE-BOTH-SOCKET-DIRS]",
76
+ "signatureSource": "pi-extensions/lib/remote-pair-roundtrip.test.ts",
77
+ "build": {
78
+ "argv": ["bash", "scripts/build-bridge.sh"],
79
+ "output": "mcp/entwurf-bridge/dist"
80
+ }
81
+ }
82
+ ]
83
+ }
@@ -0,0 +1,194 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-send",
4
+ "mutants": [
5
+ {
6
+ "claim": "REMOTE-ROUTE-UNDECLARED-LOCAL-UNCHANGED",
7
+ "title": "a declared route captures every target, so a gid the declaration never named is sent to the other host instead of the local decider",
8
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
9
+ "find": ["\tif (route === null || params.target !== route.remoteGardenId) {"],
10
+ "replace": ["\tif (route === null) {"],
11
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
12
+ "timeoutSeconds": 600,
13
+ "signature": "[QK:REMOTE-ROUTE-UNDECLARED-LOCAL-UNCHANGED]",
14
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
15
+ "build": {
16
+ "argv": ["bash", "scripts/build-bridge.sh"],
17
+ "output": "mcp/entwurf-bridge/dist"
18
+ }
19
+ },
20
+ {
21
+ "claim": "REMOTE-ROUTE-LOCAL-CONFLICT-FAILS-CLOSED",
22
+ "title": "a declared remote gid that this host also answers to is sent away anyway, so two hosts' citizens share one address and the sender silently picks the remote",
23
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
24
+ "find": ["\tif (await opts.localTrace(route.remoteGardenId)) {"],
25
+ "replace": ["\tif (Boolean(0)) {"],
26
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
27
+ "timeoutSeconds": 600,
28
+ "signature": "[QK:REMOTE-ROUTE-LOCAL-CONFLICT-FAILS-CLOSED]",
29
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
30
+ "build": {
31
+ "argv": ["bash", "scripts/build-bridge.sh"],
32
+ "output": "mcp/entwurf-bridge/dist"
33
+ }
34
+ },
35
+ {
36
+ "claim": "REMOTE-ROUTE-SENDER-MUST-BE-DECLARED",
37
+ "title": "any present envelope may use the route, so an anonymous caller or another citizen on this host speaks to the other host as the declared sender",
38
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
39
+ "find": ["\tif (!sender || sender.origin === \"external-mcp\" || sender.sessionId !== route.localGardenId) {"],
40
+ "replace": ["\tif (!sender || Boolean(0)) {"],
41
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
42
+ "timeoutSeconds": 600,
43
+ "signature": "[QK:REMOTE-ROUTE-SENDER-MUST-BE-DECLARED]",
44
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
45
+ "build": {
46
+ "argv": ["bash", "scripts/build-bridge.sh"],
47
+ "output": "mcp/entwurf-bridge/dist"
48
+ }
49
+ },
50
+ {
51
+ "claim": "REMOTE-ROUTE-EXACT-ARGV-ONCE",
52
+ "title": "the transport runs ssh without BatchMode, so a missing key turns into an interactive prompt nobody can answer instead of a bounded failure",
53
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
54
+ "find": ["\t\t\"BatchMode=yes\","],
55
+ "replace": ["\t\t\"BatchMode=no\","],
56
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
57
+ "timeoutSeconds": 600,
58
+ "signature": "[QK:REMOTE-ROUTE-EXACT-ARGV-ONCE]",
59
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
60
+ "build": {
61
+ "argv": ["bash", "scripts/build-bridge.sh"],
62
+ "output": "mcp/entwurf-bridge/dist"
63
+ }
64
+ },
65
+ {
66
+ "claim": "REMOTE-ROUTE-NO-RETRY",
67
+ "title": "the send runs the transport a second time, so an uncertain first attempt can enqueue the same message twice on the other host",
68
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
69
+ "find": ["\tconst result = await opts.transport.run("],
70
+ "replace": [
71
+ "\tawait opts.transport.run(remoteReceiveArgv(route), JSON.stringify(claim), 1);\n\tconst result = await opts.transport.run("
72
+ ],
73
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
74
+ "timeoutSeconds": 600,
75
+ "signature": "[QK:REMOTE-ROUTE-NO-RETRY]",
76
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
77
+ "build": {
78
+ "argv": ["bash", "scripts/build-bridge.sh"],
79
+ "output": "mcp/entwurf-bridge/dist"
80
+ }
81
+ },
82
+ {
83
+ "claim": "REMOTE-RECEIPT-EXIT-AND-KIND-AGREE",
84
+ "title": "an accepted-looking JSON line counts as accepted whatever the exit code says, so a refusal or a crash after printing reads as delivery",
85
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
86
+ "find": [
87
+ "\tif (r.exitCode === 0 && keys === \"isError,kind,text\" && o.kind === \"dispatched\" && o.isError === false) {"
88
+ ],
89
+ "replace": ["\tif (keys === \"isError,kind,text\" && o.kind === \"dispatched\" && o.isError === false) {"],
90
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
91
+ "timeoutSeconds": 600,
92
+ "signature": "[QK:REMOTE-RECEIPT-EXIT-AND-KIND-AGREE]",
93
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
94
+ "build": {
95
+ "argv": ["bash", "scripts/build-bridge.sh"],
96
+ "output": "mcp/entwurf-bridge/dist"
97
+ }
98
+ },
99
+ {
100
+ "claim": "REMOTE-ROUTE-DECL-NO-QUOTING-NEEDED",
101
+ "title": "the remote declaration path may carry spaces or shell metacharacters, which ssh joins into the remote shell string and the other host reinterprets",
102
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
103
+ "find": ["const REMOTE_PATH = /^\\/[A-Za-z0-9._/-]+$/;"],
104
+ "replace": ["const REMOTE_PATH = /^\\/.+$/;"],
105
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
106
+ "timeoutSeconds": 600,
107
+ "signature": "[QK:REMOTE-ROUTE-DECL-NO-QUOTING-NEEDED]",
108
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
109
+ "build": {
110
+ "argv": ["bash", "scripts/build-bridge.sh"],
111
+ "output": "mcp/entwurf-bridge/dist"
112
+ }
113
+ },
114
+ {
115
+ "claim": "REMOTE-ROUTE-LOCAL-TRACE-ANY-STATE",
116
+ "title": "a socket at the gid's control path in a named socket dir is not counted as a local trace, so a live local citizen without a record is bypassed for the remote",
117
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
118
+ "find": ["\t\t\tif (inspection.kind !== \"absent\") return true;"],
119
+ "replace": ["\t\t\tif (false) return true;"],
120
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
121
+ "timeoutSeconds": 600,
122
+ "signature": "[QK:REMOTE-ROUTE-LOCAL-TRACE-ANY-STATE]",
123
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
124
+ "build": {
125
+ "argv": ["bash", "scripts/build-bridge.sh"],
126
+ "output": "mcp/entwurf-bridge/dist"
127
+ }
128
+ },
129
+ {
130
+ "claim": "REMOTE-ROUTE-RECEIPT-PATHS-OTHER-HOST",
131
+ "title": "the accepted receipt drops the note that its paths are on the other host, so the other host's messagePath reads as a file the sender could open",
132
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
133
+ "find": ["read/answer unknown until a reply arrives; paths below are on the other host)"],
134
+ "replace": ["read/answer unknown until a reply arrives)"],
135
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
136
+ "timeoutSeconds": 600,
137
+ "signature": "[QK:REMOTE-ROUTE-RECEIPT-PATHS-OTHER-HOST]",
138
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
139
+ "build": {
140
+ "argv": ["bash", "scripts/build-bridge.sh"],
141
+ "output": "mcp/entwurf-bridge/dist"
142
+ }
143
+ },
144
+ {
145
+ "claim": "REMOTE-PAIR-OPT-IN-ABSENT-IS-OFF",
146
+ "title": "an absent opt-in file throws instead of meaning off, so every local send on a host that never opted in fails",
147
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
148
+ "find": ["\t\tif ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;"],
149
+ "replace": ["\t\tif (false) return null;"],
150
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
151
+ "timeoutSeconds": 600,
152
+ "signature": "[QK:REMOTE-PAIR-OPT-IN-ABSENT-IS-OFF]",
153
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
154
+ "build": {
155
+ "argv": ["bash", "scripts/build-bridge.sh"],
156
+ "output": "mcp/entwurf-bridge/dist"
157
+ }
158
+ },
159
+ {
160
+ "claim": "REMOTE-PAIR-OPT-IN-BROKEN-REFUSED",
161
+ "title": "a symlinked or non-regular opt-in is followed, so the route the bridge walks is whatever the link points at today",
162
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
163
+ "find": ["\tif (!st.isFile()) {\n\t\tthrow new RemoteRouteDeclarationError(`remote pair opt-in"],
164
+ "replace": ["\tif (false) {\n\t\tthrow new RemoteRouteDeclarationError(`remote pair opt-in"],
165
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
166
+ "timeoutSeconds": 600,
167
+ "signature": "[QK:REMOTE-PAIR-OPT-IN-BROKEN-REFUSED]",
168
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
169
+ "build": {
170
+ "argv": ["bash", "scripts/build-bridge.sh"],
171
+ "output": "mcp/entwurf-bridge/dist"
172
+ }
173
+ },
174
+ {
175
+ "claim": "REMOTE-REPORTED-ERROR-NO-DELIVERY-INFERENCE",
176
+ "title": "an error the other host reports after a possible write is headed as a non-delivery, inviting a resend that would deliver twice",
177
+ "subject": "pi-extensions/lib/remote-pair-send.ts",
178
+ "find": [
179
+ "\t\t\t\ttext: `entwurf_v2 remote ${via} → the other host reported an error while processing; read its receipt below, delivery is not inferred from this line; not retried (paths below are on the other host)\\n${o.text}`,"
180
+ ],
181
+ "replace": [
182
+ "\t\t\t\ttext: `entwurf_v2 remote ${via} → the other host did not deliver (paths below are on the other host)\\n${o.text}`,"
183
+ ],
184
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
185
+ "timeoutSeconds": 600,
186
+ "signature": "[QK:REMOTE-REPORTED-ERROR-NO-DELIVERY-INFERENCE]",
187
+ "signatureSource": "pi-extensions/lib/remote-pair-send.test.ts",
188
+ "build": {
189
+ "argv": ["bash", "scripts/build-bridge.sh"],
190
+ "output": "mcp/entwurf-bridge/dist"
191
+ }
192
+ }
193
+ ]
194
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "remote-pair-transport",
4
+ "mutants": [
5
+ {
6
+ "claim": "REMOTE-TRANSPORT-NO-SHELL-SEPARATE-STREAMS",
7
+ "title": "the transport runs its argv through a shell, so a remote declaration word is expanded on the sending host before ssh ever sees it",
8
+ "subject": "pi-extensions/lib/remote-pair-transport.ts",
9
+ "find": ["{ shell: false, stdio: [\"pipe\", \"pipe\", \"pipe\"] }"],
10
+ "replace": ["{ shell: true, stdio: [\"pipe\", \"pipe\", \"pipe\"] }"],
11
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
12
+ "timeoutSeconds": 600,
13
+ "signature": "[QK:REMOTE-TRANSPORT-NO-SHELL-SEPARATE-STREAMS]",
14
+ "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
15
+ "build": {
16
+ "argv": ["bash", "scripts/build-bridge.sh"],
17
+ "output": "mcp/entwurf-bridge/dist"
18
+ }
19
+ },
20
+ {
21
+ "claim": "REMOTE-TRANSPORT-TIMEOUT-REAPS-OWN-CHILD",
22
+ "title": "the bound only sends TERM, so an ssh child that ignores it outlives the send and the call never returns",
23
+ "subject": "pi-extensions/lib/remote-pair-transport.ts",
24
+ "find": ["\t\t\t\t\tchild.kill(\"SIGKILL\");"],
25
+ "replace": ["\t\t\t\t\tvoid 0;"],
26
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
27
+ "timeoutSeconds": 600,
28
+ "signature": "[QK:REMOTE-TRANSPORT-TIMEOUT-REAPS-OWN-CHILD]",
29
+ "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
30
+ "build": {
31
+ "argv": ["bash", "scripts/build-bridge.sh"],
32
+ "output": "mcp/entwurf-bridge/dist"
33
+ }
34
+ },
35
+ {
36
+ "claim": "REMOTE-TRANSPORT-SPAWN-FAILURE-INDETERMINATE",
37
+ "title": "a child that never started reports exit 0, so a missing ssh binary reads as a clean exit instead of an unknown outcome",
38
+ "subject": "pi-extensions/lib/remote-pair-transport.ts",
39
+ "find": ["\t\t\t\t\texitCode: spawnError ? null : code,"],
40
+ "replace": ["\t\t\t\t\texitCode: spawnError ? 0 : code,"],
41
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
42
+ "timeoutSeconds": 600,
43
+ "signature": "[QK:REMOTE-TRANSPORT-SPAWN-FAILURE-INDETERMINATE]",
44
+ "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
45
+ "build": {
46
+ "argv": ["bash", "scripts/build-bridge.sh"],
47
+ "output": "mcp/entwurf-bridge/dist"
48
+ }
49
+ },
50
+ {
51
+ "claim": "REMOTE-TRANSPORT-HELD-PIPES-STILL-SETTLE",
52
+ "title": "the send waits for a close that a pipe-holding descendant never lets happen, so one stuck remote leaves entwurf_v2 hanging forever",
53
+ "subject": "pi-extensions/lib/remote-pair-transport.ts",
54
+ "find": ["\t\t\t\t\tfinalTimer = setTimeout(() => {"],
55
+ "replace": ["\t\t\t\t\tfinalTimer = setTimeout(() => {\n\t\t\t\t\t\treturn;"],
56
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
57
+ "timeoutSeconds": 600,
58
+ "signature": "[QK:REMOTE-TRANSPORT-HELD-PIPES-STILL-SETTLE]",
59
+ "signatureSource": "pi-extensions/lib/remote-pair-transport.test.ts",
60
+ "build": {
61
+ "argv": ["bash", "scripts/build-bridge.sh"],
62
+ "output": "mcp/entwurf-bridge/dist"
63
+ }
64
+ }
65
+ ]
66
+ }