deadbyte-mcp 0.15.41 → 0.15.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/DEADBYTE-MCP.cmd +8 -4
  2. package/MANIFEST.SHA256 +88 -43
  3. package/PROVENANCE.json +66 -15
  4. package/README.txt +27 -18
  5. package/RELEASE.json +55 -15
  6. package/SBOM.cdx.json +2 -2
  7. package/TEST-MATRIX.json +117 -14
  8. package/bridge/package.json +1 -1
  9. package/controller/deadbyte-controller.ps1 +132 -12
  10. package/controller/deadbyte-process-policy.json +4 -4
  11. package/docs/R65-AUTHORITY-CONTINUITY-DESIGN.json +27 -0
  12. package/docs/R65-REFERENCE-GAP-MATRIX.json +22 -0
  13. package/package.json +6 -4
  14. package/scripts/deploy-r48.mjs +123 -7
  15. package/scripts/gate-windows-r65-prepublish.ps1 +65 -0
  16. package/scripts/gate-windows-r66-prepublish.ps1 +65 -0
  17. package/scripts/npm-publication-r65.mjs +139 -0
  18. package/scripts/npm-release-r48.mjs +56 -37
  19. package/scripts/r65-canonical-full.mjs +45 -0
  20. package/scripts/r65-focused.mjs +37 -0
  21. package/scripts/verify-r65-parent-source.mjs +75 -0
  22. package/src/activation-continuity-engine-r65.mjs +225 -0
  23. package/src/activation-lock-r65.mjs +155 -0
  24. package/src/activation-preflight-r65.mjs +197 -0
  25. package/src/authority-continuity-r65.mjs +541 -0
  26. package/src/authority-epoch-cli-r65.mjs +10 -0
  27. package/src/autonomous-policy.mjs +7 -3
  28. package/src/coding-plane.mjs +12 -3
  29. package/src/desktop-policy-r40.mjs +6 -3
  30. package/src/doctor-runtime-r58.mjs +3 -1
  31. package/src/doctor-transactions-r58.mjs +1 -1
  32. package/src/host-plane.mjs +9 -3
  33. package/src/process-policy.mjs +7 -4
  34. package/src/remote-authority.mjs +10 -1
  35. package/src/runtime-update.mjs +15 -5
  36. package/src/version.mjs +1 -1
  37. package/test/audit-context.test.mjs +15 -4
  38. package/test/autonomous-local-supervisor.test.mjs +7 -6
  39. package/test/autonomous-supervisor-integration.test.mjs +8 -7
  40. package/test/capability-resolver.test.mjs +11 -5
  41. package/test/codex-autonomous-r44.test.mjs +7 -6
  42. package/test/coding-observation.test.mjs +4 -3
  43. package/test/commander-real-parity-r47.test.mjs +5 -4
  44. package/test/commander-torture-r47.test.mjs +5 -4
  45. package/test/desktop-policy-r40.test.mjs +6 -4
  46. package/test/desktop-runtime-r40.test.mjs +8 -3
  47. package/test/host-inline-r45.test.mjs +4 -3
  48. package/test/machine-fs-runtime.test.mjs +4 -3
  49. package/test/process-longrun-r36.test.mjs +3 -2
  50. package/test/process-policy.test.mjs +10 -6
  51. package/test/process-runtime.test.mjs +9 -6
  52. package/test/r52-host-revocation.test.mjs +1 -0
  53. package/test/r58-doctor-runtime.test.mjs +18 -0
  54. package/test/r59-tool-surface-compat.test.mjs +1 -1
  55. package/test/r64-release-contract.test.mjs +2 -1
  56. package/test/r65-activation-lock-recovery.test.mjs +72 -0
  57. package/test/r65-activation-lock.test.mjs +59 -0
  58. package/test/r65-activation-orchestration.test.mjs +179 -0
  59. package/test/r65-activation-preflight.test.mjs +35 -0
  60. package/test/r65-authority-continuity-decision.test.mjs +58 -0
  61. package/test/r65-authority-durable-policy-binding.test.mjs +34 -0
  62. package/test/r65-authority-epoch-cli.test.mjs +125 -0
  63. package/test/r65-authority-epoch-races.test.mjs +87 -0
  64. package/test/r65-authority-epoch-recovery.test.mjs +82 -0
  65. package/test/r65-authority-epoch-store.test.mjs +94 -0
  66. package/test/r65-authority-fixture.mjs +41 -0
  67. package/test/r65-authority-grant-capture.test.mjs +37 -0
  68. package/test/r65-authority-observation-epoch.test.mjs +25 -0
  69. package/test/r65-authority-policy-envelope.test.mjs +46 -0
  70. package/test/r65-authority-restored-safe.test.mjs +75 -0
  71. package/test/r65-authority-runtime-epoch.test.mjs +115 -0
  72. package/test/r65-authority-runtime-policy-binding.test.mjs +29 -0
  73. package/test/r65-authority-test-trust.mjs +20 -0
  74. package/test/r65-cli-invocation.test.mjs +38 -0
  75. package/test/r65-controller-authority-epoch-live.test.mjs +100 -0
  76. package/test/r65-controller-authority-epoch.test.mjs +37 -0
  77. package/test/r65-deploy-preflight.test.mjs +55 -0
  78. package/test/r65-epoch-native-activation-integration.test.mjs +141 -0
  79. package/test/r65-epoch-native-continuity-engine.test.mjs +112 -0
  80. package/test/r65-epoch-native-cross-plane.test.mjs +95 -0
  81. package/test/r65-legacy-authority-migration.test.mjs +63 -0
  82. package/test/r65-legacy-auto-restore-rejection.test.mjs +17 -0
  83. package/test/r65-npm-publication.test.mjs +114 -0
  84. package/test/r65-parent-source-verifier.test.mjs +63 -0
  85. package/test/r65-release-contract.test.mjs +75 -0
  86. package/test/r65-transaction-precondition.test.mjs +36 -0
  87. package/test/r66-release-contract.test.mjs +56 -0
  88. package/test/remote-session-cli.test.mjs +6 -6
  89. package/test/standing-grants.test.mjs +20 -4
@@ -937,6 +937,47 @@ function Assert-PolicyRootsAvailable($Policy, [string]$Plane) {
937
937
  return $rootIds
938
938
  }
939
939
 
