deadbyte-mcp 0.15.34 → 0.15.35
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 +67 -22
- package/PROVENANCE.json +57 -30
- package/README.txt +18 -14
- package/RELEASE.json +40 -31
- package/SBOM.cdx.json +25 -3
- package/TEST-MATRIX.json +129 -48
- package/bridge/package.json +11 -0
- package/bridge/src/bridge.mjs +412 -0
- package/bridge/src/node-http-adapter.mjs +56 -0
- package/bridge/src/public-tool-definitions.mjs +14 -0
- package/bridge/src/r40-governor.mjs +160 -0
- package/controller/deadbyte-controller.ps1 +84 -8
- package/controller/deadbyte-process-policy.json +4 -4
- package/package.json +5 -3
- package/scripts/bridge-benchmark-r58.mjs +67 -0
- package/scripts/deploy-r48.mjs +2 -3
- package/scripts/gate-windows-r58.ps1 +33 -0
- package/scripts/owner-probe-r58.mjs +31 -0
- package/scripts/performance-r58.mjs +57 -0
- package/scripts/public-baseline-r58.mjs +72 -0
- package/scripts/public-surface-r58.mjs +84 -0
- package/scripts/r58-cross-plane.ps1 +6 -0
- package/scripts/r58-focused.ps1 +6 -0
- package/scripts/windows-gate-evidence-r58.mjs +93 -0
- package/src/deadbyte-cli.mjs +40 -12
- package/src/doctor-foreground-r58.mjs +44 -0
- package/src/doctor-installation-r58.mjs +63 -0
- package/src/doctor-r45.mjs +21 -4
- package/src/doctor-runtime-r58.mjs +82 -0
- package/src/doctor-transactions-r58.mjs +40 -0
- package/src/foreground-process-identity.mjs +27 -0
- package/src/foreground-session-lock.mjs +20 -0
- package/src/foreground-session-lock.ps1 +15 -0
- package/src/release-generation.mjs +1 -0
- package/src/release-slot.mjs +2 -1
- package/src/remote-session-guardian.mjs +8 -1
- package/src/runtime-update.mjs +85 -2
- package/src/version.mjs +1 -1
- package/test/controller-r211.test.mjs +4 -1
- package/test/controller.test.mjs +2 -1
- package/test/helpers/r58-doctor-fixture.mjs +26 -0
- package/test/r49-windows-gate.test.mjs +2 -2
- package/test/r57-release-contract.test.mjs +5 -3
- package/test/r58-bridge-dependency-binding.test.mjs +62 -0
- package/test/r58-bundled-bridge.test.mjs +22 -0
- package/test/r58-cleanup-retention.test.mjs +45 -0
- package/test/r58-completed-update-receipt.test.mjs +76 -0
- package/test/r58-concurrent-recovery.test.mjs +54 -0
- package/test/r58-controller-core-observation.test.mjs +36 -0
- package/test/r58-controller-json.test.mjs +48 -0
- package/test/r58-controller-live-local.test.mjs +85 -0
- package/test/r58-controller-readonly.test.mjs +23 -0
- package/test/r58-controller-state-coherence.test.mjs +45 -0
- package/test/r58-doctor-cli.test.mjs +20 -0
- package/test/r58-doctor-foreground.test.mjs +50 -0
- package/test/r58-doctor-installation.test.mjs +55 -0
- package/test/r58-doctor-pointer.test.mjs +41 -0
- package/test/r58-doctor-runtime.test.mjs +45 -0
- package/test/r58-doctor-transactions.test.mjs +21 -0
- package/test/r58-guardian-channel.test.mjs +26 -0
- package/test/r58-launcher-shell.test.mjs +28 -0
- package/test/r58-owner-identity.test.mjs +20 -0
- package/test/r58-release-contract.test.mjs +49 -0
- package/test/r58-session-lock.test.mjs +26 -0
- package/test/r58-stale-owner.test.mjs +71 -0
- package/test/r58-windows-gate.test.mjs +31 -0
- package/test/release-generation.test.mjs +4 -1
- package/test/remote-session-cli.test.mjs +55 -2
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
param(
|
|
4
4
|
[Parameter(Position=0)]
|
|
5
5
|
[ValidateSet('menu','start','resume','park','stop','restart','status','url','test','fulltest','toggle','clean','machinetest','armprocess','disarmprocess','processstatus','armhost','disarmhost','hoststatus','hosttest','armcoding','disarmcoding','codingstatus','codingtest','armautonomous','disarmautonomous','autonomousstatus','autonomoustest','supervisorstart','supervisorstop','supervisorstatus','supervisorrecover','armdesktop','disarmdesktop','desktopstatus')]
|
|
6
|
-
[string]$Command = 'menu'
|
|
6
|
+
[string]$Command = 'menu',
|
|
7
|
+
[switch]$Json
|
|
7
8
|
)
|
|
8
9
|
|
|
9
10
|
Set-StrictMode -Version 3.0
|
|
@@ -16,6 +17,7 @@ $LogDir = Join-Path $RuntimeDir 'logs'
|
|
|
16
17
|
$ConfigPath = if ($env:DEADBYTE_CONTROLLER_CONFIG) { $env:DEADBYTE_CONTROLLER_CONFIG } else { Join-Path $Root 'deadbyte-controller.config.psd1' }
|
|
17
18
|
|
|
18
19
|
function Fail([string]$Message) { throw "DEADBYTE controller: $Message" }
|
|
20
|
+
if ($Json -and $Command -ne 'status') { Fail 'JSON observation is available only for status' }
|
|
19
21
|
|
|
20
22
|
function Get-ControllerMutationMutexName {
|
|
21
23
|
$normalized = ([System.IO.Path]::GetFullPath($RuntimeDir)).TrimEnd('\\').ToLowerInvariant()
|
|
@@ -721,12 +723,14 @@ function Test-LocalReadyOwned($Cfg, $Bridge) {
|
|
|
721
723
|
function Get-ObservedState($Cfg) {
|
|
722
724
|
$bridge = Test-OwnedInstance 'Bridge'
|
|
723
725
|
$cloud = Test-OwnedInstance 'Cloud'
|
|
724
|
-
$
|
|
726
|
+
$core = Get-DownstreamCoreObservation $Cfg $bridge
|
|
727
|
+
$ready = if ($bridge.Alive -and $core.alive) { try { Test-LocalReadyOwned $Cfg $bridge } catch { $false } } else { $false }
|
|
725
728
|
$state = if (-not $bridge.Alive -and -not $cloud.Alive) { 'OFFLINE' }
|
|
726
729
|
elseif (-not $bridge.Alive -and $cloud.Alive) { 'PARKED' }
|
|
727
730
|
elseif ($bridge.Alive -and $cloud.Alive -and $ready) { 'ONLINE' }
|
|
728
|
-
|
|
729
|
-
|
|
731
|
+
elseif ($bridge.Alive -and $core.reason -eq 'startup-zero-child') { 'STARTING' }
|
|
732
|
+
else { 'FAILED' }
|
|
733
|
+
[pscustomobject]@{ State=$state; Bridge=$bridge; Core=$core; Cloud=$cloud; LocalReady=$ready }
|
|
730
734
|
}
|
|
731
735
|
|
|
732
736
|
function Wait-LocalReady($Cfg) {
|
|
@@ -734,7 +738,10 @@ function Wait-LocalReady($Cfg) {
|
|
|
734
738
|
do {
|
|
735
739
|
$bridge = Test-OwnedInstance 'Bridge'
|
|
736
740
|
if (-not $bridge.Alive) { return $false }
|
|
737
|
-
|
|
741
|
+
$core = Get-DownstreamCoreObservation $Cfg $bridge
|
|
742
|
+
if (-not $core.alive -and $core.reason -ne 'startup-zero-child') { return $false }
|
|
743
|
+
if ($core.alive -and (Test-LocalReadyOwned $Cfg $bridge)) { return $true }
|
|
744
|
+
if ([DateTime]::UtcNow -ge $deadline) { return $false }
|
|
738
745
|
Start-Sleep -Milliseconds 250
|
|
739
746
|
} while ([DateTime]::UtcNow -lt $deadline)
|
|
740
747
|
return $false
|
|
@@ -836,7 +843,7 @@ function Invoke-CoreGate($Cfg, [string]$ScriptName, [string[]]$ExtraArguments =
|
|
|
836
843
|
function Start-Deadbyte($Cfg) {
|
|
837
844
|
$state = Get-ObservedState $Cfg
|
|
838
845
|
if ($state.State -eq 'ONLINE') { return $state }
|
|
839
|
-
if ($state.State -
|
|
846
|
+
if ($state.State -in @('FAILED','STARTING')) { Fail "runtime is $($state.State); inspect status and reconcile verified owned components before restart" }
|
|
840
847
|
$cloudWasAlive = [bool]$state.Cloud.Alive
|
|
841
848
|
Assert-LocalReadyPortAvailable $Cfg
|
|
842
849
|
try {
|
|
@@ -1265,6 +1272,73 @@ function Recover-AutonomousSupervisor($Cfg) {
|
|
|
1265
1272
|
return [pscustomobject]@{ Runtime=$runtime; Supervisor=$supervisor; Process=$process; Coding=$coding; Autonomous=$autonomous; Desktop=$desktop; Host=$hostStatus }
|
|
1266
1273
|
}
|
|
1267
1274
|
|
|
1275
|
+
function Get-BoundedObservationReason($Value) {
|
|
1276
|
+
$reason = [string]$Value
|
|
1277
|
+
if ($reason -cmatch '^[a-z][a-z0-9-]{0,63}$') { return $reason }
|
|
1278
|
+
return 'unverified'
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
function Convert-OwnedObservation($Owned) {
|
|
1282
|
+
$pidValue = $null; $birth = $null
|
|
1283
|
+
if ($Owned.Alive -and $Owned.Ledger) {
|
|
1284
|
+
$pidValue = [int]$Owned.Ledger.pid
|
|
1285
|
+
$birth = [string]$Owned.Ledger.creation_time_utc
|
|
1286
|
+
}
|
|
1287
|
+
[ordered]@{ alive=[bool]$Owned.Alive; reason=(Get-BoundedObservationReason $Owned.Reason); pid=$pidValue; creation_time_utc=$birth }
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
function Convert-AuthorityObservation($Authority) {
|
|
1291
|
+
[ordered]@{ configured=[bool]$Authority.Configured; armed=[bool]$Authority.Armed; reason=(Get-BoundedObservationReason $Authority.Reason) }
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
function Get-DownstreamCoreObservation($Cfg, $Bridge) {
|
|
1295
|
+
$out = [ordered]@{ alive=$false; reason='bridge-unavailable'; pid=$null; parent_pid=$null; creation_time_utc=$null; identity_basis=$null }
|
|
1296
|
+
if (-not $Bridge.Alive) { return $out }
|
|
1297
|
+
$bridgePid = [int]$Bridge.Ledger.pid
|
|
1298
|
+
if (-not [string]::Equals([IO.Path]::GetFullPath([string]$Bridge.Ledger.script_path), [IO.Path]::GetFullPath([string]$Cfg.Bridge.ScriptPath), [StringComparison]::OrdinalIgnoreCase) -or [string]$Bridge.Ledger.script_sha256 -ne [string]$Cfg.Bridge.ScriptSha256) {
|
|
1299
|
+
$out.reason='bridge-config-mismatch'; return $out
|
|
1300
|
+
}
|
|
1301
|
+
try {
|
|
1302
|
+
$children = @(Get-CimInstance Win32_Process -Filter ("ParentProcessId={0} AND Name='node.exe'" -f $bridgePid) -ErrorAction Stop)
|
|
1303
|
+
if ($children.Count -eq 0) { $out.reason='startup-zero-child'; return $out }
|
|
1304
|
+
if ($children.Count -ne 1) { $out.reason='ambiguous-core'; return $out }
|
|
1305
|
+
$child = $children[0]
|
|
1306
|
+
if ([int]$child.ParentProcessId -ne $bridgePid -or [int]$child.ProcessId -lt 1 -or $null -eq $child.CreationDate) { $out.reason='core-identity-incomplete'; return $out }
|
|
1307
|
+
if (-not [string]::IsNullOrWhiteSpace([string]$child.ExecutablePath) -and -not [string]::Equals([string]$child.ExecutablePath,[string]$Cfg.Bridge.FilePath,[StringComparison]::OrdinalIgnoreCase)) { $out.reason='core-image-mismatch'; return $out }
|
|
1308
|
+
$command = [string]$child.CommandLine
|
|
1309
|
+
$needle = (Join-Path ([string]$Cfg.CoreRoot) 'src\mcp-server.mjs').Replace('/','\').ToLowerInvariant()
|
|
1310
|
+
if ([string]::IsNullOrWhiteSpace($command)) { $basis='verified-bridge-single-opaque-node-child' }
|
|
1311
|
+
elseif ($command.Replace('/','\').ToLowerInvariant().Contains($needle)) { $basis='command-line' }
|
|
1312
|
+
else { $out.reason='wrong-core-generation'; return $out }
|
|
1313
|
+
$out.alive=$true; $out.reason='verified'; $out.pid=[int]$child.ProcessId; $out.parent_pid=$bridgePid
|
|
1314
|
+
$out.creation_time_utc=$child.CreationDate.ToUniversalTime().ToString('o'); $out.identity_basis=$basis
|
|
1315
|
+
return $out
|
|
1316
|
+
} catch { $out.reason='core-observation-failed'; return $out }
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
function Get-StructuredObservation($Cfg) {
|
|
1320
|
+
$s = Get-ObservedState $Cfg
|
|
1321
|
+
$supervisor = Get-AutonomousSupervisorStatus $Cfg
|
|
1322
|
+
[ordered]@{
|
|
1323
|
+
schema='deadbyte.controller-observation.v1'
|
|
1324
|
+
observed_at_utc=[DateTime]::UtcNow.ToString('o')
|
|
1325
|
+
state=[string]$s.State
|
|
1326
|
+
core_root=[string]$Cfg.CoreRoot
|
|
1327
|
+
local_ready=[bool]$s.LocalReady
|
|
1328
|
+
bridge=(Convert-OwnedObservation $s.Bridge)
|
|
1329
|
+
core=$s.Core
|
|
1330
|
+
cloud=(Convert-OwnedObservation $s.Cloud)
|
|
1331
|
+
supervisor=[ordered]@{ configured=[bool]$supervisor.Configured; running=[bool]$supervisor.Running; reason=(Get-BoundedObservationReason $supervisor.Reason) }
|
|
1332
|
+
authority=[ordered]@{
|
|
1333
|
+
process=(Convert-AuthorityObservation (Get-ProcessGrantStatus $Cfg))
|
|
1334
|
+
coding=(Convert-AuthorityObservation (Get-CodingLeaseStatus $Cfg))
|
|
1335
|
+
autonomous=(Convert-AuthorityObservation (Get-AutonomousLeaseStatus $Cfg))
|
|
1336
|
+
desktop=(Convert-AuthorityObservation (Get-DesktopGrantStatus $Cfg))
|
|
1337
|
+
host=(Convert-AuthorityObservation (Get-HostArmStatus $Cfg))
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1268
1342
|
function Show-State($Cfg) {
|
|
1269
1343
|
$s = Get-ObservedState $Cfg
|
|
1270
1344
|
$bp = if ($s.Bridge.Alive) { $s.Bridge.Ledger.pid } else { '-' }
|
|
@@ -1272,6 +1346,7 @@ function Show-State($Cfg) {
|
|
|
1272
1346
|
$url = Get-CurrentUrl $Cfg
|
|
1273
1347
|
Write-Host ("DEADBYTE MCP = {0}" -f $s.State)
|
|
1274
1348
|
Write-Host ("Bridge PID : {0} [{1}]" -f $bp, $s.Bridge.Reason)
|
|
1349
|
+
Write-Host ("Core PID : {0} [{1}]" -f $(if ($s.Core.alive) { $s.Core.pid } else { '-' }), $s.Core.reason)
|
|
1275
1350
|
Write-Host ("Cloud PID : {0} [{1}]" -f $cp, $s.Cloud.Reason)
|
|
1276
1351
|
Write-Host ("Local ready : {0}" -f $s.LocalReady)
|
|
1277
1352
|
Write-Host ("URL : {0}" -f $(if ($url) { $url } else { '<unknown>' }))
|
|
@@ -1370,14 +1445,15 @@ function Clean-Stale {
|
|
|
1370
1445
|
function Run-CommandCore([string]$Name) {
|
|
1371
1446
|
$cfg = Get-Config
|
|
1372
1447
|
Assert-ControllerRootBound $cfg
|
|
1373
|
-
|
|
1448
|
+
$readOnly = $Name -in @('status','url','hoststatus','processstatus','codingstatus','autonomousstatus','desktopstatus','supervisorstatus')
|
|
1449
|
+
if (-not $readOnly) { Ensure-Directory $RuntimeDir; Ensure-Directory $LogDir }
|
|
1374
1450
|
switch ($Name) {
|
|
1375
1451
|
'start' { Start-Deadbyte $cfg | Out-Null; if ([bool]$cfg.AutonomousSupervisorEnabled) { Start-AutonomousSupervisor $cfg | Out-Null }; Show-State $cfg | Out-Null }
|
|
1376
1452
|
'resume' { Start-Deadbyte $cfg | Out-Null; if ([bool]$cfg.AutonomousSupervisorEnabled) { Start-AutonomousSupervisor $cfg | Out-Null }; Show-State $cfg | Out-Null }
|
|
1377
1453
|
'park' { Park-Deadbyte $cfg | Out-Null; Show-State $cfg | Out-Null }
|
|
1378
1454
|
'stop' { if ([bool]$cfg.AutonomousSupervisorEnabled) { Stop-AutonomousSupervisor $cfg | Out-Null }; Stop-Deadbyte $cfg | Out-Null; Show-State $cfg | Out-Null }
|
|
1379
1455
|
'restart' { if ([bool]$cfg.AutonomousSupervisorEnabled) { Stop-AutonomousSupervisor $cfg | Out-Null }; Stop-Deadbyte $cfg | Out-Null; Start-Deadbyte $cfg | Out-Null; if ([bool]$cfg.AutonomousSupervisorEnabled) { Start-AutonomousSupervisor $cfg | Out-Null }; Show-State $cfg | Out-Null }
|
|
1380
|
-
'status' { Show-State $cfg | Out-Null }
|
|
1456
|
+
'status' { if ($Json) { Get-StructuredObservation $cfg | ConvertTo-Json -Depth 6 -Compress | Write-Output } else { Show-State $cfg | Out-Null } }
|
|
1381
1457
|
'url' { $u=Get-CurrentUrl $cfg; if (-not $u) { Fail 'URL unavailable' }; Write-Output $u }
|
|
1382
1458
|
'test' { Invoke-Smoke $cfg $false }
|
|
1383
1459
|
'fulltest'{ Invoke-Smoke $cfg $true }
|
|
@@ -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.35-r58\\controller\\runtime\\process-grant.json",
|
|
5
|
+
"state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.35-r58\\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.35-r58\\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.35-r58",
|
|
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.35",
|
|
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-r58.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",
|
|
@@ -79,7 +79,9 @@
|
|
|
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
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
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",
|
|
82
|
-
"r57:focused:test": "node --test --test-concurrency=1 test/r57-release-contract.test.mjs test/r57-core-startup-race.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 test/remote-session-cli.test.mjs"
|
|
82
|
+
"r57:focused:test": "node --test --test-concurrency=1 test/r57-release-contract.test.mjs test/r57-core-startup-race.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 test/remote-session-cli.test.mjs",
|
|
83
|
+
"r58:focused:test": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/r58-focused.ps1",
|
|
84
|
+
"r58:cross-plane:test": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/r58-cross-plane.ps1"
|
|
83
85
|
},
|
|
84
86
|
"bundleDependencies": [
|
|
85
87
|
"@modelcontextprotocol/server",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {mkdir,readFile,writeFile,rm} from 'node:fs/promises';
|
|
2
|
+
import {spawn} from 'node:child_process';
|
|
3
|
+
import {randomBytes,createHash} from 'node:crypto';
|
|
4
|
+
import {createServer} from 'node:net';
|
|
5
|
+
import {performance} from 'node:perf_hooks';
|
|
6
|
+
import {setTimeout as delay} from 'node:timers/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import {pathToFileURL} from 'node:url';
|
|
9
|
+
import {Client,StreamableHTTPClientTransport} from '@modelcontextprotocol/client';
|
|
10
|
+
import {generateTrustKeypair} from '../src/trust.mjs';
|
|
11
|
+
import {loadCodingPolicy} from '../src/coding-plane.mjs';
|
|
12
|
+
|
|
13
|
+
const run=path.resolve(process.argv[2]||'');const base=path.resolve('D:/Projects/deadbyte-mcp/testing/0.15.35');const rel=path.relative(base,run);
|
|
14
|
+
if(!rel||rel.startsWith('..')||path.isAbsolute(rel))throw new Error('new D: R58 run root required');await mkdir(run);
|
|
15
|
+
const core='C:/Users/DEADBYTE/.deadbyte-mcp/releases/v0.15.34-2199bb59f0e0fc20';
|
|
16
|
+
const targets={baseline:'D:/Projects/deadbyte-chatgpt-bridge-r40-dev',candidate:'D:/Projects/deadbyte-mcp/development/deadbyte-mcp-0.15.35-r58/bridge'};
|
|
17
|
+
const entries=Object.entries(targets);if(process.argv[3]==='candidate-first')entries.reverse();
|
|
18
|
+
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
19
|
+
if(sha(await readFile(path.join(core,'MANIFEST.SHA256')))!=='2199bb59f0e0fc205d470d11f990d3ce3df444be5eba2a7d8dbc60d5f5b790bb')throw new Error('core baseline drift');
|
|
20
|
+
const summaries={};
|
|
21
|
+
const extended=process.argv.includes('--extended');
|
|
22
|
+
const corpus=[{name:'coding_session_status',arguments:{}},{name:'capability_manifest',arguments:{}}];
|
|
23
|
+
if(extended)corpus.push({name:'coding_file_read',arguments:{root_id:'bench',path:'input.txt'}},{name:'coding_tree',arguments:{root_id:'bench',path:'.',max_depth:2,max_entries:100}});
|
|
24
|
+
for(const [label,target] of entries){
|
|
25
|
+
const root=path.join(run,label);await mkdir(root);const state=path.join(root,'state'),workspace=path.join(root,'workspace'),temp=path.join(root,'temp');
|
|
26
|
+
for(const dir of [state,workspace,temp])await mkdir(dir);
|
|
27
|
+
const keys=await generateTrustKeypair({privateKeyPath:path.join(root,'private.pem'),publicKeyPath:path.join(root,'public.pem')});
|
|
28
|
+
const policy=path.join(root,'policy.json');
|
|
29
|
+
await writeFile(policy,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:path.join(state,'grant.json'),evidence_dir:path.join(state,'evidence'),roots:{bench:{path:workspace,read:true,write:false,exec:false,deny_paths:[]}},commands:{},max_read_bytes:65536,max_write_bytes:65536}),{flag:'wx'});
|
|
30
|
+
const fixture='bounded fixture alpha\n'.repeat(100);await writeFile(path.join(workspace,'input.txt'),fixture,{flag:'wx'});
|
|
31
|
+
if(extended){const loaded=await loadCodingPolicy(policy);await writeFile(path.join(state,'grant.json'),JSON.stringify({schema:'deadbyte.coding-grant.v2',policy_sha256:loaded.policy_sha256,instance_nonce:randomBytes(32).toString('hex'),root_ids:['bench']}),{flag:'wx'});}
|
|
32
|
+
const reservation=createServer();await new Promise(resolve=>reservation.listen(0,'127.0.0.1',resolve));const port=reservation.address().port;await new Promise(resolve=>reservation.close(resolve));
|
|
33
|
+
const token=randomBytes(32).toString('hex');const env={...process.env};for(const key of Object.keys(env))if(key.startsWith('DEADBYTE_'))delete env[key];
|
|
34
|
+
Object.assign(env,{TEMP:temp,TMP:temp,npm_config_cache:path.join(root,'npm-cache'),DEADBYTE_CORE_ROOT:core,DEADBYTE_STATE_ROOT:state,DEADBYTE_WORKSPACE_ROOT:workspace,DEADBYTE_BRIDGE_PORT:String(port),DEADBYTE_BRIDGE_PATH_TOKEN:token,DEADBYTE_SIGNING_KEY:keys.privateKeyPath,DEADBYTE_VERIFY_KEY:keys.publicKeyPath,DEADBYTE_PRIVILEGED_POLICY:'',DEADBYTE_CAPABILITY_PROFILE:'compact',DEADBYTE_MACHINE_RUNTIME:'0',DEADBYTE_AGENT_RUNTIME:'0',DEADBYTE_PROCESS_RUNTIME:'0',DEADBYTE_CODING_RUNTIME:'1',DEADBYTE_CODING_POLICY:policy,DEADBYTE_MACHINE_FS_RUNTIME:'0',DEADBYTE_OBSERVATION_RUNTIME:'0',DEADBYTE_DESKTOP_RUNTIME:'0',DEADBYTE_AUTONOMOUS_RUNTIME:'0',DEADBYTE_AUDIT_RUNTIME:'0'});
|
|
35
|
+
const bridgePath=path.join(target,'src/bridge.mjs');const script=`process.on('message',m=>{if(m==='stop')process.emit('SIGTERM')});await import(${JSON.stringify(pathToFileURL(bridgePath).href)});`;
|
|
36
|
+
const start=performance.now();const child=spawn(process.execPath,['--input-type=module','-e',script],{cwd:target,env,windowsHide:true,stdio:['ignore','pipe','pipe','ipc']});
|
|
37
|
+
let stdout='',stderr='';child.stdout.on('data',b=>{stdout+=b;});child.stderr.on('data',b=>{stderr+=b;});const exited=new Promise(resolve=>child.once('exit',code=>resolve(code)));
|
|
38
|
+
const samples=[];let catalog;
|
|
39
|
+
try{
|
|
40
|
+
const deadline=Date.now()+20000;while(!stdout.includes('BRIDGE_READY')&&child.exitCode===null&&Date.now()<deadline)await delay(20);
|
|
41
|
+
if(!stdout.includes('BRIDGE_READY'))throw new Error(`${label} bridge startup failed: ${stderr}`);
|
|
42
|
+
const startup=performance.now()-start;
|
|
43
|
+
for(let batch=0;batch<3;batch++){
|
|
44
|
+
const client=new Client({name:'r58-isolated-bridge-benchmark',version:'1.0.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
45
|
+
try{
|
|
46
|
+
await client.connect(new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${port}/mcp/${token}`)));
|
|
47
|
+
const tools=(await client.listTools()).tools;if(!catalog){catalog=tools;await writeFile(path.join(root,'catalog.json'),JSON.stringify(tools,null,2),{flag:'wx'});}
|
|
48
|
+
for(let iteration=0;iteration<120;iteration++)for(const request of corpus){
|
|
49
|
+
const {name}=request;const t=performance.now();const result=await client.callTool(request);const elapsed=performance.now()-t;
|
|
50
|
+
if(result.isError||!result.structuredContent)throw new Error(`${label} benchmark tool failed: ${name}`);
|
|
51
|
+
if(name==='coding_file_read'&&(result.structuredContent.content!==fixture||result.structuredContent.sha256!==sha(fixture)))throw new Error('read behavior/hash oracle mismatch');
|
|
52
|
+
if(iteration>=20)samples.push({batch,iteration:iteration-20,tool:name,roundtrip_ms:elapsed});
|
|
53
|
+
}
|
|
54
|
+
}finally{await client.close();}
|
|
55
|
+
}
|
|
56
|
+
const quant=values=>{const v=[...values].sort((a,b)=>a-b),q=p=>v[Math.ceil(v.length*p)-1];return{n:v.length,min:v[0],p50:q(.5),p90:q(.9),p95:q(.95),p99:q(.99),max:v.at(-1)}};
|
|
57
|
+
summaries[label]={startup_ms:startup,script_sha256:sha(await readFile(bridgePath)),catalog_count:catalog.length,rows:Object.fromEntries(corpus.map(({name})=>[name,quant(samples.filter(s=>s.tool===name).map(s=>s.roundtrip_ms))])),aggregate:quant(samples.map(s=>s.roundtrip_ms))};
|
|
58
|
+
await writeFile(path.join(root,'raw.json'),JSON.stringify(samples),{flag:'wx'});
|
|
59
|
+
}finally{
|
|
60
|
+
await rm(path.join(state,'grant.json'),{force:true});
|
|
61
|
+
if(child.connected)child.send('stop');
|
|
62
|
+
const code=await Promise.race([exited,delay(5000).then(()=>null)]);if(code===null){child.kill();throw new Error('owned fixture bridge did not close through normal shutdown');}
|
|
63
|
+
await writeFile(path.join(root,'stdout.log'),stdout,{flag:'wx'});await writeFile(path.join(root,'stderr.log'),stderr,{flag:'wx'});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const result={schema:'deadbyte.r58.isolated-bridge-performance.v1',status:'MEASURED_NOT_FULL_PERFORMANCE_ACCEPTANCE',core,corpus,workload_sha256:sha(JSON.stringify(corpus)),test_read_grant:extended,grant_removed_after_target:true,summaries,p95_reduction_pct:100*(1-summaries.candidate.aggregate.p95/summaries.baseline.aggregate.p95),limitations:['bounded read-only categories only','not production machine ping/public transport','no mutation/build/test/durable workload','sequential target order; no statistical inference','no production activation']};
|
|
67
|
+
await writeFile(path.join(run,'summary.json'),JSON.stringify(result,null,2),{flag:'wx'});console.log(JSON.stringify(result,null,2));
|
package/scripts/deploy-r48.mjs
CHANGED
|
@@ -4,7 +4,7 @@ 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 {
|
|
7
|
+
import { runSlotUpdateCli } from '../src/runtime-update.mjs';
|
|
8
8
|
import { parseActivePointer } from '../src/release-slot.mjs';
|
|
9
9
|
|
|
10
10
|
const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
@@ -58,8 +58,7 @@ async function waitForActivation({handoffPath,expectedVersion,expectedManifest,t
|
|
|
58
58
|
|
|
59
59
|
const manifest=await sha(path.join(root,'MANIFEST.SHA256'));
|
|
60
60
|
const pointer=JSON.parse(await readFile(path.join(state,'active-release.json'),'utf8'));
|
|
61
|
-
const
|
|
62
|
-
const bridgeRoot=path.resolve(cfg.Bridge.WorkingDirectory);
|
|
61
|
+
const bridgeRoot=path.join(root,'bridge');
|
|
63
62
|
const bridgeScript=path.join(bridgeRoot,'src','bridge.mjs');
|
|
64
63
|
const pkg=JSON.parse(await readFile(path.join(root,'package.json'),'utf8'));
|
|
65
64
|
const expectedVersion=pkg.version;
|
|
@@ -0,0 +1,33 @@
|
|
|
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.35 / R58 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.35 / R58 gate failed at $Name with exit code $LASTEXITCODE" }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Invoke-NodeTest 'r58-package-boundary' @('test/package-boundary.test.mjs','test/r58-bundled-bridge.test.mjs')
|
|
18
|
+
Invoke-NodeTest 'r58-process-policy' @('test/process-policy-refresh.test.mjs','test/process-release-gate.test.mjs')
|
|
19
|
+
Invoke-GateStep 'r58-focused-contracts' @('run','r58:focused:test')
|
|
20
|
+
|
|
21
|
+
Write-Host '==== recorded-prepublish-evidence ===='
|
|
22
|
+
$matrix=Get-Content -LiteralPath (Join-Path (Split-Path $PSScriptRoot -Parent) 'TEST-MATRIX.json') -Raw | ConvertFrom-Json
|
|
23
|
+
if($matrix.observed_pre_release_evidence.performance.status -ne 'PASS_BOUNDED_PREPUBLISH'){ throw 'R58 performance evidence is not PASS_BOUNDED_PREPUBLISH' }
|
|
24
|
+
if($matrix.observed_pre_release_evidence.cross_plane.status -ne 'PASS'){ throw 'R58 cross-plane evidence is not PASS' }
|
|
25
|
+
if($matrix.observed_pre_release_evidence.public_surface.status -ne 'PASS'){ throw 'R58 public surface evidence is not PASS' }
|
|
26
|
+
if($matrix.observed_pre_release_evidence.full_regression.status -ne 'PASS'){ throw 'R58 fresh full regression evidence is not PASS' }
|
|
27
|
+
|
|
28
|
+
Invoke-GateStep 'manifest-write' @('run','manifest:write')
|
|
29
|
+
Invoke-GateStep 'manifest-verify' @('run','manifest:verify')
|
|
30
|
+
Invoke-GateStep 'doctor' @('run','doctor')
|
|
31
|
+
& node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence-r58.mjs')
|
|
32
|
+
if ($LASTEXITCODE -ne 0) { throw "R58 evidence writer failed with exit code $LASTEXITCODE" }
|
|
33
|
+
Write-Host '==== DEADBYTE 0.15.35 / R58 WINDOWS GATE: PASS ===='
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {spawn,spawnSync} from 'node:child_process';
|
|
2
|
+
import {writeFile} from 'node:fs/promises';
|
|
3
|
+
import {performance} from 'node:perf_hooks';
|
|
4
|
+
import {createHash} from 'node:crypto';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import {windowsPowerShellEnvironment} from '../src/runtime-update.mjs';
|
|
7
|
+
|
|
8
|
+
// Diagnostic only. Queries only a child created and held by this process.
|
|
9
|
+
// Not an ownership authority, cleanup path, or public PID control tool.
|
|
10
|
+
const out=path.resolve(process.argv[2]||'');
|
|
11
|
+
const base=path.resolve('D:/Projects/deadbyte-mcp/testing/0.15.35');
|
|
12
|
+
const rel=path.relative(base,out);
|
|
13
|
+
if(!rel||rel.startsWith('..')||path.isAbsolute(rel))throw new Error('D: R58 evidence destination required');
|
|
14
|
+
const ps=path.join(process.env.SystemRoot,'System32/WindowsPowerShell/v1.0/powershell.exe');
|
|
15
|
+
const child=spawn(process.execPath,['-e','setTimeout(()=>{},30000)'],{stdio:'ignore',windowsHide:true});
|
|
16
|
+
const closed=new Promise(resolve=>child.once('close',resolve));
|
|
17
|
+
const samples=[];
|
|
18
|
+
try{
|
|
19
|
+
if(!Number.isInteger(child.pid)||child.pid<1)throw new Error('diagnostic child failed');
|
|
20
|
+
for(let i=0;i<3;i++){
|
|
21
|
+
const query=`$p=Get-CimInstance Win32_Process -Filter 'ProcessId=${child.pid}'; if ($null -eq $p) {exit 2}; [pscustomobject]@{pid=$p.ProcessId; parent_pid=$p.ParentProcessId; creation_utc=$p.CreationDate.ToUniversalTime().ToString('o'); executable_path=$p.ExecutablePath; command_line=$p.CommandLine} | ConvertTo-Json -Compress`;
|
|
22
|
+
const t=performance.now();const result=spawnSync(ps,['-NoLogo','-NoProfile','-Command',query],{encoding:'utf8',windowsHide:true,env:windowsPowerShellEnvironment(process.env),timeout:15000});
|
|
23
|
+
if(result.error||result.status!==0)throw new Error('narrow process diagnostic failed');
|
|
24
|
+
const info=JSON.parse(result.stdout);
|
|
25
|
+
if(info.pid!==child.pid||info.parent_pid!==process.pid||path.resolve(info.executable_path).toLowerCase()!==path.resolve(process.execPath).toLowerCase())throw new Error('owned diagnostic process identity mismatch');
|
|
26
|
+
samples.push({pid:info.pid,parent_pid:info.parent_pid,creation_utc:info.creation_utc,executable_path:info.executable_path,command_line_sha256:createHash('sha256').update(info.command_line).digest('hex'),query_ms:performance.now()-t});
|
|
27
|
+
}
|
|
28
|
+
if(new Set(samples.map(s=>s.creation_utc)).size!==1)throw new Error('creation identity changed');
|
|
29
|
+
await writeFile(out,JSON.stringify({schema:'deadbyte.r58.owner-probe.v1',observed_at:new Date().toISOString(),status:'DIAGNOSTIC_ONLY',samples,limitations:['not production ownership verification','not PID-reuse recovery acceptance','CIM spawn latency unsuitable for frequent guardian polling without measured redesign']},null,2),{flag:'wx'});
|
|
30
|
+
console.log(JSON.stringify({status:'DIAGNOSTIC_ONLY',samples:samples.length,query_ms:samples.map(s=>s.query_ms)}));
|
|
31
|
+
} finally {if(child.exitCode===null)child.kill();await closed;}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { performance } from 'node:perf_hooks';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { Client } from '@modelcontextprotocol/client';
|
|
6
|
+
import { StdioClientTransport, getDefaultEnvironment } from '@modelcontextprotocol/client/stdio';
|
|
7
|
+
import { generateTrustKeypair } from '../src/trust.mjs';
|
|
8
|
+
|
|
9
|
+
// Stage-one stdio measurements only. Never substitutes for bridge/public,
|
|
10
|
+
// machine-bound, mutating or durable-job release acceptance measurements.
|
|
11
|
+
const [targetArg,runArg]=process.argv.slice(2);
|
|
12
|
+
if(!targetArg||!runArg) throw new Error('usage: performance-r58.mjs <package-root> <new-D-testing-run-root>');
|
|
13
|
+
const target=path.resolve(targetArg), run=path.resolve(runArg);
|
|
14
|
+
const allowed=path.resolve('D:/Projects/deadbyte-mcp/testing/0.15.35');
|
|
15
|
+
const relative=path.relative(allowed,run);
|
|
16
|
+
if(!relative||relative.startsWith('..')||path.isAbsolute(relative)) throw new Error('benchmark run must be inside R58 D: testing root');
|
|
17
|
+
await mkdir(run); // Exclusive run identity; never rerun into existing evidence.
|
|
18
|
+
const state=path.join(run,'state'),workspace=path.join(run,'workspace'),demo=path.join(workspace,'demo');
|
|
19
|
+
await mkdir(demo,{recursive:true});await mkdir(state,{recursive:true});
|
|
20
|
+
const fixture='alpha benchmark fixture\n'.repeat(100);
|
|
21
|
+
await writeFile(path.join(demo,'input.txt'),fixture,{flag:'wx'});
|
|
22
|
+
const keys=await generateTrustKeypair({privateKeyPath:path.join(run,'private.pem'),publicKeyPath:path.join(run,'public.pem')});
|
|
23
|
+
const policyPath=path.join(run,'coding-policy.json');
|
|
24
|
+
await writeFile(policyPath,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:path.join(state,'coding-grant.json'),evidence_dir:path.join(state,'evidence'),roots:{bench:{path:demo,read:true,write:false,exec:false,deny_paths:[]}},commands:{},max_read_bytes:65536,max_write_bytes:65536}),{flag:'wx'});
|
|
25
|
+
const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
26
|
+
const sourceHashes={};
|
|
27
|
+
for(const file of ['package.json','MANIFEST.SHA256','src/mcp-server.mjs','src/coding-plane.mjs','src/compact-gateway-mcp-tools.mjs']) sourceHashes[file]=sha(await readFile(path.join(target,file)));
|
|
28
|
+
const workload=[
|
|
29
|
+
{name:'workspace_open',arguments:{workspace_id:'demo'}},
|
|
30
|
+
{name:'file_read',arguments:{workspace_id:'demo',path:'input.txt'}},
|
|
31
|
+
{name:'coding_session_status',arguments:{}}
|
|
32
|
+
];
|
|
33
|
+
const samples=[],cold=[];
|
|
34
|
+
let catalog;
|
|
35
|
+
const start=new Date().toISOString();
|
|
36
|
+
for(let batch=0;batch<3;batch++){
|
|
37
|
+
const client=new Client({name:'deadbyte-r58-performance',version:'1.0.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
38
|
+
const transport=new StdioClientTransport({command:process.execPath,args:[path.join(target,'src/mcp-server.mjs')],cwd:target,stderr:'pipe',env:{...getDefaultEnvironment(),DEADBYTE_STATE_ROOT:state,DEADBYTE_WORKSPACE_ROOT:workspace,DEADBYTE_SIGNING_KEY:keys.privateKeyPath,DEADBYTE_VERIFY_KEY:keys.publicKeyPath,DEADBYTE_PRIVILEGED_POLICY:'',DEADBYTE_CODING_RUNTIME:'1',DEADBYTE_CODING_POLICY:policyPath,DEADBYTE_MACHINE_RUNTIME:'0',DEADBYTE_PROCESS_RUNTIME:'0',DEADBYTE_AUTONOMOUS_RUNTIME:'0',DEADBYTE_DESKTOP_RUNTIME:'0',DEADBYTE_CAPABILITY_PROFILE:'full'}});
|
|
39
|
+
const errors=[];transport.stderr?.on('data',b=>errors.push(b.toString()));
|
|
40
|
+
try{
|
|
41
|
+
const connectStart=performance.now();await client.connect(transport);cold.push({batch,connect_ms:performance.now()-connectStart});
|
|
42
|
+
const tools=(await client.listTools()).tools;
|
|
43
|
+
if(!catalog){catalog=tools;await writeFile(path.join(run,'catalog.json'),JSON.stringify(tools,null,2),{flag:'wx'});}
|
|
44
|
+
for(let i=0;i<220;i++)for(const request of workload){
|
|
45
|
+
const t=performance.now();const result=await client.callTool(request);const elapsed=performance.now()-t;
|
|
46
|
+
if(result.isError) throw new Error(`benchmark ${request.name} error: ${JSON.stringify(result.structuredContent??result.content)}`);
|
|
47
|
+
if(request.name==='file_read'&&result.structuredContent?.text!==fixture)throw new Error('file read behavioral oracle failed');
|
|
48
|
+
if(i>=20)samples.push({batch,iteration:i-20,tool:request.name,total_stdio_roundtrip_ms:elapsed});
|
|
49
|
+
}
|
|
50
|
+
}finally{await client.close();await writeFile(path.join(run,`stderr-${batch}.log`),errors.join(''),{flag:'wx'});}
|
|
51
|
+
}
|
|
52
|
+
function summary(values){const v=[...values].sort((a,b)=>a-b);const q=p=>v[Math.ceil(p*v.length)-1];return {n:v.length,min:v[0],p50:q(.5),p90:q(.9),p95:q(.95),p99:q(.99),max:v.at(-1)};}
|
|
53
|
+
const rows=Object.fromEntries(workload.map(w=>[w.name,summary(samples.filter(s=>s.tool===w.name).map(s=>s.total_stdio_roundtrip_ms))]));
|
|
54
|
+
const result={schema:'deadbyte.r58.performance-stage1.v1',status:'MEASURED_NOT_RELEASE_ACCEPTANCE',start,end:new Date().toISOString(),target,node:process.version,sourceHashes,workload_sha256:sha(JSON.stringify(workload)),fixture_sha256:sha(fixture),cold_start:cold,rows,aggregate:summary(samples.map(s=>s.total_stdio_roundtrip_ms)),failures:0,timeouts:0,scope:'stdio client through MCP dispatch/core/response; coding disarmed; no live bridge/cloud or active machine binding',missing:['capability_manifest (compact profile)','machine_status','machine_ping','mutating actions','durable jobs','bridge/cloud','latency decomposition','contention','candidate comparison']};
|
|
55
|
+
await writeFile(path.join(run,'raw.json'),JSON.stringify(samples),{flag:'wx'});
|
|
56
|
+
await writeFile(path.join(run,'summary.json'),JSON.stringify(result,null,2),{flag:'wx'});
|
|
57
|
+
console.log(JSON.stringify(result,null,2));
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { readFile, mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
3
|
+
import { performance } from 'node:perf_hooks';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
|
|
6
|
+
import { verifyMachinePingPublic } from '../src/machine-identity.mjs';
|
|
7
|
+
|
|
8
|
+
const run=path.resolve(process.argv[2]||'');
|
|
9
|
+
const mode=process.argv[3]||'public';
|
|
10
|
+
if(!['public','local'].includes(mode))throw new Error('transport must be public or local');
|
|
11
|
+
const base=path.resolve('D:/Projects/deadbyte-mcp/testing/0.15.35');
|
|
12
|
+
const rel=path.relative(base,run);
|
|
13
|
+
if(!rel||rel.startsWith('..')||path.isAbsolute(rel))throw new Error('new R58 testing run root required');
|
|
14
|
+
await mkdir(run);
|
|
15
|
+
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
16
|
+
const prod='C:/Users/DEADBYTE/.deadbyte-mcp';
|
|
17
|
+
const before=await readFile(path.join(prod,'active-release.json'));
|
|
18
|
+
const pointer=JSON.parse(before);
|
|
19
|
+
if(pointer.release_id!=='v0.15.34-2199bb59f0e0fc20'||pointer.manifest_sha256!=='2199bb59f0e0fc205d470d11f990d3ce3df444be5eba2a7d8dbc60d5f5b790bb')throw new Error('production baseline changed');
|
|
20
|
+
const config=await readFile(pointer.config_path,'utf8');
|
|
21
|
+
const urlPath=config.match(/McpUrlFile\s*=\s*'([^']+)'/)?.[1];
|
|
22
|
+
const urlHash=config.match(/McpUrlFileSha256\s*=\s*'([0-9a-f]{64})'/)?.[1];
|
|
23
|
+
if(!urlPath||!urlHash)throw new Error('pinned public endpoint metadata missing');
|
|
24
|
+
const bytes=await readFile(urlPath);
|
|
25
|
+
if(sha(bytes)!==urlHash)throw new Error('public endpoint metadata hash mismatch');
|
|
26
|
+
const endpoint=new URL(bytes.toString().trim());
|
|
27
|
+
if(endpoint.protocol!=='https:')throw new Error('HTTPS endpoint required');
|
|
28
|
+
let transportEndpoint=endpoint;
|
|
29
|
+
if(mode==='local'){
|
|
30
|
+
const readyText=config.match(/LocalReadyUri\s*=\s*'([^']+)'/)?.[1];
|
|
31
|
+
if(!readyText)throw new Error('pinned loopback readiness address missing');
|
|
32
|
+
const ready=new URL(readyText);
|
|
33
|
+
if(ready.protocol!=='http:'||ready.hostname!=='127.0.0.1')throw new Error('local benchmark must use configured loopback only');
|
|
34
|
+
transportEndpoint=new URL(endpoint.pathname+endpoint.search,ready.origin);
|
|
35
|
+
}
|
|
36
|
+
const client=new Client({name:'deadbyte-r58-public-readonly-baseline',version:'1.0.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
37
|
+
const traceFetch=process.argv[4]==='--trace-fetch';
|
|
38
|
+
const httpEvents=[];
|
|
39
|
+
const measuredFetch=async(input,init)=>{
|
|
40
|
+
let request;try{request=JSON.parse(init?.body||'null');}catch{}
|
|
41
|
+
const event={method:request?.method??init?.method??'GET',tool:request?.params?.name??null,started_ms:performance.now()};
|
|
42
|
+
httpEvents.push(event);
|
|
43
|
+
const response=await fetch(input,init);
|
|
44
|
+
event.headers_ms=performance.now();event.fetch_to_headers_ms=event.headers_ms-event.started_ms;
|
|
45
|
+
event.http_status=response.status;event.content_type=response.headers.get('content-type');
|
|
46
|
+
const json=response.json.bind(response);
|
|
47
|
+
response.json=async()=>{const t=performance.now();try{return await json();}finally{event.json_body_ms=performance.now()-t;event.body_finished_ms=performance.now();}};
|
|
48
|
+
return response;
|
|
49
|
+
};
|
|
50
|
+
const transport=new StreamableHTTPClientTransport(transportEndpoint,traceFetch?{fetch:measuredFetch}:undefined);
|
|
51
|
+
const samples=[];const start=new Date().toISOString();
|
|
52
|
+
function body(result){if(result.isError)throw new Error('public read-only call failed');const s=result.structuredContent;if(!s||typeof s!=='object')throw new Error('structured response missing');return s.result??s;}
|
|
53
|
+
try{
|
|
54
|
+
await client.connect(transport);
|
|
55
|
+
const catalog=(await client.listTools()).tools;
|
|
56
|
+
await writeFile(path.join(run,'catalog.json'),JSON.stringify(catalog,null,2),{flag:'wx'});
|
|
57
|
+
const status=body(await client.callTool({name:'machine_observe',arguments:{op:'machine_status'}}));
|
|
58
|
+
if(status.release_id!==pointer.release_id||status.release_manifest_sha256!==pointer.manifest_sha256||status.generation_manifest_sha256!==pointer.generation_manifest_sha256)throw new Error('public machine baseline binding mismatch');
|
|
59
|
+
for(let i=0;i<100;i++){
|
|
60
|
+
const nonce=randomBytes(24).toString('hex');const t=performance.now();const eventOffset=httpEvents.length;
|
|
61
|
+
const ping=body(await client.callTool({name:'machine_observe',arguments:{op:'machine_ping',nonce}}));
|
|
62
|
+
const elapsed=performance.now()-t;
|
|
63
|
+
if(ping.nonce!==nonce||ping.release_id!==pointer.release_id||ping.generation_manifest_sha256!==pointer.generation_manifest_sha256||!await verifyMachinePingPublic({ping,publicKeySpkiBase64:status.public_key_spki_base64}))throw new Error('public signed ping independent verification failed');
|
|
64
|
+
samples.push({tool:'machine_ping',iteration:i,public_roundtrip_ms:elapsed,...(traceFetch?{http_requests:httpEvents.slice(eventOffset).map(e=>({...e,after_body_to_client_ms:e.body_finished_ms===undefined?null:t+elapsed-e.body_finished_ms}))}:{})});
|
|
65
|
+
}
|
|
66
|
+
if(!before.equals(await readFile(path.join(prod,'active-release.json'))))throw new Error('production pointer changed during snapshot');
|
|
67
|
+
const v=samples.map(x=>x.public_roundtrip_ms).sort((a,b)=>a-b),q=p=>v[Math.ceil(v.length*p)-1];
|
|
68
|
+
const result={schema:'deadbyte.r58.public-baseline.v1',status:'OBSERVED_BASELINE_NOT_CANDIDATE_ACCEPTANCE',transport_scope:mode==='local'?'LOOPBACK_BRIDGE':'HTTPS_PUBLIC',start,end:new Date().toISOString(),pointer,endpoint_metadata_sha256:urlHash,catalog_count:catalog.length,catalog_sha256:sha(JSON.stringify(catalog)),signed_ping_count:samples.length,latency:{n:v.length,min:v[0],p50:q(.5),p90:q(.9),p95:q(.95),p99:q(.99),max:v.at(-1)},limitations:['100 samples only','transport difference is not exact causal layer decomposition','no candidate comparison','read-only observation not authority lifecycle acceptance']};
|
|
69
|
+
await writeFile(path.join(run,'raw.json'),JSON.stringify(samples),{flag:'wx'});
|
|
70
|
+
await writeFile(path.join(run,'summary.json'),JSON.stringify(result,null,2),{flag:'wx'});
|
|
71
|
+
console.log(JSON.stringify({status:result.status,catalog_count:catalog.length,signed_ping_count:samples.length,latency:result.latency}));
|
|
72
|
+
} finally {await client.close();}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {createHash,randomBytes} from 'node:crypto';
|
|
2
|
+
import {createServer} from 'node:net';
|
|
3
|
+
import {mkdir,readFile,writeFile} from 'node:fs/promises';
|
|
4
|
+
import {spawn} from 'node:child_process';
|
|
5
|
+
import {setTimeout as delay} from 'node:timers/promises';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import {Client,StreamableHTTPClientTransport} from '@modelcontextprotocol/client';
|
|
8
|
+
import {generateTrustKeypair} from '../src/trust.mjs';
|
|
9
|
+
|
|
10
|
+
const [generationArg,baselineArg,runArg]=process.argv.slice(2);
|
|
11
|
+
if(!generationArg||!baselineArg||!runArg) throw new Error('usage: public-surface-r58.mjs <generation-root> <baseline-catalog-json> <new-run-root>');
|
|
12
|
+
const root=path.resolve(new URL('..',import.meta.url).pathname.replace(/^\/(?:[A-Za-z]:)/,m=>m.slice(1)));
|
|
13
|
+
const gen=path.resolve(generationArg),baselinePath=path.resolve(baselineArg),run=path.resolve(runArg);
|
|
14
|
+
const allowed=path.resolve('D:/Projects/deadbyte-mcp/testing/0.15.35'),rel=path.relative(allowed,run);
|
|
15
|
+
if(!rel||rel.startsWith('..')||path.isAbsolute(rel)) throw new Error('run root must be inside R58 testing root');
|
|
16
|
+
await mkdir(run);
|
|
17
|
+
const state=path.join(run,'state');await mkdir(state);
|
|
18
|
+
const keys=await generateTrustKeypair({privateKeyPath:path.join(run,'private.pem'),publicKeyPath:path.join(run,'public.pem')});
|
|
19
|
+
const semanticPath=path.join(gen,'semantic-lsp-config.json');
|
|
20
|
+
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
21
|
+
const semanticSha=sha(await readFile(semanticPath));
|
|
22
|
+
const baseline=JSON.parse(await readFile(baselinePath,'utf8'));
|
|
23
|
+
const baseSurface=baseline.map(x=>({name:x.name,inputSchema:x.inputSchema,outputSchema:x.outputSchema})).sort((a,b)=>a.name.localeCompare(b.name));
|
|
24
|
+
const reservation=createServer();await new Promise(resolve=>reservation.listen(0,'127.0.0.1',resolve));const port=reservation.address().port;await new Promise(resolve=>reservation.close(resolve));
|
|
25
|
+
const token=randomBytes(32).toString('hex');
|
|
26
|
+
const env={...process.env};for(const key of Object.keys(env))if(key.startsWith('DEADBYTE_'))delete env[key];
|
|
27
|
+
Object.assign(env,{
|
|
28
|
+
DEADBYTE_CORE_ROOT:root,
|
|
29
|
+
DEADBYTE_STATE_ROOT:state,
|
|
30
|
+
DEADBYTE_WORKSPACE_ROOT:path.join(root,'workspaces'),
|
|
31
|
+
DEADBYTE_BRIDGE_PORT:String(port),
|
|
32
|
+
DEADBYTE_BRIDGE_PATH_TOKEN:token,
|
|
33
|
+
DEADBYTE_SIGNING_KEY:keys.privateKeyPath,
|
|
34
|
+
DEADBYTE_VERIFY_KEY:keys.publicKeyPath,
|
|
35
|
+
DEADBYTE_CAPABILITY_PROFILE:'compact',
|
|
36
|
+
DEADBYTE_AUDIT_RUNTIME:'0',
|
|
37
|
+
DEADBYTE_MACHINE_RUNTIME:'1',
|
|
38
|
+
DEADBYTE_AGENT_RUNTIME:'1',
|
|
39
|
+
DEADBYTE_PROCESS_RUNTIME:'1',
|
|
40
|
+
DEADBYTE_PROCESS_POLICY:path.join(gen,'process-policy.json'),
|
|
41
|
+
DEADBYTE_CODING_RUNTIME:'1',
|
|
42
|
+
DEADBYTE_CODING_POLICY:path.join(gen,'coding-policy.json'),
|
|
43
|
+
DEADBYTE_MACHINE_FS_RUNTIME:'1',
|
|
44
|
+
DEADBYTE_OBSERVATION_RUNTIME:'1',
|
|
45
|
+
DEADBYTE_DESKTOP_RUNTIME:'1',
|
|
46
|
+
DEADBYTE_DESKTOP_POLICY:path.join(gen,'desktop-policy.json'),
|
|
47
|
+
DEADBYTE_SEMANTIC_LSP_CONFIG:semanticPath,
|
|
48
|
+
DEADBYTE_SEMANTIC_LSP_CONFIG_SHA256:semanticSha,
|
|
49
|
+
DEADBYTE_AUTONOMOUS_RUNTIME:'1',
|
|
50
|
+
DEADBYTE_AUTONOMOUS_POLICY:path.join(gen,'autonomous-policy.json'),
|
|
51
|
+
DEADBYTE_AUTONOMOUS_SUPERVISOR_MODE:'external',
|
|
52
|
+
DEADBYTE_PRIVILEGED_POLICY:path.join(gen,'host-policy.json')
|
|
53
|
+
});
|
|
54
|
+
const bridge=path.join(root,'bridge','src','bridge.mjs');
|
|
55
|
+
const child=spawn(process.execPath,[bridge],{cwd:path.join(root,'bridge'),env,windowsHide:true,stdio:['ignore','pipe','pipe']});
|
|
56
|
+
let stdout='',stderr='';child.stdout.on('data',b=>stdout+=b);child.stderr.on('data',b=>stderr+=b);
|
|
57
|
+
const exited=new Promise(resolve=>child.once('exit',code=>resolve(code)));
|
|
58
|
+
try{
|
|
59
|
+
const deadline=Date.now()+20000;while(!stdout.includes('BRIDGE_READY')&&child.exitCode===null&&Date.now()<deadline)await delay(20);
|
|
60
|
+
if(!stdout.includes('BRIDGE_READY')) throw new Error('candidate bridge failed startup: '+stderr);
|
|
61
|
+
const client=new Client({name:'deadbyte-r58-public-surface',version:'1.0.0'},{versionNegotiation:{mode:{pin:'2026-07-28'}}});
|
|
62
|
+
try{
|
|
63
|
+
await client.connect(new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${port}/mcp/${token}`)));
|
|
64
|
+
const listed=(await client.listTools()).tools;
|
|
65
|
+
const candidate=listed.map(x=>({name:x.name,inputSchema:x.inputSchema,outputSchema:x.outputSchema})).sort((a,b)=>a.name.localeCompare(b.name));
|
|
66
|
+
const baseNames=baseSurface.map(x=>x.name),candidateNames=candidate.map(x=>x.name);
|
|
67
|
+
if(JSON.stringify(candidateNames)!==JSON.stringify(baseNames)) throw new Error(`public compact name drift baseline=${baseNames.length} candidate=${candidateNames.length}`);
|
|
68
|
+
const drift=[];
|
|
69
|
+
for(let i=0;i<baseSurface.length;i++){
|
|
70
|
+
if(JSON.stringify(baseSurface[i].inputSchema)!==JSON.stringify(candidate[i].inputSchema)||JSON.stringify(baseSurface[i].outputSchema)!==JSON.stringify(candidate[i].outputSchema)) drift.push(baseSurface[i].name);
|
|
71
|
+
}
|
|
72
|
+
if(drift.length) throw new Error('public schema drift: '+drift.join(','));
|
|
73
|
+
const result={schema:'deadbyte.r58.public-surface-compat.v1',status:'PASS',tool_count:candidate.length,names_sha256:sha(Buffer.from(JSON.stringify(candidateNames))),schema_sha256:sha(Buffer.from(JSON.stringify(candidate))),baseline_catalog_sha256:sha(await readFile(baselinePath)),candidate_bridge_sha256:sha(await readFile(bridge)),drift:[]};
|
|
74
|
+
await writeFile(path.join(run,'candidate-catalog.json'),JSON.stringify(listed,null,2));
|
|
75
|
+
await writeFile(path.join(run,'summary.json'),JSON.stringify(result,null,2));
|
|
76
|
+
console.log(JSON.stringify(result,null,2));
|
|
77
|
+
}finally{await client.close().catch(()=>{});}
|
|
78
|
+
}finally{
|
|
79
|
+
child.kill('SIGTERM');
|
|
80
|
+
await Promise.race([exited,delay(5000)]);
|
|
81
|
+
if(child.exitCode===null) child.kill();
|
|
82
|
+
await writeFile(path.join(run,'bridge.stdout.log'),stdout);
|
|
83
|
+
await writeFile(path.join(run,'bridge.stderr.log'),stderr);
|
|
84
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
$ErrorActionPreference='Stop'
|
|
2
|
+
Set-StrictMode -Version 3.0
|
|
3
|
+
$root=Split-Path $PSScriptRoot -Parent
|
|
4
|
+
Set-Location -LiteralPath $root
|
|
5
|
+
& node.exe --test --test-concurrency=1 test/r58-concurrent-recovery.test.mjs test/r58-controller-core-observation.test.mjs test/r58-controller-state-coherence.test.mjs test/r58-guardian-channel.test.mjs test/r58-owner-identity.test.mjs test/r58-session-lock.test.mjs test/r58-stale-owner.test.mjs test/remote-session-cli.test.mjs test/coding-runtime.test.mjs test/durable-job-r44.test.mjs test/external-job-provider-r44.test.mjs test/autonomous-local-supervisor.test.mjs test/autonomous-supervisor-integration.test.mjs test/runtime-self-update.test.mjs test/release-slot.test.mjs test/release-activation-gate.test.mjs test/named-tunnel-host.test.mjs test/r56-rollback-launcher-restore.test.mjs test/r57-core-startup-race.test.mjs
|
|
6
|
+
exit $LASTEXITCODE
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
$ErrorActionPreference='Stop'
|
|
2
|
+
Set-StrictMode -Version 3.0
|
|
3
|
+
$root=Split-Path $PSScriptRoot -Parent
|
|
4
|
+
Set-Location -LiteralPath $root
|
|
5
|
+
& node.exe --test --test-concurrency=1 test/r58-*.test.mjs test/release-generation.test.mjs test/runtime-self-update.test.mjs test/r57-core-startup-race.test.mjs test/r56-rollback-launcher-restore.test.mjs test/r51-runtime-coherence.test.mjs test/production-docs.test.mjs
|
|
6
|
+
exit $LASTEXITCODE
|