deadbyte-mcp 0.8.7 → 0.8.8
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/MANIFEST.SHA256 +46 -45
- package/README.txt +9 -1
- package/bin/WORKER-REGISTRY.txt +3 -3
- package/bin/appcontainer-stage.exe +0 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.exe +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.exe +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.exe +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.exe +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.exe +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.exe +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.exe +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.exe +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.exe +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.exe +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.exe +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.exe +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +14 -7
- package/controller/deadbyte-controller.ps1 +1 -1
- package/controller/deadbyte-process-policy.json +1 -1
- package/docs/ARCHITECTURE.md +7 -2
- package/package.json +1 -1
- package/scripts/deferred-slot-operation.mjs +1 -1
- package/scripts/final-closure-verify.mjs +3 -3
- package/scripts/final-closure.mjs +3 -3
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/windows-gate-evidence.mjs +4 -4
- package/src/deadbyte-cli.mjs +156 -7
- package/src/remote-mcp-r33-parity-client.mjs +1 -1
- package/src/version.mjs +1 -1
- package/test/core.test.mjs +1 -1
- package/test/r33-closeout-regression.test.mjs +1 -1
- package/test/r33-finalization.test.mjs +2 -2
- package/test/release-version.test.mjs +12 -12
- package/test/remote-session-cli.test.mjs +151 -0
package/MANIFEST.SHA256
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
bde1964535226804e68392837f5ae331fbbc96770ba48119b6ffbab97d6de8c7 bin/appcontainer-stage.exe
|
|
2
|
+
1e45ccca193a855a1459d7652d4868b3beb809dd15b1148ceecd0fa4b10b9262 bin/appcontainer-stage.obj
|
|
3
|
+
6203145a96488d74a0231ec88d88098eaa7299ab86c87baf3fc32c781164effa bin/bootstrap-advapi32.exe
|
|
4
|
+
998e5eadea269f886522fa81dc94f28d06f25801614c4517d9b9aec5f3104dc0 bin/bootstrap-advapi32.obj
|
|
5
|
+
cc490744c28841b0255468166e9b30be8909fde4b755a403c600348c5adbb7ac bin/bootstrap-exitcode.exe
|
|
6
|
+
2faf57970b25064b3b9b08a8fd3286925411a40b62544d5f4d83a81d095d0cca bin/bootstrap-exitcode.obj
|
|
7
|
+
9479a28a2b1d4b852aace47d22797f2e7b3f6033da67bd9704006077fd66249a bin/bootstrap-kernel32.exe
|
|
8
|
+
24ab7b165be0e1163df344eae310059e536b95989e0be62267485c7d36a8e733 bin/bootstrap-kernel32.obj
|
|
9
|
+
1910d31ae61b93bb819ecd89e59647ffe3daa3756195335d921bc67033140db8 bin/child-control-probe.exe
|
|
10
|
+
4d1ad4fac339be8165f6165765be4f6c53820d3f5d9ebb76d9113e010e5d0cd0 bin/child-control-probe.obj
|
|
11
|
+
04de94357c2624a5c44e07dd0a73af62929b67b71d93659b24c8c89cd353efcf bin/child-control-stage.exe
|
|
12
|
+
5c43588f4b4be151b213cf85d66d5ceaa896e429080ad50330e2b9545e98417f bin/child-control-stage.obj
|
|
13
|
+
8d7c3557b65bef05c34205a2602c0a78b4f4ecc3f406b6ff12f7426841ac993f bin/contained-reverse-worker.exe
|
|
14
|
+
d719ebd54247365782249bfcb5b9c878bd68573c08f20b88a50b807457454a8f bin/contained-reverse-worker.obj
|
|
15
|
+
516c364213ba55735b2cedb2cd1a55aa4806b384e027b8c2a679c1d5a5245d44 bin/contained-transform-worker.exe
|
|
16
|
+
f1d07cdf627a967f78a060eecfbec67f815fe3c152ea8282238e10d5f5afa7a7 bin/contained-transform-worker.obj
|
|
17
|
+
49d90123ee929888e487fa46dc7ac9419b82e0e01c0fe5266323f3c51f5417ba bin/containment-probe.exe
|
|
18
|
+
b6e7ba245226d027fb1775517f484479243c097108e6f4cf52be28f6bbc4c83a bin/containment-probe.obj
|
|
19
|
+
1d1ad5bd3547a9cff3af75fa067a0c96100b53d3dba41224f93618937a51631d bin/deadbyte-contain.exe
|
|
20
|
+
15d1cf4eb520b2b2eb3d890fd1e9dafc777cce4c1c4cec22638d41e2a85019d4 bin/deadbyte-contain.obj
|
|
21
|
+
6b01347b84461998096fe3f1ffafa7724f3b49b4c02608f828d8eaf73c512c08 bin/deadbyte-exec.exe
|
|
22
|
+
c8076e6d21dc4247ddb086a8cd60572479dd70dd95b16c54d2ea8b2b1570b3d4 bin/deadbyte-exec.obj
|
|
23
|
+
7db33f35d5fc8f9200825121412f78bd6c1286eb7f4d5005d392f728489fc11d bin/deadbyte-process-host.exe
|
|
24
|
+
1b8aed18a457df2e4fe8008a21871c462a7249ded9fac05c80d31fed6eba8415 bin/deadbyte-process-host.obj
|
|
25
|
+
a2fd532a612837c09d8604dde04f45fea66084f5dadffdafe825741b8b23444b bin/deadbyte-tunnel-host.exe
|
|
26
|
+
71aa710bd865823cecb034c833308649ffc71bf32d7c8ca18023ce808b86bea8 bin/deadbyte-tunnel-host.obj
|
|
27
|
+
2bb0c509abceb7f4523ed95286897bced769f86e9b850dad11f289356c612445 bin/WORKER-REGISTRY.txt
|
|
28
28
|
e74d45bd9facf03c9a2a0ff52600252924deb804a87e4b5503f48662a2b45a3b conpty-input-observer.obj
|
|
29
29
|
f8e46c4bd8eaeb804ffa5af87d6543e37eba66d817d8e5555f9d0462a99e4fdb controller/deadbyte-controller.config.psd1.example
|
|
30
|
-
|
|
30
|
+
755376c8be51daee9039a7e3aae2a29ccc06fb2a6edff6e5f95c12315d658fde controller/deadbyte-controller.ps1
|
|
31
31
|
5e8ef223b0dbc52173aaf044a075837eef8964ff0e7e16f83a595e0d17695625 controller/deadbyte-host-policy.json.example
|
|
32
32
|
6f0cc469f51444dd18211fa3346c826abeea4d2ec7a8945f0200dc5c622031ef controller/DEADBYTE-MCP.cmd
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
44ba8c44a7e6e34b124af7205d5c4e4d9ff82c5d1525e3fb07e4ea6b0e5a15da controller/deadbyte-process-policy.json
|
|
34
|
+
d4210667ca937abc86a16d8a53a8003fb6f2d9d5f64f7f699d7c913cbd24f115 controller/README.TXT
|
|
35
35
|
101e613518c73c6aa31c725fe1b5f9a24c995dc9876b7b28e1f3e97ac9f8d362 DEADBYTE-MCP-R27-FINAL/R27-ADMIN-CLOSURE.json
|
|
36
36
|
e9baf9abf4410ff8bd0f68e6b957dbbf9790fc88d9126311c5c135e943424952 DEADBYTE-MCP-R27-FINAL/R27-CLEANUP-FINAL-RECEIPT.json
|
|
37
37
|
39cb483c0897af5027bf1790a35a4c3b9a8cd5f6e3a2e0440787615f69cd14b2 DEADBYTE-MCP-R27-FINAL/R27-FINAL-CLOSURE.json
|
|
38
38
|
9aaf6d07e7511a1f0046ee8cc731d4b9660bbbf47dcea785a9c6b6cec95640bc DEADBYTE-MCP-R27-FINAL/R27-SLOT-UPDATE-RECEIPT.json
|
|
39
39
|
70dfccba12797ce5fea60668c97026cf71e7942cb4d886cac5853e05b362b6c1 DEADBYTE-MCP.cmd
|
|
40
|
-
|
|
40
|
+
eb02bae01c36411cece8973323ef6d750e0cb30d06b03f483b9aa78de2d05a3e docs/ARCHITECTURE.md
|
|
41
41
|
3f455f407933d8e044682f3415bdb51e68d7c4b508411dda7d8ed65b6e1d7e79 docs/AUTHORITY.md
|
|
42
42
|
3be291331862ac5bd892345e84d6ce8d9b6d835855235d7c5f28d5cd4b04afdb docs/CHILD-CONTROL.md
|
|
43
43
|
a9cbd1e2def00aae93569835f2ee17aa5cfd181e5770d7c1185c9c62deb0769e docs/CONSTRUCTION-LADDER.md
|
|
@@ -1159,7 +1159,7 @@ db605a698f917c4006462596e6526fe6a9c6eff9b8409e8472fe545d4b70027c node_modules/z
|
|
|
1159
1159
|
f67a25ded944912bd4621b68df17c7c70a52aae117278c076c0aabbc32a3abba node_modules/zod/v4/mini/schemas.d.ts
|
|
1160
1160
|
51b3a7869df2d3a1bd98acb9d5b6a61bbccc7653d7a3d8fca7f0e0db7e84e284 node_modules/zod/v4/mini/schemas.js
|
|
1161
1161
|
3e3125b5a537a24c3632c1c5c09640ce7bcb3935901b127ad8ae3c37a27f133f node_modules/zod/v4/package.json
|
|
1162
|
-
|
|
1162
|
+
b51eb609159ab9c46bebd04de7dfe23be44327fb6c5f1e00dd91ce02c7bab0e8 package.json
|
|
1163
1163
|
b3bb2324a0ee2ca81eac1e8e44ff5141fe0cb6434843c6c3325764abdca2a71a proof/CONTAINMENT-BUILD.txt
|
|
1164
1164
|
a8efa13e44ff50902aee64cfca542d19605a1ae23db95280ad2d44b324f3eae7 proof/MCP-SMOKE-STATUS.txt
|
|
1165
1165
|
7c115069cc4a343ca21b0ebdee74bd8f544b02d4aa906ffa13308725825d891a proof/NODE-SYNTAX.txt
|
|
@@ -1217,22 +1217,22 @@ d433aaea5cccd1e184775ac4d915f34e0b39c6c99916dddd009731ad5fd6443f proof/V073-WIN
|
|
|
1217
1217
|
bd0773a9e02e8ab11475c9cc5a7db29a8313233b7eab7f837922737e75ec5938 proof/VERIFY.txt
|
|
1218
1218
|
2c821808d4596965c577f40191daee224d3aea81989778c4af97f53a83b487db proof/WINDOWS-CONTAINED-STATUS.txt
|
|
1219
1219
|
f8bc839c7b4fcb0ea7b7e7ad9448847c3beae6f95f2eb4d407d1b284aaa4ff68 proof/WINDOWS-CONTAINMENT-STATUS.txt
|
|
1220
|
-
|
|
1220
|
+
09e05d473cdfcd5ca65207fee6c23f023ddcea9ffc9f291f11ffc4ed146bd3dc README.txt
|
|
1221
1221
|
1d4e9dee6f0669bd825334a6a72e13ee85ee29ab430dcef21d893ffd744774b5 scripts/autonomous-benchmark.mjs
|
|
1222
1222
|
06447dea18be1fa0a5e5a1167a6e3dcbd10ddfd28dd18d7bfd17383cf5bfc080 scripts/autonomous-build.ps1
|
|
1223
1223
|
6ae23099102eb0f0be4969598ba76600d19b00abf534a039d48e63bc7d7fffe3 scripts/autonomous-tests.ps1
|
|
1224
1224
|
1d987d12c5af6ffbaec1fe2f95aadc4740fe25933c0f0941f362daa2d2d84f48 scripts/build-containment.ps1
|
|
1225
1225
|
7d3c741de2b1c29f82efa96ab81fc819d8520f97413ce5ab0d4a1b1efd0e8b42 scripts/coding-live-smoke.mjs
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1226
|
+
61406ebd8669909e01cb677c91deb8383829094dc9f0d14df1c442678714301b scripts/deferred-slot-operation.mjs
|
|
1227
|
+
c9dacb54b67421ce8481b5d31f157c04cff2b348ed918881e48f174a4b253aea scripts/final-closure-verify.mjs
|
|
1228
|
+
4e4e591cc80db547e2be5208b18ea12f5b11e474d14d101676ac0b0e6f8c3b79 scripts/final-closure.mjs
|
|
1229
|
+
2b90e787022c1abb85a76be9f57e39943a13a9e706c3218914110d3caa1eafbb scripts/gate-windows.ps1
|
|
1230
1230
|
a64ab9a70c26495ac5d94c024a8813d8bd2bc8a708f236b672cb18556396c262 scripts/init-host-policy.ps1
|
|
1231
1231
|
b655f2f9c63c7e4b651e7182c6461f9ec63d0991f770f24fe5d44b209ad6bdfb scripts/refresh-process-policy.mjs
|
|
1232
1232
|
c92b518b7232849d945f0fcd9c428a2366758e5c9410be68104ed50ef869a33e scripts/release-manifest.mjs
|
|
1233
1233
|
d5284978c3b82a6eaef0ddd0ded0754467791d441dfe2d2da11dc25289301607 scripts/release-parity.mjs
|
|
1234
1234
|
caac2867971dfdf56456528b816ff56282a11cbba81510c13e1723accffac678 scripts/runtime-self-update.mjs
|
|
1235
|
-
|
|
1235
|
+
557a79ac42765ad7cf80a3a87875148633466294861bf3196475200f3eba38e2 scripts/windows-gate-evidence.mjs
|
|
1236
1236
|
5f4a73a1c3dc178c4b5de193b6cfc4774cfc46d5ad95ef0b786d4d386d82323b src/agent-mcp-tools.mjs
|
|
1237
1237
|
5cca555943318990ae8dc82481ab0d172e813261c71b541cc99114f411b040fa src/agent-runtime.mjs
|
|
1238
1238
|
0e2d1cdcc5e592ffe36e32fa6da68d84e00f992ca3a189b7a3735d8bbac476a6 src/audit-context.mjs
|
|
@@ -1260,7 +1260,7 @@ dcd4c9784e88e253e91ddad3c24b38cb0b36906ed737f6d7bee7712360f66f7a src/containmen
|
|
|
1260
1260
|
0fd1141a749596e4314a532ad99dabfeac213eef857e400eea1aa0ad09e0383d src/containment-construction.mjs
|
|
1261
1261
|
fe1761b98738e1aea1d25ddf3a0ba56ccad95a43d45104a89b8665197c7c9e18 src/containment-result.mjs
|
|
1262
1262
|
705a89cb12fedb993d55dfed32a5870d33e10db26422c944d1e52223566c096c src/containment-smoke.mjs
|
|
1263
|
-
|
|
1263
|
+
2b364866aaffb1da92a8a78ac1c827d20b7ba80c2fa321d7cf92b79fe959d19a src/deadbyte-cli.mjs
|
|
1264
1264
|
f5fafd46052b09f71a528594eb230edc5766ee0d006432d744590ec97c9c580d src/executor.mjs
|
|
1265
1265
|
264d21a4385a0a04613fe78203e7f5e231a5c06397086cfacc88076e60b89b71 src/hash.mjs
|
|
1266
1266
|
1cc648f59d739cb3269827a7aff23dc9dc6617a77c4da607ba947ca6e4626548 src/host-plane.mjs
|
|
@@ -1300,7 +1300,7 @@ a7a63ea58291e0676c7199633ae234030f46285840cdfc519c879c279ae8bb14 src/release-sl
|
|
|
1300
1300
|
efd3f7ae0a3a614485933942ab5e27e874175feb81eb3e5130913c1e6837e7ca src/remote-mcp-host-smoke-client.mjs
|
|
1301
1301
|
aeed462a1090611ce04f2d4e453e4a6e9163091d6d99f768233943f1c24b949f src/remote-mcp-machine-smoke-client.mjs
|
|
1302
1302
|
510691cf1d5d1f995b835881651da9b2a7bc22c02bc4da12e3a8266713bcc7e5 src/remote-mcp-r24-disarmed-smoke-client.mjs
|
|
1303
|
-
|
|
1303
|
+
56ab88d00979ee8f524c364a6548dd37adda99070f80b6c29de49eb3bef7e479 src/remote-mcp-r33-parity-client.mjs
|
|
1304
1304
|
86a641f0a1c34ad23bc8f50809a37b57d820ea7810ef86cb4315ce75d0406237 src/remote-mcp-smoke-client.mjs
|
|
1305
1305
|
827b156eac01cc9ec6f5ca9a49219612f0da511fde770a9eb1235aa913b5e514 src/request-identity.mjs
|
|
1306
1306
|
ce2223bf6075e96cc02505c1439acce18bb1f204c5e86cf9152bb7194daf3cd2 src/runtime-identity.mjs
|
|
@@ -1313,7 +1313,7 @@ a765372ee27cf34b3f42ca77e43b839a306a4ca7d8b1c5e2fdd4367ab0c95769 src/tunnel-std
|
|
|
1313
1313
|
16df134040e3ff1e73df722b568d3e8ac0a6923b097696cead7580da75aa8d2a src/tunnel-stdio-compat.mjs
|
|
1314
1314
|
642cb67d1854850e336ee73fbd71b329056bdcbdab35cea19c1a995a155ff5d9 src/verifier-cli.mjs
|
|
1315
1315
|
8f818a4852ce3be3a380cd4736c3073a7a3e0e45cd7c7ca90588a6b843d3d022 src/verifier.mjs
|
|
1316
|
-
|
|
1316
|
+
c8b13e6d6cb66949f701f2ef20069de4cb0c3f5f858334e62316207e3bd37766 src/version.mjs
|
|
1317
1317
|
7e09c57a97289360aabfaf3d531208e54872efbfb3182f3c18203d2cb88c46b5 src/worker-registry.mjs
|
|
1318
1318
|
2a78c818058b25efdc143a3a97c832da231ccd6ff9d90c7796d681a0251b85c4 test/agent-crash-child.mjs
|
|
1319
1319
|
d9461ab7c118ee75d37a2d6f5e637d7e43505af6a9ad8c7ddafffc8ace185a5b test/agent-crash-worker.mjs
|
|
@@ -1347,7 +1347,7 @@ a972bd20fa927427e6d8e4181699a27e792e916b02dcf8a1ac3e2b44afd238c1 test/controlle
|
|
|
1347
1347
|
ceba7d1a09ccdcb20f33fe4e6de7667ffe0f0170d1bc9fefadfdba4d7f228090 test/controller-r29.test.mjs
|
|
1348
1348
|
4d0dc810d9af13907f31c834a13acfb7e01ffbbe65575b69649fe52741e42175 test/controller-r30.test.mjs
|
|
1349
1349
|
b013bb2a100d3e784f0c0a2ef63d9d9d57cadd71a8db4fb845cbedb4a7b2c222 test/controller.test.mjs
|
|
1350
|
-
|
|
1350
|
+
7830426cd19d602cae5314d7e7a8d9bcadda152ea6751167ae9b03d882f8ce0e test/core.test.mjs
|
|
1351
1351
|
7ba4b06a1c4141ba87b5b371157fb59940d15a1016b4c599a13753d63ad0d3d3 test/DEADBYTE-MCP-WRITE-PROBE.txt
|
|
1352
1352
|
3d4b0bdef293fa3889dec60e8e321594a67e9f7095d3c541b382c82c33b2642e test/deferred-slot-operation-behavior.test.mjs
|
|
1353
1353
|
33eff6932951dd9cfd42d68b3333f8080f1a0b9fdc01b05aef5c96faf44b032e test/deferred-slot-operation.test.mjs
|
|
@@ -1373,14 +1373,15 @@ b84622d07d2ecfe27b55e45f7e89949f29a2d14184d8c6f6f82ed7f1e5fa59be test/process-n
|
|
|
1373
1373
|
a54301192c4cc842cbb6e113db2615a13f448c702273ef0585cc015859716f8a test/process-release-gate.test.mjs
|
|
1374
1374
|
e19a477abb83c63a1fb7ab5d5d1e9925113cded95d57084186b6ecd6161780e0 test/process-runtime.test.mjs
|
|
1375
1375
|
34afc8a01e0c21501ec2647b7b0198b73570bce89eaaa983bd50c5709bb83fb8 test/process-supervision.test.mjs
|
|
1376
|
-
|
|
1377
|
-
|
|
1376
|
+
fa43776151fceb7c6aaace6d83af2bfb1632ebf633c6d24827fea741f6184683 test/r33-closeout-regression.test.mjs
|
|
1377
|
+
1274d7d089fc859b2851918967ec82c3edd07bec134036df1e926d5ec140a450 test/r33-finalization.test.mjs
|
|
1378
1378
|
8776f707a78b29ccf2721b8bcf0ae4038a20022710ef9d6ccfea997c8c6d9d17 test/release-generation.test.mjs
|
|
1379
1379
|
bb58887a2c393cd5aac3fa3bb3a04de2704bd2a30dd2083ea638543485fa7e60 test/release-manifest-windows.test.mjs
|
|
1380
1380
|
7cc69e786bfd9e4a7e70888c4c1b5f756a264bc1a991139c468b63af23f24c38 test/release-slot.test.mjs
|
|
1381
1381
|
0109c76b480cc600f6ed42be4519df3fa6835012bb9e4ba4ae6be6635468c4a8 test/release-smoke-isolation.test.mjs
|
|
1382
|
-
|
|
1382
|
+
9fcf554d86c4bc0a4d652e32f1a5fffffafcdb0418f6fd98ae792fff12bfc025 test/release-version.test.mjs
|
|
1383
1383
|
1fdb6cbd3a51476834382086bad2b92029987b6214153576cd803f9da0b06902 test/remote-r24-catalog.test.mjs
|
|
1384
|
+
ea016d1a773c702e17152d73135ac5a8591baf6d220e304292758c8c7d4ee586 test/remote-session-cli.test.mjs
|
|
1384
1385
|
c05c64db73839698fdcdd4faa2bdbd78df861f53495f7a3b68a1fb53abb7d3c2 test/runtime-self-update.test.mjs
|
|
1385
1386
|
2f421a60ff6baa9cc3de0cbc4804ffe6b2d26805f94d4f57e6c4a1758f464afb test/standing-grants.test.mjs
|
|
1386
1387
|
6ecc712b7bcb2abdb934e7d40232ed97ac355f3f47665f557c2168b04d113b41 test/tool-audit.test.mjs
|
package/README.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
DEADBYTE MCP V0.8.
|
|
1
|
+
DEADBYTE MCP V0.8.8 / R33 FINAL MACHINE BASELINE
|
|
2
2
|
=========================
|
|
3
3
|
|
|
4
4
|
AUTHENTICATED MACHINE TRUTH + DURABLE AGENT + CODING + AUTONOMOUS PRODUCTION ENGINE
|
|
@@ -14,6 +14,14 @@ Use the npm CLI entry point instead of the legacy CMD convenience wrapper:
|
|
|
14
14
|
npx deadbyte-mcp@latest audit verify
|
|
15
15
|
|
|
16
16
|
The remote CLI invokes the stable active-release PowerShell launcher directly with shell=false.
|
|
17
|
+
Bare `remote` is a foreground device session: it starts/resumes the verified runtime, arms process,
|
|
18
|
+
coding, autonomous, and host authority in dependency order, independently checks that all four
|
|
19
|
+
planes report ARMED, then streams new audit plus controller-runtime log records until Ctrl+C or the
|
|
20
|
+
foreground input closes. Session shutdown revokes all four planes and parks the Bridge. A small
|
|
21
|
+
runtime owner marker prevents concurrent foreground sessions; if the prior owner died, the next
|
|
22
|
+
session first revokes stale authority and parks before starting cleanly. Explicit subcommands such
|
|
23
|
+
as `remote status` remain one-shot controller operations.
|
|
24
|
+
|
|
17
25
|
The legacy CMD file remains only as an R33 compatibility artifact until activation/rollback/restore
|
|
18
26
|
proof confirms the npx path; it is not the primary operator interface. Audit data lives under the
|
|
19
27
|
stable mutable state root and never inside immutable release slots.
|
package/bin/WORKER-REGISTRY.txt
CHANGED
|
@@ -2,11 +2,11 @@ schema=deadbyte.worker-registry.v1
|
|
|
2
2
|
version=0.6.0
|
|
3
3
|
policy=compile-time-operation-to-executable
|
|
4
4
|
launcher.executable=deadbyte-exec.exe
|
|
5
|
-
launcher.sha256=
|
|
5
|
+
launcher.sha256=6b01347b84461998096fe3f1ffafa7724f3b49b4c02608f828d8eaf73c512c08
|
|
6
6
|
operation.lowercase_ascii=contained-transform-v1
|
|
7
7
|
operation.reverse_bytes=contained-reverse-v1
|
|
8
8
|
operation.uppercase_ascii=contained-transform-v1
|
|
9
9
|
worker.contained-reverse-v1.executable=contained-reverse-worker.exe
|
|
10
|
-
worker.contained-reverse-v1.sha256=
|
|
10
|
+
worker.contained-reverse-v1.sha256=8d7c3557b65bef05c34205a2602c0a78b4f4ecc3f406b6ff12f7426841ac993f
|
|
11
11
|
worker.contained-transform-v1.executable=contained-transform-worker.exe
|
|
12
|
-
worker.contained-transform-v1.sha256=
|
|
12
|
+
worker.contained-transform-v1.sha256=516c364213ba55735b2cedb2cd1a55aa4806b384e027b8c2a679c1d5a5245d44
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/deadbyte-contain.exe
CHANGED
|
Binary file
|
package/bin/deadbyte-contain.obj
CHANGED
|
Binary file
|
package/bin/deadbyte-exec.exe
CHANGED
|
Binary file
|
package/bin/deadbyte-exec.obj
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/controller/README.TXT
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
DEADBYTE MCP V0.8.
|
|
1
|
+
DEADBYTE MCP V0.8.8 / R33 CONTROLLER
|
|
2
2
|
====================================
|
|
3
3
|
|
|
4
4
|
ENTRY POINT
|
|
5
5
|
-----------
|
|
6
|
-
|
|
6
|
+
Primary operator entry point:
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
npx deadbyte-mcp@latest remote
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Bare `remote` is a foreground device session. It starts the verified runtime, arms process,
|
|
11
|
+
coding, autonomous, and host authority, verifies all four planes are ARMED, then streams new
|
|
12
|
+
audit/runtime logs. Ctrl+C/SIGTERM or foreground input closure revokes all four planes and parks
|
|
13
|
+
the Bridge. A stale dead-owner session is recovered by revoking authority before the next start.
|
|
14
|
+
`remote status` and the other explicit remote subcommands remain one-shot operations.
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
The package/controller CMD launchers remain compatibility-only and forward into the canonical
|
|
17
|
+
controller root. A copied/misbound controller fails closed before creating command runtime state.
|
|
18
|
+
|
|
19
|
+
CLOSING OR EXITING THE LEGACY MENU DOES NOT STOP A STARTED RUNTIME.
|
|
20
|
+
Only explicit park/stop/restart lifecycle commands mutate verified owned processes outside the
|
|
21
|
+
foreground `remote` session contract.
|
|
15
22
|
|
|
16
23
|
STATE
|
|
17
24
|
-----
|
|
@@ -1026,7 +1026,7 @@ while ($true) {
|
|
|
1026
1026
|
Clear-Host
|
|
1027
1027
|
$cfg = Get-Config
|
|
1028
1028
|
Assert-ControllerRootBound $cfg
|
|
1029
|
-
Write-Host 'DEADBYTE MCP ON-DEMAND CONTROLLER V0.8.
|
|
1029
|
+
Write-Host 'DEADBYTE MCP ON-DEMAND CONTROLLER V0.8.8 / R33'
|
|
1030
1030
|
Write-Host '======================================'
|
|
1031
1031
|
Show-State $cfg | Out-Null
|
|
1032
1032
|
Write-Host ''
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"state_dir": "C:\\Users\\DEADBYTE\\Downloads\\deadbyte-mcp-r33-final-candidate-v2\\controller\\runtime\\process-state",
|
|
6
6
|
"native_host": {
|
|
7
7
|
"path": "C:\\Users\\DEADBYTE\\Downloads\\deadbyte-mcp-r33-final-candidate-v2\\bin\\deadbyte-process-host.exe",
|
|
8
|
-
"sha256": "
|
|
8
|
+
"sha256": "7db33f35d5fc8f9200825121412f78bd6c1286eb7f4d5005d392f728489fc11d"
|
|
9
9
|
},
|
|
10
10
|
"roots": {
|
|
11
11
|
"core": {
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# DEADBYTE MCP V0.8.
|
|
1
|
+
# DEADBYTE MCP V0.8.8 / R33 ARCHITECTURE
|
|
2
2
|
|
|
3
3
|
```mermaid
|
|
4
4
|
flowchart TD
|
|
@@ -40,7 +40,12 @@ flowchart TD
|
|
|
40
40
|
|
|
41
41
|
The lifecycle controller is not execution authority. It starts, parks, resumes,
|
|
42
42
|
observes, or stops verified owned processes and feature-gates the agent catalog;
|
|
43
|
-
it cannot manufacture arbitrary MCP capabilities.
|
|
43
|
+
it cannot manufacture arbitrary MCP capabilities. The npx foreground `remote` session is an
|
|
44
|
+
operator-side orchestrator over existing controller commands: it acquires the four explicit
|
|
45
|
+
standing grants in dependency order, verifies their observed ARMED state, tails only newly appended
|
|
46
|
+
audit/runtime logs, and revokes all four grants plus parks the Bridge on graceful session exit.
|
|
47
|
+
A PID-bound owner marker prevents concurrent sessions and lets the next invocation fail closed by
|
|
48
|
+
revoking stale authority before recovery when the prior owner process died.
|
|
44
49
|
|
|
45
50
|
## Exact capability catalogs
|
|
46
51
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authenticated MCP machine-truth runtime with signed audit chain, immutable release slots, contained execution, coding/autonomous production authority, and npx-first remote control.",
|
|
@@ -22,7 +22,7 @@ const atomicJson=async(file,value)=>{
|
|
|
22
22
|
};
|
|
23
23
|
function activationArgs(manifestSha){
|
|
24
24
|
if(!HEX64.test(manifestSha??'')) throw new Error('activate requires one lowercase manifest SHA-256');
|
|
25
|
-
return ['--stage',packageRoot,'--development-root',packageRoot,'--expected-version','0.8.
|
|
25
|
+
return ['--stage',packageRoot,'--development-root',packageRoot,'--expected-version','0.8.8',
|
|
26
26
|
'--expected-manifest',manifestSha,'--process-policy',path.join(packageRoot,'controller','deadbyte-process-policy.json'),
|
|
27
27
|
'--process-policy-sha256',null,'--enable-machine-fs','--enable-observation'];
|
|
28
28
|
}
|
|
@@ -84,7 +84,7 @@ function verifyPing(ping,status,pointer){
|
|
|
84
84
|
|
|
85
85
|
export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.homedir(),'.deadbyte-mcp')}={}){
|
|
86
86
|
insist(envelope?.body?.schema==='deadbyte.r33-final-closure.v1','closure schema mismatch');
|
|
87
|
-
insist(envelope.body.version==='0.8.
|
|
87
|
+
insist(envelope.body.version==='0.8.8','closure version mismatch');
|
|
88
88
|
insist(envelope.body.release_label==='R33 FINAL MACHINE BASELINE','closure release label mismatch');
|
|
89
89
|
const keyInfo=publicKeyInfo(await readFile(path.join(stateRoot,'trust','ed25519-public.pem')));
|
|
90
90
|
const bodyBytes=Buffer.from(canonicalJson(envelope.body),'utf8');
|
|
@@ -97,7 +97,7 @@ export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.
|
|
|
97
97
|
|
|
98
98
|
const pointer=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
|
|
99
99
|
insist(same(pointer,envelope.body.active_pointer),'active pointer drift');
|
|
100
|
-
insist(pointer.version==='0.8.
|
|
100
|
+
insist(pointer.version==='0.8.8','active pointer version mismatch');
|
|
101
101
|
insist(pointer.release_id===`v${pointer.version}-${pointer.manifest_sha256.slice(0,16)}`,'release id/content address mismatch');
|
|
102
102
|
const releaseFiles=await verifyTree(pointer.release_root,'MANIFEST.SHA256',pointer.manifest_sha256);
|
|
103
103
|
const generationFiles=await verifyTree(pointer.generation_root,'GENERATION.SHA256',pointer.generation_manifest_sha256);
|
|
@@ -129,7 +129,7 @@ export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.
|
|
|
129
129
|
const windowsGate=JSON.parse(await readFile(evidence.windows_gate.path,'utf8'));
|
|
130
130
|
insist(windowsGate.schema==='deadbyte.r33-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'Windows gate evidence invalid');
|
|
131
131
|
insist(windowsGate.manifest_sha256===pointer.manifest_sha256,'Windows gate manifest binding mismatch');
|
|
132
|
-
insist(windowsGate.marker==='DEADBYTE V0.8.
|
|
132
|
+
insist(windowsGate.marker==='DEADBYTE V0.8.8 / R33 WINDOWS BATCH GATE: PASS','Windows gate PASS marker mismatch');
|
|
133
133
|
|
|
134
134
|
const machine=envelope.body.machine;
|
|
135
135
|
insist(machine?.status?.release_id===pointer.release_id&&machine.status.generation_manifest_sha256===pointer.generation_manifest_sha256,'machine status binding mismatch');
|
|
@@ -22,7 +22,7 @@ function structured(result,label){
|
|
|
22
22
|
async function publicMachineEvidence(){
|
|
23
23
|
const endpoint=new URL((await readFile(path.join(stateRoot,'bridge','mcp-url.txt'),'utf8')).trim());
|
|
24
24
|
insist(endpoint.protocol==='https:','final closure requires HTTPS public endpoint');
|
|
25
|
-
const client=new Client({name:'deadbyte-r33-final-closure',version:'0.8.
|
|
25
|
+
const client=new Client({name:'deadbyte-r33-final-closure',version:'0.8.8'},
|
|
26
26
|
{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
27
27
|
const transport=new StreamableHTTPClientTransport(endpoint);
|
|
28
28
|
try{
|
|
@@ -61,7 +61,7 @@ async function atomicCreate(file,bytes){
|
|
|
61
61
|
|
|
62
62
|
export async function writeFinalClosure({parityPath,activationPath,windowsGatePath}){
|
|
63
63
|
const pointer=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
|
|
64
|
-
insist(pointer.version==='0.8.
|
|
64
|
+
insist(pointer.version==='0.8.8','final closure requires V0.8.8 active release');
|
|
65
65
|
const parity=JSON.parse(await readFile(path.resolve(parityPath),'utf8'));
|
|
66
66
|
insist(parity.schema==='deadbyte.r33-parity.v1'&&parity.status==='passed','parity evidence is not passed');
|
|
67
67
|
insist(parity.release_id===pointer.release_id&&parity.manifest_sha256===pointer.manifest_sha256,'parity/current release mismatch');
|
|
@@ -76,7 +76,7 @@ export async function writeFinalClosure({parityPath,activationPath,windowsGatePa
|
|
|
76
76
|
rollback:await fileEvidence(parity.rollback.receipt_path), restore:await fileEvidence(parity.restore.receipt_path),
|
|
77
77
|
windows_gate:await fileEvidence(windowsGatePath)
|
|
78
78
|
};
|
|
79
|
-
const body={schema:'deadbyte.r33-final-closure.v1',version:'0.8.
|
|
79
|
+
const body={schema:'deadbyte.r33-final-closure.v1',version:'0.8.8',release_label:'R33 FINAL MACHINE BASELINE',
|
|
80
80
|
completed_at_utc:new Date().toISOString(),active_pointer:pointer,evidence,
|
|
81
81
|
public_catalog:{tool_count:machine.tool_count,strict_output_schemas:machine.strict_output_schemas},
|
|
82
82
|
machine:{status:machine.status,ping:machine.ping,nonce:machine.nonce},
|
package/scripts/gate-windows.ps1
CHANGED
|
@@ -9,7 +9,7 @@ function Invoke-GateStep {
|
|
|
9
9
|
Write-Host "==== $Name ===="
|
|
10
10
|
& npm.cmd @NpmArgs
|
|
11
11
|
if ($LASTEXITCODE -ne 0) {
|
|
12
|
-
throw "DEADBYTE V0.8.
|
|
12
|
+
throw "DEADBYTE V0.8.8 / R33 gate failed at $Name with exit code $LASTEXITCODE"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -36,7 +36,7 @@ Invoke-GateStep -Name 'release-manifest-final' -NpmArgs @('run', 'manifest:verif
|
|
|
36
36
|
Write-Host '==== windows-gate-evidence ===='
|
|
37
37
|
& node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence.mjs')
|
|
38
38
|
if ($LASTEXITCODE -ne 0) {
|
|
39
|
-
throw "DEADBYTE V0.8.
|
|
39
|
+
throw "DEADBYTE V0.8.8 / R33 gate failed at windows-gate-evidence with exit code $LASTEXITCODE"
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
Write-Host '==== DEADBYTE V0.8.
|
|
42
|
+
Write-Host '==== DEADBYTE V0.8.8 / R33 WINDOWS BATCH GATE: PASS ===='
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
const here=path.dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const root=path.resolve(here,'..');
|
|
9
9
|
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
10
|
-
const marker='DEADBYTE V0.8.
|
|
10
|
+
const marker='DEADBYTE V0.8.8 / R33 WINDOWS BATCH GATE: PASS';
|
|
11
11
|
function insist(ok,message){if(!ok) throw new Error(message);}
|
|
12
12
|
|
|
13
13
|
export async function writeWindowsGateEvidence({
|
|
@@ -19,11 +19,11 @@ export async function writeWindowsGateEvidence({
|
|
|
19
19
|
const manifestBytes=await readFile(path.join(candidate,'MANIFEST.SHA256'));
|
|
20
20
|
const manifestSha256=sha256(manifestBytes);
|
|
21
21
|
const pkg=JSON.parse(await readFile(path.join(candidate,'package.json'),'utf8'));
|
|
22
|
-
insist(pkg.version==='0.8.
|
|
22
|
+
insist(pkg.version==='0.8.8',`Windows gate evidence requires V0.8.8, found ${pkg.version}`);
|
|
23
23
|
const completed=clock();
|
|
24
24
|
insist(completed instanceof Date&&!Number.isNaN(completed.getTime()),'Windows gate evidence clock invalid');
|
|
25
25
|
const evidence={
|
|
26
|
-
schema:'deadbyte.r33-windows-gate.v1',status:'passed',exit_code:0,version:'0.8.
|
|
26
|
+
schema:'deadbyte.r33-windows-gate.v1',status:'passed',exit_code:0,version:'0.8.8',
|
|
27
27
|
marker,completed_at_utc:completed.toISOString(),manifest_sha256:manifestSha256
|
|
28
28
|
};
|
|
29
29
|
const bytes=Buffer.from(`${JSON.stringify(evidence,null,2)}\n`,'utf8');
|
|
@@ -39,7 +39,7 @@ export async function writeWindowsGateEvidence({
|
|
|
39
39
|
const existingBytes=await readFile(file);
|
|
40
40
|
const existing=JSON.parse(existingBytes.toString('utf8'));
|
|
41
41
|
insist(existing.schema===evidence.schema&&existing.status==='passed'&&existing.exit_code===0,'existing Windows gate evidence invalid');
|
|
42
|
-
insist(existing.version==='0.8.
|
|
42
|
+
insist(existing.version==='0.8.8'&&existing.marker===marker&&existing.manifest_sha256===manifestSha256,'existing Windows gate evidence binding mismatch');
|
|
43
43
|
return {status:'existing',path:file,sha256:sha256(existingBytes),manifest_sha256:manifestSha256};
|
|
44
44
|
}
|
|
45
45
|
}
|
package/src/deadbyte-cli.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { lstat } from 'node:fs/promises';
|
|
2
|
+
import { lstat, mkdir, open, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
6
7
|
import { defaultPublicKeyPath } from './trust.mjs';
|
|
7
8
|
import { verifyAuditChain } from './audit-verify.mjs';
|
|
8
9
|
|
|
@@ -11,30 +12,178 @@ const REMOTE_COMMANDS=new Set([
|
|
|
11
12
|
'armprocess','disarmprocess','processstatus','armhost','disarmhost','hoststatus','hosttest',
|
|
12
13
|
'armcoding','disarmcoding','codingstatus','codingtest','armautonomous','disarmautonomous','autonomousstatus','autonomoustest'
|
|
13
14
|
]);
|
|
15
|
+
const SESSION_START=['start','armprocess','armcoding','armautonomous','armhost'];
|
|
16
|
+
const SESSION_STATUS=[
|
|
17
|
+
['processstatus',/^Process plane\s*:\s*ARMED\b/m],
|
|
18
|
+
['codingstatus',/^Coding plane\s*:\s*ARMED\b/m],
|
|
19
|
+
['autonomousstatus',/^Autonomous\s*:\s*ARMED\b/m],
|
|
20
|
+
['hoststatus',/^Host plane\s*:\s*ARMED\b/m]
|
|
21
|
+
];
|
|
22
|
+
const SESSION_CLEANUP=['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park'];
|
|
14
23
|
|
|
15
24
|
function stateRoot(){return path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));}
|
|
16
25
|
async function requireRegular(file,label){const info=await lstat(file);if(!info.isFile()||info.isSymbolicLink()) throw new Error(`${label} must be a regular non-symlink file`);return file;}
|
|
17
26
|
function printHelp(){
|
|
18
27
|
process.stdout.write([
|
|
19
28
|
'DEADBYTE MCP CLI','',
|
|
20
|
-
' npx deadbyte-mcp@latest remote',
|
|
29
|
+
' npx deadbyte-mcp@latest remote # foreground device session',
|
|
21
30
|
' npx deadbyte-mcp@latest remote status',
|
|
22
31
|
' npx deadbyte-mcp@latest remote restart',
|
|
23
32
|
' npx deadbyte-mcp@latest audit verify',
|
|
24
33
|
' npx deadbyte-mcp@latest audit status',''
|
|
25
34
|
].join('\n'));
|
|
26
35
|
}
|
|
27
|
-
async function
|
|
36
|
+
async function remoteContext(){
|
|
28
37
|
if(process.platform!=='win32') throw new Error('remote controller is currently Windows-only');
|
|
29
|
-
if(args.length>1) throw new Error('remote accepts at most one controller command');
|
|
30
|
-
const command=args[0]||'start';if(!REMOTE_COMMANDS.has(command)) throw new Error(`unsupported remote command '${command}'`);
|
|
31
38
|
const root=stateRoot();
|
|
32
39
|
const launcher=await requireRegular(path.join(root,'bin','DEADBYTE-MCP.ps1'),'stable DEADBYTE launcher');
|
|
33
40
|
const systemRoot=process.env.SystemRoot||process.env.WINDIR;if(!systemRoot) throw new Error('SystemRoot/WINDIR missing');
|
|
34
41
|
const powershell=await requireRegular(path.join(systemRoot,'System32','WindowsPowerShell','v1.0','powershell.exe'),'Windows PowerShell');
|
|
35
|
-
|
|
42
|
+
return {root,launcher,powershell};
|
|
43
|
+
}
|
|
44
|
+
function invokeController(ctx,command,{capture=false,allowFailure=false}={}){
|
|
45
|
+
const result=spawnSync(ctx.powershell,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',ctx.launcher,command],{
|
|
46
|
+
stdio:capture?['ignore','pipe','pipe']:'inherit',encoding:capture?'utf8':undefined,windowsHide:false,shell:false
|
|
47
|
+
});
|
|
36
48
|
if(result.error) throw result.error;
|
|
37
|
-
|
|
49
|
+
const status=Number.isInteger(result.status)?result.status:1;
|
|
50
|
+
const stdout=capture?String(result.stdout||''):'';
|
|
51
|
+
const stderr=capture?String(result.stderr||''):'';
|
|
52
|
+
if(capture){if(stdout) process.stdout.write(stdout);if(stderr) process.stderr.write(stderr);}
|
|
53
|
+
if(status!==0&&!allowFailure) throw new Error(`remote controller '${command}' failed exit=${status}`);
|
|
54
|
+
return {status,stdout,stderr};
|
|
55
|
+
}
|
|
56
|
+
async function listLogFiles(root){
|
|
57
|
+
const files=[];
|
|
58
|
+
const audit=path.join(root,'audit');
|
|
59
|
+
const runtimeLogs=path.join(root,'runtime','logs');
|
|
60
|
+
for(const [dir,accept] of [
|
|
61
|
+
[audit,name=>/^segment-\d{8}\.jsonl$/.test(name)],
|
|
62
|
+
[runtimeLogs,name=>/\.log$/i.test(name)]
|
|
63
|
+
]){
|
|
64
|
+
let names=[];try{names=await readdir(dir);}catch(error){if(error?.code==='ENOENT') continue;throw error;}
|
|
65
|
+
for(const name of names.sort()) if(accept(name)) files.push(path.join(dir,name));
|
|
66
|
+
}
|
|
67
|
+
return files;
|
|
68
|
+
}
|
|
69
|
+
function formatLogLine(file,line){
|
|
70
|
+
if(!line) return null;
|
|
71
|
+
if(/^segment-\d{8}\.jsonl$/.test(path.basename(file))){
|
|
72
|
+
try{
|
|
73
|
+
const event=JSON.parse(line);
|
|
74
|
+
const seq=Number.isInteger(event.seq)?`#${event.seq}`:'#?';
|
|
75
|
+
const request=typeof event.request_id==='string'?` ${event.request_id.slice(0,8)}`:'';
|
|
76
|
+
const tool=typeof event.tool==='string'?` ${event.tool}`:'';
|
|
77
|
+
return `[AUDIT ${seq}] ${event.event_type||'event'}${tool}${request}`;
|
|
78
|
+
}catch{return `[AUDIT] ${line}`;}
|
|
79
|
+
}
|
|
80
|
+
const label=path.basename(file).replace(/\.log$/i,'').toUpperCase();
|
|
81
|
+
return `[${label}] ${line}`;
|
|
82
|
+
}
|
|
83
|
+
async function readAppend(file,offset){
|
|
84
|
+
let info;try{info=await stat(file);}catch(error){if(error?.code==='ENOENT') return {offset:0,text:''};throw error;}
|
|
85
|
+
let start=offset;
|
|
86
|
+
if(info.size<start) start=0;
|
|
87
|
+
if(info.size===start) return {offset:start,text:''};
|
|
88
|
+
const length=info.size-start;
|
|
89
|
+
const buffer=Buffer.alloc(length);
|
|
90
|
+
const handle=await open(file,'r');
|
|
91
|
+
try{await handle.read(buffer,0,length,start);}finally{await handle.close();}
|
|
92
|
+
return {offset:info.size,text:buffer.toString('utf8')};
|
|
93
|
+
}
|
|
94
|
+
async function tailRemoteLogs(root,signal){
|
|
95
|
+
const offsets=new Map();
|
|
96
|
+
for(const file of await listLogFiles(root)){
|
|
97
|
+
try{offsets.set(file,(await stat(file)).size);}catch{}
|
|
98
|
+
}
|
|
99
|
+
process.stdout.write('[LOG] Live logs active. Press Ctrl+C to disconnect and revoke authority.\n');
|
|
100
|
+
while(!signal.aborted){
|
|
101
|
+
for(const file of await listLogFiles(root)){
|
|
102
|
+
const prior=offsets.has(file)?offsets.get(file):0;
|
|
103
|
+
const next=await readAppend(file,prior);
|
|
104
|
+
offsets.set(file,next.offset);
|
|
105
|
+
for(const line of next.text.split(/\r?\n/)){
|
|
106
|
+
const formatted=formatLogLine(file,line);
|
|
107
|
+
if(formatted) process.stdout.write(`${formatted}\n`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
try{await sleep(250,null,{signal});}catch(error){if(error?.name!=='AbortError') throw error;}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function cleanupRemoteSession(ctx){
|
|
114
|
+
for(const command of SESSION_CLEANUP){
|
|
115
|
+
try{invokeController(ctx,command,{allowFailure:true});}
|
|
116
|
+
catch(error){process.stderr.write(`[WARN] cleanup ${command}: ${String(error?.message||error)}\n`);}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function remoteSessionMarker(root){return path.join(root,'runtime','remote-session.json');}
|
|
120
|
+
function pidAlive(pid){
|
|
121
|
+
try{process.kill(pid,0);return true;}
|
|
122
|
+
catch(error){return error?.code!=='ESRCH';}
|
|
123
|
+
}
|
|
124
|
+
async function readRemoteSessionMarker(root){
|
|
125
|
+
const file=remoteSessionMarker(root);
|
|
126
|
+
let text;try{text=await readFile(file,'utf8');}catch(error){if(error?.code==='ENOENT') return null;throw error;}
|
|
127
|
+
let value;try{value=JSON.parse(text);}catch{throw new Error('remote session marker is invalid JSON');}
|
|
128
|
+
if(value?.schema!=='deadbyte.remote-session.v1'||!Number.isInteger(value?.pid)||value.pid<1) throw new Error('remote session marker schema invalid');
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
async function recoverRemoteSession(ctx){
|
|
132
|
+
const prior=await readRemoteSessionMarker(ctx.root);
|
|
133
|
+
if(!prior) return;
|
|
134
|
+
if(pidAlive(prior.pid)) throw new Error(`remote session already active pid=${prior.pid}`);
|
|
135
|
+
process.stdout.write(`[RECOVERY] Stale remote session pid=${prior.pid}; revoking authority before restart.\n`);
|
|
136
|
+
await cleanupRemoteSession(ctx);
|
|
137
|
+
await rm(remoteSessionMarker(ctx.root),{force:true});
|
|
138
|
+
}
|
|
139
|
+
async function claimRemoteSession(ctx){
|
|
140
|
+
const dir=path.join(ctx.root,'runtime');await mkdir(dir,{recursive:true});
|
|
141
|
+
const marker={schema:'deadbyte.remote-session.v1',pid:process.pid,started_at_utc:new Date().toISOString()};
|
|
142
|
+
try{await writeFile(remoteSessionMarker(ctx.root),`${JSON.stringify(marker)}\n`,{encoding:'utf8',flag:'wx'});}
|
|
143
|
+
catch(error){if(error?.code==='EEXIST') throw new Error('remote session already claimed');throw error;}
|
|
144
|
+
return marker;
|
|
145
|
+
}
|
|
146
|
+
async function releaseRemoteSession(ctx,marker){
|
|
147
|
+
let current=null;try{current=await readRemoteSessionMarker(ctx.root);}catch(error){process.stderr.write(`[WARN] remote session marker cleanup: ${String(error?.message||error)}\n`);return;}
|
|
148
|
+
if(current&¤t.pid===marker.pid) await rm(remoteSessionMarker(ctx.root),{force:true});
|
|
149
|
+
}
|
|
150
|
+
async function runRemoteSession(){
|
|
151
|
+
const ctx=await remoteContext();
|
|
152
|
+
await recoverRemoteSession(ctx);
|
|
153
|
+
const marker=await claimRemoteSession(ctx);
|
|
154
|
+
const aborter=new AbortController();
|
|
155
|
+
const abort=()=>aborter.abort();
|
|
156
|
+
const watchStdin=!process.stdin.isTTY;
|
|
157
|
+
process.once('SIGINT',abort);process.once('SIGTERM',abort);
|
|
158
|
+
if(watchStdin){process.stdin.once('end',abort);process.stdin.once('close',abort);process.stdin.resume();}
|
|
159
|
+
let ready=false;
|
|
160
|
+
try{
|
|
161
|
+
process.stdout.write('DEADBYTE MCP DEVICE SESSION\n');
|
|
162
|
+
process.stdout.write('[INFO] Starting local + remote runtime...\n');
|
|
163
|
+
for(const command of SESSION_START) invokeController(ctx,command);
|
|
164
|
+
process.stdout.write('[AUTHORITY] Verifying runtime planes...\n');
|
|
165
|
+
for(const [command,pattern] of SESSION_STATUS){
|
|
166
|
+
const result=invokeController(ctx,command,{capture:true});
|
|
167
|
+
if(!pattern.test(result.stdout)) throw new Error(`remote session authority verification failed: ${command} did not report ARMED`);
|
|
168
|
+
}
|
|
169
|
+
ready=true;
|
|
170
|
+
process.stdout.write('[DEVICE] DEADBYTE MCP online; all authority planes ARMED.\n');
|
|
171
|
+
await tailRemoteLogs(ctx.root,aborter.signal);
|
|
172
|
+
}finally{
|
|
173
|
+
process.removeListener('SIGINT',abort);process.removeListener('SIGTERM',abort);
|
|
174
|
+
if(watchStdin){process.stdin.removeListener('end',abort);process.stdin.removeListener('close',abort);process.stdin.pause();}
|
|
175
|
+
if(ready||!aborter.signal.aborted) process.stdout.write('[INFO] Closing remote device session and revoking authority...\n');
|
|
176
|
+
await cleanupRemoteSession(ctx);
|
|
177
|
+
await releaseRemoteSession(ctx,marker);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function runRemote(args){
|
|
181
|
+
if(args.length===0){await runRemoteSession();return;}
|
|
182
|
+
if(args.length>1) throw new Error('remote accepts at most one controller command');
|
|
183
|
+
const command=args[0];if(!REMOTE_COMMANDS.has(command)) throw new Error(`unsupported remote command '${command}'`);
|
|
184
|
+
const ctx=await remoteContext();
|
|
185
|
+
const result=invokeController(ctx,command,{allowFailure:true});
|
|
186
|
+
process.exitCode=result.status;
|
|
38
187
|
}
|
|
39
188
|
async function runAudit(args){
|
|
40
189
|
const command=args[0]||'status';if(args.length>1) throw new Error('audit accepts one command');
|
|
@@ -67,7 +67,7 @@ export async function runR33Parity(endpointText) {
|
|
|
67
67
|
if (endpoint.protocol !== 'https:') throw new Error('R33 parity requires HTTPS');
|
|
68
68
|
const pointer = JSON.parse(await readFile(path.join(stateRoot, 'active-release.json'), 'utf8'));
|
|
69
69
|
const policy = await loadCodingPolicy(path.join(pointer.generation_root, 'coding-policy.json'));
|
|
70
|
-
const client = new Client({ name:'deadbyte-r33-parity', version:'0.8.
|
|
70
|
+
const client = new Client({ name:'deadbyte-r33-parity', version:'0.8.8' },
|
|
71
71
|
{ versionNegotiation:{ mode:{ pin:'2026-07-28' } } });
|
|
72
72
|
const transport = new StreamableHTTPClientTransport(endpoint);
|
|
73
73
|
const tag = randomBytes(8).toString('hex');
|
package/src/version.mjs
CHANGED
package/test/core.test.mjs
CHANGED
|
@@ -105,7 +105,7 @@ test('proof execution creates deterministic output and signed verifiable receipt
|
|
|
105
105
|
assert.equal(result.receipt.request.schema, 'deadbyte.request.v1');
|
|
106
106
|
assert.match(result.receipt.request.nonce, /^[0-9a-f]{64}$/);
|
|
107
107
|
assert.match(result.receipt.request.sha256, /^[0-9a-f]{64}$/);
|
|
108
|
-
assert.equal(result.receipt.runtime.package_version, '0.8.
|
|
108
|
+
assert.equal(result.receipt.runtime.package_version, '0.8.8');
|
|
109
109
|
assert.match(result.receipt.runtime.mcp_ingress_adapter, /^(?:none|tunnel-stdio-probe-compat-v1)$/);
|
|
110
110
|
assert.match(result.receipt.runtime.mcp_ingress_adapter_sha256, /^[0-9a-f]{64}$/);
|
|
111
111
|
assert.match(result.receipt.runtime.mcp_ingress_mode_source_sha256, /^[0-9a-f]{64}$/);
|
|
@@ -103,7 +103,7 @@ test('Windows R33 gate emits manifest-bound machine-readable evidence outside th
|
|
|
103
103
|
assert.equal(evidence.status,'passed');
|
|
104
104
|
assert.equal(evidence.exit_code,0);
|
|
105
105
|
assert.equal(evidence.manifest_sha256,manifestSha);
|
|
106
|
-
assert.equal(evidence.marker,'DEADBYTE V0.8.
|
|
106
|
+
assert.equal(evidence.marker,'DEADBYTE V0.8.8 / R33 WINDOWS BATCH GATE: PASS');
|
|
107
107
|
assert.ok(summary.path.startsWith(path.join(stateRoot,'evidence','release')));
|
|
108
108
|
}finally{await rm(stateRoot,{recursive:true,force:true});}
|
|
109
109
|
});
|
|
@@ -30,8 +30,8 @@ test('final closure verifier is implementation-independent from production helpe
|
|
|
30
30
|
assert.match(verifier, /DEADBYTE-R27-SLOT-UPDATE-V1/);
|
|
31
31
|
assert.match(verifier, /DEADBYTE-MACHINE-PING-V1/);
|
|
32
32
|
assert.match(verifier, /DEADBYTE-R33-FINAL-CLOSURE-V1/);
|
|
33
|
-
assert.match(writer, /pointer\.version==='0\.8\.
|
|
34
|
-
assert.match(verifier, /envelope\.body\.version==='0\.8\.
|
|
33
|
+
assert.match(writer, /pointer\.version==='0\.8\.8'/);
|
|
34
|
+
assert.match(verifier, /envelope\.body\.version==='0\.8\.8'/);
|
|
35
35
|
assert.match(verifier, /release_label==='R33 FINAL MACHINE BASELINE'/);
|
|
36
36
|
});
|
|
37
37
|
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
const root = new URL('../', import.meta.url);
|
|
7
7
|
const text = rel => readFile(new URL(rel, root), 'utf8');
|
|
8
8
|
|
|
9
|
-
test('R33
|
|
9
|
+
test('R33 patch successor release authority agrees on V0.8.8 / R33 identity', async () => {
|
|
10
10
|
const pkg = JSON.parse(await text('package.json'));
|
|
11
11
|
const [version, controller, gate, readme, architecture, controllerReadme, deferred, parity, closure, closureVerify] = await Promise.all([
|
|
12
12
|
text('src/version.mjs'),
|
|
@@ -20,16 +20,16 @@ test('R33 final release authority agrees on V0.8.7 / R33 identity', async () =>
|
|
|
20
20
|
text('scripts/final-closure.mjs'),
|
|
21
21
|
text('scripts/final-closure-verify.mjs')
|
|
22
22
|
]);
|
|
23
|
-
assert.equal(pkg.version, '0.8.
|
|
24
|
-
assert.match(version, /DEADBYTE_VERSION = '0\.8\.
|
|
25
|
-
assert.match(controller, /CONTROLLER V0\.8\.
|
|
26
|
-
assert.match(gate, /DEADBYTE V0\.8\.
|
|
27
|
-
assert.match(readme, /^DEADBYTE MCP V0\.8\.
|
|
28
|
-
assert.match(architecture, /^# DEADBYTE MCP V0\.8\.
|
|
29
|
-
assert.match(controllerReadme, /^DEADBYTE MCP V0\.8\.
|
|
23
|
+
assert.equal(pkg.version, '0.8.8');
|
|
24
|
+
assert.match(version, /DEADBYTE_VERSION = '0\.8\.8'/);
|
|
25
|
+
assert.match(controller, /CONTROLLER V0\.8\.8 \/ R33/);
|
|
26
|
+
assert.match(gate, /DEADBYTE V0\.8\.8 \/ R33 WINDOWS BATCH GATE: PASS/);
|
|
27
|
+
assert.match(readme, /^DEADBYTE MCP V0\.8\.8 \/ R33 FINAL MACHINE BASELINE$/m);
|
|
28
|
+
assert.match(architecture, /^# DEADBYTE MCP V0\.8\.8 \/ R33 ARCHITECTURE$/m);
|
|
29
|
+
assert.match(controllerReadme, /^DEADBYTE MCP V0\.8\.8 \/ R33 CONTROLLER$/m);
|
|
30
30
|
assert.match(controllerReadme, /68-tool public catalog/);
|
|
31
|
-
assert.match(deferred, /--expected-version','0\.8\.
|
|
32
|
-
assert.match(parity, /version:'0\.8\.
|
|
33
|
-
assert.match(closure, /version:'0\.8\.
|
|
34
|
-
assert.match(closureVerify, /DEADBYTE V0\.8\.
|
|
31
|
+
assert.match(deferred, /--expected-version','0\.8\.8'/);
|
|
32
|
+
assert.match(parity, /version:'0\.8\.8'/);
|
|
33
|
+
assert.match(closure, /version:'0\.8\.8'/);
|
|
34
|
+
assert.match(closureVerify, /DEADBYTE V0\.8\.8 \/ R33 WINDOWS BATCH GATE: PASS/);
|
|
35
35
|
});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
|
|
10
|
+
const cliPath=path.join(root,'src','deadbyte-cli.mjs');
|
|
11
|
+
const isWindows=process.platform==='win32';
|
|
12
|
+
const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
|
13
|
+
|
|
14
|
+
async function fixture({failCommand=''}={}){
|
|
15
|
+
const dir=await mkdtemp(path.join(os.tmpdir(),'deadbyte-remote-session-'));
|
|
16
|
+
const state=path.join(dir,'state');
|
|
17
|
+
const bin=path.join(state,'bin');
|
|
18
|
+
const trace=path.join(dir,'trace.txt');
|
|
19
|
+
await mkdir(bin,{recursive:true});
|
|
20
|
+
const launcher=path.join(bin,'DEADBYTE-MCP.ps1');
|
|
21
|
+
const ps1=`param([string]$Command)\nAdd-Content -LiteralPath $env:DEADBYTE_REMOTE_TEST_TRACE -Value $Command -Encoding UTF8\nif ($env:DEADBYTE_REMOTE_TEST_FAIL -and $Command -eq $env:DEADBYTE_REMOTE_TEST_FAIL) { Write-Error \"forced $Command failure\"; exit 9 }\nswitch ($Command) {\n 'start' { Write-Host 'DEADBYTE MCP = ONLINE' }\n 'processstatus' { Write-Host 'Process plane : ARMED [standing-grant]' }\n 'codingstatus' { Write-Host 'Coding plane : ARMED [standing-grant]' }\n 'autonomousstatus' { Write-Host 'Autonomous : ARMED [standing-grant]' }\n 'hoststatus' { Write-Host 'Host plane : ARMED [standing-grant]' }\n 'park' { Write-Host 'DEADBYTE MCP = PARKED' }\n default { Write-Host \"$Command OK\" }\n}\nexit 0\n`;
|
|
22
|
+
await writeFile(launcher,ps1,'utf8');
|
|
23
|
+
return {dir,state,trace,env:{...process.env,DEADBYTE_STATE_ROOT:state,DEADBYTE_REMOTE_TEST_TRACE:trace,DEADBYTE_REMOTE_TEST_FAIL:failCommand}};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function traceCommands(file){
|
|
27
|
+
try{return (await readFile(file,'utf8')).split(/\r?\n/).map(x=>x.trim()).filter(Boolean);}catch(error){if(error?.code==='ENOENT') return [];throw error;}
|
|
28
|
+
}
|
|
29
|
+
async function waitFor(file,predicate,{timeoutMs=6000}={}){
|
|
30
|
+
const deadline=Date.now()+timeoutMs;
|
|
31
|
+
while(Date.now()<deadline){
|
|
32
|
+
const commands=await traceCommands(file);
|
|
33
|
+
if(predicate(commands)) return commands;
|
|
34
|
+
await sleep(50);
|
|
35
|
+
}
|
|
36
|
+
return traceCommands(file);
|
|
37
|
+
}
|
|
38
|
+
async function collect(child){
|
|
39
|
+
let stdout='',stderr='';
|
|
40
|
+
child.stdout?.on('data',chunk=>{stdout+=chunk;});
|
|
41
|
+
child.stderr?.on('data',chunk=>{stderr+=chunk;});
|
|
42
|
+
const closed=new Promise(resolve=>child.once('close',(code,signal)=>resolve({code,signal})));
|
|
43
|
+
return {closed,get stdout(){return stdout;},get stderr(){return stderr;}};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const winTest=isWindows?test:test.skip;
|
|
47
|
+
|
|
48
|
+
winTest('bare remote arms every authority plane, verifies ARMED state, streams logs, then disarms and parks when the foreground session ends',async()=>{
|
|
49
|
+
const fx=await fixture();
|
|
50
|
+
let child=null;
|
|
51
|
+
try{
|
|
52
|
+
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
|
|
53
|
+
const output=await collect(child);
|
|
54
|
+
const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'));
|
|
55
|
+
assert.deepEqual(ready.slice(0,9),[
|
|
56
|
+
'start','armprocess','armcoding','armautonomous','armhost',
|
|
57
|
+
'processstatus','codingstatus','autonomousstatus','hoststatus'
|
|
58
|
+
]);
|
|
59
|
+
assert.equal(child.exitCode,null,'remote session must remain foreground after becoming ready');
|
|
60
|
+
const tailDeadline=Date.now()+3000;
|
|
61
|
+
while(Date.now()<tailDeadline&&!/\[LOG\] Live logs active/.test(output.stdout)) await sleep(50);
|
|
62
|
+
assert.match(output.stdout,/\[LOG\] Live logs active/);
|
|
63
|
+
const auditDir=path.join(fx.state,'audit');
|
|
64
|
+
await mkdir(auditDir,{recursive:true});
|
|
65
|
+
await writeFile(path.join(auditDir,'segment-00000001.jsonl'),`${JSON.stringify({seq:1,event_type:'tool.request',tool:'coding_tree',request_id:'abcdef1234567890'})}\n`,'utf8');
|
|
66
|
+
const logDeadline=Date.now()+3000;
|
|
67
|
+
while(Date.now()<logDeadline&&!/\[AUDIT #1\] tool\.request coding_tree abcdef12/.test(output.stdout)) await sleep(50);
|
|
68
|
+
assert.match(output.stdout,/\[AUDIT #1\] tool\.request coding_tree abcdef12/);
|
|
69
|
+
child.stdin.end();
|
|
70
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
71
|
+
assert.equal(ended.timeout,undefined,'remote session did not exit after foreground input closed');
|
|
72
|
+
const commands=await traceCommands(fx.trace);
|
|
73
|
+
assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
74
|
+
assert.match(output.stdout,/DEADBYTE MCP DEVICE SESSION/i);
|
|
75
|
+
assert.match(output.stdout,/Live logs/i);
|
|
76
|
+
}finally{
|
|
77
|
+
if(child?.exitCode===null) child.kill();
|
|
78
|
+
await rm(fx.dir,{recursive:true,force:true});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
winTest('bare remote rolls back authority and parks if one plane fails to arm',async()=>{
|
|
83
|
+
const fx=await fixture({failCommand:'armhost'});
|
|
84
|
+
try{
|
|
85
|
+
const child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
|
|
86
|
+
const output=await collect(child);
|
|
87
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
88
|
+
assert.equal(ended.timeout,undefined,'failed startup did not terminate');
|
|
89
|
+
assert.notEqual(ended.code,0);
|
|
90
|
+
const commands=await traceCommands(fx.trace);
|
|
91
|
+
assert.deepEqual(commands.slice(0,5),['start','armprocess','armcoding','armautonomous','armhost']);
|
|
92
|
+
assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
93
|
+
assert.doesNotMatch(output.stdout,/Live logs/i);
|
|
94
|
+
}finally{await rm(fx.dir,{recursive:true,force:true});}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
winTest('bare remote recovers a stale crashed session before arming a new one',async()=>{
|
|
98
|
+
const fx=await fixture();
|
|
99
|
+
let child=null;
|
|
100
|
+
try{
|
|
101
|
+
const runtime=path.join(fx.state,'runtime');
|
|
102
|
+
await mkdir(runtime,{recursive:true});
|
|
103
|
+
await writeFile(path.join(runtime,'remote-session.json'),JSON.stringify({schema:'deadbyte.remote-session.v1',pid:2147483000,started_at_utc:'2026-01-01T00:00:00.000Z'}),'utf8');
|
|
104
|
+
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
|
|
105
|
+
const output=await collect(child);
|
|
106
|
+
const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'));
|
|
107
|
+
assert.deepEqual(ready.slice(0,5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
108
|
+
assert.equal(ready[5],'start');
|
|
109
|
+
child.stdin.end();
|
|
110
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
111
|
+
assert.equal(ended.timeout,undefined);
|
|
112
|
+
assert.equal(ended.code,0,output.stderr);
|
|
113
|
+
}finally{
|
|
114
|
+
if(child?.exitCode===null) child.kill();
|
|
115
|
+
await rm(fx.dir,{recursive:true,force:true});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
winTest('bare remote refuses a second live foreground session without touching authority',async()=>{
|
|
120
|
+
const fx=await fixture();
|
|
121
|
+
let child=null;
|
|
122
|
+
try{
|
|
123
|
+
const runtime=path.join(fx.state,'runtime');
|
|
124
|
+
await mkdir(runtime,{recursive:true});
|
|
125
|
+
await writeFile(path.join(runtime,'remote-session.json'),JSON.stringify({schema:'deadbyte.remote-session.v1',pid:process.pid,started_at_utc:new Date().toISOString()}),'utf8');
|
|
126
|
+
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
|
|
127
|
+
const output=await collect(child);
|
|
128
|
+
await sleep(500);
|
|
129
|
+
if(child.exitCode===null) child.stdin.end();
|
|
130
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
131
|
+
assert.equal(ended.timeout,undefined);
|
|
132
|
+
assert.notEqual(ended.code,0);
|
|
133
|
+
assert.deepEqual(await traceCommands(fx.trace),[]);
|
|
134
|
+
assert.match(output.stderr,/remote session already active/i);
|
|
135
|
+
}finally{
|
|
136
|
+
if(child?.exitCode===null) child.kill();
|
|
137
|
+
await rm(fx.dir,{recursive:true,force:true});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
winTest('explicit remote status remains a one-shot controller command',async()=>{
|
|
142
|
+
const fx=await fixture();
|
|
143
|
+
try{
|
|
144
|
+
const child=spawn(process.execPath,[cliPath,'remote','status'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
|
|
145
|
+
const output=await collect(child);
|
|
146
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
147
|
+
assert.equal(ended.timeout,undefined);
|
|
148
|
+
assert.equal(ended.code,0,output.stderr);
|
|
149
|
+
assert.deepEqual(await traceCommands(fx.trace),['status']);
|
|
150
|
+
}finally{await rm(fx.dir,{recursive:true,force:true});}
|
|
151
|
+
});
|