940
+ function Get-AuthorityEpochStatus($Cfg, [string]$Plane, [string]$GrantFile, [string]$GrantNonce) {
941
+ if ([string]::IsNullOrWhiteSpace($GrantNonce) -or $GrantNonce -cnotmatch '^[0-9a-f]{64}$') {
942
+ return [pscustomobject]@{ Trusted=$false; Reason='epoch-grant-nonce-invalid'; Seq=$null; Action=$null; EventSha256=$null }
943
+ }
944
+ try {
945
+ $verified = Invoke-AuthorityEpochCommand $Cfg $Plane 'status' $GrantFile
946
+ if (-not $verified.trusted) {
947
+ return [pscustomobject]@{ Trusted=$false; Reason=[string]$verified.reason; Seq=$verified.seq; Action=$verified.action; EventSha256=$verified.event_sha256 }
948
+ }
949
+ return [pscustomobject]@{ Trusted=$true; Reason=[string]$verified.reason; Seq=$verified.seq; Action=$verified.action; EventSha256=$verified.event_sha256 }
950
+ } catch {
951
+ return [pscustomobject]@{ Trusted=$false; Reason='authority-epoch-verifier-unavailable'; Seq=$null; Action=$null; EventSha256=$null }
952
+ }
953
+ }
954
+
955
+ function Invoke-AuthorityEpochCommand($Cfg, [string]$Plane, [string]$Action, [string]$GrantFile, [string]$UpdateId = '', [string]$ExpectedHead = '') {
956
+ $cli = Join-Path ([string]$Cfg.CoreRoot) 'src\authority-epoch-cli-r65.mjs'
957
+ if (-not (Test-Path -LiteralPath $cli -PathType Leaf)) { Fail "authority epoch CLI missing: $cli" }
958
+ $node = [string]$Cfg.Bridge.FilePath
959
+ if ([string]::IsNullOrWhiteSpace($node) -or -not (Test-Path -LiteralPath $node -PathType Leaf)) { Fail 'authority epoch Node executable unavailable' }
960
+ $policyFile = switch ($Plane) {
961
+ 'process' { [string]$Cfg.ProcessPolicyFile }
962
+ 'coding' { [string]$Cfg.CodingPolicyFile }
963
+ 'autonomous' { [string]$Cfg.AutonomousPolicyFile }
964
+ 'desktop' { [string]$Cfg.DesktopPolicyFile }
965
+ 'host' { [string]$Cfg.HostPolicyFile }
966
+ default { Fail "authority epoch plane invalid: $Plane" }
967
+ }
968
+ if ([string]::IsNullOrWhiteSpace($policyFile) -or -not (Test-Path -LiteralPath $policyFile -PathType Leaf)) { Fail "authority epoch policy unavailable for $Plane" }
969
+ $args = @($cli, $Action, '--plane', $Plane, '--grant-file', $GrantFile, '--policy-file', $policyFile)
970
+ if ($Action -in @('transaction-revoke','transaction-restore')) {
971
+ if ([string]::IsNullOrWhiteSpace($UpdateId) -or $ExpectedHead -cnotmatch '^[0-9a-f]{64}$') { Fail 'authority epoch transaction binding invalid' }
972
+ $args += @('--update-id', $UpdateId, '--expected-head', $ExpectedHead)
973
+ }
974
+ $output = @(& $node @args)
975
+ $exit = $LASTEXITCODE
976
+ if ($exit -ne 0) { Fail "authority epoch command '$Action' failed for $Plane (exit=$exit)" }
977
+ try { return (($output -join [Environment]::NewLine) | ConvertFrom-Json) }
978
+ catch { Fail "authority epoch command '$Action' returned invalid JSON for $Plane" }
979
+ }
980
+
940
981
  function Get-HostPolicyMetadata($Cfg) {
941
982
  if ([string]::IsNullOrWhiteSpace([string]$Cfg.HostPolicyFile)) { Fail 'privileged host plane is not configured' }
942
983
  $policyPath = [string]$Cfg.HostPolicyFile
@@ -961,7 +1002,10 @@ function Get-HostArmStatus($Cfg) {
961
1002
  try { $arm = Get-Content -LiteralPath $meta.ArmFile -Raw -Encoding UTF8 | ConvertFrom-Json } catch { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='invalid-grant' } }
962
1003
  if ($arm.schema -ne 'deadbyte.host-grant.v2') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='grant-schema' } }
963
1004
  if ([string]$arm.policy_sha256 -ne [string]$meta.Sha256) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='policy-digest' } }
964
- return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant' }
1005
+ if ([string]$arm.instance_nonce -cnotmatch '^[0-9a-f]{64}$') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='nonce-invalid' } }
1006
+ $epoch = Get-AuthorityEpochStatus $Cfg 'host' $meta.ArmFile ([string]$arm.instance_nonce)
1007
+ if (-not $epoch.Trusted) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason=[string]$epoch.Reason } }
1008
+ return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; EpochSeq=$epoch.Seq; EpochSha256=$epoch.EventSha256 }
965
1009
  }
966
1010
 
967
1011
  function Arm-Host($Cfg) {
@@ -981,15 +1025,23 @@ function Arm-Host($Cfg) {
981
1025
  $tmp = $meta.ArmFile + '.tmp'
982
1026
  $body | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $tmp -Encoding UTF8
983
1027
  Move-Item -LiteralPath $tmp -Destination $meta.ArmFile -Force
1028
+ try { Invoke-AuthorityEpochCommand $Cfg 'host' 'grant' $meta.ArmFile | Out-Null }
1029
+ catch {
1030
+ Remove-Item -LiteralPath $meta.ArmFile -Force -ErrorAction SilentlyContinue
1031
+ throw
1032
+ }
984
1033
  Write-Host 'PRIVILEGED HOST PLANE ENABLED UNTIL EXPLICIT REVOKE'
985
1034
  }
986
1035
 
987
1036
  function Disarm-Host($Cfg) {
988
1037
  $meta = Get-HostPolicyMetadata $Cfg
1038
+ $epochError = $null
989
1039
  if (Test-Path -LiteralPath $meta.ArmFile) {
990
- Remove-Item -LiteralPath $meta.ArmFile -Force -ErrorAction Stop
1040
+ try { Invoke-AuthorityEpochCommand $Cfg 'host' 'user-revoke' $meta.ArmFile | Out-Null } catch { $epochError = $_.Exception }
1041
+ Remove-Item -LiteralPath $meta.ArmFile -Force -ErrorAction SilentlyContinue
991
1042
  }
992
1043
  if (Test-Path -LiteralPath $meta.ArmFile) { throw 'Host authority revocation failed: grant remains present' }
1044
+ if ($null -ne $epochError) { throw $epochError }
993
1045
  Write-Host 'PRIVILEGED HOST PLANE DISARMED'
994
1046
  }
995
1047
 
@@ -1021,10 +1073,13 @@ function Get-ProcessGrantStatus($Cfg) {
1021
1073
  try { $grant = Get-Content -LiteralPath $meta.GrantFile -Raw -Encoding UTF8 | ConvertFrom-Json } catch { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='invalid-grant' } }
1022
1074
  if ($grant.schema -ne 'deadbyte.process-grant.v1') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='grant-schema' } }
1023
1075
  if ([string]$grant.policy_sha256 -ne [string]$meta.Sha256) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='policy-digest' } }
1076
+ if ([string]$grant.instance_nonce -cnotmatch '^[0-9a-f]{64}$') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='nonce-invalid' } }
1024
1077
  $profiles = @($grant.profile_ids); $roots = @($grant.root_ids)
