deadbyte-mcp 0.8.8 → 0.8.10
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 +48 -46
- package/README.txt +7 -5
- 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 +6 -3
- package/controller/deadbyte-controller.ps1 +1 -1
- package/controller/deadbyte-process-policy.json +1 -1
- package/deadbyte-mcp-0.8.9.tgz +0 -0
- package/docs/ARCHITECTURE.md +6 -3
- 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 +71 -16
- package/src/remote-mcp-r33-parity-client.mjs +1 -1
- package/src/remote-session-guardian.mjs +76 -0
- 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 +112 -8
package/MANIFEST.SHA256
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
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
|
+
e78db563f44fd23ba11aa729405a1de83879b4d650f76dfe08fea529ba78546c bin/appcontainer-stage.exe
|
|
2
|
+
5bcad768906db242d26992155fa3551d88a23b5f04f537f2bd07000a34289602 bin/appcontainer-stage.obj
|
|
3
|
+
96d63e6dd3d8a7778df1067765a52d93a604971519490ffd5ef4014635b2b725 bin/bootstrap-advapi32.exe
|
|
4
|
+
3a6d24ab23593e2aafbaf8768634386ac06fe42b12b21f922ae6defb2283a241 bin/bootstrap-advapi32.obj
|
|
5
|
+
a3f967d7a8c6c0d5aee16f3f6311ebd6f33feccb49571b0bdb12bdca54b09fc1 bin/bootstrap-exitcode.exe
|
|
6
|
+
db17dc13ae4fbeb354afac9939309adfb090e5b2a367f02aad7b0b00fad954f6 bin/bootstrap-exitcode.obj
|
|
7
|
+
a15b60141640fdf6c49424fc2ae2d1587c0e46928e843d8e526cca3d292571f6 bin/bootstrap-kernel32.exe
|
|
8
|
+
62ece87b2b038a374262f8cac04a7c4b8a2a51dbc4815cc6227238d0cb213f74 bin/bootstrap-kernel32.obj
|
|
9
|
+
d6f19d51210829dad7c22a5a19d619fceb186eb5cdb51973a4c4bd2150bf7dab bin/child-control-probe.exe
|
|
10
|
+
5293fab3a4e9caf924614729b31213c0593f18d0bfc8d070796e8f50fa322b86 bin/child-control-probe.obj
|
|
11
|
+
5fa70d9436e99705a4a194a57a97fc5d1e8663a24b644e4b9443c95d01b9c0d3 bin/child-control-stage.exe
|
|
12
|
+
cd41a9756874da59a2827c92deed28e810ae83986770dfe32232a4254753933a bin/child-control-stage.obj
|
|
13
|
+
bac6a67f73503d23de7049fca4f0db9709bf9600342d16f2be3b63b3fd582d50 bin/contained-reverse-worker.exe
|
|
14
|
+
458b946eadc29fa5f07042539b90ef35952325bb06cdbea39dd01ad5c7b60cfa bin/contained-reverse-worker.obj
|
|
15
|
+
7f3d7c4cc60accdec7e385f6ccbb58c33545b5f4068b94e62796c6a18bf39b96 bin/contained-transform-worker.exe
|
|
16
|
+
2badaaaa0b8c3bbd503843e1fdf935ed34fb8c1706b6492e56001e7b159068f0 bin/contained-transform-worker.obj
|
|
17
|
+
dd0af7c54c832a19a3660629c50c560512aaa93047de498910bdc7ee316869d3 bin/containment-probe.exe
|
|
18
|
+
64282e7f5f252be318ab666587f5301cbd787866e970de8dca03ce7f6d774249 bin/containment-probe.obj
|
|
19
|
+
ea07aaebd0f6a1057050fc14b5a55bbee89f03c7ba259951e2591e476a3368c8 bin/deadbyte-contain.exe
|
|
20
|
+
7914c57d2f8c812a70f174bad4df26f13fd51fba1d93021249b0fe0def6e7c2c bin/deadbyte-contain.obj
|
|
21
|
+
99e061e94d451ab4c53b69730ecb33cced30960a03a2acfe07df8b3789c215ec bin/deadbyte-exec.exe
|
|
22
|
+
06e59e49353147e1a5a1ca11d79587516d6bbdd620687d868b7d45fe78974b65 bin/deadbyte-exec.obj
|
|
23
|
+
6e8ca7085495a04b9c56e3f7b17142a0e866b1571475ef6a6d90d87f544aab41 bin/deadbyte-process-host.exe
|
|
24
|
+
4752d9692acfbd0825edba18555ee1193fbbd7a592a45e8fe3fe60758af0e02d bin/deadbyte-process-host.obj
|
|
25
|
+
63064a1fc9a2266b5396eff0eea135d53b19d9e4ad4ac865409f2ee7a6edeb07 bin/deadbyte-tunnel-host.exe
|
|
26
|
+
d486ae5c27d864476aadb8ab1ac70a0fe8a1ef2599c59d4476b703553824d793 bin/deadbyte-tunnel-host.obj
|
|
27
|
+
9030f4b9a2ec1dbf8ec524c5630e5f9107bfd0898917d423016a2634453c86e2 bin/WORKER-REGISTRY.txt
|
|
28
28
|
e74d45bd9facf03c9a2a0ff52600252924deb804a87e4b5503f48662a2b45a3b conpty-input-observer.obj
|
|
29
29
|
f8e46c4bd8eaeb804ffa5af87d6543e37eba66d817d8e5555f9d0462a99e4fdb controller/deadbyte-controller.config.psd1.example
|
|
30
|
-
|
|
30
|
+
5ed252f9bba5da56fd1fb37fe89737a211db9f34eb4afc860cb875d7d17f5a76 controller/deadbyte-controller.ps1
|
|
31
31
|
5e8ef223b0dbc52173aaf044a075837eef8964ff0e7e16f83a595e0d17695625 controller/deadbyte-host-policy.json.example
|
|
32
32
|
6f0cc469f51444dd18211fa3346c826abeea4d2ec7a8945f0200dc5c622031ef controller/DEADBYTE-MCP.cmd
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
f90e17950993e0fdb139f930d7da5c3376f7417caa63e6c616cd35aeaabe49de controller/deadbyte-process-policy.json
|
|
34
|
+
f7bcbda1b20d2a00994404b64900655fd4175add4561911313a3560e177be795 controller/README.TXT
|
|
35
|
+
9b8104c6fc779737e02aac1155572388ed753ff215996ba95e3bd3183b010104 deadbyte-mcp-0.8.9.tgz
|
|
35
36
|
101e613518c73c6aa31c725fe1b5f9a24c995dc9876b7b28e1f3e97ac9f8d362 DEADBYTE-MCP-R27-FINAL/R27-ADMIN-CLOSURE.json
|
|
36
37
|
e9baf9abf4410ff8bd0f68e6b957dbbf9790fc88d9126311c5c135e943424952 DEADBYTE-MCP-R27-FINAL/R27-CLEANUP-FINAL-RECEIPT.json
|
|
37
38
|
39cb483c0897af5027bf1790a35a4c3b9a8cd5f6e3a2e0440787615f69cd14b2 DEADBYTE-MCP-R27-FINAL/R27-FINAL-CLOSURE.json
|
|
38
39
|
9aaf6d07e7511a1f0046ee8cc731d4b9660bbbf47dcea785a9c6b6cec95640bc DEADBYTE-MCP-R27-FINAL/R27-SLOT-UPDATE-RECEIPT.json
|
|
39
40
|
70dfccba12797ce5fea60668c97026cf71e7942cb4d886cac5853e05b362b6c1 DEADBYTE-MCP.cmd
|
|
40
|
-
|
|
41
|
+
ca63aed417079deff5cdaa7f1be577c30bab4370db6aba797419b9745ef0c53b docs/ARCHITECTURE.md
|
|
41
42
|
3f455f407933d8e044682f3415bdb51e68d7c4b508411dda7d8ed65b6e1d7e79 docs/AUTHORITY.md
|
|
42
43
|
3be291331862ac5bd892345e84d6ce8d9b6d835855235d7c5f28d5cd4b04afdb docs/CHILD-CONTROL.md
|
|
43
44
|
a9cbd1e2def00aae93569835f2ee17aa5cfd181e5770d7c1185c9c62deb0769e docs/CONSTRUCTION-LADDER.md
|
|
@@ -1159,7 +1160,7 @@ db605a698f917c4006462596e6526fe6a9c6eff9b8409e8472fe545d4b70027c node_modules/z
|
|
|
1159
1160
|
f67a25ded944912bd4621b68df17c7c70a52aae117278c076c0aabbc32a3abba node_modules/zod/v4/mini/schemas.d.ts
|
|
1160
1161
|
51b3a7869df2d3a1bd98acb9d5b6a61bbccc7653d7a3d8fca7f0e0db7e84e284 node_modules/zod/v4/mini/schemas.js
|
|
1161
1162
|
3e3125b5a537a24c3632c1c5c09640ce7bcb3935901b127ad8ae3c37a27f133f node_modules/zod/v4/package.json
|
|
1162
|
-
|
|
1163
|
+
99bb03660e5f1915c92d6c12e1526fcde23e15838ee62589a2117e2458178765 package.json
|
|
1163
1164
|
b3bb2324a0ee2ca81eac1e8e44ff5141fe0cb6434843c6c3325764abdca2a71a proof/CONTAINMENT-BUILD.txt
|
|
1164
1165
|
a8efa13e44ff50902aee64cfca542d19605a1ae23db95280ad2d44b324f3eae7 proof/MCP-SMOKE-STATUS.txt
|
|
1165
1166
|
7c115069cc4a343ca21b0ebdee74bd8f544b02d4aa906ffa13308725825d891a proof/NODE-SYNTAX.txt
|
|
@@ -1217,22 +1218,22 @@ d433aaea5cccd1e184775ac4d915f34e0b39c6c99916dddd009731ad5fd6443f proof/V073-WIN
|
|
|
1217
1218
|
bd0773a9e02e8ab11475c9cc5a7db29a8313233b7eab7f837922737e75ec5938 proof/VERIFY.txt
|
|
1218
1219
|
2c821808d4596965c577f40191daee224d3aea81989778c4af97f53a83b487db proof/WINDOWS-CONTAINED-STATUS.txt
|
|
1219
1220
|
f8bc839c7b4fcb0ea7b7e7ad9448847c3beae6f95f2eb4d407d1b284aaa4ff68 proof/WINDOWS-CONTAINMENT-STATUS.txt
|
|
1220
|
-
|
|
1221
|
+
cea2eaf7e63dceb381f8165294e07efbb99c321772428cc243b76fbce19d14a7 README.txt
|
|
1221
1222
|
1d4e9dee6f0669bd825334a6a72e13ee85ee29ab430dcef21d893ffd744774b5 scripts/autonomous-benchmark.mjs
|
|
1222
1223
|
06447dea18be1fa0a5e5a1167a6e3dcbd10ddfd28dd18d7bfd17383cf5bfc080 scripts/autonomous-build.ps1
|
|
1223
1224
|
6ae23099102eb0f0be4969598ba76600d19b00abf534a039d48e63bc7d7fffe3 scripts/autonomous-tests.ps1
|
|
1224
1225
|
1d987d12c5af6ffbaec1fe2f95aadc4740fe25933c0f0941f362daa2d2d84f48 scripts/build-containment.ps1
|
|
1225
1226
|
7d3c741de2b1c29f82efa96ab81fc819d8520f97413ce5ab0d4a1b1efd0e8b42 scripts/coding-live-smoke.mjs
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1227
|
+
82c8b994c428d4003276d0ad8ad21953291eef0a7a0617697bad4fff3f911e16 scripts/deferred-slot-operation.mjs
|
|
1228
|
+
4d34f4d9ec40946befa6804a43dcdcf8c6cd1c28b61709b82674e41cd4cdbc19 scripts/final-closure-verify.mjs
|
|
1229
|
+
b6813860e3f9e80148ceb3b1180bb1c3dbbd6d05faa757f9f8801797e132a42d scripts/final-closure.mjs
|
|
1230
|
+
e4464059bdc099c63e03d2365a79076874ea9d025052b8360fd1761750a88231 scripts/gate-windows.ps1
|
|
1230
1231
|
a64ab9a70c26495ac5d94c024a8813d8bd2bc8a708f236b672cb18556396c262 scripts/init-host-policy.ps1
|
|
1231
1232
|
b655f2f9c63c7e4b651e7182c6461f9ec63d0991f770f24fe5d44b209ad6bdfb scripts/refresh-process-policy.mjs
|
|
1232
1233
|
c92b518b7232849d945f0fcd9c428a2366758e5c9410be68104ed50ef869a33e scripts/release-manifest.mjs
|
|
1233
1234
|
d5284978c3b82a6eaef0ddd0ded0754467791d441dfe2d2da11dc25289301607 scripts/release-parity.mjs
|
|
1234
1235
|
caac2867971dfdf56456528b816ff56282a11cbba81510c13e1723accffac678 scripts/runtime-self-update.mjs
|
|
1235
|
-
|
|
1236
|
+
b2323480beb14e1c9e7763e06dfd59ebf0389bec232429f84614754bb7da4e4d scripts/windows-gate-evidence.mjs
|
|
1236
1237
|
5f4a73a1c3dc178c4b5de193b6cfc4774cfc46d5ad95ef0b786d4d386d82323b src/agent-mcp-tools.mjs
|
|
1237
1238
|
5cca555943318990ae8dc82481ab0d172e813261c71b541cc99114f411b040fa src/agent-runtime.mjs
|
|
1238
1239
|
0e2d1cdcc5e592ffe36e32fa6da68d84e00f992ca3a189b7a3735d8bbac476a6 src/audit-context.mjs
|
|
@@ -1260,7 +1261,7 @@ dcd4c9784e88e253e91ddad3c24b38cb0b36906ed737f6d7bee7712360f66f7a src/containmen
|
|
|
1260
1261
|
0fd1141a749596e4314a532ad99dabfeac213eef857e400eea1aa0ad09e0383d src/containment-construction.mjs
|
|
1261
1262
|
fe1761b98738e1aea1d25ddf3a0ba56ccad95a43d45104a89b8665197c7c9e18 src/containment-result.mjs
|
|
1262
1263
|
705a89cb12fedb993d55dfed32a5870d33e10db26422c944d1e52223566c096c src/containment-smoke.mjs
|
|
1263
|
-
|
|
1264
|
+
19d2f6504c47968cbbe9fc460f622634f0aee71a84db068c5b536256ec0cdedb src/deadbyte-cli.mjs
|
|
1264
1265
|
f5fafd46052b09f71a528594eb230edc5766ee0d006432d744590ec97c9c580d src/executor.mjs
|
|
1265
1266
|
264d21a4385a0a04613fe78203e7f5e231a5c06397086cfacc88076e60b89b71 src/hash.mjs
|
|
1266
1267
|
1cc648f59d739cb3269827a7aff23dc9dc6617a77c4da607ba947ca6e4626548 src/host-plane.mjs
|
|
@@ -1300,8 +1301,9 @@ a7a63ea58291e0676c7199633ae234030f46285840cdfc519c879c279ae8bb14 src/release-sl
|
|
|
1300
1301
|
efd3f7ae0a3a614485933942ab5e27e874175feb81eb3e5130913c1e6837e7ca src/remote-mcp-host-smoke-client.mjs
|
|
1301
1302
|
aeed462a1090611ce04f2d4e453e4a6e9163091d6d99f768233943f1c24b949f src/remote-mcp-machine-smoke-client.mjs
|
|
1302
1303
|
510691cf1d5d1f995b835881651da9b2a7bc22c02bc4da12e3a8266713bcc7e5 src/remote-mcp-r24-disarmed-smoke-client.mjs
|
|
1303
|
-
|
|
1304
|
+
4b83018de431e348b97bf787429d40013459d4f312ce85a4fe1e7c294bcb74c2 src/remote-mcp-r33-parity-client.mjs
|
|
1304
1305
|
86a641f0a1c34ad23bc8f50809a37b57d820ea7810ef86cb4315ce75d0406237 src/remote-mcp-smoke-client.mjs
|
|
1306
|
+
c8fd6fd3e49e866f2c3be326ab07222b36a44528ee0fc3f7b371c34a60e3c45b src/remote-session-guardian.mjs
|
|
1305
1307
|
827b156eac01cc9ec6f5ca9a49219612f0da511fde770a9eb1235aa913b5e514 src/request-identity.mjs
|
|
1306
1308
|
ce2223bf6075e96cc02505c1439acce18bb1f204c5e86cf9152bb7194daf3cd2 src/runtime-identity.mjs
|
|
1307
1309
|
7b7ab858adec2febe9459d7bf355e24500181dc48c575c47a53796735504bcb8 src/runtime-update.mjs
|
|
@@ -1313,7 +1315,7 @@ a765372ee27cf34b3f42ca77e43b839a306a4ca7d8b1c5e2fdd4367ab0c95769 src/tunnel-std
|
|
|
1313
1315
|
16df134040e3ff1e73df722b568d3e8ac0a6923b097696cead7580da75aa8d2a src/tunnel-stdio-compat.mjs
|
|
1314
1316
|
642cb67d1854850e336ee73fbd71b329056bdcbdab35cea19c1a995a155ff5d9 src/verifier-cli.mjs
|
|
1315
1317
|
8f818a4852ce3be3a380cd4736c3073a7a3e0e45cd7c7ca90588a6b843d3d022 src/verifier.mjs
|
|
1316
|
-
|
|
1318
|
+
0ad4334b94e66248ff70d866e306068aa66b010a6254c14eddf066340c5e35cd src/version.mjs
|
|
1317
1319
|
7e09c57a97289360aabfaf3d531208e54872efbfb3182f3c18203d2cb88c46b5 src/worker-registry.mjs
|
|
1318
1320
|
2a78c818058b25efdc143a3a97c832da231ccd6ff9d90c7796d681a0251b85c4 test/agent-crash-child.mjs
|
|
1319
1321
|
d9461ab7c118ee75d37a2d6f5e637d7e43505af6a9ad8c7ddafffc8ace185a5b test/agent-crash-worker.mjs
|
|
@@ -1347,7 +1349,7 @@ a972bd20fa927427e6d8e4181699a27e792e916b02dcf8a1ac3e2b44afd238c1 test/controlle
|
|
|
1347
1349
|
ceba7d1a09ccdcb20f33fe4e6de7667ffe0f0170d1bc9fefadfdba4d7f228090 test/controller-r29.test.mjs
|
|
1348
1350
|
4d0dc810d9af13907f31c834a13acfb7e01ffbbe65575b69649fe52741e42175 test/controller-r30.test.mjs
|
|
1349
1351
|
b013bb2a100d3e784f0c0a2ef63d9d9d57cadd71a8db4fb845cbedb4a7b2c222 test/controller.test.mjs
|
|
1350
|
-
|
|
1352
|
+
38bdf72463a1f4fa055c4a19b0ee30df2606303e54bb6fbeeb41eda33bf201a9 test/core.test.mjs
|
|
1351
1353
|
7ba4b06a1c4141ba87b5b371157fb59940d15a1016b4c599a13753d63ad0d3d3 test/DEADBYTE-MCP-WRITE-PROBE.txt
|
|
1352
1354
|
3d4b0bdef293fa3889dec60e8e321594a67e9f7095d3c541b382c82c33b2642e test/deferred-slot-operation-behavior.test.mjs
|
|
1353
1355
|
33eff6932951dd9cfd42d68b3333f8080f1a0b9fdc01b05aef5c96faf44b032e test/deferred-slot-operation.test.mjs
|
|
@@ -1373,15 +1375,15 @@ b84622d07d2ecfe27b55e45f7e89949f29a2d14184d8c6f6f82ed7f1e5fa59be test/process-n
|
|
|
1373
1375
|
a54301192c4cc842cbb6e113db2615a13f448c702273ef0585cc015859716f8a test/process-release-gate.test.mjs
|
|
1374
1376
|
e19a477abb83c63a1fb7ab5d5d1e9925113cded95d57084186b6ecd6161780e0 test/process-runtime.test.mjs
|
|
1375
1377
|
34afc8a01e0c21501ec2647b7b0198b73570bce89eaaa983bd50c5709bb83fb8 test/process-supervision.test.mjs
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
+
a8502a3bb65dfbec7a9eba80c6c7970d2d7109e41be7b2572016981e37d6e11a test/r33-closeout-regression.test.mjs
|
|
1379
|
+
0348d80f5a1490245d17308e252c5cc56035e2398f9b6af5eb66a692144172ee test/r33-finalization.test.mjs
|
|
1378
1380
|
8776f707a78b29ccf2721b8bcf0ae4038a20022710ef9d6ccfea997c8c6d9d17 test/release-generation.test.mjs
|
|
1379
1381
|
bb58887a2c393cd5aac3fa3bb3a04de2704bd2a30dd2083ea638543485fa7e60 test/release-manifest-windows.test.mjs
|
|
1380
1382
|
7cc69e786bfd9e4a7e70888c4c1b5f756a264bc1a991139c468b63af23f24c38 test/release-slot.test.mjs
|
|
1381
1383
|
0109c76b480cc600f6ed42be4519df3fa6835012bb9e4ba4ae6be6635468c4a8 test/release-smoke-isolation.test.mjs
|
|
1382
|
-
|
|
1384
|
+
caff0ed12e5603fc2151327128d6bd75dd6140097480a2ae5bdf4d66891ba364 test/release-version.test.mjs
|
|
1383
1385
|
1fdb6cbd3a51476834382086bad2b92029987b6214153576cd803f9da0b06902 test/remote-r24-catalog.test.mjs
|
|
1384
|
-
|
|
1386
|
+
d08222f39ec3247b3f022d1e447d99f1dde5d5fd9a1f7f8b1e5771cc143904a3 test/remote-session-cli.test.mjs
|
|
1385
1387
|
c05c64db73839698fdcdd4faa2bdbd78df861f53495f7a3b68a1fb53abb7d3c2 test/runtime-self-update.test.mjs
|
|
1386
1388
|
2f421a60ff6baa9cc3de0cbc4804ffe6b2d26805f94d4f57e6c4a1758f464afb test/standing-grants.test.mjs
|
|
1387
1389
|
6ecc712b7bcb2abdb934e7d40232ed97ac355f3f47665f557c2168b04d113b41 test/tool-audit.test.mjs
|
package/README.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
DEADBYTE MCP V0.8.
|
|
1
|
+
DEADBYTE MCP V0.8.10 / R33 FINAL MACHINE BASELINE
|
|
2
2
|
=========================
|
|
3
3
|
|
|
4
4
|
AUTHENTICATED MACHINE TRUTH + DURABLE AGENT + CODING + AUTONOMOUS PRODUCTION ENGINE
|
|
@@ -17,10 +17,12 @@ The remote CLI invokes the stable active-release PowerShell launcher directly wi
|
|
|
17
17
|
Bare `remote` is a foreground device session: it starts/resumes the verified runtime, arms process,
|
|
18
18
|
coding, autonomous, and host authority in dependency order, independently checks that all four
|
|
19
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
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
foreground input closes. Session shutdown revokes all four planes and parks the Bridge. A detached
|
|
21
|
+
nonce-bound guardian watches the foreground owner and performs the same revoke+park cleanup if the
|
|
22
|
+
owner is hard-killed before `finally` can run. The v2 runtime marker binds owner PID, guardian PID,
|
|
23
|
+
and a random 256-bit session nonce, prevents concurrent foreground sessions, and lets a later start
|
|
24
|
+
recover only a dead, unguarded stale owner. Explicit subcommands such as `remote status` remain
|
|
25
|
+
one-shot controller operations.
|
|
24
26
|
|
|
25
27
|
The legacy CMD file remains only as an R33 compatibility artifact until activation/rollback/restore
|
|
26
28
|
proof confirms the npx path; it is not the primary operator interface. Audit data lives under the
|
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=99e061e94d451ab4c53b69730ecb33cced30960a03a2acfe07df8b3789c215ec
|
|
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=bac6a67f73503d23de7049fca4f0db9709bf9600342d16f2be3b63b3fd582d50
|
|
11
11
|
worker.contained-transform-v1.executable=contained-transform-worker.exe
|
|
12
|
-
worker.contained-transform-v1.sha256=
|
|
12
|
+
worker.contained-transform-v1.sha256=7f3d7c4cc60accdec7e385f6ccbb58c33545b5f4068b94e62796c6a18bf39b96
|
|
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,4 +1,4 @@
|
|
|
1
|
-
DEADBYTE MCP V0.8.
|
|
1
|
+
DEADBYTE MCP V0.8.10 / R33 CONTROLLER
|
|
2
2
|
====================================
|
|
3
3
|
|
|
4
4
|
ENTRY POINT
|
|
@@ -10,8 +10,11 @@ Primary operator entry point:
|
|
|
10
10
|
Bare `remote` is a foreground device session. It starts the verified runtime, arms process,
|
|
11
11
|
coding, autonomous, and host authority, verifies all four planes are ARMED, then streams new
|
|
12
12
|
audit/runtime logs. Ctrl+C/SIGTERM or foreground input closure revokes all four planes and parks
|
|
13
|
-
the Bridge. A
|
|
14
|
-
|
|
13
|
+
the Bridge. A detached nonce-bound guardian performs the same fixed revoke+park cleanup if the
|
|
14
|
+
foreground owner is hard-killed. The v2 session marker records owner PID, guardian PID, and random
|
|
15
|
+
256-bit nonce so a guardian cannot remove a replacement session marker; a later start recovers only
|
|
16
|
+
a dead stale owner with no live guardian. `remote status` and other explicit subcommands remain
|
|
17
|
+
one-shot operations.
|
|
15
18
|
|
|
16
19
|
The package/controller CMD launchers remain compatibility-only and forward into the canonical
|
|
17
20
|
controller root. A copied/misbound controller fails closed before creating command runtime state.
|
|
@@ -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.10 / 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": "6e8ca7085495a04b9c56e3f7b17142a0e866b1571475ef6a6d90d87f544aab41"
|
|
9
9
|
},
|
|
10
10
|
"roots": {
|
|
11
11
|
"core": {
|
|
Binary file
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# DEADBYTE MCP V0.8.
|
|
1
|
+
# DEADBYTE MCP V0.8.10 / R33 ARCHITECTURE
|
|
2
2
|
|
|
3
3
|
```mermaid
|
|
4
4
|
flowchart TD
|
|
@@ -44,8 +44,11 @@ it cannot manufacture arbitrary MCP capabilities. The npx foreground `remote` se
|
|
|
44
44
|
operator-side orchestrator over existing controller commands: it acquires the four explicit
|
|
45
45
|
standing grants in dependency order, verifies their observed ARMED state, tails only newly appended
|
|
46
46
|
audit/runtime logs, and revokes all four grants plus parks the Bridge on graceful session exit.
|
|
47
|
-
A
|
|
48
|
-
|
|
47
|
+
A detached guardian is bound to the foreground owner by a random session nonce. The v2 marker
|
|
48
|
+
records owner PID, guardian PID, and nonce; if the owner is hard-killed before graceful cleanup,
|
|
49
|
+
the guardian independently invokes only the fixed revoke+park controller sequence and removes the
|
|
50
|
+
marker only when the same nonce is still current. Concurrent sessions fail closed, while a later
|
|
51
|
+
invocation may recover a stale owner only when no live guardian remains.
|
|
49
52
|
|
|
50
53
|
## Exact capability catalogs
|
|
51
54
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
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.10',
|
|
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.10','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.10','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.10 / 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.10'},
|
|
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.10','final closure requires V0.8.10 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.10',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.10 / 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.10 / 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.10 / 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.10 / 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.10',`Windows gate evidence requires V0.8.10, 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.10',
|
|
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.10'&&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,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { lstat, mkdir, open, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
4
|
+
import { randomBytes } from 'node:crypto';
|
|
4
5
|
import os from 'node:os';
|
|
5
6
|
import path from 'node:path';
|
|
6
7
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
7
9
|
import { defaultPublicKeyPath } from './trust.mjs';
|
|
8
10
|
import { verifyAuditChain } from './audit-verify.mjs';
|
|
9
11
|
|
|
@@ -74,11 +76,25 @@ function formatLogLine(file,line){
|
|
|
74
76
|
const seq=Number.isInteger(event.seq)?`#${event.seq}`:'#?';
|
|
75
77
|
const request=typeof event.request_id==='string'?` ${event.request_id.slice(0,8)}`:'';
|
|
76
78
|
const tool=typeof event.tool==='string'?` ${event.tool}`:'';
|
|
77
|
-
|
|
79
|
+
let marker='';
|
|
80
|
+
if(event.event_type==='tool.request') marker='📥 ';
|
|
81
|
+
else if(event.event_type==='tool.result'){
|
|
82
|
+
if(event.outcome?.is_error===true) marker='📤❌ ';
|
|
83
|
+
else if(event.outcome?.is_error===false) marker='📤✅ ';
|
|
84
|
+
else marker='📤 ';
|
|
85
|
+
}
|
|
86
|
+
return `${marker}[AUDIT ${seq}] ${event.event_type||'event'}${tool}${request}`;
|
|
78
87
|
}catch{return `[AUDIT] ${line}`;}
|
|
79
88
|
}
|
|
80
89
|
const label=path.basename(file).replace(/\.log$/i,'').toUpperCase();
|
|
81
|
-
|
|
90
|
+
let marker='';
|
|
91
|
+
if(/\[TOOL IN \]/.test(line)) marker='📥 ';
|
|
92
|
+
else if(/\[TOOL OUT\]/.test(line)){
|
|
93
|
+
if(/"is_error"\s*:\s*true/.test(line)) marker='📤❌ ';
|
|
94
|
+
else if(/"is_error"\s*:\s*false/.test(line)) marker='📤✅ ';
|
|
95
|
+
else marker='📤 ';
|
|
96
|
+
}
|
|
97
|
+
return `${marker}[${label}] ${line}`;
|
|
82
98
|
}
|
|
83
99
|
async function readAppend(file,offset){
|
|
84
100
|
let info;try{info=await stat(file);}catch(error){if(error?.code==='ENOENT') return {offset:0,text:''};throw error;}
|
|
@@ -96,7 +112,7 @@ async function tailRemoteLogs(root,signal){
|
|
|
96
112
|
for(const file of await listLogFiles(root)){
|
|
97
113
|
try{offsets.set(file,(await stat(file)).size);}catch{}
|
|
98
114
|
}
|
|
99
|
-
process.stdout.write('[LOG] Live logs active. Press Ctrl+C to disconnect and revoke authority.\n');
|
|
115
|
+
process.stdout.write('📜 [LOG] Live logs active. Press Ctrl+C to disconnect and revoke authority.\n');
|
|
100
116
|
while(!signal.aborted){
|
|
101
117
|
for(const file of await listLogFiles(root)){
|
|
102
118
|
const prior=offsets.has(file)?offsets.get(file):0;
|
|
@@ -113,39 +129,78 @@ async function tailRemoteLogs(root,signal){
|
|
|
113
129
|
async function cleanupRemoteSession(ctx){
|
|
114
130
|
for(const command of SESSION_CLEANUP){
|
|
115
131
|
try{invokeController(ctx,command,{allowFailure:true});}
|
|
116
|
-
catch(error){process.stderr.write(
|
|
132
|
+
catch(error){process.stderr.write(`⚠️ [WARN] cleanup ${command}: ${String(error?.message||error)}\n`);}
|
|
117
133
|
}
|
|
118
134
|
}
|
|
135
|
+
const GUARDIAN_SCRIPT=fileURLToPath(new URL('./remote-session-guardian.mjs',import.meta.url));
|
|
119
136
|
function remoteSessionMarker(root){return path.join(root,'runtime','remote-session.json');}
|
|
120
137
|
function pidAlive(pid){
|
|
121
138
|
try{process.kill(pid,0);return true;}
|
|
122
139
|
catch(error){return error?.code!=='ESRCH';}
|
|
123
140
|
}
|
|
141
|
+
function remoteOwnerPid(marker){return marker?.schema==='deadbyte.remote-session.v2'?marker.owner_pid:marker?.pid;}
|
|
124
142
|
async function readRemoteSessionMarker(root){
|
|
125
143
|
const file=remoteSessionMarker(root);
|
|
126
144
|
let text;try{text=await readFile(file,'utf8');}catch(error){if(error?.code==='ENOENT') return null;throw error;}
|
|
127
145
|
let value;try{value=JSON.parse(text);}catch{throw new Error('remote session marker is invalid JSON');}
|
|
128
|
-
if(value?.schema
|
|
129
|
-
|
|
146
|
+
if(value?.schema==='deadbyte.remote-session.v1'){
|
|
147
|
+
if(!Number.isInteger(value?.pid)||value.pid<1) throw new Error('remote session marker schema invalid');
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
150
|
+
if(value?.schema==='deadbyte.remote-session.v2'){
|
|
151
|
+
if(!Number.isInteger(value?.owner_pid)||value.owner_pid<1||
|
|
152
|
+
!/^[0-9a-f]{64}$/.test(String(value?.session_nonce||''))||
|
|
153
|
+
!Number.isInteger(value?.guardian_pid)||value.guardian_pid<1) throw new Error('remote session marker schema invalid');
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
throw new Error('remote session marker schema invalid');
|
|
130
157
|
}
|
|
131
158
|
async function recoverRemoteSession(ctx){
|
|
132
|
-
|
|
159
|
+
let prior=await readRemoteSessionMarker(ctx.root);
|
|
133
160
|
if(!prior) return;
|
|
134
|
-
|
|
135
|
-
|
|
161
|
+
const ownerPid=remoteOwnerPid(prior);
|
|
162
|
+
if(pidAlive(ownerPid)) throw new Error(`remote session already active pid=${ownerPid}`);
|
|
163
|
+
if(prior.schema==='deadbyte.remote-session.v2'&&pidAlive(prior.guardian_pid)){
|
|
164
|
+
const deadline=Date.now()+3000;
|
|
165
|
+
while(Date.now()<deadline){
|
|
166
|
+
await sleep(100);
|
|
167
|
+
prior=await readRemoteSessionMarker(ctx.root);
|
|
168
|
+
if(!prior) return;
|
|
169
|
+
if(remoteOwnerPid(prior)!==ownerPid) throw new Error('remote session ownership changed during guardian recovery');
|
|
170
|
+
}
|
|
171
|
+
throw new Error(`remote session guardian cleanup still active pid=${prior.guardian_pid}`);
|
|
172
|
+
}
|
|
173
|
+
process.stdout.write(`♻️ [RECOVERY] Stale remote session pid=${ownerPid}; revoking authority before restart.\n`);
|
|
136
174
|
await cleanupRemoteSession(ctx);
|
|
137
175
|
await rm(remoteSessionMarker(ctx.root),{force:true});
|
|
138
176
|
}
|
|
139
177
|
async function claimRemoteSession(ctx){
|
|
140
178
|
const dir=path.join(ctx.root,'runtime');await mkdir(dir,{recursive:true});
|
|
141
|
-
const
|
|
142
|
-
|
|
179
|
+
const nonce=randomBytes(32).toString('hex');
|
|
180
|
+
const marker={schema:'deadbyte.remote-session.v2',owner_pid:process.pid,guardian_pid:0,session_nonce:nonce,started_at_utc:new Date().toISOString()};
|
|
181
|
+
const markerPath=remoteSessionMarker(ctx.root);
|
|
182
|
+
try{await writeFile(markerPath,`${JSON.stringify(marker)}\n`,{encoding:'utf8',flag:'wx'});}
|
|
143
183
|
catch(error){if(error?.code==='EEXIST') throw new Error('remote session already claimed');throw error;}
|
|
144
|
-
|
|
184
|
+
let guardian=null;
|
|
185
|
+
try{
|
|
186
|
+
guardian=spawn(process.execPath,[GUARDIAN_SCRIPT,'--state-root',ctx.root,'--owner-pid',String(process.pid),'--session-nonce',nonce],{
|
|
187
|
+
detached:true,stdio:'ignore',windowsHide:true,shell:false,env:process.env
|
|
188
|
+
});
|
|
189
|
+
if(!Number.isInteger(guardian.pid)||guardian.pid<1) throw new Error('remote session guardian did not start');
|
|
190
|
+
marker.guardian_pid=guardian.pid;
|
|
191
|
+
await writeFile(markerPath,`${JSON.stringify(marker)}\n`,'utf8');
|
|
192
|
+
guardian.unref();
|
|
193
|
+
return marker;
|
|
194
|
+
}catch(error){
|
|
195
|
+
try{guardian?.kill();}catch{}
|
|
196
|
+
await rm(markerPath,{force:true});
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
145
199
|
}
|
|
146
200
|
async function releaseRemoteSession(ctx,marker){
|
|
147
|
-
let current=null;try{current=await readRemoteSessionMarker(ctx.root);}catch(error){process.stderr.write(
|
|
148
|
-
|
|
201
|
+
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;}
|
|
202
|
+
const same=current?.schema==='deadbyte.remote-session.v2'&¤t.owner_pid===marker.owner_pid&¤t.session_nonce===marker.session_nonce;
|
|
203
|
+
if(same) await rm(remoteSessionMarker(ctx.root),{force:true});
|
|
149
204
|
}
|
|
150
205
|
async function runRemoteSession(){
|
|
151
206
|
const ctx=await remoteContext();
|
|
@@ -161,7 +216,7 @@ async function runRemoteSession(){
|
|
|
161
216
|
process.stdout.write('DEADBYTE MCP DEVICE SESSION\n');
|
|
162
217
|
process.stdout.write('[INFO] Starting local + remote runtime...\n');
|
|
163
218
|
for(const command of SESSION_START) invokeController(ctx,command);
|
|
164
|
-
process.stdout.write('[AUTHORITY] Verifying runtime planes...\n');
|
|
219
|
+
process.stdout.write('🛡️ [AUTHORITY] Verifying runtime planes...\n');
|
|
165
220
|
for(const [command,pattern] of SESSION_STATUS){
|
|
166
221
|
const result=invokeController(ctx,command,{capture:true});
|
|
167
222
|
if(!pattern.test(result.stdout)) throw new Error(`remote session authority verification failed: ${command} did not report ARMED`);
|
|
@@ -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.10' },
|
|
71
71
|
{ versionNegotiation:{ mode:{ pin:'2026-07-28' } } });
|
|
72
72
|
const transport = new StreamableHTTPClientTransport(endpoint);
|
|
73
73
|
const tag = randomBytes(8).toString('hex');
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { lstat, readFile, rm } from 'node:fs/promises';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
7
|
+
|
|
8
|
+
const CLEANUP=['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park'];
|
|
9
|
+
|
|
10
|
+
function parseArgs(argv){
|
|
11
|
+
const out={};
|
|
12
|
+
for(let i=0;i<argv.length;i+=2){
|
|
13
|
+
const key=argv[i],value=argv[i+1];
|
|
14
|
+
if(!key?.startsWith('--')||value===undefined) throw new Error('guardian arguments must be key/value pairs');
|
|
15
|
+
out[key.slice(2)]=value;
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
async function requireRegular(file,label){
|
|
20
|
+
const info=await lstat(file);
|
|
21
|
+
if(!info.isFile()||info.isSymbolicLink()) throw new Error(`${label} must be a regular non-symlink file`);
|
|
22
|
+
return file;
|
|
23
|
+
}
|
|
24
|
+
function pidAlive(pid){
|
|
25
|
+
try{process.kill(pid,0);return true;}
|
|
26
|
+
catch(error){return error?.code!=='ESRCH';}
|
|
27
|
+
}
|
|
28
|
+
async function readMarker(file){
|
|
29
|
+
let text;
|
|
30
|
+
try{text=await readFile(file,'utf8');}
|
|
31
|
+
catch(error){if(error?.code==='ENOENT') return null;throw error;}
|
|
32
|
+
try{return JSON.parse(text);}catch{return null;}
|
|
33
|
+
}
|
|
34
|
+
function markerMatches(marker,{ownerPid,nonce}){
|
|
35
|
+
return marker?.schema==='deadbyte.remote-session.v2'&&
|
|
36
|
+
marker?.owner_pid===ownerPid&&
|
|
37
|
+
marker?.session_nonce===nonce;
|
|
38
|
+
}
|
|
39
|
+
function invokeCleanup(powershell,launcher,command){
|
|
40
|
+
const result=spawnSync(powershell,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',launcher,command],{
|
|
41
|
+
stdio:'ignore',windowsHide:true,shell:false
|
|
42
|
+
});
|
|
43
|
+
return !result.error&&result.status===0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function main(){
|
|
47
|
+
if(process.platform!=='win32') return;
|
|
48
|
+
const args=parseArgs(process.argv.slice(2));
|
|
49
|
+
const root=path.resolve(args['state-root']||path.join(os.homedir(),'.deadbyte-mcp'));
|
|
50
|
+
const ownerPid=Number(args['owner-pid']);
|
|
51
|
+
const nonce=String(args['session-nonce']||'');
|
|
52
|
+
if(!Number.isInteger(ownerPid)||ownerPid<1) throw new Error('guardian owner pid invalid');
|
|
53
|
+
if(!/^[0-9a-f]{64}$/.test(nonce)) throw new Error('guardian session nonce invalid');
|
|
54
|
+
|
|
55
|
+
const launcher=await requireRegular(path.join(root,'bin','DEADBYTE-MCP.ps1'),'stable DEADBYTE launcher');
|
|
56
|
+
const systemRoot=process.env.SystemRoot||process.env.WINDIR;
|
|
57
|
+
if(!systemRoot) throw new Error('SystemRoot/WINDIR missing');
|
|
58
|
+
const powershell=await requireRegular(path.join(systemRoot,'System32','WindowsPowerShell','v1.0','powershell.exe'),'Windows PowerShell');
|
|
59
|
+
const markerPath=path.join(root,'runtime','remote-session.json');
|
|
60
|
+
|
|
61
|
+
for(;;){
|
|
62
|
+
const marker=await readMarker(markerPath);
|
|
63
|
+
if(!marker||!markerMatches(marker,{ownerPid,nonce})) return;
|
|
64
|
+
if(pidAlive(ownerPid)){
|
|
65
|
+
await sleep(250);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for(const command of CLEANUP) invokeCleanup(powershell,launcher,command);
|
|
70
|
+
const current=await readMarker(markerPath);
|
|
71
|
+
if(current&&markerMatches(current,{ownerPid,nonce})) await rm(markerPath,{force:true});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main().catch(()=>{process.exitCode=1;});
|
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.10');
|
|
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.10 / 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\.10'/);
|
|
34
|
+
assert.match(verifier, /envelope\.body\.version==='0\.8\.10'/);
|
|
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 patch successor release authority agrees on V0.8.
|
|
9
|
+
test('R33 patch successor release authority agrees on V0.8.10 / 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 patch successor release authority agrees on V0.8.8 / R33 identity', as
|
|
|
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.10');
|
|
24
|
+
assert.match(version, /DEADBYTE_VERSION = '0\.8\.10'/);
|
|
25
|
+
assert.match(controller, /CONTROLLER V0\.8\.10 \/ R33/);
|
|
26
|
+
assert.match(gate, /DEADBYTE V0\.8\.10 \/ R33 WINDOWS BATCH GATE: PASS/);
|
|
27
|
+
assert.match(readme, /^DEADBYTE MCP V0\.8\.10 \/ R33 FINAL MACHINE BASELINE$/m);
|
|
28
|
+
assert.match(architecture, /^# DEADBYTE MCP V0\.8\.10 \/ R33 ARCHITECTURE$/m);
|
|
29
|
+
assert.match(controllerReadme, /^DEADBYTE MCP V0\.8\.10 \/ 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\.10'/);
|
|
32
|
+
assert.match(parity, /version:'0\.8\.10'/);
|
|
33
|
+
assert.match(closure, /version:'0\.8\.10'/);
|
|
34
|
+
assert.match(closureVerify, /DEADBYTE V0\.8\.10 \/ R33 WINDOWS BATCH GATE: PASS/);
|
|
35
35
|
});
|
|
@@ -23,8 +23,16 @@ async function fixture({failCommand=''}={}){
|
|
|
23
23
|
return {dir,state,trace,env:{...process.env,DEADBYTE_STATE_ROOT:state,DEADBYTE_REMOTE_TEST_TRACE:trace,DEADBYTE_REMOTE_TEST_FAIL:failCommand}};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
async function traceCommands(file){
|
|
27
|
-
|
|
26
|
+
async function traceCommands(file,{read=readFile,retryDelayMs=10,maxAttempts=20}={}){
|
|
27
|
+
for(let attempt=1;attempt<=maxAttempts;attempt+=1){
|
|
28
|
+
try{return (await read(file,'utf8')).split(/\r?\n/).map(x=>x.trim()).filter(Boolean);}
|
|
29
|
+
catch(error){
|
|
30
|
+
if(error?.code==='ENOENT') return [];
|
|
31
|
+
if(error?.code==='EBUSY'&&attempt<maxAttempts){await sleep(retryDelayMs);continue;}
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
28
36
|
}
|
|
29
37
|
async function waitFor(file,predicate,{timeoutMs=6000}={}){
|
|
30
38
|
const deadline=Date.now()+timeoutMs;
|
|
@@ -35,6 +43,18 @@ async function waitFor(file,predicate,{timeoutMs=6000}={}){
|
|
|
35
43
|
}
|
|
36
44
|
return traceCommands(file);
|
|
37
45
|
}
|
|
46
|
+
|
|
47
|
+
test('trace reader tolerates a transient Windows sharing violation and returns complete commands',async()=>{
|
|
48
|
+
let calls=0;
|
|
49
|
+
const fakeRead=async()=>{
|
|
50
|
+
calls+=1;
|
|
51
|
+
if(calls<3){const error=new Error('simulated sharing violation');error.code='EBUSY';throw error;}
|
|
52
|
+
return 'start\narmprocess\n';
|
|
53
|
+
};
|
|
54
|
+
const commands=await traceCommands('ignored',{read:fakeRead,retryDelayMs:1,maxAttempts:4});
|
|
55
|
+
assert.deepEqual(commands,['start','armprocess']);
|
|
56
|
+
assert.equal(calls,3);
|
|
57
|
+
});
|
|
38
58
|
async function collect(child){
|
|
39
59
|
let stdout='',stderr='';
|
|
40
60
|
child.stdout?.on('data',chunk=>{stdout+=chunk;});
|
|
@@ -51,21 +71,41 @@ winTest('bare remote arms every authority plane, verifies ARMED state, streams l
|
|
|
51
71
|
try{
|
|
52
72
|
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
|
|
53
73
|
const output=await collect(child);
|
|
54
|
-
const ready=await waitFor(fx.trace,commands=>commands.
|
|
74
|
+
const ready=await waitFor(fx.trace,commands=>commands.slice(0,9).join(',')==='start,armprocess,armcoding,armautonomous,armhost,processstatus,codingstatus,autonomousstatus,hoststatus');
|
|
55
75
|
assert.deepEqual(ready.slice(0,9),[
|
|
56
76
|
'start','armprocess','armcoding','armautonomous','armhost',
|
|
57
77
|
'processstatus','codingstatus','autonomousstatus','hoststatus'
|
|
58
78
|
]);
|
|
59
79
|
assert.equal(child.exitCode,null,'remote session must remain foreground after becoming ready');
|
|
60
80
|
const tailDeadline=Date.now()+3000;
|
|
61
|
-
while(Date.now()<tailDeadline
|
|
62
|
-
assert.match(output.stdout
|
|
81
|
+
while(Date.now()<tailDeadline&&!/📜 \[LOG\] Live logs active/.test(output.stdout)) await sleep(50);
|
|
82
|
+
assert.match(output.stdout,/📜 \[LOG\] Live logs active\. Press Ctrl\+C to disconnect and revoke authority\./);
|
|
83
|
+
assert.match(output.stdout,/🛡️ \[AUTHORITY\] Verifying runtime planes\.\.\./);
|
|
63
84
|
const auditDir=path.join(fx.state,'audit');
|
|
85
|
+
const runtimeLogs=path.join(fx.state,'runtime','logs');
|
|
64
86
|
await mkdir(auditDir,{recursive:true});
|
|
65
|
-
await
|
|
87
|
+
await mkdir(runtimeLogs,{recursive:true});
|
|
88
|
+
const auditEvents=[
|
|
89
|
+
{seq:1,event_type:'tool.request',tool:'coding_tree',request_id:'abcdef1234567890'},
|
|
90
|
+
{seq:2,event_type:'tool.result',tool:'coding_tree',request_id:'abcdef1234567890',outcome:{is_error:false}},
|
|
91
|
+
{seq:3,event_type:'tool.request',tool:'coding_file_read',request_id:'fedcba9876543210'},
|
|
92
|
+
{seq:4,event_type:'tool.result',tool:'coding_file_read',request_id:'fedcba9876543210',outcome:{is_error:true}}
|
|
93
|
+
];
|
|
94
|
+
await writeFile(path.join(auditDir,'segment-00000001.jsonl'),`${auditEvents.map(event=>JSON.stringify(event)).join('\n')}\n`,'utf8');
|
|
95
|
+
await writeFile(path.join(runtimeLogs,'bridge.stdout.log'),[
|
|
96
|
+
'[TOOL IN ] 2026-09-16T00:00:00.000Z #000001 coding_tree {}',
|
|
97
|
+
'[TOOL OUT] 2026-09-16T00:00:00.001Z #000001 coding_tree {"is_error":false}',
|
|
98
|
+
'[TOOL OUT] 2026-09-16T00:00:00.002Z #000002 coding_file_read {"is_error":true}'
|
|
99
|
+
].join('\n')+'\n','utf8');
|
|
66
100
|
const logDeadline=Date.now()+3000;
|
|
67
|
-
while(Date.now()<logDeadline
|
|
68
|
-
assert.match(output.stdout
|
|
101
|
+
while(Date.now()<logDeadline&&!/📤❌ \[BRIDGE\.STDOUT\] \[TOOL OUT\].*coding_file_read/.test(output.stdout)) await sleep(50);
|
|
102
|
+
assert.match(output.stdout,/📥 \[AUDIT #1\] tool\.request coding_tree abcdef12/);
|
|
103
|
+
assert.match(output.stdout,/📤✅ \[AUDIT #2\] tool\.result coding_tree abcdef12/);
|
|
104
|
+
assert.match(output.stdout,/📥 \[AUDIT #3\] tool\.request coding_file_read fedcba98/);
|
|
105
|
+
assert.match(output.stdout,/📤❌ \[AUDIT #4\] tool\.result coding_file_read fedcba98/);
|
|
106
|
+
assert.match(output.stdout,/📥 \[BRIDGE\.STDOUT\] \[TOOL IN \].*coding_tree/);
|
|
107
|
+
assert.match(output.stdout,/📤✅ \[BRIDGE\.STDOUT\] \[TOOL OUT\].*coding_tree/);
|
|
108
|
+
assert.match(output.stdout,/📤❌ \[BRIDGE\.STDOUT\] \[TOOL OUT\].*coding_file_read/);
|
|
69
109
|
child.stdin.end();
|
|
70
110
|
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
71
111
|
assert.equal(ended.timeout,undefined,'remote session did not exit after foreground input closed');
|
|
@@ -73,6 +113,50 @@ winTest('bare remote arms every authority plane, verifies ARMED state, streams l
|
|
|
73
113
|
assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
74
114
|
assert.match(output.stdout,/DEADBYTE MCP DEVICE SESSION/i);
|
|
75
115
|
assert.match(output.stdout,/Live logs/i);
|
|
116
|
+
const withoutApprovedEmoji=output.stdout.replace(/[📜📥📤✅❌⚠♻🛡]/gu,'');
|
|
117
|
+
assert.doesNotMatch(withoutApprovedEmoji,/\p{Extended_Pictographic}/u,'human live stream may use only the approved semantic emoji set');
|
|
118
|
+
}finally{
|
|
119
|
+
if(child?.exitCode===null) child.kill();
|
|
120
|
+
await rm(fx.dir,{recursive:true,force:true});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
winTest('detached guardian revokes authority, parks, and removes the session marker after the owner is hard-killed',async()=>{
|
|
125
|
+
const fx=await fixture();
|
|
126
|
+
let child=null;
|
|
127
|
+
try{
|
|
128
|
+
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
|
|
129
|
+
const output=await collect(child);
|
|
130
|
+
const ready=await waitFor(fx.trace,commands=>commands.slice(0,9).join(',')==='start,armprocess,armcoding,armautonomous,armhost,processstatus,codingstatus,autonomousstatus,hoststatus');
|
|
131
|
+
assert.deepEqual(ready.slice(0,9),[
|
|
132
|
+
'start','armprocess','armcoding','armautonomous','armhost',
|
|
133
|
+
'processstatus','codingstatus','autonomousstatus','hoststatus'
|
|
134
|
+
]);
|
|
135
|
+
const markerPath=path.join(fx.state,'runtime','remote-session.json');
|
|
136
|
+
const markerDeadline=Date.now()+3000;
|
|
137
|
+
let marker=null;
|
|
138
|
+
while(Date.now()<markerDeadline){
|
|
139
|
+
try{marker=JSON.parse(await readFile(markerPath,'utf8'));if(marker?.guardian_pid) break;}catch{}
|
|
140
|
+
await sleep(50);
|
|
141
|
+
}
|
|
142
|
+
assert.equal(marker?.schema,'deadbyte.remote-session.v2');
|
|
143
|
+
assert.equal(marker?.owner_pid,child.pid);
|
|
144
|
+
assert.match(String(marker?.session_nonce||''),/^[0-9a-f]{64}$/);
|
|
145
|
+
assert.ok(Number.isInteger(marker?.guardian_pid)&&marker.guardian_pid>0,'guardian pid missing from v2 marker');
|
|
146
|
+
|
|
147
|
+
const killed=child.kill('SIGKILL');
|
|
148
|
+
assert.equal(killed,true,'failed to hard-kill remote owner');
|
|
149
|
+
await Promise.race([output.closed,sleep(3000)]);
|
|
150
|
+
|
|
151
|
+
const cleaned=await waitFor(fx.trace,commands=>commands.slice(-5).join(',')==='disarmautonomous,disarmcoding,disarmprocess,disarmhost,park',{timeoutMs:10000});
|
|
152
|
+
assert.deepEqual(cleaned.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
153
|
+
const markerGoneDeadline=Date.now()+3000;
|
|
154
|
+
let markerGone=false;
|
|
155
|
+
while(Date.now()<markerGoneDeadline){
|
|
156
|
+
try{await readFile(markerPath,'utf8');}catch(error){if(error?.code==='ENOENT'){markerGone=true;break;}throw error;}
|
|
157
|
+
await sleep(50);
|
|
158
|
+
}
|
|
159
|
+
assert.equal(markerGone,true,'guardian left stale remote-session marker after hard kill');
|
|
76
160
|
}finally{
|
|
77
161
|
if(child?.exitCode===null) child.kill();
|
|
78
162
|
await rm(fx.dir,{recursive:true,force:true});
|
|
@@ -106,6 +190,7 @@ winTest('bare remote recovers a stale crashed session before arming a new one',a
|
|
|
106
190
|
const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'));
|
|
107
191
|
assert.deepEqual(ready.slice(0,5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
|
|
108
192
|
assert.equal(ready[5],'start');
|
|
193
|
+
assert.match(output.stdout,/♻️ \[RECOVERY\] Stale remote session pid=2147483000; revoking authority before restart\./);
|
|
109
194
|
child.stdin.end();
|
|
110
195
|
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
111
196
|
assert.equal(ended.timeout,undefined);
|
|
@@ -116,6 +201,25 @@ winTest('bare remote recovers a stale crashed session before arming a new one',a
|
|
|
116
201
|
}
|
|
117
202
|
});
|
|
118
203
|
|
|
204
|
+
winTest('remote warning lines use the approved warning emoji without changing the warning token',async()=>{
|
|
205
|
+
const fx=await fixture();
|
|
206
|
+
let child=null;
|
|
207
|
+
try{
|
|
208
|
+
child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
|
|
209
|
+
const output=await collect(child);
|
|
210
|
+
await waitFor(fx.trace,commands=>commands.includes('hoststatus'));
|
|
211
|
+
const markerPath=path.join(fx.state,'runtime','remote-session.json');
|
|
212
|
+
await writeFile(markerPath,'{invalid-json\n','utf8');
|
|
213
|
+
child.stdin.end();
|
|
214
|
+
const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
|
|
215
|
+
assert.equal(ended.timeout,undefined,'remote session did not exit after warning fixture');
|
|
216
|
+
assert.match(output.stderr,/⚠️ \[WARN\] remote session marker cleanup:/);
|
|
217
|
+
}finally{
|
|
218
|
+
if(child?.exitCode===null) child.kill();
|
|
219
|
+
await rm(fx.dir,{recursive:true,force:true});
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
119
223
|
winTest('bare remote refuses a second live foreground session without touching authority',async()=>{
|
|
120
224
|
const fx=await fixture();
|
|
121
225
|
let child=null;
|