deadbyte-mcp 0.15.32 → 0.15.33
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 +15 -11
- package/PROVENANCE.json +25 -22
- package/README.txt +18 -14
- package/RELEASE.json +26 -22
- package/SBOM.cdx.json +3 -3
- package/TEST-MATRIX.json +50 -33
- package/controller/deadbyte-process-policy.json +4 -4
- package/package.json +4 -3
- package/scripts/gate-windows-r56.ps1 +27 -0
- package/scripts/windows-gate-evidence-r56.mjs +81 -0
- package/src/runtime-update.mjs +68 -8
- package/src/version.mjs +1 -1
- package/test/r49-windows-gate.test.mjs +15 -16
- package/test/r55-release-contract.test.mjs +5 -3
- package/test/r56-release-contract.test.mjs +63 -0
- package/test/r56-rollback-launcher-restore.test.mjs +103 -0
package/MANIFEST.SHA256
CHANGED
|
@@ -49,7 +49,7 @@ ad9821d027ac70612820617ed3c197d465c98e42a9e2a5bbb40f571fb2314894 controller/dea
|
|
|
49
49
|
8c70a873fd77e5b1579512ec218220182c2bddba63dc50c56ec70a7b449c52d9 controller/deadbyte-desktop-policy.json
|
|
50
50
|
5e8ef223b0dbc52173aaf044a075837eef8964ff0e7e16f83a595e0d17695625 controller/deadbyte-host-policy.json.example
|
|
51
51
|
6f0cc469f51444dd18211fa3346c826abeea4d2ec7a8945f0200dc5c622031ef controller/DEADBYTE-MCP.cmd
|
|
52
|
-
|
|
52
|
+
cd499f8a4fc00663f9943e7b021e63a967fee77c152438ec3db0b628c77275b6 controller/deadbyte-process-policy.json
|
|
53
53
|
d274b099a298c1033fea8f1e8849751693bbc0448778d619400acb82d4f53a3b controller/deadbyte-semantic-lsp-config.json
|
|
54
54
|
3023d2985f5b6e5cc7c0d08cb8b342b362c93dce7ebd4224635362194be40cf2 controller/README.TXT
|
|
55
55
|
101e613518c73c6aa31c725fe1b5f9a24c995dc9876b7b28e1f3e97ac9f8d362 DEADBYTE-MCP-R27-FINAL/R27-ADMIN-CLOSURE.json
|
|
@@ -1343,7 +1343,7 @@ db605a698f917c4006462596e6526fe6a9c6eff9b8409e8472fe545d4b70027c node_modules/z
|
|
|
1343
1343
|
f67a25ded944912bd4621b68df17c7c70a52aae117278c076c0aabbc32a3abba node_modules/zod/v4/mini/schemas.d.ts
|
|
1344
1344
|
51b3a7869df2d3a1bd98acb9d5b6a61bbccc7653d7a3d8fca7f0e0db7e84e284 node_modules/zod/v4/mini/schemas.js
|
|
1345
1345
|
3e3125b5a537a24c3632c1c5c09640ce7bcb3935901b127ad8ae3c37a27f133f node_modules/zod/v4/package.json
|
|
1346
|
-
|
|
1346
|
+
566fc8a38e7558b511369c3f8f6828735dd7382ed28ec48d3262d95de591ea76 package.json
|
|
1347
1347
|
872947dffd89755b03558b217129f009dc9f4fd1ce55e93c602fc6ea97ba8b48 proof/commander-closure-20260927/CONTINUATION.json
|
|
1348
1348
|
2959980d295814aaa0df71fdb358d2cbfd01c1357ee36ef6b10c149875bdb262 proof/commander-closure-20260927/RESULT.json
|
|
1349
1349
|
2c2866309ca3a6fc8de5b03d445f1dcf0778474fa25cefb822b2ab729bc91c62 proof/commander-closure-20260927/SEARCH-CONTINUATION.json
|
|
@@ -1408,7 +1408,7 @@ d433aaea5cccd1e184775ac4d915f34e0b39c6c99916dddd009731ad5fd6443f proof/V073-WIN
|
|
|
1408
1408
|
bd0773a9e02e8ab11475c9cc5a7db29a8313233b7eab7f837922737e75ec5938 proof/VERIFY.txt
|
|
1409
1409
|
2c821808d4596965c577f40191daee224d3aea81989778c4af97f53a83b487db proof/WINDOWS-CONTAINED-STATUS.txt
|
|
1410
1410
|
f8bc839c7b4fcb0ea7b7e7ad9448847c3beae6f95f2eb4d407d1b284aaa4ff68 proof/WINDOWS-CONTAINMENT-STATUS.txt
|
|
1411
|
-
|
|
1411
|
+
ad94ad04d0ae744e6528b43e0dcaf8ffc27ebe81326ffc2f2704a195c61a1d45 PROVENANCE.json
|
|
1412
1412
|
27ca0f3c9ee3a1b6374a9c8dd98008decdd0c7659c7a569c70ad7b9734c74655 R34-BASELINE.json
|
|
1413
1413
|
0b7ec5ee347ddfa6cca59740fc7a8fe3fc5d51406265bb12189e82fa106319d2 R41-PARENT.json
|
|
1414
1414
|
bd2a789b0aab5663f0d208af2ca8e4ec98179bc8c7b57e70a962d4e06a3dcfc4 R42-PARENT.json
|
|
@@ -1417,9 +1417,9 @@ f932ef78b7a72b1bb0d7aedb5fe42fbb9951c2492eb528b72442f46ddff81a6c R44-DONORS.jso
|
|
|
1417
1417
|
731b4c559fc0d25dea701e4474f02400b27e8e3f4cac9f230d5214497d4490a9 R44-PARENT.json
|
|
1418
1418
|
d33ec5d167dd44800ba4e68372b08db43deb8d01df2ef71dd435ff004ac66c8b R45-PARENT.json
|
|
1419
1419
|
3dc607603fea511e2f428e9546a875ab7e38b6a0bbd5e803e4510de082f30804 R49-PARENT.json
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1420
|
+
ed5b11e9895e040d8fe09b810e27c6845d6f51ad139a6ab46374e60ae7d081d4 README.txt
|
|
1421
|
+
0480675e951e6ebfec7d0074403571d76ddbf75497be9dfa2c7d185d4931143a RELEASE.json
|
|
1422
|
+
a3f04699a6302367d1ac577e532ffd416e324a8a662560018489bb1bd18eb40a SBOM.cdx.json
|
|
1423
1423
|
7c86062c4f69db3179a129d65945ccfab1b1c1c5bcc29b91383eac097d50f2aa scripts/activate-skill-creator-1.1.1.mjs
|
|
1424
1424
|
bd138fe5a64088e8e1a7a5bf6104c5b17317bdc8cf3ad8191ea00ed82ace7d9b scripts/agent-eval-r42.mjs
|
|
1425
1425
|
8d90256a6863f3bbbff02e95cb12389fc6f9e8dbcb77bf1c20c902de371425e8 scripts/archive-source-zips.mjs
|
|
@@ -1517,6 +1517,7 @@ a62d69eea0c9db8778cd1551185ff6721ee6390d91afcb6863aecb75f9f422d1 scripts/gate-w
|
|
|
1517
1517
|
2df3dfb98aabef25e25a61035d9f17d644aecb52257047230142783b3ce5a1a3 scripts/gate-windows-r53.ps1
|
|
1518
1518
|
89f930eb3d3b9d8972d777a327f16bcfebcf12576a6ada48e53f64d1142adb2d scripts/gate-windows-r54.ps1
|
|
1519
1519
|
7dddf9b547f59b4b36ab4a7e7576d598ecd3f9e0ec24807608b2c52b0b6e6963 scripts/gate-windows-r55.ps1
|
|
1520
|
+
078066f300debe5cbb4a7dc5565a193e78d247e68089da96d220a91ef14b05c9 scripts/gate-windows-r56.ps1
|
|
1520
1521
|
9a085b34b9e54023eb0efadcea1e74a1bef44b984105d064768d66910999173e scripts/gate-windows.ps1
|
|
1521
1522
|
9e625bdc701298c05eb2a63c208d023a487a1baf306c05940eb29c19fb1d6544 scripts/init-desktop-policy-r40.ps1
|
|
1522
1523
|
01451045bff624a157e7eea79afd7edfa8cb8212ea0256c8ec744fe1e1b269ff scripts/init-host-policy.ps1
|
|
@@ -1610,6 +1611,7 @@ f344639080f68b7da5cda765b518e0fb91bc8818229b6f460e82b173018ad30c scripts/window
|
|
|
1610
1611
|
2eb7373875a9a6b6eab62dfb10136ec0f3525836015c80f097d9ae2714356b68 scripts/windows-gate-evidence-r53.mjs
|
|
1611
1612
|
127497b8ac8701da6a1211efb9f311aab3a67c4995430588617210d681139cf2 scripts/windows-gate-evidence-r54.mjs
|
|
1612
1613
|
93021201c4f37191545502a411886eafef8df031675b716c5d7eb4b50d5e30df scripts/windows-gate-evidence-r55.mjs
|
|
1614
|
+
be332ed7cef04abaec8679198e379d7f42fc67e0833be9f42e25103c88cb5b26 scripts/windows-gate-evidence-r56.mjs
|
|
1613
1615
|
2255b8eb78ca61267df54448560a671357f04893b6bb1df27b8b9fc8a944d255 scripts/windows-gate-evidence.mjs
|
|
1614
1616
|
105a5c6dcd54e4fabb416df9eaac093654f3ea39c4233a56e0bc6d53371b2128 scripts/workload-contract-regression-r47.mjs
|
|
1615
1617
|
c32cb9054a1b9641ae071c00622c0054272bdb0b519ea22c4ff926a1600a2b46 scripts/workload-stream-regression.mjs
|
|
@@ -1774,7 +1776,7 @@ fafeb0ec6e31762f14de46a5f021582b9a54de8af4c73c3ecc92ac71020cc8b7 src/remote-ses
|
|
|
1774
1776
|
45fcd7e9447545785e851fbeec439551c10a85c93f60a19437729870222c697c src/runtime-catalog-expectation.mjs
|
|
1775
1777
|
066c97427989298ff3d7db06e40572f4d634269ea7dfd5836575ea98c52d92bc src/runtime-coherence.mjs
|
|
1776
1778
|
ce2223bf6075e96cc02505c1439acce18bb1f204c5e86cf9152bb7194daf3cd2 src/runtime-identity.mjs
|
|
1777
|
-
|
|
1779
|
+
b0050ff8b0d07d99184cb14d6b8866f87ecf927d71645e4410dae89756c8b9cb src/runtime-update.mjs
|
|
1778
1780
|
c61335adb38bfc415fe1cdabfe2c0a87e61579dfd1e52cce91c44d6993479457 src/search-cursor.mjs
|
|
1779
1781
|
fc5407ef8338ebeeede16225b3249166dc4d45e903d873eb46c15c3df07dc9ad src/semantic-backend-registry.mjs
|
|
1780
1782
|
686e9b55b9f4352b941579f186a9b9d348d86af53d052cbd5da953e7d15470ff src/semantic-code.mjs
|
|
@@ -1794,12 +1796,12 @@ c99c2402fb0df4f68634fa906eb198c551c55dad9f0921a7b8ed6e33d503884e src/tunnel-std
|
|
|
1794
1796
|
aa765e9a28c69ff58a5b5a0d29b49ea181af4db9076633b102dbca25861e708e src/tunnel-stdio-compat.mjs
|
|
1795
1797
|
642cb67d1854850e336ee73fbd71b329056bdcbdab35cea19c1a995a155ff5d9 src/verifier-cli.mjs
|
|
1796
1798
|
8f818a4852ce3be3a380cd4736c3073a7a3e0e45cd7c7ca90588a6b843d3d022 src/verifier.mjs
|
|
1797
|
-
|
|
1799
|
+
2afcfc97ef9d39e24563308cb48a22d6bbaacff95b4a7856f2f14a25fb45c9a0 src/version.mjs
|
|
1798
1800
|
7e09c57a97289360aabfaf3d531208e54872efbfb3182f3c18203d2cb88c46b5 src/worker-registry.mjs
|
|
1799
1801
|
76361d5ae9a710273cf64a7525082197b692236bf23689875e5fd1ef4aa96d2b src/worker-scheduler.mjs
|
|
1800
1802
|
4da1b32f5198bb089bc68b7eb6de21ea296678b5020018a73742bf0df57d62fa src/workload-substrate.mjs
|
|
1801
1803
|
1bd637e7634ca0259791c5108fcf324554f70b1db49e5eac3505287c04bbc3be STABILIZATION-PROGRESS.md
|
|
1802
|
-
|
|
1804
|
+
7d84b869cc45f61a00daaf97c56ff8f8e919f9893823b37ea98163546828c872 TEST-MATRIX.json
|
|
1803
1805
|
e4f1fb97545f23772ddff28ad3f9954a4714f9854062fca62e0e12c1cb2ec4ae test/agent-backend-r44.test.mjs
|
|
1804
1806
|
2a78c818058b25efdc143a3a97c832da231ccd6ff9d90c7796d681a0251b85c4 test/agent-crash-child.mjs
|
|
1805
1807
|
d9461ab7c118ee75d37a2d6f5e637d7e43505af6a9ad8c7ddafffc8ace185a5b test/agent-crash-worker.mjs
|
|
@@ -2044,7 +2046,7 @@ eaaf2547cf06fad4c16db72413ea137143c280a9bc641b3230ee2d85a0b65b5a test/r44-final
|
|
|
2044
2046
|
25a21ccffcf566b020b8f3c6c0a5a3b7ff06b243fff84e405207e458640ba487 test/r47-release-contract.test.mjs
|
|
2045
2047
|
2871a825520cca851a10f65f42a6033c4c17d7446c1930d7a64316a76aacf681 test/r48-release-contract.test.mjs
|
|
2046
2048
|
ec6fc253774c318b048dc943c83b496f942d8dd034f6db9439a99a46ae3a6158 test/r49-remote-control-donors.test.mjs
|
|
2047
|
-
|
|
2049
|
+
74a1b45b6256aa97a0974c404ac7af26986ba3956760ba204d1e1f2fff4f8d30 test/r49-windows-gate.test.mjs
|
|
2048
2050
|
c3f0a8b6ced2c15ed8580fcb261ad65bf3b885e6593d70de7394be63aba8dd1c test/r51-live-log-polling.test.mjs
|
|
2049
2051
|
3821085180a09707110e4c1a10e711343e9fb2fcf871c7c1e34149a77c7fba50 test/r51-release-contract.test.mjs
|
|
2050
2052
|
cc1ca8fe9514ca047ace52cd688f3f4fa5b7680a280d7a31cc2196ce915b91c9 test/r51-runtime-coherence.test.mjs
|
|
@@ -2055,7 +2057,9 @@ b0a9cca4f2c5dcf1a24d6e7675b42c72e88339b29ddc9220aa679316ae1467f5 test/r53-relea
|
|
|
2055
2057
|
04fe09cdd94ae23cff6a9acebb64d5a09391fd5e7f5fc778dd8dd8e10a3dd3e2 test/r54-offline-predecessor-self-exclusion.test.mjs
|
|
2056
2058
|
4148924e4edc935398e20a763cb27d903095b978898e8140b695b5642b63fe8c test/r54-release-contract.test.mjs
|
|
2057
2059
|
4847402324bff518df66c9b7dbd1091bf8c0f5c5547e70c1a042c963b770bd28 test/r55-offline-predecessor-guardian-family.test.mjs
|
|
2058
|
-
|
|
2060
|
+
b1e6b35cf8a20214e1797cc1051c5e9c733f8d0f69b564b4ef73edc60132b252 test/r55-release-contract.test.mjs
|
|
2061
|
+
f193c42af942d34f03f0e916ba7d8c61ed0b6450ad11df87dbddb4c3cf00d6e7 test/r56-release-contract.test.mjs
|
|
2062
|
+
74c25d78ddebb04fad40576b284639eabbfb4487b4ec090fb1dcf6874cef878c test/r56-rollback-launcher-restore.test.mjs
|
|
2059
2063
|
e45a6cd299d8d65bdeb9bc0117ce1eb2b47fdebad89a02413ee979c9d0ae3a5c test/release-activation-gate.test.mjs
|
|
2060
2064
|
85f6dc2059fd19d03452309ffe67bed5b87da8e6f0ce3a85cab58cba8b197ceb test/release-generation.test.mjs
|
|
2061
2065
|
bb58887a2c393cd5aac3fa3bb3a04de2704bd2a30dd2083ea638543485fa7e60 test/release-manifest-windows.test.mjs
|
package/PROVENANCE.json
CHANGED
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.provenance.v1",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"builder": "deadbyte-
|
|
5
|
-
"source_model": "exact published 0.15.
|
|
3
|
+
"version": "0.15.33",
|
|
4
|
+
"builder": "deadbyte-r56-signed-rollback-launcher-restore-hotfix",
|
|
5
|
+
"source_model": "exact published and active 0.15.32 artifact -> signed activation receipt verified -> explicit rollback failed before mutation because predecessor verification compared the successor live launcher to the prior launcher digest -> signed activation handoff confirmed exact predecessor launcher snapshots -> parent regression RED -> surgical split stored-installation verification plus signed predecessor launcher restore before pointer commit plus successor launcher recovery ordering -> focused/full regression -> package verification -> registry round-trip -> activation/rollback/restore",
|
|
6
6
|
"signing": "ed25519",
|
|
7
|
-
"parent_release_id": "v0.15.
|
|
8
|
-
"parent_manifest_sha256": "
|
|
9
|
-
"
|
|
10
|
-
"
|
|
7
|
+
"parent_release_id": "v0.15.32-e7223f467777f5df",
|
|
8
|
+
"parent_manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
9
|
+
"parent_generation_manifest_sha256": "740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e",
|
|
10
|
+
"parent_tarball_sha256": "c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638",
|
|
11
|
+
"parent_activation_status": "ACTIVATED_ROLLBACK_DEFECT_OBSERVED",
|
|
11
12
|
"runtime_predecessor": {
|
|
12
|
-
"release_id": "v0.15.
|
|
13
|
-
"manifest_sha256": "
|
|
14
|
-
"generation_manifest_sha256": "
|
|
13
|
+
"release_id": "v0.15.32-e7223f467777f5df",
|
|
14
|
+
"manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
15
|
+
"generation_manifest_sha256": "740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e"
|
|
15
16
|
},
|
|
16
|
-
"source_predecessor_version": "0.15.
|
|
17
|
-
"source_predecessor_tarball_sha256": "
|
|
18
|
-
"source_predecessor_manifest_file_sha256": "
|
|
19
|
-
"
|
|
20
|
-
"defect": "
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
17
|
+
"source_predecessor_version": "0.15.32",
|
|
18
|
+
"source_predecessor_tarball_sha256": "c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638",
|
|
19
|
+
"source_predecessor_manifest_file_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
20
|
+
"r56_hotfix": {
|
|
21
|
+
"defect": "explicit rollback verifies predecessor against successor launcher before restoring signed predecessor launcher snapshot",
|
|
22
|
+
"signed_handoff_launcher_snapshot_required": true,
|
|
23
|
+
"stored_predecessor_verified_without_live_launcher": true,
|
|
24
|
+
"predecessor_launcher_restored_before_pointer_commit": true,
|
|
25
|
+
"successor_launcher_restored_before_recovery_pointer": true,
|
|
26
|
+
"exact_parent_activation_receipt_sha256": "6518a04154f485cfae42e582269634d69a8b05a0183149d5e10006fbdd9d933c",
|
|
27
|
+
"observed_parent_rollback_failure_receipt_sha256": "00cbd497e4902c67ab39313a378e2fcf32159113b46339ad1d54b5e5a7714205",
|
|
28
|
+
"red_parent_0_15_32": "FAIL_5_OF_5",
|
|
29
|
+
"green_r56_candidate": "PASS_5_OF_5",
|
|
27
30
|
"full_regression": "PASS",
|
|
28
31
|
"stable_final_claim": false
|
|
29
32
|
},
|
|
30
|
-
"reproducibility": "0.15.
|
|
33
|
+
"reproducibility": "0.15.32 remains immutable and active while R56 is built. Rollback input remains the signed activation receipt; predecessor launcher bytes are accepted only from the signature-verified sibling handoff whose prior/new pointers match that receipt. The predecessor release/generation are verified independently before shutdown; the signed predecessor launcher snapshot is restored before pointer commit. Recovery reinstalls the signed successor launcher before restoring the successor pointer.",
|
|
31
34
|
"operator_override": {
|
|
32
35
|
"four_hour_soak": "NOT_COMPLETED",
|
|
33
36
|
"reason": "owner explicitly directed deploy before the 4-hour hard soak completed",
|
package/README.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
DEADBYTE MCP V0.15.
|
|
1
|
+
DEADBYTE MCP V0.15.33 / R56 SIGNED ROLLBACK LAUNCHER RESTORE HOTFIX
|
|
2
2
|
=========================
|
|
3
3
|
|
|
4
4
|
AUTHENTICATED MACHINE TRUTH + DURABLE AGENT + CODING + AUTONOMOUS PRODUCTION ENGINE
|
|
@@ -7,12 +7,12 @@ NPX PRIMARY OPERATOR UX
|
|
|
7
7
|
------------------------
|
|
8
8
|
Use the npm CLI entry point instead of the legacy CMD convenience wrapper:
|
|
9
9
|
|
|
10
|
-
npx -y deadbyte-mcp@0.15.
|
|
11
|
-
npx -y deadbyte-mcp@0.15.
|
|
12
|
-
npx -y deadbyte-mcp@0.15.
|
|
13
|
-
npx -y deadbyte-mcp@0.15.
|
|
14
|
-
npx -y deadbyte-mcp@0.15.
|
|
15
|
-
npx -y deadbyte-mcp@0.15.
|
|
10
|
+
npx -y deadbyte-mcp@0.15.33 mcp
|
|
11
|
+
npx -y deadbyte-mcp@0.15.33 remote
|
|
12
|
+
npx -y deadbyte-mcp@0.15.33 remote status
|
|
13
|
+
npx -y deadbyte-mcp@0.15.33 remote restart
|
|
14
|
+
npx -y deadbyte-mcp@0.15.33 audit status
|
|
15
|
+
npx -y deadbyte-mcp@0.15.33 audit verify
|
|
16
16
|
|
|
17
17
|
The `mcp` command is the quiet stdio server entry for local MCP clients; stdout is reserved for MCP.
|
|
18
18
|
The remote CLI invokes the stable active-release PowerShell launcher directly with shell=false.
|
|
@@ -29,6 +29,10 @@ and a random 256-bit session nonce, prevents concurrent foreground sessions, and
|
|
|
29
29
|
recover only a dead, unguarded stale owner. Explicit subcommands such as `remote status` remain
|
|
30
30
|
one-shot controller operations.
|
|
31
31
|
|
|
32
|
+
R56 SIGNED ROLLBACK LAUNCHER RESTORE HOTFIX
|
|
33
|
+
------------------------------------------------
|
|
34
|
+
0.15.33 fixes the explicit rollback defect observed after the successful 0.15.32 production activation. The prior immutable release and generation are now verified without incorrectly comparing them to the currently active successor launcher. Rollback then loads the signature-verified activation handoff, requires its prior/new pointers to match the signed activation receipt, restores the signed predecessor launcher snapshot before committing the predecessor pointer, and verifies the complete predecessor installation before restart. If rollback recovery is required, the signed successor launcher bytes are reinstalled before the successor pointer is restored. 0.15.32 remains immutable and published.
|
|
35
|
+
|
|
32
36
|
R55 ACTIVATION GUARDIAN FAMILY HOTFIX
|
|
33
37
|
--------------------------------------
|
|
34
38
|
0.15.32 fixes the remaining 0.15.31 offline-recovery self-classification defect observed during production activation. R54 excluded the detached updater supervisor's ancestor chain but the foreground remote-session guardian is a sibling owned by the deadbyte-cli ancestor. R55 excludes that guardian only when its declared --owner-pid is in the updater ancestry, its actual ParentProcessId equals that owner, and its 256-bit session nonce matches the foreground-session contract. Unrelated guardians and stale DEADBYTE runtimes still block recovery. 0.15.31 remains immutable and published; production runtime predecessor remains exact 0.15.29 until R55 activation completes.
|
|
@@ -280,7 +284,7 @@ CONTROLLER
|
|
|
280
284
|
----------
|
|
281
285
|
Primary operator entry point:
|
|
282
286
|
|
|
283
|
-
npx -y deadbyte-mcp@0.15.
|
|
287
|
+
npx -y deadbyte-mcp@0.15.33 remote
|
|
284
288
|
|
|
285
289
|
The legacy CMD entry remains compatibility-only for R33 rollback safety.
|
|
286
290
|
|
|
@@ -341,7 +345,7 @@ MCP CLIENT CONFIGURATION
|
|
|
341
345
|
------------------------
|
|
342
346
|
The local stdio entry point is quiet and suitable for MCP hosts:
|
|
343
347
|
|
|
344
|
-
npx -y deadbyte-mcp@0.15.
|
|
348
|
+
npx -y deadbyte-mcp@0.15.33 mcp
|
|
345
349
|
|
|
346
350
|
CLAUDE DESKTOP
|
|
347
351
|
Use the standard local-server entry in claude_desktop_config.json:
|
|
@@ -350,7 +354,7 @@ Use the standard local-server entry in claude_desktop_config.json:
|
|
|
350
354
|
"mcpServers": {
|
|
351
355
|
"deadbyte": {
|
|
352
356
|
"command": "npx",
|
|
353
|
-
"args": ["-y", "deadbyte-mcp@0.15.
|
|
357
|
+
"args": ["-y", "deadbyte-mcp@0.15.33", "mcp"]
|
|
354
358
|
}
|
|
355
359
|
}
|
|
356
360
|
}
|
|
@@ -363,7 +367,7 @@ Create .cursor/mcp.json:
|
|
|
363
367
|
"deadbyte": {
|
|
364
368
|
"type": "stdio",
|
|
365
369
|
"command": "npx",
|
|
366
|
-
"args": ["-y", "deadbyte-mcp@0.15.
|
|
370
|
+
"args": ["-y", "deadbyte-mcp@0.15.33", "mcp"]
|
|
367
371
|
}
|
|
368
372
|
}
|
|
369
373
|
}
|
|
@@ -376,7 +380,7 @@ Create .vscode/mcp.json:
|
|
|
376
380
|
"deadbyte": {
|
|
377
381
|
"type": "stdio",
|
|
378
382
|
"command": "npx",
|
|
379
|
-
"args": ["-y", "deadbyte-mcp@0.15.
|
|
383
|
+
"args": ["-y", "deadbyte-mcp@0.15.33", "mcp"]
|
|
380
384
|
}
|
|
381
385
|
}
|
|
382
386
|
}
|
|
@@ -386,9 +390,9 @@ Add this to ~/.codex/config.toml:
|
|
|
386
390
|
|
|
387
391
|
[mcp_servers.deadbyte]
|
|
388
392
|
command = "npx"
|
|
389
|
-
args = ["-y", "deadbyte-mcp@0.15.
|
|
393
|
+
args = ["-y", "deadbyte-mcp@0.15.33", "mcp"]
|
|
390
394
|
|
|
391
|
-
The remote device path remains `npx -y deadbyte-mcp@0.15.
|
|
395
|
+
The remote device path remains `npx -y deadbyte-mcp@0.15.33 remote`. Remote public MCP uses the
|
|
392
396
|
verified HTTPS named-tunnel URL selected by the active generation; do not commit a private device
|
|
393
397
|
URL or tunnel token into a repository.
|
|
394
398
|
|
package/RELEASE.json
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.release.v1",
|
|
3
3
|
"name": "deadbyte-mcp",
|
|
4
|
-
"version": "0.15.
|
|
5
|
-
"train": "
|
|
6
|
-
"label": "
|
|
4
|
+
"version": "0.15.33",
|
|
5
|
+
"train": "R56",
|
|
6
|
+
"label": "SIGNED ROLLBACK LAUNCHER RESTORE HOTFIX",
|
|
7
7
|
"protocol_revision": "2026-07-28",
|
|
8
8
|
"parent": {
|
|
9
|
-
"version": "0.15.
|
|
10
|
-
"release_id": "v0.15.
|
|
11
|
-
"manifest_sha256": "
|
|
12
|
-
"
|
|
13
|
-
"
|
|
9
|
+
"version": "0.15.32",
|
|
10
|
+
"release_id": "v0.15.32-e7223f467777f5df",
|
|
11
|
+
"manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
12
|
+
"generation_manifest_sha256": "740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e",
|
|
13
|
+
"tarball_sha256": "c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638",
|
|
14
|
+
"activation_status": "ACTIVATED_ROLLBACK_DEFECT_OBSERVED"
|
|
14
15
|
},
|
|
15
16
|
"runtime_predecessor": {
|
|
16
|
-
"release_id": "v0.15.
|
|
17
|
-
"manifest_sha256": "
|
|
18
|
-
"generation_manifest_sha256": "
|
|
17
|
+
"release_id": "v0.15.32-e7223f467777f5df",
|
|
18
|
+
"manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
19
|
+
"generation_manifest_sha256": "740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e"
|
|
19
20
|
},
|
|
20
21
|
"source_predecessor": {
|
|
21
|
-
"version": "0.15.
|
|
22
|
-
"tarball_sha256": "
|
|
23
|
-
"manifest_file_sha256": "
|
|
22
|
+
"version": "0.15.32",
|
|
23
|
+
"tarball_sha256": "c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638",
|
|
24
|
+
"manifest_file_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b"
|
|
24
25
|
},
|
|
25
26
|
"hotfix": {
|
|
26
|
-
"defect": "
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
27
|
+
"defect": "explicit rollback verifies predecessor against successor launcher before restoring signed predecessor launcher snapshot",
|
|
28
|
+
"signed_handoff_launcher_snapshot_required": true,
|
|
29
|
+
"stored_predecessor_verified_without_live_launcher": true,
|
|
30
|
+
"predecessor_launcher_restored_before_pointer_commit": true,
|
|
31
|
+
"successor_launcher_restored_before_recovery_pointer": true,
|
|
32
|
+
"exact_parent_activation_receipt_sha256": "6518a04154f485cfae42e582269634d69a8b05a0183149d5e10006fbdd9d933c",
|
|
33
|
+
"observed_parent_rollback_failure_receipt_sha256": "00cbd497e4902c67ab39313a378e2fcf32159113b46339ad1d54b5e5a7714205",
|
|
34
|
+
"red_parent_0_15_32": "FAIL_5_OF_5",
|
|
35
|
+
"green_r56_candidate": "PASS_5_OF_5",
|
|
33
36
|
"full_regression": "PASS",
|
|
34
37
|
"stable_final_claim": false
|
|
35
38
|
},
|
|
@@ -138,6 +141,7 @@
|
|
|
138
141
|
"human_livelog_single_parse": true,
|
|
139
142
|
"offline_predecessor_host_revoke_before_capture": true,
|
|
140
143
|
"offline_recovery_self_process_exclusion": true,
|
|
141
|
-
"offline_recovery_foreground_guardian_family_exclusion": true
|
|
144
|
+
"offline_recovery_foreground_guardian_family_exclusion": true,
|
|
145
|
+
"signed_rollback_launcher_snapshot_restore": true
|
|
142
146
|
}
|
|
143
147
|
}
|
package/SBOM.cdx.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.6",
|
|
4
|
-
"serialNumber": "urn:cdx:deadbyte-mcp:
|
|
4
|
+
"serialNumber": "urn:cdx:deadbyte-mcp:r56:0.15.33",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
7
|
"component": {
|
|
8
8
|
"type": "application",
|
|
9
9
|
"name": "deadbyte-mcp",
|
|
10
|
-
"version": "0.15.
|
|
10
|
+
"version": "0.15.33"
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"components": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
{
|
|
35
35
|
"type": "file",
|
|
36
36
|
"name": "deadbyte-hardware-observer-r45.exe",
|
|
37
|
-
"version": "0.15.
|
|
37
|
+
"version": "0.15.33",
|
|
38
38
|
"hashes": [
|
|
39
39
|
{
|
|
40
40
|
"alg": "SHA-256",
|
package/TEST-MATRIX.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.test-matrix.v1",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"train": "
|
|
3
|
+
"version": "0.15.33",
|
|
4
|
+
"train": "R56",
|
|
5
5
|
"primary_platform": "win32-x64",
|
|
6
6
|
"reference": {
|
|
7
7
|
"package": "@wonderwhy-er/desktop-commander",
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
},
|
|
12
12
|
"required": [
|
|
13
13
|
{
|
|
14
|
-
"id": "
|
|
15
|
-
"command": "npm run
|
|
16
|
-
"expected": "PASS
|
|
14
|
+
"id": "r56-focused",
|
|
15
|
+
"command": "npm run r56:focused:test",
|
|
16
|
+
"expected": "PASS signed rollback handoff launcher restore, ordering, activation recovery regressions, runtime update/slot contracts"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"id": "full-regression",
|
|
20
20
|
"command": "npm run r48:full:test",
|
|
21
|
-
"expected": "PASS current
|
|
21
|
+
"expected": "PASS current R56 successor"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"id": "package-boundary",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
{
|
|
29
29
|
"id": "windows-gate",
|
|
30
30
|
"command": "npm run gate:windows",
|
|
31
|
-
"expected": "PASS
|
|
31
|
+
"expected": "PASS R56 focused + recorded full regression + manifest/doctor evidence"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"id": "package-verify",
|
|
@@ -37,51 +37,63 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"id": "activation",
|
|
40
|
-
"command": "npx --yes deadbyte-mcp@0.15.
|
|
41
|
-
"expected": "
|
|
40
|
+
"command": "npx --yes deadbyte-mcp@0.15.33 remote",
|
|
41
|
+
"expected": "activate exact R56 from exact active 0.15.32"
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
"id": "
|
|
45
|
-
"command": "signed
|
|
46
|
-
"expected": "
|
|
44
|
+
"id": "rollback",
|
|
45
|
+
"command": "runtime-update --rollback-receipt <signed R56 activation receipt>",
|
|
46
|
+
"expected": "restore exact signed 0.15.32 pointer, signed predecessor launcher snapshot, ONLINE runtime, all authority DISARMED"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
"id": "
|
|
50
|
-
"command": "
|
|
51
|
-
"expected": "
|
|
49
|
+
"id": "restore",
|
|
50
|
+
"command": "npx --yes deadbyte-mcp@0.15.33 remote",
|
|
51
|
+
"expected": "restore same exact R56 release/generation and foreground authority contract"
|
|
52
52
|
}
|
|
53
53
|
],
|
|
54
54
|
"observed_pre_release_evidence": {
|
|
55
|
-
"
|
|
55
|
+
"red_parent_0_15_32": {
|
|
56
56
|
"status": "FAIL_EXPECTED",
|
|
57
|
-
"tests":
|
|
58
|
-
"failed":
|
|
59
|
-
"receipt_id": "
|
|
60
|
-
"receipt_sha256": "
|
|
57
|
+
"tests": 5,
|
|
58
|
+
"failed": 5,
|
|
59
|
+
"receipt_id": "483a2b5bbda756dc85954752",
|
|
60
|
+
"receipt_sha256": "f3b446306691d61e97896ab4d237abaa20d1243237299812e790233c46451dba"
|
|
61
61
|
},
|
|
62
|
-
"
|
|
62
|
+
"green_r56_candidate": {
|
|
63
63
|
"status": "PASS",
|
|
64
|
-
"tests":
|
|
64
|
+
"tests": 5,
|
|
65
65
|
"failed": 0,
|
|
66
|
-
"receipt_id": "
|
|
67
|
-
"receipt_sha256": "
|
|
66
|
+
"receipt_id": "7bf8f8dd93f175f5d7de118a",
|
|
67
|
+
"receipt_sha256": "4198930f38a3fc4b7978cfc94ca4509127561c170b05f7566bdf79513e449a8b"
|
|
68
|
+
},
|
|
69
|
+
"parent_activation": {
|
|
70
|
+
"status": "PASS",
|
|
71
|
+
"release_id": "v0.15.32-e7223f467777f5df",
|
|
72
|
+
"manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
73
|
+
"generation_manifest_sha256": "740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e",
|
|
74
|
+
"activation_receipt_sha256": "6518a04154f485cfae42e582269634d69a8b05a0183149d5e10006fbdd9d933c"
|
|
75
|
+
},
|
|
76
|
+
"parent_rollback": {
|
|
77
|
+
"status": "FAIL_EXPECTED",
|
|
78
|
+
"error": "active pointer launcher digest mismatch",
|
|
79
|
+
"command_receipt_sha256": "00cbd497e4902c67ab39313a378e2fcf32159113b46339ad1d54b5e5a7714205"
|
|
68
80
|
},
|
|
69
81
|
"full_regression": {
|
|
70
82
|
"status": "PASS",
|
|
71
|
-
"files":
|
|
83
|
+
"files": 233,
|
|
72
84
|
"batches": 8,
|
|
73
|
-
"elapsed_ms":
|
|
74
|
-
"receipt_id": "
|
|
75
|
-
"receipt_sha256": "
|
|
76
|
-
"request_sha256": "
|
|
85
|
+
"elapsed_ms": 245761.429,
|
|
86
|
+
"receipt_id": "3dce7b1649f489fc02b8f055",
|
|
87
|
+
"receipt_sha256": "35da0a6a0a7d98c08f32f24b5f06df434d353018089acfaf51b9dd51693b7083",
|
|
88
|
+
"request_sha256": "af035b60299d84e743aa2babaa2321e89555bea4bbb2cd95036f6dc9fe086010"
|
|
77
89
|
}
|
|
78
90
|
},
|
|
79
91
|
"inherited_parent_evidence": {
|
|
80
|
-
"version": "0.15.
|
|
92
|
+
"version": "0.15.32",
|
|
81
93
|
"parent_full_regression": "PASS",
|
|
82
|
-
"parent_manifest_sha256": "
|
|
83
|
-
"parent_tarball_sha256": "
|
|
84
|
-
"
|
|
94
|
+
"parent_manifest_sha256": "e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b",
|
|
95
|
+
"parent_tarball_sha256": "c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638",
|
|
96
|
+
"parent_registry_identity": "PASS",
|
|
85
97
|
"four_hour_soak": "NOT_COMPLETED_OPERATOR_BYPASS"
|
|
86
98
|
},
|
|
87
99
|
"operator_override": {
|
|
@@ -114,6 +126,11 @@
|
|
|
114
126
|
"guardian_owner_parent_binding_required": true,
|
|
115
127
|
"guardian_session_nonce_contract_required": true,
|
|
116
128
|
"unrelated_stale_runtime_fail_closed": true
|
|
129
|
+
},
|
|
130
|
+
"r56": {
|
|
131
|
+
"signed_handoff_launcher_snapshot_required": true,
|
|
132
|
+
"predecessor_launcher_restored_before_pointer_commit": true,
|
|
133
|
+
"successor_launcher_restored_before_recovery_pointer": true
|
|
117
134
|
}
|
|
118
135
|
},
|
|
119
136
|
"non_win32": {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.process-policy.v1",
|
|
3
3
|
"enabled": true,
|
|
4
|
-
"grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
5
|
-
"state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
4
|
+
"grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.33-r56\\controller\\runtime\\process-grant.json",
|
|
5
|
+
"state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.33-r56\\controller\\runtime\\process-state",
|
|
6
6
|
"native_host": {
|
|
7
|
-
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
7
|
+
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.33-r56\\bin\\deadbyte-process-host.exe",
|
|
8
8
|
"sha256": "daf9cfb371bee88cafbf5597eaa507fec504dbe0b0ddd40d0c3c2e02817f49e4"
|
|
9
9
|
},
|
|
10
10
|
"roots": {
|
|
11
11
|
"core": {
|
|
12
|
-
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
12
|
+
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.33-r56",
|
|
13
13
|
"deny_paths": [
|
|
14
14
|
"node_modules",
|
|
15
15
|
"controller/runtime",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.33",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"contained:run": "node src/contained-cli.mjs workspaces/demo input.txt",
|
|
43
43
|
"contained:smoke": "node src/contained-smoke.mjs",
|
|
44
44
|
"mcp:contained:smoke": "node src/mcp-contained-smoke-client.mjs",
|
|
45
|
-
"gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-
|
|
45
|
+
"gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r56.ps1",
|
|
46
46
|
"authority:smoke": "node src/authority-smoke.mjs",
|
|
47
47
|
"mcp:remote:smoke": "node src/remote-mcp-smoke-client.mjs",
|
|
48
48
|
"mcp:host:smoke": "node src/mcp-host-smoke-client.mjs",
|
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
"r52:focused:test": "node --test --test-concurrency=1 test/r52-release-contract.test.mjs test/r52-offline-predecessor-recovery.test.mjs test/r52-host-revocation.test.mjs test/r51-runtime-coherence.test.mjs test/r51-live-log-polling.test.mjs test/coding-runtime.test.mjs test/remote-live-log-r37.test.mjs test/runtime-self-update.test.mjs",
|
|
78
78
|
"r53:focused:test": "node --test --test-concurrency=1 test/r53-release-contract.test.mjs test/stabilization-update-child-root.test.mjs test/stabilization-state-root.test.mjs test/stabilization-guardian.test.mjs test/stabilization-semver.test.mjs test/stabilization-powershell.test.mjs test/release-slot.test.mjs test/runtime-self-update.test.mjs test/r51-runtime-coherence.test.mjs test/remote-session-cli.test.mjs test/r52-offline-predecessor-recovery.test.mjs test/r52-host-revocation.test.mjs",
|
|
79
79
|
"r54:focused:test": "node --test --test-concurrency=1 test/r54-release-contract.test.mjs test/r54-offline-predecessor-self-exclusion.test.mjs test/r52-offline-predecessor-recovery.test.mjs test/runtime-self-update.test.mjs test/r51-runtime-coherence.test.mjs test/remote-session-cli.test.mjs",
|
|
80
|
-
"r55:focused:test": "node --test --test-concurrency=1 test/r55-release-contract.test.mjs test/r55-offline-predecessor-guardian-family.test.mjs test/r54-offline-predecessor-self-exclusion.test.mjs test/r52-offline-predecessor-recovery.test.mjs test/runtime-self-update.test.mjs test/r51-runtime-coherence.test.mjs test/remote-session-cli.test.mjs"
|
|
80
|
+
"r55:focused:test": "node --test --test-concurrency=1 test/r55-release-contract.test.mjs test/r55-offline-predecessor-guardian-family.test.mjs test/r54-offline-predecessor-self-exclusion.test.mjs test/r52-offline-predecessor-recovery.test.mjs test/runtime-self-update.test.mjs test/r51-runtime-coherence.test.mjs test/remote-session-cli.test.mjs",
|
|
81
|
+
"r56:focused:test": "node --test --test-concurrency=1 test/r56-release-contract.test.mjs test/r56-rollback-launcher-restore.test.mjs test/r55-offline-predecessor-guardian-family.test.mjs test/r54-offline-predecessor-self-exclusion.test.mjs test/runtime-self-update.test.mjs test/release-slot.test.mjs test/r51-runtime-coherence.test.mjs"
|
|
81
82
|
},
|
|
82
83
|
"bundleDependencies": [
|
|
83
84
|
"@modelcontextprotocol/server",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
$ErrorActionPreference = 'Stop'
|
|
2
|
+
Set-StrictMode -Version 3.0
|
|
3
|
+
|
|
4
|
+
function Invoke-GateStep {
|
|
5
|
+
param([Parameter(Mandatory)][string]$Name,[Parameter(Mandatory)][string[]]$NpmArgs)
|
|
6
|
+
Write-Host "==== $Name ===="
|
|
7
|
+
& npm.cmd @NpmArgs
|
|
8
|
+
if ($LASTEXITCODE -ne 0) { throw "DEADBYTE 0.15.33 / R56 gate failed at $Name with exit code $LASTEXITCODE" }
|
|
9
|
+
}
|
|
10
|
+
function Invoke-NodeTest {
|
|
11
|
+
param([Parameter(Mandatory)][string]$Name,[Parameter(Mandatory)][string[]]$TestFiles)
|
|
12
|
+
Write-Host "==== $Name ===="
|
|
13
|
+
& node.exe --test --test-concurrency=1 @TestFiles
|
|
14
|
+
if ($LASTEXITCODE -ne 0) { throw "DEADBYTE 0.15.33 / R56 gate failed at $Name with exit code $LASTEXITCODE" }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Invoke-NodeTest 'r56-package-boundary' @('test/package-boundary.test.mjs')
|
|
18
|
+
Invoke-GateStep 'r56-focused-contracts' @('run','r56:focused:test')
|
|
19
|
+
Write-Host '==== full-regression-evidence ===='
|
|
20
|
+
$matrix=Get-Content -LiteralPath (Join-Path (Split-Path $PSScriptRoot -Parent) 'TEST-MATRIX.json') -Raw | ConvertFrom-Json
|
|
21
|
+
if($matrix.observed_pre_release_evidence.full_regression.status -ne 'PASS'){ throw 'R56 full regression evidence is not PASS' }
|
|
22
|
+
Invoke-GateStep 'manifest-write' @('run','manifest:write')
|
|
23
|
+
Invoke-GateStep 'manifest-verify' @('run','manifest:verify')
|
|
24
|
+
Invoke-GateStep 'doctor' @('run','doctor')
|
|
25
|
+
& node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence-r56.mjs')
|
|
26
|
+
if ($LASTEXITCODE -ne 0) { throw "R56 evidence writer failed with exit code $LASTEXITCODE" }
|
|
27
|
+
Write-Host '==== DEADBYTE 0.15.33 / R56 WINDOWS GATE: PASS ===='
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, open, readFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { doctor } from '../src/doctor-r45.mjs';
|
|
7
|
+
|
|
8
|
+
const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
9
|
+
const stateRoot=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
|
|
10
|
+
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
11
|
+
const insist=(ok,message)=>{if(!ok)throw new Error(message);};
|
|
12
|
+
const pkg=JSON.parse(await readFile(path.join(root,'package.json'),'utf8'));
|
|
13
|
+
const release=JSON.parse(await readFile(path.join(root,'RELEASE.json'),'utf8'));
|
|
14
|
+
const provenance=JSON.parse(await readFile(path.join(root,'PROVENANCE.json'),'utf8'));
|
|
15
|
+
const matrix=JSON.parse(await readFile(path.join(root,'TEST-MATRIX.json'),'utf8'));
|
|
16
|
+
const active=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
|
|
17
|
+
const manifestSha256=sha256(await readFile(path.join(root,'MANIFEST.SHA256')));
|
|
18
|
+
|
|
19
|
+
insist(pkg.version==='0.15.33'&&release.version===pkg.version&&release.train==='R56','R56 candidate identity mismatch');
|
|
20
|
+
insist(release.parent.version==='0.15.32','R56 parent mismatch');
|
|
21
|
+
insist(release.parent.manifest_sha256==='e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b','R56 parent manifest mismatch');
|
|
22
|
+
insist(release.parent.generation_manifest_sha256==='740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e','R56 parent generation mismatch');
|
|
23
|
+
insist(release.parent.tarball_sha256==='c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638','R56 parent tarball mismatch');
|
|
24
|
+
insist(
|
|
25
|
+
active.release_id===release.runtime_predecessor.release_id&&
|
|
26
|
+
active.manifest_sha256===release.runtime_predecessor.manifest_sha256&&
|
|
27
|
+
active.generation_manifest_sha256===release.runtime_predecessor.generation_manifest_sha256,
|
|
28
|
+
'active runtime is not exact sealed 0.15.32 predecessor'
|
|
29
|
+
);
|
|
30
|
+
insist(release.hotfix?.signed_handoff_launcher_snapshot_required===true,'R56 signed rollback handoff launcher requirement missing');
|
|
31
|
+
insist(release.hotfix?.stored_predecessor_verified_without_live_launcher===true,'R56 stored predecessor verification split missing');
|
|
32
|
+
insist(release.hotfix?.predecessor_launcher_restored_before_pointer_commit===true,'R56 predecessor launcher ordering missing');
|
|
33
|
+
insist(release.hotfix?.successor_launcher_restored_before_recovery_pointer===true,'R56 successor recovery ordering missing');
|
|
34
|
+
insist(release.hotfix?.full_regression==='PASS','R56 full regression metadata is not PASS');
|
|
35
|
+
insist(matrix.observed_pre_release_evidence?.full_regression?.status==='PASS','R56 full regression evidence is not PASS');
|
|
36
|
+
insist(provenance.operator_override?.stable_final_claim===false,'R56 must not claim stable/final');
|
|
37
|
+
insist(matrix.operator_override?.four_hour_soak==='NOT_COMPLETED','R56 matrix must preserve soak bypass');
|
|
38
|
+
|
|
39
|
+
const health=await doctor();
|
|
40
|
+
insist(health.status==='ok'&&health.package_version===pkg.version&&health.manifest?.verified===true,'R56 doctor evidence invalid');
|
|
41
|
+
|
|
42
|
+
const evidence={
|
|
43
|
+
schema:'deadbyte.r56-windows-gate.v1',
|
|
44
|
+
status:'passed',
|
|
45
|
+
exit_code:0,
|
|
46
|
+
version:pkg.version,
|
|
47
|
+
train:'R56',
|
|
48
|
+
completed_at_utc:new Date().toISOString(),
|
|
49
|
+
manifest_sha256:manifestSha256,
|
|
50
|
+
parent:release.parent,
|
|
51
|
+
runtime_predecessor:release.runtime_predecessor,
|
|
52
|
+
hotfix:release.hotfix,
|
|
53
|
+
operator_override:provenance.operator_override,
|
|
54
|
+
active_predecessor:{
|
|
55
|
+
release_id:active.release_id,
|
|
56
|
+
version:active.version,
|
|
57
|
+
manifest_sha256:active.manifest_sha256,
|
|
58
|
+
generation_manifest_sha256:active.generation_manifest_sha256
|
|
59
|
+
},
|
|
60
|
+
doctor:{verified_entries:health.manifest.verified_entries},
|
|
61
|
+
gates:{
|
|
62
|
+
r56_focused:true,
|
|
63
|
+
package_boundary:true,
|
|
64
|
+
full_regression:true,
|
|
65
|
+
manifest_final_verify:true,
|
|
66
|
+
four_hour_soak_completed:false
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const bytes=Buffer.from(JSON.stringify(evidence,null,2)+'\n');
|
|
70
|
+
const dir=path.join(stateRoot,'evidence','release');
|
|
71
|
+
await mkdir(dir,{recursive:true});
|
|
72
|
+
const target=path.join(dir,`r56-windows-gate-${manifestSha256.slice(0,16)}.json`);
|
|
73
|
+
try{
|
|
74
|
+
const handle=await open(target,'wx',0o600);
|
|
75
|
+
try{await handle.writeFile(bytes);await handle.sync();}finally{await handle.close();}
|
|
76
|
+
}catch(error){
|
|
77
|
+
if(error?.code!=='EEXIST')throw error;
|
|
78
|
+
const prior=JSON.parse(await readFile(target,'utf8'));
|
|
79
|
+
insist(prior.schema===evidence.schema&&prior.status==='passed'&&prior.version===evidence.version&&prior.manifest_sha256===manifestSha256,'conflicting R56 gate evidence identity');
|
|
80
|
+
}
|
|
81
|
+
console.log(JSON.stringify({status:'passed',path:target,sha256:sha256(bytes),manifest_sha256:manifestSha256}));
|
package/src/runtime-update.mjs
CHANGED
|
@@ -861,16 +861,21 @@ async function verifyPackageRoot(root,expectedVersion,expectedManifest,label){
|
|
|
861
861
|
if(pkg?.name!=='deadbyte-mcp'||pkg?.version!==expectedVersion) throw new Error(`${label} package identity mismatch`);
|
|
862
862
|
return {root:absolute,manifest_sha256:digest,entries:entries.size};
|
|
863
863
|
}
|
|
864
|
-
async function
|
|
864
|
+
async function verifyStoredInstallation(stateRoot,pointer){
|
|
865
865
|
const state=path.resolve(stateRoot); const expectedRelease=path.join(state,'releases',releaseId(pointer.version,pointer.manifest_sha256));
|
|
866
866
|
if(path.resolve(pointer.release_root)!==path.resolve(expectedRelease)) throw new Error('active pointer release root is not content-addressed store path');
|
|
867
867
|
const release=await verifyPackageRoot(pointer.release_root,pointer.version,pointer.manifest_sha256,'active release');
|
|
868
868
|
const generation=await verifyGenerationBundle(pointer.generation_root,pointer.generation_manifest_sha256);
|
|
869
869
|
const expectedConfig=path.join(path.resolve(pointer.generation_root),'controller-config.psd1');
|
|
870
870
|
if(path.resolve(pointer.config_path)!==path.resolve(expectedConfig)) throw new Error('active pointer config path mismatch');
|
|
871
|
+
return {release,generation};
|
|
872
|
+
}
|
|
873
|
+
async function verifyActiveInstallation(stateRoot,pointer){
|
|
874
|
+
const state=path.resolve(stateRoot);
|
|
875
|
+
const verified=await verifyStoredInstallation(state,pointer);
|
|
871
876
|
const currentLauncher=await sha256File(launcherPath(state));
|
|
872
877
|
if(currentLauncher!==pointer.launcher_sha256) throw new Error('active pointer launcher digest mismatch');
|
|
873
|
-
return
|
|
878
|
+
return verified;
|
|
874
879
|
}
|
|
875
880
|
async function loadPointerIfPresent(stateRoot){
|
|
876
881
|
const file=path.join(path.resolve(stateRoot),'active-release.json');
|
|
@@ -1084,6 +1089,41 @@ function decodeSnapshot(snapshot,label){
|
|
|
1084
1089
|
}
|
|
1085
1090
|
return {exists:false,bytes:null,sha256:null};
|
|
1086
1091
|
}
|
|
1092
|
+
export function rollbackLauncherPlanFromHandoff(body,priorPointer,activePointer,stateRoot=DEFAULT_STATE_ROOT){
|
|
1093
|
+
if(!body||typeof body!=='object') throw new Error('rollback handoff body required');
|
|
1094
|
+
const handoffPrior=body.prior_pointer?parseActivePointer(JSON.stringify(body.prior_pointer)):null;
|
|
1095
|
+
const handoffActive=body.new_pointer?parseActivePointer(JSON.stringify(body.new_pointer)):null;
|
|
1096
|
+
if(!samePublicPointer(handoffPrior,priorPointer)||!samePublicPointer(handoffActive,activePointer)) throw new Error('rollback handoff pointer binding mismatch');
|
|
1097
|
+
const state=path.resolve(stateRoot);
|
|
1098
|
+
const launchers={
|
|
1099
|
+
ps1:path.resolve(String(body.launchers?.ps1??'')),
|
|
1100
|
+
cmd:path.resolve(String(body.launchers?.cmd??'')),
|
|
1101
|
+
top:path.resolve(String(body.launchers?.top??TOP_LAUNCHER)),
|
|
1102
|
+
launcher_sha256:String(body.launchers?.launcher_sha256??''),
|
|
1103
|
+
ps1Bytes:Buffer.from(String(body.launchers?.ps1_bytes??''),'base64'),
|
|
1104
|
+
cmdBytes:Buffer.from(String(body.launchers?.cmd_bytes??''),'base64'),
|
|
1105
|
+
snapshots:{
|
|
1106
|
+
ps1:decodeSnapshot(body.launchers?.snapshots?.ps1,'rollback.launcher.ps1'),
|
|
1107
|
+
cmd:decodeSnapshot(body.launchers?.snapshots?.cmd,'rollback.launcher.cmd'),
|
|
1108
|
+
top:decodeSnapshot(body.launchers?.snapshots?.top,'rollback.launcher.top')
|
|
1109
|
+
},
|
|
1110
|
+
installed:true
|
|
1111
|
+
};
|
|
1112
|
+
if(launchers.ps1!==path.resolve(launcherPath(state))||
|
|
1113
|
+
launchers.cmd!==path.resolve(path.join(state,'bin','DEADBYTE-MCP.cmd'))||
|
|
1114
|
+
launchers.top!==path.resolve(TOP_LAUNCHER)) throw new Error('rollback launcher paths are not canonical');
|
|
1115
|
+
if(!HEX64.test(launchers.launcher_sha256)||sha256Bytes(launchers.ps1Bytes)!==launchers.launcher_sha256) throw new Error('rollback successor launcher bytes/hash mismatch');
|
|
1116
|
+
if(launchers.launcher_sha256!==activePointer.launcher_sha256) throw new Error('rollback successor launcher hash does not match active pointer');
|
|
1117
|
+
if(!launchers.snapshots.ps1.exists||launchers.snapshots.ps1.sha256!==priorPointer.launcher_sha256) throw new Error('rollback predecessor launcher snapshot does not match signed prior pointer');
|
|
1118
|
+
return launchers;
|
|
1119
|
+
}
|
|
1120
|
+
async function restoreRollbackLaunchers(plan){
|
|
1121
|
+
await restoreFile(plan.ps1,plan.snapshots.ps1);
|
|
1122
|
+
await restoreFile(plan.cmd,plan.snapshots.cmd);
|
|
1123
|
+
await restoreFile(plan.top,plan.snapshots.top);
|
|
1124
|
+
if(await sha256File(plan.ps1)!==plan.snapshots.ps1.sha256) throw new Error('rollback predecessor launcher restore hash mismatch');
|
|
1125
|
+
return plan;
|
|
1126
|
+
}
|
|
1087
1127
|
const UPDATE_PHASE_RANK=Object.freeze({
|
|
1088
1128
|
initial:0,candidate_prepared:10,old_runtime_verified:20,shutdown_handoff_armed:25,supervisor_spawned:30,
|
|
1089
1129
|
authority_revoked:40,old_runtime_stopped:50,workspace_ready:60,launcher_installed:70,pointer_committed:80,
|
|
@@ -1587,19 +1627,28 @@ export async function performSlotRollback({activationReceipt,stateRoot=DEFAULT_S
|
|
|
1587
1627
|
const activePointer=parseActivePointer(JSON.stringify(activationEnvelope.body.active_pointer));
|
|
1588
1628
|
const pointerInfo=await loadPointerIfPresent(state);
|
|
1589
1629
|
if(!pointerInfo.pointer||canonicalJson(publicPointer(pointerInfo.pointer))!==canonicalJson(publicPointer(activePointer))) throw new Error('rollback current pointer does not match signed activation pointer');
|
|
1590
|
-
|
|
1630
|
+
|
|
1631
|
+
const handoffPath=path.join(path.dirname(receiptFile),'handoff.json');
|
|
1632
|
+
const {body:handoffBody}=await readHandoffEnvelope(handoffPath,state);
|
|
1633
|
+
if(handoffBody.update_id!==activationEnvelope.body.update_id) throw new Error('rollback handoff update identity mismatch');
|
|
1634
|
+
const rollbackLaunchers=rollbackLauncherPlanFromHandoff(handoffBody,priorPointer,activePointer,state);
|
|
1635
|
+
await verifyStoredInstallation(state,priorPointer);
|
|
1636
|
+
|
|
1591
1637
|
const currentCtx=slotContext(state,pointerInfo.pointer),currentRuntime=await captureRuntime(currentCtx);
|
|
1592
1638
|
const revoked=await revokeAuthority(currentCtx,currentRuntime.status);
|
|
1593
1639
|
const rollbackId=`r31-rollback-${activationEnvelope.receipt_sha256.slice(0,16)}-${Date.now().toString(36)}-${randomBytes(4).toString('hex')}`;
|
|
1594
1640
|
const evidenceDir=path.join(state,'evidence','updates',rollbackId),statePath=path.join(evidenceDir,'state.json'),receiptPath=path.join(evidenceDir,'receipt.json');
|
|
1595
1641
|
await mkdir(evidenceDir,{recursive:true});
|
|
1596
1642
|
const journal={schema:'deadbyte.r31-slot-rollback-state.v1',rollback_id:rollbackId,activation_receipt:path.resolve(receiptFile),
|
|
1597
|
-
activation_receipt_sha256:activationEnvelope.receipt_sha256,
|
|
1643
|
+
activation_receipt_sha256:activationEnvelope.receipt_sha256,handoff_path:handoffPath,
|
|
1644
|
+
from_pointer:publicPointer(activePointer),to_pointer:publicPointer(priorPointer),created_at_utc:new Date().toISOString()};
|
|
1598
1645
|
await writeState(statePath,journal,'verified');
|
|
1599
|
-
let stopped=false,pointerCommitted=false,priorCtx=null,priorRuntime=null;
|
|
1646
|
+
let stopped=false,launchersRestored=false,pointerCommitted=false,priorCtx=null,priorRuntime=null;
|
|
1600
1647
|
try {
|
|
1601
1648
|
await stopAndVerify(currentCtx,currentRuntime); stopped=true;
|
|
1602
1649
|
await writeState(statePath,journal,'successor_stopped');
|
|
1650
|
+
await restoreRollbackLaunchers(rollbackLaunchers); launchersRestored=true;
|
|
1651
|
+
await writeState(statePath,journal,'predecessor_launcher_restored',{launcher_sha256:priorPointer.launcher_sha256});
|
|
1603
1652
|
await atomicWriteActivePointer(pointerInfo.file,priorPointer); pointerCommitted=true;
|
|
1604
1653
|
await verifyActiveInstallation(state,priorPointer);
|
|
1605
1654
|
await writeState(statePath,journal,'prior_pointer_restored',{active_pointer:publicPointer(priorPointer)});
|
|
@@ -1610,16 +1659,27 @@ export async function performSlotRollback({activationReceipt,stateRoot=DEFAULT_S
|
|
|
1610
1659
|
if(finalStatus.process_armed||finalStatus.coding_armed||finalStatus.autonomous_armed||finalStatus.desktop_armed||finalStatus.host_armed) throw new Error('rollback predecessor authority must remain disarmed');
|
|
1611
1660
|
const body={schema:ROLLBACK_SCHEMA,rollback_id:rollbackId,activation_receipt_sha256:activationEnvelope.receipt_sha256,
|
|
1612
1661
|
completed_at_utc:new Date().toISOString(),from_pointer:publicPointer(activePointer),active_pointer:publicPointer(priorPointer),
|
|
1613
|
-
old_runtime:generationTuple(currentRuntime),new_runtime:generationTuple(priorRuntime),stabilization,
|
|
1662
|
+
launcher_restored:true,old_runtime:generationTuple(currentRuntime),new_runtime:generationTuple(priorRuntime),stabilization,
|
|
1663
|
+
authority_revoked:revoked.revoked,rollback_performed:true};
|
|
1614
1664
|
const receipt=await writeEnvelope(receiptPath,body,key);
|
|
1615
1665
|
await writeState(statePath,journal,'completed',{receipt_path:receiptPath,receipt_sha256:receipt.receipt_sha256});
|
|
1616
1666
|
return {ok:true,rollback_id:rollbackId,state_path:statePath,receipt_path:receiptPath,receipt_sha256:receipt.receipt_sha256,pointer:priorPointer,new_runtime:priorRuntime};
|
|
1617
1667
|
} catch(error){
|
|
1618
|
-
const recovery={attempted:false,prior_runtime_stopped:false,successor_pointer_restored:false,successor_runtime_restarted:false,errors:[]};
|
|
1668
|
+
const recovery={attempted:false,prior_runtime_stopped:false,successor_launcher_restored:false,successor_pointer_restored:false,successor_runtime_restarted:false,errors:[]};
|
|
1619
1669
|
if(stopped){
|
|
1620
1670
|
recovery.attempted=true;
|
|
1621
1671
|
if(pointerCommitted&&priorCtx){ try { controllerCaptured(priorCtx,'stop',30000); recovery.prior_runtime_stopped=true; } catch(recoveryError){ recovery.errors.push(`stop-prior:${recoveryError.message}`); } }
|
|
1622
|
-
if(
|
|
1672
|
+
if(launchersRestored){
|
|
1673
|
+
try { await installLaunchers(rollbackLaunchers); recovery.successor_launcher_restored=true; }
|
|
1674
|
+
catch(recoveryError){ recovery.errors.push(`restore-successor-launcher:${recoveryError.message}`); }
|
|
1675
|
+
}
|
|
1676
|
+
if(pointerCommitted){
|
|
1677
|
+
try { await atomicWriteActivePointer(pointerInfo.file,activePointer); await verifyActiveInstallation(state,activePointer); recovery.successor_pointer_restored=true; }
|
|
1678
|
+
catch(recoveryError){ recovery.errors.push(`restore-pointer:${recoveryError.message}`); }
|
|
1679
|
+
}else if(recovery.successor_launcher_restored){
|
|
1680
|
+
try { await verifyActiveInstallation(state,activePointer); recovery.successor_pointer_restored=true; }
|
|
1681
|
+
catch(recoveryError){ recovery.errors.push(`verify-successor-pointer:${recoveryError.message}`); }
|
|
1682
|
+
}
|
|
1623
1683
|
try { await startAndVerify(currentCtx,currentRuntime); recovery.successor_runtime_restarted=true; } catch(recoveryError){ recovery.errors.push(`restart-successor:${recoveryError.message}`); }
|
|
1624
1684
|
}
|
|
1625
1685
|
await writeState(statePath,journal,'failed',{error:{name:error?.name??'Error',message:String(error?.message??error)},recovery}).catch(()=>{});
|
package/src/version.mjs
CHANGED
|
@@ -4,9 +4,11 @@ import test from 'node:test';
|
|
|
4
4
|
|
|
5
5
|
const read=path=>readFile(new URL(`../${path}`,import.meta.url),'utf8');
|
|
6
6
|
|
|
7
|
-
test('
|
|
8
|
-
const [pkgText,gate,evidence,historicalR54,historicalEvidenceR54,historicalR53,historicalEvidenceR53,historicalR52,historicalEvidenceR52,historicalR51,historicalEvidenceR51,historicalR50,historicalR49,deferred]=await Promise.all([
|
|
7
|
+
test('R56 canonical Windows gate is successor-bound and preserves R55/R54/R53/R52/R51/R50/R49 historical gates',async()=>{
|
|
8
|
+
const [pkgText,gate,evidence,historicalR55,historicalEvidenceR55,historicalR54,historicalEvidenceR54,historicalR53,historicalEvidenceR53,historicalR52,historicalEvidenceR52,historicalR51,historicalEvidenceR51,historicalR50,historicalR49,deferred]=await Promise.all([
|
|
9
9
|
read('package.json'),
|
|
10
|
+
read('scripts/gate-windows-r56.ps1'),
|
|
11
|
+
read('scripts/windows-gate-evidence-r56.mjs'),
|
|
10
12
|
read('scripts/gate-windows-r55.ps1'),
|
|
11
13
|
read('scripts/windows-gate-evidence-r55.mjs'),
|
|
12
14
|
read('scripts/gate-windows-r54.ps1'),
|
|
@@ -22,18 +24,20 @@ test('R55 canonical Windows gate is successor-bound and preserves R54/R53/R52/R5
|
|
|
22
24
|
read('scripts/deferred-slot-operation-r46.mjs')
|
|
23
25
|
]);
|
|
24
26
|
const pkg=JSON.parse(pkgText);
|
|
25
|
-
assert.match(pkg.scripts['gate:windows'],/gate-windows-
|
|
26
|
-
assert.match(gate,/DEADBYTE 0\.15\.
|
|
27
|
-
assert.match(gate,/
|
|
28
|
-
assert.match(gate,/
|
|
29
|
-
assert.match(gate,/full-regression/);
|
|
27
|
+
assert.match(pkg.scripts['gate:windows'],/gate-windows-r56\.ps1$/);
|
|
28
|
+
assert.match(gate,/DEADBYTE 0\.15\.33 \/ R56 WINDOWS GATE: PASS/);
|
|
29
|
+
assert.match(gate,/r56-package-boundary/);
|
|
30
|
+
assert.match(gate,/r56-focused-contracts/);
|
|
31
|
+
assert.match(gate,/full-regression-evidence/);
|
|
30
32
|
assert.match(gate,/manifest-verify/);
|
|
31
33
|
assert.match(gate,/doctor/);
|
|
32
|
-
assert.match(evidence,/deadbyte\.
|
|
33
|
-
assert.match(evidence,/pkg\.version==='0\.15\.
|
|
34
|
-
assert.match(evidence,/release\.train==='
|
|
35
|
-
assert.match(evidence,/release\.parent\.version==='0\.15\.
|
|
34
|
+
assert.match(evidence,/deadbyte\.r56-windows-gate\.v1/);
|
|
35
|
+
assert.match(evidence,/pkg\.version==='0\.15\.33'/);
|
|
36
|
+
assert.match(evidence,/release\.train==='R56'/);
|
|
37
|
+
assert.match(evidence,/release\.parent\.version==='0\.15\.32'/);
|
|
36
38
|
assert.match(evidence,/four_hour_soak_completed:false/);
|
|
39
|
+
assert.match(historicalR55,/DEADBYTE 0\.15\.32 \/ R55 WINDOWS GATE: PASS/);
|
|
40
|
+
assert.match(historicalEvidenceR55,/deadbyte\.r55-windows-gate\.v1/);
|
|
37
41
|
assert.match(historicalR54,/DEADBYTE 0\.15\.31 \/ R54 WINDOWS GATE: PASS/);
|
|
38
42
|
assert.match(historicalEvidenceR54,/deadbyte\.r54-windows-gate\.v1/);
|
|
39
43
|
assert.match(historicalR53,/DEADBYTE 0\.15\.30 \/ R53 WINDOWS GATE: PASS/);
|
|
@@ -46,10 +50,5 @@ test('R55 canonical Windows gate is successor-bound and preserves R54/R53/R52/R5
|
|
|
46
50
|
assert.match(historicalR49,/DEADBYTE 0\.15\.26 \/ R49 WINDOWS GATE: PASS/);
|
|
47
51
|
assert.match(deferred,/const expectedVersion=packageIdentity\.version/);
|
|
48
52
|
assert.match(deferred,/'--expected-version',expectedVersion/);
|
|
49
|
-
assert.match(deferred,/async function awaitHandoffCompletion/);
|
|
50
53
|
assert.match(deferred,/verifySlotUpdateEnvelope\(envelope,publicKey\)/);
|
|
51
|
-
assert.match(deferred,/active pointer does not match signed activation receipt/);
|
|
52
|
-
assert.match(deferred,/failure-receipt\.json/);
|
|
53
|
-
assert.match(deferred,/await awaitHandoffCompletion\(await runSlotUpdateCli/);
|
|
54
|
-
assert.doesNotMatch(deferred,/'--expected-version','0\.15\.5'/);
|
|
55
54
|
});
|
|
@@ -5,8 +5,10 @@ import { readFile } from 'node:fs/promises';
|
|
|
5
5
|
const root=new URL('../',import.meta.url);
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
|
+
const currentPackage=await json('package.json');
|
|
9
|
+
const r55test=currentPackage.version==='0.15.32'?test:test.skip;
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
r55test('R55 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
10
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
11
13
|
json('package.json'),json('package-lock.json'),json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs')
|
|
12
14
|
]);
|
|
@@ -25,7 +27,7 @@ test('R55 release identity is coherent across package lock source metadata SBOM
|
|
|
25
27
|
assert.match(pkg.scripts['r55:focused:test'],/r55-offline-predecessor-guardian-family\.test\.mjs/);
|
|
26
28
|
});
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
r55test('R55 source predecessor is exact immutable published 0.15.31 while runtime predecessor remains exact 0.15.29',async()=>{
|
|
29
31
|
const [release,provenance]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json')]);
|
|
30
32
|
assert.equal(release.parent.version,'0.15.31');
|
|
31
33
|
assert.equal(release.parent.release_id,'v0.15.31-16854fe5b3eb0fa1');
|
|
@@ -44,7 +46,7 @@ test('R55 source predecessor is exact immutable published 0.15.31 while runtime
|
|
|
44
46
|
assert.deepEqual(provenance.runtime_predecessor,release.runtime_predecessor);
|
|
45
47
|
});
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
r55test('R55 records the guardian sibling RED to GREEN and preserves fail-closed negative controls',async()=>{
|
|
48
50
|
const [release,provenance,matrix]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json')]);
|
|
49
51
|
assert.equal(release.hotfix.activation_ancestry_excluded,true);
|
|
50
52
|
assert.equal(release.hotfix.foreground_guardian_owner_parent_binding,true);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
const root=new URL('../',import.meta.url);
|
|
6
|
+
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
|
+
const json=rel=>read(rel).then(JSON.parse);
|
|
8
|
+
|
|
9
|
+
test('R56 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
10
|
+
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
11
|
+
json('package.json'),json('package-lock.json'),json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs')
|
|
12
|
+
]);
|
|
13
|
+
assert.equal(pkg.version,'0.15.33');
|
|
14
|
+
assert.equal(lock.version,pkg.version);
|
|
15
|
+
assert.equal(lock.packages[''].version,pkg.version);
|
|
16
|
+
assert.match(versionSource,/DEADBYTE_VERSION = '0\.15\.33'/);
|
|
17
|
+
assert.equal(release.version,pkg.version);
|
|
18
|
+
assert.equal(release.train,'R56');
|
|
19
|
+
assert.equal(provenance.version,pkg.version);
|
|
20
|
+
assert.equal(matrix.version,pkg.version);
|
|
21
|
+
assert.equal(matrix.train,'R56');
|
|
22
|
+
assert.equal(sbom.metadata.component.version,pkg.version);
|
|
23
|
+
assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r56:0.15.33');
|
|
24
|
+
assert.match(pkg.scripts['gate:windows'],/gate-windows-r56\.ps1/);
|
|
25
|
+
assert.match(pkg.scripts['r56:focused:test'],/r56-rollback-launcher-restore\.test\.mjs/);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('R56 source and runtime predecessor are exact active published 0.15.32',async()=>{
|
|
29
|
+
const [release,provenance]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json')]);
|
|
30
|
+
assert.equal(release.parent.version,'0.15.32');
|
|
31
|
+
assert.equal(release.parent.release_id,'v0.15.32-e7223f467777f5df');
|
|
32
|
+
assert.equal(release.parent.manifest_sha256,'e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b');
|
|
33
|
+
assert.equal(release.parent.generation_manifest_sha256,'740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e');
|
|
34
|
+
assert.equal(release.parent.tarball_sha256,'c9e1f5875dd2177cee0089305b40321c128c54ce7f5522e34e507d4ecfb22638');
|
|
35
|
+
assert.equal(release.parent.activation_status,'ACTIVATED_ROLLBACK_DEFECT_OBSERVED');
|
|
36
|
+
assert.equal(release.source_predecessor.version,'0.15.32');
|
|
37
|
+
assert.deepEqual(release.runtime_predecessor,{
|
|
38
|
+
release_id:'v0.15.32-e7223f467777f5df',
|
|
39
|
+
manifest_sha256:'e7223f467777f5dfeb20fd2cc7a6eca22619a44ed95e5bc0b32d9c7aabba361b',
|
|
40
|
+
generation_manifest_sha256:'740443fd207c5e6ffd5952079214bf6e81e9281a6ec880de9bbe3b8ce1deb00e'
|
|
41
|
+
});
|
|
42
|
+
assert.equal(provenance.parent_manifest_sha256,release.parent.manifest_sha256);
|
|
43
|
+
assert.equal(provenance.parent_generation_manifest_sha256,release.parent.generation_manifest_sha256);
|
|
44
|
+
assert.deepEqual(provenance.runtime_predecessor,release.runtime_predecessor);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('R56 records signed rollback launcher ordering RED to GREEN and preserves non-final claim',async()=>{
|
|
48
|
+
const [release,provenance,matrix]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json')]);
|
|
49
|
+
assert.equal(release.hotfix.signed_handoff_launcher_snapshot_required,true);
|
|
50
|
+
assert.equal(release.hotfix.stored_predecessor_verified_without_live_launcher,true);
|
|
51
|
+
assert.equal(release.hotfix.predecessor_launcher_restored_before_pointer_commit,true);
|
|
52
|
+
assert.equal(release.hotfix.successor_launcher_restored_before_recovery_pointer,true);
|
|
53
|
+
assert.equal(release.hotfix.exact_parent_activation_receipt_sha256,'6518a04154f485cfae42e582269634d69a8b05a0183149d5e10006fbdd9d933c');
|
|
54
|
+
assert.equal(release.hotfix.observed_parent_rollback_failure_receipt_sha256,'00cbd497e4902c67ab39313a378e2fcf32159113b46339ad1d54b5e5a7714205');
|
|
55
|
+
assert.equal(release.hotfix.red_parent_0_15_32,'FAIL_5_OF_5');
|
|
56
|
+
assert.equal(release.hotfix.green_r56_candidate,'PASS_5_OF_5');
|
|
57
|
+
assert.equal(matrix.observed_pre_release_evidence.red_parent_0_15_32.receipt_sha256,'f3b446306691d61e97896ab4d237abaa20d1243237299812e790233c46451dba');
|
|
58
|
+
assert.equal(matrix.observed_pre_release_evidence.green_r56_candidate.receipt_sha256,'4198930f38a3fc4b7978cfc94ca4509127561c170b05f7566bdf79513e449a8b');
|
|
59
|
+
assert.equal(release.hotfix.stable_final_claim,false);
|
|
60
|
+
assert.equal(provenance.operator_override.four_hour_soak,'NOT_COMPLETED');
|
|
61
|
+
assert.equal(provenance.operator_override.stable_final_claim,false);
|
|
62
|
+
assert.equal(matrix.operator_override.stable_final_claim,false);
|
|
63
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
|
|
9
|
+
const target=process.env.R56_RUNTIME_UPDATE_PATH
|
|
10
|
+
? path.resolve(process.env.R56_RUNTIME_UPDATE_PATH)
|
|
11
|
+
: path.resolve(new URL('../src/runtime-update.mjs',import.meta.url).pathname.replace(/^\/(?:[A-Za-z]:)/,m=>m.slice(1)));
|
|
12
|
+
const runtimeUpdate=await import(pathToFileURL(target).href+'?r56='+Date.now());
|
|
13
|
+
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
14
|
+
const stateRoot=path.resolve(process.env.R56_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
|
|
15
|
+
const topLauncher=path.resolve(path.join(os.homedir(),'Downloads','DEADBYTE-MCP.cmd'));
|
|
16
|
+
|
|
17
|
+
function pointer(version,manifest,launcher){
|
|
18
|
+
const releaseId=`v${version}-${manifest.slice(0,16)}`;
|
|
19
|
+
const genId=`${releaseId}-g${'9'.repeat(16)}`;
|
|
20
|
+
return {
|
|
21
|
+
schema:'deadbyte.active-release.v1',
|
|
22
|
+
release_id:releaseId,
|
|
23
|
+
version,
|
|
24
|
+
manifest_sha256:manifest,
|
|
25
|
+
release_root:path.join(stateRoot,'releases',releaseId),
|
|
26
|
+
generation_root:path.join(stateRoot,'generations',genId),
|
|
27
|
+
generation_manifest_sha256:'8'.repeat(64),
|
|
28
|
+
launcher_sha256:launcher,
|
|
29
|
+
config_path:path.join(stateRoot,'generations',genId,'controller-config.psd1')
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function snapshot(bytes){
|
|
33
|
+
const b=Buffer.from(bytes);
|
|
34
|
+
return {exists:true,sha256:sha256(b),bytes_base64:b.toString('base64')};
|
|
35
|
+
}
|
|
36
|
+
function fixture(){
|
|
37
|
+
const priorBytes=Buffer.from('prior-launcher-r55\r\n');
|
|
38
|
+
const activeBytes=Buffer.from('active-launcher-r56\r\n');
|
|
39
|
+
const cmdBytes=Buffer.from('@echo off\r\n');
|
|
40
|
+
const prior=pointer('0.15.29','1'.repeat(64),sha256(priorBytes));
|
|
41
|
+
const active=pointer('0.15.32','2'.repeat(64),sha256(activeBytes));
|
|
42
|
+
const body={
|
|
43
|
+
prior_pointer:prior,
|
|
44
|
+
new_pointer:active,
|
|
45
|
+
launchers:{
|
|
46
|
+
ps1:path.join(stateRoot,'bin','DEADBYTE-MCP.ps1'),
|
|
47
|
+
cmd:path.join(stateRoot,'bin','DEADBYTE-MCP.cmd'),
|
|
48
|
+
top:topLauncher,
|
|
49
|
+
launcher_sha256:sha256(activeBytes),
|
|
50
|
+
ps1_bytes:activeBytes.toString('base64'),
|
|
51
|
+
cmd_bytes:cmdBytes.toString('base64'),
|
|
52
|
+
snapshots:{
|
|
53
|
+
ps1:snapshot(priorBytes),
|
|
54
|
+
cmd:snapshot(cmdBytes),
|
|
55
|
+
top:snapshot(cmdBytes)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return {prior,active,body};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
test('R56 exposes rollback launcher planning from the signed activation handoff',()=>{
|
|
63
|
+
assert.equal(typeof runtimeUpdate.rollbackLauncherPlanFromHandoff,'function');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('R56 accepts a prior launcher snapshot whose hash differs from the active launcher and binds both signed pointers',()=>{
|
|
67
|
+
const {prior,active,body}=fixture();
|
|
68
|
+
const plan=runtimeUpdate.rollbackLauncherPlanFromHandoff(body,prior,active,stateRoot);
|
|
69
|
+
assert.equal(plan.snapshots.ps1.sha256,prior.launcher_sha256);
|
|
70
|
+
assert.equal(plan.launcher_sha256,active.launcher_sha256);
|
|
71
|
+
assert.notEqual(plan.snapshots.ps1.sha256,plan.launcher_sha256);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('R56 rejects a predecessor launcher snapshot that does not match the signed prior pointer',()=>{
|
|
75
|
+
const {prior,active,body}=fixture();
|
|
76
|
+
body.launchers.snapshots.ps1=snapshot(Buffer.from('wrong-prior-launcher\r\n'));
|
|
77
|
+
assert.throws(()=>runtimeUpdate.rollbackLauncherPlanFromHandoff(body,prior,active,stateRoot),/predecessor launcher snapshot/i);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('R56 rejects handoff pointer drift instead of using unsigned rollback state',()=>{
|
|
81
|
+
const {prior,active,body}=fixture();
|
|
82
|
+
const drift={...prior,manifest_sha256:'3'.repeat(64),release_id:`v0.15.29-${'3'.repeat(16)}`,release_root:path.join(stateRoot,'releases',`v0.15.29-${'3'.repeat(16)}`)};
|
|
83
|
+
assert.throws(()=>runtimeUpdate.rollbackLauncherPlanFromHandoff(body,drift,active,stateRoot),/pointer binding mismatch/i);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('R56 rollback verifies stored predecessor bytes before stop, restores signed predecessor launcher before pointer commit, and reinstalls successor launcher before recovery pointer',async()=>{
|
|
87
|
+
const source=await readFile(target,'utf8');
|
|
88
|
+
const start=source.indexOf('export async function performSlotRollback');
|
|
89
|
+
const end=source.indexOf('export async function runSlotUpdateCli',start);
|
|
90
|
+
assert.ok(start>=0&&end>start);
|
|
91
|
+
const perform=source.slice(start,end);
|
|
92
|
+
const stored=perform.indexOf('verifyStoredInstallation(state,priorPointer)');
|
|
93
|
+
const stop=perform.indexOf('stopAndVerify(currentCtx,currentRuntime)');
|
|
94
|
+
const restoreLauncher=perform.indexOf('restoreRollbackLaunchers(rollbackLaunchers)');
|
|
95
|
+
const commit=perform.indexOf('atomicWriteActivePointer(pointerInfo.file,priorPointer)');
|
|
96
|
+
const verifyPrior=perform.indexOf('verifyActiveInstallation(state,priorPointer)');
|
|
97
|
+
const reinstall=perform.indexOf('installLaunchers(rollbackLaunchers)');
|
|
98
|
+
const restoreSuccessor=perform.indexOf('atomicWriteActivePointer(pointerInfo.file,activePointer)');
|
|
99
|
+
assert.ok(stored>=0&&stored<stop);
|
|
100
|
+
assert.ok(restoreLauncher>stop&&restoreLauncher<commit);
|
|
101
|
+
assert.ok(verifyPrior>commit);
|
|
102
|
+
assert.ok(reinstall>verifyPrior&&reinstall<restoreSuccessor);
|
|
103
|
+
});
|