1025
1078
  if ($profiles.Count -lt 1 -or @($profiles | Where-Object { $_ -notin $meta.ProfileIds }).Count -gt 0) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='profiles-invalid' } }
1026
1079
  if ($roots.Count -lt 1 -or @($roots | Where-Object { $_ -notin $meta.RootIds }).Count -gt 0) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='roots-invalid' } }
1027
- return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant' }
1080
+ $epoch = Get-AuthorityEpochStatus $Cfg 'process' $meta.GrantFile ([string]$grant.instance_nonce)
1081
+ if (-not $epoch.Trusted) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason=[string]$epoch.Reason } }
1082
+ return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; EpochSeq=$epoch.Seq; EpochSha256=$epoch.EventSha256 }
1028
1083
  }
1029
1084
 
1030
1085
  function Arm-Process($Cfg) {
@@ -1045,12 +1100,23 @@ function Arm-Process($Cfg) {
1045
1100
  $tmp = $meta.GrantFile + '.tmp'
1046
1101
  $body | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $tmp -Encoding UTF8
1047
1102
  Move-Item -LiteralPath $tmp -Destination $meta.GrantFile -Force
1103
+ try { Invoke-AuthorityEpochCommand $Cfg 'process' 'grant' $meta.GrantFile | Out-Null }
1104
+ catch {
1105
+ Remove-Item -LiteralPath $meta.GrantFile -Force -ErrorAction SilentlyContinue
1106
+ throw
1107
+ }
1048
1108
  Write-Host 'PROCESS PLANE ENABLED UNTIL EXPLICIT REVOKE'
1049
1109
  }
1050
1110
 
1051
1111
  function Disarm-Process($Cfg) {
1052
1112
  $meta = Get-ProcessPolicyMetadata $Cfg
1053
- Remove-Item -LiteralPath $meta.GrantFile -Force -ErrorAction SilentlyContinue
1113
+ $epochError = $null
1114
+ if (Test-Path -LiteralPath $meta.GrantFile -PathType Leaf) {
1115
+ try { Invoke-AuthorityEpochCommand $Cfg 'process' 'user-revoke' $meta.GrantFile | Out-Null } catch { $epochError = $_.Exception }
1116
+ Remove-Item -LiteralPath $meta.GrantFile -Force -ErrorAction SilentlyContinue
1117
+ }
1118
+ if (Test-Path -LiteralPath $meta.GrantFile) { throw 'Process authority revocation failed: grant remains present' }
1119
+ if ($null -ne $epochError) { throw $epochError }
1054
1120
  Write-Host 'PROCESS PLANE DISARMED'
1055
1121
  }
1056
1122
 
@@ -1080,9 +1146,12 @@ function Get-CodingLeaseStatus($Cfg) {
1080
1146
  try { $lease = Get-Content -LiteralPath $meta.LeaseFile -Raw -Encoding UTF8 | ConvertFrom-Json } catch { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='invalid-grant' } }
1081
1147
  if ($lease.schema -ne 'deadbyte.coding-grant.v2') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='grant-schema' } }
1082
1148
  if ([string]$lease.policy_sha256 -ne [string]$meta.Sha256) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='policy-digest' } }
1149
+ if ([string]$lease.instance_nonce -cnotmatch '^[0-9a-f]{64}$') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='nonce-invalid' } }
1083
1150
  $roots = @($lease.root_ids)
1084
1151
  if ($roots.Count -lt 1 -or @($roots | Where-Object { $_ -notin $meta.RootIds }).Count -gt 0) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='roots-invalid' } }
1085
- return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant' }
1152
+ $epoch = Get-AuthorityEpochStatus $Cfg 'coding' $meta.LeaseFile ([string]$lease.instance_nonce)
1153
+ if (-not $epoch.Trusted) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason=[string]$epoch.Reason } }
1154
+ return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; EpochSeq=$epoch.Seq; EpochSha256=$epoch.EventSha256 }
1086
1155
  }
1087
1156
 
1088
1157
  function Arm-Coding($Cfg) {
@@ -1103,13 +1172,27 @@ function Arm-Coding($Cfg) {
1103
1172
  $tmp = $meta.LeaseFile + '.tmp'
1104
1173
  $body | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $tmp -Encoding UTF8
1105
1174
  Move-Item -LiteralPath $tmp -Destination $meta.LeaseFile -Force
1175
+ try { Invoke-AuthorityEpochCommand $Cfg 'coding' 'grant' $meta.LeaseFile | Out-Null }
1176
+ catch {
1177
+ Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1178
+ throw
1179
+ }
1106
1180
  Write-Host 'CODING PLANE ENABLED UNTIL EXPLICIT REVOKE'
1107
1181
  }
1108
1182
 
1109
1183
  function Disarm-Coding($Cfg) {
1110
1184
  $meta = Get-CodingPolicyMetadata $Cfg
1111
- Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1112
- try { Disarm-Autonomous $Cfg -Quiet } catch { Write-Warning "autonomous lease cleanup failed after coding revocation: $($_.Exception.Message)" }
1185
+ $epochError = $null
1186
+ if (Test-Path -LiteralPath $meta.LeaseFile -PathType Leaf) {
1187
+ try { Invoke-AuthorityEpochCommand $Cfg 'coding' 'user-revoke' $meta.LeaseFile | Out-Null } catch { $epochError = $_.Exception }
1188
+ Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1189
+ }
1190
+ try { Disarm-Autonomous $Cfg -Quiet } catch {
1191
+ if ($null -eq $epochError) { $epochError = $_.Exception }
1192
+ else { Write-Warning "autonomous lease cleanup failed after coding revocation: $($_.Exception.Message)" }
1193
+ }
1194
+ if (Test-Path -LiteralPath $meta.LeaseFile) { throw 'Coding authority revocation failed: grant remains present' }
1195
+ if ($null -ne $epochError) { throw $epochError }
1113
1196
  Write-Host 'CODING PLANE DISARMED; AUTONOMOUS AUTHORITY REVOKED'
1114
1197
  }
1115
1198
 
@@ -1145,9 +1228,12 @@ function Get-AutonomousLeaseStatus($Cfg) {
1145
1228
  if ($lease.schema -ne 'deadbyte.autonomous-grant.v2') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='grant-schema' } }
1146
1229
  if ([string]$lease.policy_sha256 -ne [string]$meta.Sha256) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='policy-digest' } }
1147
1230
  if ([string]$lease.coding_policy_sha256 -ne [string]$meta.CodingPolicySha256) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='coding-policy-digest' } }
1231
+ if ([string]$lease.instance_nonce -cnotmatch '^[0-9a-f]{64}$') { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='nonce-invalid' } }
1148
1232
  $roots = @($lease.root_ids)
1149
1233
  if ($roots.Count -lt 1 -or @($roots | Where-Object { $_ -notin $meta.RootIds }).Count -gt 0) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='roots-invalid' } }
1150
- return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant' }
1234
+ $epoch = Get-AuthorityEpochStatus $Cfg 'autonomous' $meta.LeaseFile ([string]$lease.instance_nonce)
1235
+ if (-not $epoch.Trusted) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason=[string]$epoch.Reason } }
1236
+ return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; EpochSeq=$epoch.Seq; EpochSha256=$epoch.EventSha256 }
1151
1237
  }
1152
1238
 
1153
1239
  function Arm-Autonomous($Cfg) {
@@ -1164,13 +1250,24 @@ function Arm-Autonomous($Cfg) {
1164
1250
  $tmp = $meta.LeaseFile + '.tmp'
1165
1251
  $body | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $tmp -Encoding UTF8
1166
1252
  Move-Item -LiteralPath $tmp -Destination $meta.LeaseFile -Force
1253
+ try { Invoke-AuthorityEpochCommand $Cfg 'autonomous' 'grant' $meta.LeaseFile | Out-Null }
1254
+ catch {
1255
+ Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1256
+ throw
1257
+ }
1167
1258
  Write-Host 'AUTONOMOUS PLANE ENABLED UNTIL EXPLICIT REVOKE'
1168
1259
  }
1169
1260
 
1170
1261
  function Disarm-Autonomous($Cfg, [switch]$Quiet) {
1171
1262
  if ([string]::IsNullOrWhiteSpace([string]$Cfg.AutonomousPolicyFile)) { return }
1172
1263
  $meta = Get-AutonomousPolicyMetadata $Cfg
1173
- Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1264
+ $epochError = $null
1265
+ if (Test-Path -LiteralPath $meta.LeaseFile -PathType Leaf) {
1266
+ try { Invoke-AuthorityEpochCommand $Cfg 'autonomous' 'user-revoke' $meta.LeaseFile | Out-Null } catch { $epochError = $_.Exception }
1267
+ Remove-Item -LiteralPath $meta.LeaseFile -Force -ErrorAction SilentlyContinue
1268
+ }
1269
+ if (Test-Path -LiteralPath $meta.LeaseFile) { throw 'Autonomous authority revocation failed: grant remains present' }
1270
+ if ($null -ne $epochError) { throw $epochError }
1174
1271
  if (-not $Quiet) { Write-Host 'AUTONOMOUS PLANE DISARMED' }
1175
1272
  }
1176
1273
 
@@ -1244,7 +1341,9 @@ function Get-DesktopGrantStatus($Cfg) {
1244
1341
  $unique = @($actions | Sort-Object -Unique)
1245
1342
  if ($actions.Count -lt 1 -or $actions.Count -ne $unique.Count) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='actions-invalid'; ActionKinds=@() } }
1246
1343
  if (@($actions | Where-Object { $_ -notin $meta.ActionKinds }).Count -gt 0) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason='actions-outside-policy'; ActionKinds=@() } }
1247
- return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; ActionKinds=$actions }
1344
+ $epoch = Get-AuthorityEpochStatus $Cfg 'desktop' $meta.GrantFile ([string]$grant.instance_nonce)
1345
+ if (-not $epoch.Trusted) { return [pscustomobject]@{ Configured=$true; Armed=$false; Reason=[string]$epoch.Reason; ActionKinds=$actions } }
1346
+ return [pscustomobject]@{ Configured=$true; Armed=$true; Reason='standing-grant'; ActionKinds=$actions; EpochSeq=$epoch.Seq; EpochSha256=$epoch.EventSha256 }
1248
1347
  }
1249
1348
 
1250
1349
  function Arm-Desktop($Cfg) {
@@ -1265,13 +1364,24 @@ function Arm-Desktop($Cfg) {
1265
1364
  $tmp = $meta.GrantFile + '.tmp'
1266
1365
  $body | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $tmp -Encoding UTF8
1267
1366
  Move-Item -LiteralPath $tmp -Destination $meta.GrantFile -Force
1367
+ try { Invoke-AuthorityEpochCommand $Cfg 'desktop' 'grant' $meta.GrantFile | Out-Null }
1368
+ catch {
1369
+ Remove-Item -LiteralPath $meta.GrantFile -Force -ErrorAction SilentlyContinue
1370
+ throw
1371
+ }
1268
1372
  Write-Host ("DESKTOP PLANE ENABLED UNTIL EXPLICIT REVOKE [{0}]" -f ($meta.ActionKinds -join ','))
1269
1373
  }
1270
1374
 
1271
1375
  function Disarm-Desktop($Cfg, [switch]$Quiet) {
1272
1376
  $grantFile = Get-DesktopGrantFileForRevoke $Cfg
1273
1377
  if ([string]::IsNullOrWhiteSpace([string]$grantFile)) { return }
1274
- Remove-Item -LiteralPath $grantFile -Force -ErrorAction SilentlyContinue
1378
+ $epochError = $null
1379
+ if (Test-Path -LiteralPath $grantFile -PathType Leaf) {
1380
+ try { Invoke-AuthorityEpochCommand $Cfg 'desktop' 'user-revoke' $grantFile | Out-Null } catch { $epochError = $_.Exception }
1381
+ Remove-Item -LiteralPath $grantFile -Force -ErrorAction SilentlyContinue
1382
+ }
1383
+ if (Test-Path -LiteralPath $grantFile) { throw 'Desktop authority revocation failed: grant remains present' }
1384
+ if ($null -ne $epochError) { throw $epochError }
1275
1385
  if (-not $Quiet) { Write-Host 'DESKTOP PLANE DISARMED' }
1276
1386
  }
1277
1387
 
@@ -1346,7 +1456,17 @@ function Convert-OwnedObservation($Owned) {
1346
1456
  }
1347
1457
 
1348
1458
  function Convert-AuthorityObservation($Authority) {
1349
- [ordered]@{ configured=[bool]$Authority.Configured; armed=[bool]$Authority.Armed; reason=(Get-BoundedObservationReason $Authority.Reason) }
1459
+ $out = [ordered]@{ configured=[bool]$Authority.Configured; armed=[bool]$Authority.Armed; reason=(Get-BoundedObservationReason $Authority.Reason) }
1460
+ $seqProp = $Authority.PSObject.Properties['EpochSeq']
1461
+ $shaProp = $Authority.PSObject.Properties['EpochSha256']
1462
+ if ($null -ne $seqProp -or $null -ne $shaProp) {
1463
+ if ($null -eq $seqProp -or $null -eq $shaProp -or [int64]$seqProp.Value -lt 1 -or [string]$shaProp.Value -cnotmatch '^[0-9a-f]{64}$') {
1464
+ Fail 'authority epoch observation incomplete or invalid'
1465
+ }
1466
+ $out['epoch_seq'] = [int64]$seqProp.Value
1467
+ $out['epoch_sha256'] = [string]$shaProp.Value
1468
+ }
1469
+ return $out
1350
1470
  }
1351
1471
 
1352
1472
  function Get-DownstreamCoreObservation($Cfg, $Bridge) {
@@ -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.41-r64\\controller\\runtime\\process-grant.json",
5
- "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.41-r64\\controller\\runtime\\process-state",
4
+ "grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.43-r66\\controller\\runtime\\process-grant.json",
5
+ "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.43-r66\\controller\\runtime\\process-state",
6
6
  "native_host": {
7
- "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.41-r64\\bin\\deadbyte-process-host.exe",
7
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.43-r66\\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.41-r64",
12
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.43-r66",
13
13
  "deny_paths": [
14
14
  "node_modules",
15
15
  "controller/runtime",
@@ -0,0 +1,27 @@
1
+ {
2
+ "schema": "deadbyte.r65-authority-continuity-design.v1",
3
+ "status": "PARTIAL_IMPLEMENTATION",
4
+ "authority": "Current R65 candidate source and read-only R64 generation policies; production remains immutable.",
5
+ "observed_contracts": {
6
+ "controller": "controller/deadbyte-controller.ps1 Get-*GrantStatus checks schema and policy_sha256; Process/Coding/Autonomous/Desktop additionally carry scope and instance_nonce; Host carries nonce but no explicit scope.",
7
+ "process": "src/process-policy.mjs rechecks policy hash, nonce, profile_ids and root_ids; grant schema deadbyte.process-grant.v1.",
8
+ "coding": "src/coding-plane.mjs rechecks policy hash, nonce and root_ids; standing grant schema deadbyte.coding-grant.v2.",
9
+ "autonomous": "controller/deadbyte-controller.ps1 requires a Coding grant, coding_policy_sha256 and root_ids; grant schema deadbyte.autonomous-grant.v2.",
10
+ "desktop": "src/desktop-policy-r40.mjs and controller validate policy hash, nonce and action_kinds; grant schema deadbyte.desktop-grant.v1.",
11
+ "host": "controller/deadbyte-controller.ps1 validates policy hash; grant schema deadbyte.host-grant.v2 includes instance_nonce and granted_at_utc but no scoped IDs.",
12
+ "revocation": "R64 controller arm/disarm replace/delete grant files but expose no durable monotonic per-plane revocation epoch or transaction-owned temporary revoke. An absent grant after temporary revoke cannot prove no independent user revoke occurred."
13
+ },
14
+ "selected_method": {
15
+ "policy_envelope": "Derive canonical authority-bearing fields from each known policy schema; omit only operational grant/evidence storage paths and presentation descriptions. Unknown fields fail closed. Raw policy SHA remains evidence, not the sole ceiling comparator.",
16
+ "comparison": "EQUAL, NARROWER, WIDER, UNVERIFIED. Added capabilities, relaxed deny rules and larger ceilings are WIDER. Changed executable/native pins or disjoint roots are UNVERIFIED. Both deny automatic restoration.",
17
+ "r64_predecessor_continuity": "Because R64 has no durable revocation epoch, an armed predecessor cannot receive automatic cross-generation restoration. Outcome must be REAUTH_REQUIRED and disarmed unless a later explicit user grant is observed.",
18
+ "updater_boundary": "One restoration engine is required. The current inner updater's Process/Coding/Autonomous re-arm must be disabled or constrained by a verified continuity plan before any R65 activation with standing authority is permitted.",
19
+ "current_safety_guard": "scripts/deploy-r48.mjs --preflight returns AUTHORITY_POLICY_UNVERIFIED for armed vectors before opening an update transaction. This guard must not be removed until continuity integration is proven."
20
+ },
21
+ "acceptance_open": [
22
+ "Read-only capture of exact grant bytes and scope, bound to predecessor release/generation and candidate manifest.",
23
+ "Durable transaction-owned revocation epoch with crash-safe exclusion of external revocation/replacement.",
24
+ "Single restoration decision path across updater and deploy; separate runtime and authority outcomes.",
25
+ "Isolated end-to-end activation, interruption, rollback and independent receipt verification."
26
+ ]
27
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "schema": "deadbyte.r65-reference-gap-matrix.v1",
3
+ "purpose": "Release/control-plane mechanisms only; donor source is read-only and no donor bytes are copied.",
4
+ "license_review": {
5
+ "better-remote-commander": "package.json declares MIT; no source bytes copied",
6
+ "cua": "pyproject.toml declares MIT; no source bytes copied",
7
+ "desktop-commander": "root LICENSE declares MIT; no source bytes copied",
8
+ "open-remote-mcp": "no root LICENSE or package declaration confirmed in this pass; architecture principle only, no source bytes copied",
9
+ "remcp": "package.json declares MIT; no source bytes copied",
10
+ "secure-host-mcp": "package.json declares MIT; no source bytes copied",
11
+ "winremote-mcp": "pyproject.toml declares MIT; no source bytes copied"
12
+ },
13
+ "decisions": [
14
+ {"reference":"better-remote-commander","evidence_path":"packages/agent/src/transport/ws-client.ts","mechanism":"bounded exponential reconnect and explicit unauthorized branch","deadbyte_comparison":"R64 has remote guardian and recovery, but npm visibility after accepted publish was not reconciled","decision":"ADAPT","r65_action":"bounded registry availability polling and terminal/unknown classification; no relay or multi-device import"},
15
+ {"reference":"cua","evidence_path":"rfcs/3007-cua-driver-lifecycle-sessions.md","mechanism":"idempotent lifecycle cleanup and host-held resume identity","deadbyte_comparison":"DEADBYTE has owned supervisor and signed transaction evidence; deterministic precondition failures still need terminality","decision":"ADAPT","r65_action":"preflight/transaction boundary tests and exact ownership preservation; no desktop redesign"},
16
+ {"reference":"desktop-commander","evidence_path":"dist/utils/toolHistory.js","mechanism":"bounded presentation history and trim target","deadbyte_comparison":"DEADBYTE evidence durability and bounded LIVELOG are stronger for authoritative release receipts","decision":"KEEP-OURS","r65_action":"do not batch or trim authoritative transaction journals"},
17
+ {"reference":"open-remote-mcp","evidence_path":"docs/ARCHITECTURE.md","mechanism":"relay policy may narrow but local device remains final enforcement","deadbyte_comparison":"DEADBYTE already enforces local authority planes; activation restore must preserve exact vector","decision":"KEEP-OURS","r65_action":"regress no-widening during activation orchestration"},
18
+ {"reference":"remcp","evidence_path":"packages/client/test/cli-update-runtime.test.mjs","mechanism":"separate client/runtime update and coherence checks","deadbyte_comparison":"DEADBYTE has immutable slots and version binding; exact-version npm invocation needs reproducible tests","decision":"ADAPT","r65_action":"CLI/package resolution matrix and isolated install test without runtime dependency"},
19
+ {"reference":"secure-host-mcp","evidence_path":"src/runtime.ts","mechanism":"explicit bounded runtime state vocabulary","deadbyte_comparison":"DEADBYTE has verified identities but activation preflight was not a separate read-only state classification","decision":"ADAPT","r65_action":"typed preflight classification; reject dirty/unknown state before mutation"},
20
+ {"reference":"winremote-mcp","evidence_path":"src/winremote/process_mgr.py","mechanism":"Windows process enumeration with stale-process handling","deadbyte_comparison":"DEADBYTE ledger binds PID to creation identity and hash, stronger than PID/name kill paths","decision":"SKIP","r65_action":"retain verified ownership; never adopt caller-selected PID/name termination"}
21
+ ]
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.41",
3
+ "version": "0.15.43",
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.",
@@ -8,7 +8,7 @@
8
8
  "node": ">=22"
9
9
  },
10
10
  "scripts": {
11
- "test": "node --test test/*.test.mjs",
11
+ "test": "node --test --test-concurrency=4 test/*.test.mjs",
12
12
  "manifest:write": "node scripts/release-manifest.mjs write",
13
13
  "manifest:verify": "node scripts/release-manifest.mjs verify",
14
14
  "r41:parent:verify": "node scripts/verify-r41-parent.mjs",
@@ -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-r64-prepublish.ps1",
45
+ "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r66-prepublish.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",
@@ -89,7 +89,9 @@
89
89
  "r61:focused:test": "node --test --test-concurrency=1 test/r61-release-contract.test.mjs test/r61-release-bridge-binding.test.mjs test/r61-control-lane.test.mjs test/r61-live-timeline-bounds.test.mjs test/r61-npm-artifact-identity.test.mjs test/remote-live-log-r37.test.mjs test/bridge-runtime-r59.test.mjs test/commander-schema-differential-r48.test.mjs test/package-boundary.test.mjs test/r60-bridge-dispatch.test.mjs test/r60-authority-enforcement.test.mjs",
90
90
  "r62:focused:test": "node --test --test-concurrency=1 test/r62-release-contract.test.mjs test/r62-doctor-transactions-reconcile.test.mjs test/r62-doctor-receipt-semantics.test.mjs test/r62-rollback-failure-receipt.test.mjs test/r58-doctor-transactions.test.mjs test/r58-completed-update-receipt.test.mjs test/runtime-self-update.test.mjs test/r56-rollback-launcher-restore.test.mjs",
91
91
  "r63:focused:test": "node --test --test-concurrency=1 test/r63-release-contract.test.mjs test/r63-one-shot-coherence.test.mjs test/r51-runtime-coherence.test.mjs test/remote-session-cli.test.mjs",
92
- "r64:focused:test": "node --test --test-concurrency=1 test/r64-release-contract.test.mjs test/r64-machine-fs-large-read.test.mjs test/machine-fs-runtime.test.mjs test/compact-gateway-r36.test.mjs test/r61-control-lane.test.mjs test/r60-bridge-dispatch.test.mjs"
92
+ "r64:focused:test": "node --test --test-concurrency=1 test/r64-release-contract.test.mjs test/r64-machine-fs-large-read.test.mjs test/machine-fs-runtime.test.mjs test/compact-gateway-r36.test.mjs test/r61-control-lane.test.mjs test/r60-bridge-dispatch.test.mjs",
93
+ "r65:focused:test": "node scripts/r65-focused.mjs",
94
+ "r66:focused:test": "node --test --test-concurrency=1 test/r66-release-contract.test.mjs test/r58-doctor-runtime.test.mjs test/r58-doctor-foreground.test.mjs test/r58-doctor-installation.test.mjs test/r65-controller-authority-epoch.test.mjs test/r65-authority-observation-epoch.test.mjs"
93
95
  },
94
96
  "bundleDependencies": [
95
97
  "@modelcontextprotocol/server",
@@ -1,17 +1,91 @@
1
- import { createHash } from 'node:crypto';
2
- import { readFile, access } from 'node:fs/promises';
1
+ import { createHash,randomBytes } from 'node:crypto';
2
+ import { readFile, access,open,mkdir,unlink,lstat } from 'node:fs/promises';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
- import { runSlotUpdateCli } from '../src/runtime-update.mjs';
7
+ import { runSlotUpdateCli,windowsPowerShellEnvironment,loadPowerShellDataFile } from '../src/runtime-update.mjs';
8
8
  import { parseActivePointer } from '../src/release-slot.mjs';
9
+ import {parseAuthorityObservation} from '../src/remote-authority.mjs';
10
+ import {classifyActivationPreflight,classifyAuthorityContinuity,orchestrateActivation} from '../src/activation-preflight-r65.mjs';
11
+ import {createEpochNativeContinuityEngine} from '../src/activation-continuity-engine-r65.mjs';
12
+ import {createActivationClaimManager} from '../src/activation-lock-r65.mjs';
9
13
 
10
14
  const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
11
15
  const state=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
12
16
  const sha=async f=>createHash('sha256').update(await readFile(f)).digest('hex');
13
17
  const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
14
18
 
19
+ async function writeExclusive(file,value){
20
+ const handle=await open(file,'wx',0o600);
21
+ try{await handle.writeFile(JSON.stringify(value)+'\n');await handle.sync();}
22
+ finally{await handle.close();}
23
+ }
24
+
25
+ const activationClaimManager=createActivationClaimManager({stateRoot:state});
26
+ let activationClaimOperationId=null;
27
+
28
+ async function claimActivation(subjectSha256){
29
+ const claim=await activationClaimManager.claim(subjectSha256);
30
+ activationClaimOperationId=claim.operation_id;
31
+ return claim.release;
32
+ }
33
+
34
+ async function activePolicyPaths(){
35
+ const active=parseActivePointer(await readFile(path.join(state,'active-release.json'),'utf8'));
36
+ const config=await loadPowerShellDataFile(active.config_path);
37
+ const fields={process:'ProcessPolicyFile',coding:'CodingPolicyFile',autonomous:'AutonomousPolicyFile',desktop:'DesktopPolicyFile',host:'HostPolicyFile'};
38
+ return Object.fromEntries(Object.entries(fields).map(([plane,key])=>{
39
+ const file=config[key];
40
+ return [plane,typeof file==='string'&&path.isAbsolute(file)?path.resolve(file):null];
41
+ }));
42
+ }
43
+
44
+ async function observeController(){
45
+ const launcher=path.join(state,'bin','DEADBYTE-MCP.ps1');
46
+ const powershell=path.join(process.env.SystemRoot||'C:\\Windows','System32','WindowsPowerShell','v1.0','powershell.exe');
47
+ const run=spawnSync(powershell,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',launcher,'status','-Json'],{
48
+ cwd:root,env:windowsPowerShellEnvironment(),encoding:'utf8',timeout:20000,stdio:['ignore','pipe','pipe'],windowsHide:true});
49
+ if(run.error||run.status!==0)throw new Error(`activation preflight controller observation failed exit=${run.status} code=${run.error?.code??'none'}`);
50
+ const observed=parseAuthorityObservation(run.stdout);
51
+ const active=parseActivePointer(await readFile(path.join(state,'active-release.json'),'utf8'));
52
+ const policyPaths=await activePolicyPaths(),policySha256={};
53
+ for(const [plane,file] of Object.entries(policyPaths)){
54
+ if(!observed.authority[plane].configured){policySha256[plane]=null;continue;}
55
+ if(typeof file!=='string'||!path.isAbsolute(file))throw new Error(`activation ${plane} policy path missing`);
56
+ const info=await lstat(file);
57
+ if(!info.isFile()||info.isSymbolicLink())throw new Error(`activation ${plane} policy must be a regular file`);
58
+ policySha256[plane]=await sha(file);
59
+ }
60
+ return {...observed,policy_sha256:policySha256,policy_paths:policyPaths,active_release_id:active.release_id,active_manifest_sha256:active.manifest_sha256,
61
+ active_generation_manifest_sha256:active.generation_manifest_sha256};
62
+ }
63
+
64
+ function controllerCommand(command){
65
+ if(!/^(?:arm|disarm)(?:process|coding|autonomous|desktop|host)$|^supervisorstop$|^stop$/.test(command))throw new Error('activation controller command not declared');
66
+ const launcher=path.join(state,'bin','DEADBYTE-MCP.ps1');
67
+ const powershell=path.join(process.env.SystemRoot||'C:\\Windows','System32','WindowsPowerShell','v1.0','powershell.exe');
68
+ const run=spawnSync(powershell,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',launcher,command],{
69
+ cwd:root,env:windowsPowerShellEnvironment(),encoding:'utf8',timeout:30000,stdio:['ignore','pipe','pipe'],windowsHide:true});
70
+ if(run.error||run.status!==0)throw new Error(`activation controller ${command} failed exit=${run.status} code=${run.error?.code??'none'}`);
71
+ }
72
+
73
+ async function activationPreflight(manifest,pkg,pointer){
74
+ const release=JSON.parse(await readFile(path.join(root,'RELEASE.json'),'utf8'));
75
+ const observed=await observeController();
76
+ const result=classifyActivationPreflight({pointer,expectedParent:release.parent,
77
+ candidate:{version:pkg.version,manifest_sha256:manifest},
78
+ expectedCandidate:{version:release.version,manifest_sha256:manifest},observation:observed});
79
+ const continuity=classifyAuthorityContinuity(observed);
80
+ if(continuity.state==='UNVERIFIED')return {...result,state:'AUTHORITY_CONTINUITY_UNVERIFIED',safe_to_activate:false,
81
+ reason:continuity.reason??'authority continuity observation unverified',authority_continuity:'UNVERIFIED',reauth_planes:continuity.reauth_planes??[]};
82
+ if(continuity.state==='EPOCH_NATIVE')return {...result,authority_continuity:'EPOCH_NATIVE',
83
+ epoch_planes:continuity.epoch_planes??[],reauth_planes:[]};
84
+ if(continuity.state==='LEGACY_REAUTH_REQUIRED'||continuity.state==='MIXED_REAUTH_REQUIRED')
85
+ return {...result,authority_continuity:'REAUTH_REQUIRED',reauth_planes:continuity.reauth_planes??continuity.armed_planes??[]};
86
+ return {...result,authority_continuity:'NOT_APPLICABLE',reauth_planes:[]};
87
+ }
88
+
15
89
  async function waitForActivation({handoffPath,expectedVersion,expectedManifest,timeoutMs=900000,pollMs=1000}){
16
90
  const evidenceDir=path.dirname(path.resolve(handoffPath));
17
91
  const statePath=path.join(evidenceDir,'state.json');
@@ -62,6 +136,15 @@ const bridgeRoot=path.join(root,'bridge');
62
136
  const bridgeScript=path.join(bridgeRoot,'src','bridge.mjs');
63
137
  const pkg=JSON.parse(await readFile(path.join(root,'package.json'),'utf8'));
64
138
  const expectedVersion=pkg.version;
139
+ const release=JSON.parse(await readFile(path.join(root,'RELEASE.json'),'utf8'));
140
+ const preflight=await activationPreflight(manifest,pkg,pointer);
141
+ if(process.argv.includes('--preflight')){
142
+ console.log(JSON.stringify(preflight));
143
+ process.exit(0);
144
+ }
145
+ if(process.argv.length>2)throw new Error('deploy accepts only --preflight');
146
+ if(!['ONLINE_READY','ONLINE_HOST_ARMED','PARKED_DIRTY','OFFLINE_CLEAN'].includes(preflight.state))
147
+ throw new Error(`activation preflight rejected: ${preflight.state} subject=${preflight.subject_sha256??'<incomplete>'}`);
65
148
  const args=[
66
149
  '--stage',root,'--development-root',root,'--expected-version',expectedVersion,'--expected-manifest',manifest,
67
150
  '--process-policy',path.join(root,'controller','deadbyte-process-policy.json'),'--process-policy-sha256',await sha(path.join(root,'controller','deadbyte-process-policy.json')),
@@ -70,9 +153,40 @@ const args=[
70
153
  '--bridge-root',bridgeRoot,'--bridge-script-sha256',await sha(bridgeScript),
71
154
  '--enable-machine-fs','--enable-observation','--enable-desktop','--enable-autonomous-supervisor','--recover-offline-predecessor'
72
155
  ];
73
- const result=await runSlotUpdateCli(args,{stateRoot:state});
74
- if(!result.handed_off) throw new Error('release activation unexpectedly completed inline; refusing to skip post-activation verification');
75
- const verification=await waitForActivation({handoffPath:result.handoff_path,expectedVersion,expectedManifest:manifest});
156
+ let result=null,verification=null,activationOutcomePath=null;
157
+ let continuityEngine=null,continuityUpdateId=null;
158
+
159
+ async function recordActivationOutcome(outcome){
160
+ if(typeof activationClaimOperationId!=='string')throw new Error('activation claim operation id unavailable');
161
+ const outcomeFile=path.join(state,'evidence','updates',`r65-activation-outcome-${Date.now()}-${randomBytes(8).toString('hex')}.json`);
162
+ await writeExclusive(outcomeFile,{schema:'deadbyte.r65-activation-outcome.v1',claim_operation_id:activationClaimOperationId,
163
+ candidate_version:expectedVersion,candidate_manifest_sha256:manifest,
164
+ predecessor_release_id:pointer.release_id,preflight_subject_sha256:preflight.subject_sha256,outcome,
165
+ update_id:result?.update_id??null,continuity_update_id:continuityUpdateId,
166
+ state_path:result?.state_path??null,observed_at_utc:new Date().toISOString()});
167
+ activationOutcomePath=outcomeFile;
168
+ }
169
+
170
+ if(preflight.authority_continuity==='EPOCH_NATIVE'){
171
+ const predecessorObservation=await observeController();
172
+ continuityUpdateId=`r65-${randomBytes(16).toString('hex')}`;
173
+ continuityEngine=createEpochNativeContinuityEngine({stateRoot:state,predecessorPolicyPaths:predecessorObservation.policy_paths,
174
+ successorPolicyPaths:async()=>activePolicyPaths(),updateId:continuityUpdateId});
175
+ }
176
+ const outcome=await orchestrateActivation({pointer,expectedParent:release.parent,
177
+ candidate:{version:expectedVersion,manifest_sha256:manifest},expectedCandidate:{version:release.version,manifest_sha256:manifest},
178
+ observe:async()=>observeController(),command:async command=>controllerCommand(command),claim:claimActivation,continuityEngine,
179
+ recordOutcome:recordActivationOutcome,
180
+ activate:async()=>{
181
+ result=await runSlotUpdateCli(args,{stateRoot:state});
182
+ if(!result.handed_off)throw new Error('release activation unexpectedly completed inline');
183
+ verification=await waitForActivation({handoffPath:result.handoff_path,expectedVersion,expectedManifest:manifest});
184
+ return {verified:true,release_id:verification.release_id};
185
+ }});
186
+ if(outcome.state!=='ACTIVATED'){
187
+ console.log(JSON.stringify({...outcome,update_id:result?.update_id??null,state_path:result?.state_path??null,outcome_path:activationOutcomePath}));
188
+ process.exitCode=2;
189
+ }else{
76
190
  console.log(JSON.stringify({
77
191
  status:'activated',
78
192
  manifest_sha256:manifest,
@@ -81,5 +195,7 @@ console.log(JSON.stringify({
81
195
  supervisor_pid:result.supervisor_pid,
82
196
  release_id:verification.release_id,
83
197
  receipt_path:verification.receiptPath,
84
- state_path:verification.statePath
198
+ state_path:verification.statePath,
199
+ outcome_path:activationOutcomePath
85
200
  },null,2));
201
+ }
@@ -0,0 +1,65 @@
1
+ param(
2
+ [ValidateSet('all','preflight','focused','full','manifest','doctor')]
3
+ [string]$Stage='all'
4
+ )
5
+
6
+ $ErrorActionPreference='Stop'
7
+ Set-StrictMode -Version 3.0
8
+ $root=Split-Path $PSScriptRoot -Parent
9
+ Set-Location -LiteralPath $root
10
+
11
+ function Invoke-Npm([string]$Name,[string[]]$NpmArgs){
12
+ Write-Host "==== $Name ===="
13
+ & npm.cmd @NpmArgs
14
+ if($LASTEXITCODE -ne 0){ throw "R65 prepublish gate failed at $Name exit=$LASTEXITCODE" }
15
+ }
16
+
17
+ function Get-FileSha256([string]$File){
18
+ $hasher=[Security.Cryptography.SHA256]::Create()
19
+ try{
20
+ $bytes=[IO.File]::ReadAllBytes($File)
21
+ return (($hasher.ComputeHash($bytes) | ForEach-Object { $_.ToString('x2') }) -join '')
22
+ }finally{ $hasher.Dispose() }
23
+ }
24
+
25
+ $sourceRoot='D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.41-r64'
26
+ $sourceManifest='63a78ad159ad3003db3fefafcd468bef22599c829a867f4f10a46c7a20748b3e'
27
+ if(-not (Test-Path -LiteralPath $sourceRoot -PathType Container)){ throw 'R65 source predecessor missing' }
28
+ $observedSourceManifest=Get-FileSha256 (Join-Path $sourceRoot 'MANIFEST.SHA256')
29
+ if($observedSourceManifest -ne $sourceManifest){ throw 'R65 source predecessor manifest identity mismatch' }
30
+ & node (Join-Path $root 'scripts\\verify-r65-parent-source.mjs') --root $sourceRoot --expected-manifest-sha256 $sourceManifest
31
+ if($LASTEXITCODE -ne 0){ throw 'R65 source predecessor declared-manifest verification failed' }
32
+
33
+ $stateRoot=Join-Path $env:USERPROFILE '.deadbyte-mcp'
34
+ $pointer=Join-Path $stateRoot 'active-release.json'
35
+ if(-not (Test-Path -LiteralPath $pointer -PathType Leaf)){ throw "R65 runtime predecessor pointer missing: $pointer" }
36
+ $active=Get-Content -LiteralPath $pointer -Raw | ConvertFrom-Json
37
+ if($active.release_id -ne 'v0.15.41-63a78ad159ad3003'){ throw "R65 runtime predecessor release mismatch: $($active.release_id)" }
38
+ if($active.manifest_sha256 -ne '63a78ad159ad3003db3fefafcd468bef22599c829a867f4f10a46c7a20748b3e'){ throw 'R65 runtime predecessor manifest mismatch' }
39
+ if($active.generation_manifest_sha256 -ne '19ae2efcdcde9f80c474f0e55851d4ada51c22813d3e05af03b11acb28c3fca5'){ throw 'R65 runtime predecessor generation mismatch' }
40
+ if($Stage -eq 'preflight'){Write-Host '==== R65 WINDOWS GATE: PASS preflight ====';return}
41
+
42
+ if($Stage -eq 'all' -or $Stage -eq 'focused'){
43
+ Invoke-Npm 'r65-focused' @('run','r65:focused:test')
44
+ if($Stage -eq 'focused'){Write-Host '==== R65 WINDOWS GATE: PASS focused ====';return}
45
+ }
46
+ if($Stage -eq 'all' -or $Stage -eq 'full'){
47
+ Invoke-Npm 'full-regression' @('test')
48
+ if($Stage -eq 'full'){Write-Host '==== R65 WINDOWS GATE: PASS full ====';return}
49
+ }
50
+ if($Stage -eq 'all' -or $Stage -eq 'manifest'){
51
+ Invoke-Npm 'manifest-write' @('run','manifest:write')
52
+ Invoke-Npm 'manifest-verify' @('run','manifest:verify')
53
+ if($Stage -eq 'manifest'){Write-Host '==== R65 WINDOWS GATE: PASS manifest ====';return}
54
+ }
55
+ if($Stage -eq 'all' -or $Stage -eq 'doctor'){
56
+ $doctorRoot='D:\Projects\deadbyte-mcp\testing\0.15.42-r65\doctor-isolated-empty'
57
+ if(Test-Path -LiteralPath (Join-Path $doctorRoot 'active-release.json')){ throw 'R65 isolated doctor root unexpectedly contains a release pointer' }
58
+ $priorStateRoot=$env:DEADBYTE_STATE_ROOT
59
+ try{
60
+ $env:DEADBYTE_STATE_ROOT=$doctorRoot
61
+ Invoke-Npm 'doctor-isolated-empty-state' @('run','doctor')
62
+ }finally{ $env:DEADBYTE_STATE_ROOT=$priorStateRoot }
63
+ if($Stage -eq 'doctor'){Write-Host '==== R65 WINDOWS GATE: PASS doctor ====';return}
64
+ }
65
+ Write-Host '==== R65 PREPUBLISH WINDOWS GATE: PASS ===='