deadbyte-mcp 0.15.34 → 0.15.36

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 (101) hide show
  1. package/MANIFEST.SHA256 +100 -38
  2. package/PROVENANCE.json +87 -41
  3. package/README.txt +72 -14
  4. package/RELEASE.json +187 -150
  5. package/SBOM.cdx.json +25 -3
  6. package/TEST-MATRIX.json +258 -151
  7. package/bridge/package.json +13 -0
  8. package/bridge/src/bridge-health-r59.mjs +52 -0
  9. package/bridge/src/bridge.mjs +487 -0
  10. package/bridge/src/node-http-adapter.mjs +56 -0
  11. package/bridge/src/public-tool-definitions.mjs +14 -0
  12. package/bridge/src/r40-governor.mjs +206 -0
  13. package/controller/deadbyte-controller.ps1 +152 -18
  14. package/controller/deadbyte-process-policy.json +4 -4
  15. package/docs/R59-TASK-CONTRACT.md +26 -0
  16. package/package.json +7 -3
  17. package/proof/r59-full-regression-current.json +13 -0
  18. package/proof/r59-full-regression-current.stderr.log +0 -0
  19. package/proof/r59-full-regression-current.stdout.log +1268 -0
  20. package/scripts/bridge-benchmark-r58.mjs +67 -0
  21. package/scripts/deploy-r48.mjs +2 -3
  22. package/scripts/gate-windows-r58.ps1 +33 -0
  23. package/scripts/gate-windows-r59-prepublish.ps1 +41 -0
  24. package/scripts/owner-probe-r58.mjs +31 -0
  25. package/scripts/performance-r58.mjs +57 -0
  26. package/scripts/public-baseline-r58.mjs +72 -0
  27. package/scripts/public-surface-r58.mjs +84 -0
  28. package/scripts/r58-cross-plane.ps1 +6 -0
  29. package/scripts/r58-focused.ps1 +6 -0
  30. package/scripts/r59-full-regression-capture.mjs +35 -0
  31. package/scripts/windows-gate-evidence-r58.mjs +93 -0
  32. package/src/capability-resolver.mjs +25 -7
  33. package/src/capability-snapshot.mjs +52 -0
  34. package/src/compact-gateway-mcp-tools.mjs +10 -11
  35. package/src/deadbyte-cli.mjs +40 -12
  36. package/src/doctor-foreground-r58.mjs +44 -0
  37. package/src/doctor-installation-r58.mjs +63 -0
  38. package/src/doctor-r45.mjs +21 -4
  39. package/src/doctor-runtime-r58.mjs +82 -0
  40. package/src/doctor-transactions-r58.mjs +40 -0
  41. package/src/foreground-process-identity.mjs +27 -0
  42. package/src/foreground-session-lock.mjs +20 -0
  43. package/src/foreground-session-lock.ps1 +15 -0
  44. package/src/mcp-server.mjs +179 -118
  45. package/src/r40-compact-disarmed-probe.mjs +1 -1
  46. package/src/r44-compact-disarmed-probe.mjs +1 -1
  47. package/src/r45-compact-disarmed-probe.mjs +1 -1
  48. package/src/release-generation.mjs +1 -0
  49. package/src/release-slot.mjs +2 -1
  50. package/src/remote-mcp-r40-parity-client.mjs +1 -1
  51. package/src/remote-mcp-r44-parity-client.mjs +1 -1
  52. package/src/remote-mcp-r45-parity-client.mjs +1 -1
  53. package/src/remote-mcp-smoke-client.mjs +1 -1
  54. package/src/remote-session-guardian.mjs +8 -1
  55. package/src/runtime-plane-registry.mjs +74 -0
  56. package/src/runtime-update.mjs +85 -2
  57. package/src/version.mjs +1 -1
  58. package/test/bridge-runtime-r59.test.mjs +60 -0
  59. package/test/capability-resolver.test.mjs +16 -0
  60. package/test/capability-snapshot-r59.test.mjs +39 -0
  61. package/test/compact-gateway-r36.test.mjs +22 -2
  62. package/test/compact-max-catalog-r44.test.mjs +1 -1
  63. package/test/compact-max-catalog-r45.test.mjs +1 -1
  64. package/test/contained.test.mjs +2 -1
  65. package/test/controller-policy-preflight-r59.test.mjs +39 -0
  66. package/test/controller-r211.test.mjs +4 -1
  67. package/test/controller.test.mjs +2 -1
  68. package/test/fixtures/r59-compact-surface-v0.15.35.json +222 -0
  69. package/test/helpers/r58-doctor-fixture.mjs +26 -0
  70. package/test/observation-integration.test.mjs +2 -3
  71. package/test/optional-plane-degraded-r59.test.mjs +44 -0
  72. package/test/r49-windows-gate.test.mjs +2 -2
  73. package/test/r57-release-contract.test.mjs +5 -3
  74. package/test/r58-bridge-dependency-binding.test.mjs +62 -0
  75. package/test/r58-bundled-bridge.test.mjs +24 -0
  76. package/test/r58-cleanup-retention.test.mjs +45 -0
  77. package/test/r58-completed-update-receipt.test.mjs +76 -0
  78. package/test/r58-concurrent-recovery.test.mjs +54 -0
  79. package/test/r58-controller-core-observation.test.mjs +36 -0
  80. package/test/r58-controller-json.test.mjs +48 -0
  81. package/test/r58-controller-live-local.test.mjs +98 -0
  82. package/test/r58-controller-readonly.test.mjs +23 -0
  83. package/test/r58-controller-state-coherence.test.mjs +45 -0
  84. package/test/r58-doctor-cli.test.mjs +20 -0
  85. package/test/r58-doctor-foreground.test.mjs +50 -0
  86. package/test/r58-doctor-installation.test.mjs +55 -0
  87. package/test/r58-doctor-pointer.test.mjs +41 -0
  88. package/test/r58-doctor-runtime.test.mjs +45 -0
  89. package/test/r58-doctor-transactions.test.mjs +21 -0
  90. package/test/r58-guardian-channel.test.mjs +26 -0
  91. package/test/r58-launcher-shell.test.mjs +28 -0
  92. package/test/r58-owner-identity.test.mjs +20 -0
  93. package/test/r58-release-contract.test.mjs +50 -0
  94. package/test/r58-session-lock.test.mjs +26 -0
  95. package/test/r58-stale-owner.test.mjs +71 -0
  96. package/test/r58-windows-gate.test.mjs +32 -0
  97. package/test/r59-release-contract.test.mjs +61 -0
  98. package/test/r59-tool-surface-compat.test.mjs +90 -0
  99. package/test/release-generation.test.mjs +4 -1
  100. package/test/remote-session-cli.test.mjs +55 -2
  101. package/test/runtime-plane-registry-r59.test.mjs +40 -0
@@ -0,0 +1,206 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ const DESKTOP_RAW_KEYS=new Set([
4
+ 'pixels','pixel_bytes','frame_bytes','raw_bgra','raw_rgba','raw_image','screenshot_bytes','bitmap_bytes'
5
+ ]);
6
+ const DEFAULT_LIMITS=Object.freeze({
7
+ normal:Object.freeze({max_active:8,max_queue:32,queue_timeout_ms:30000}),
8
+ autonomous:Object.freeze({max_active:2,max_queue:8,queue_timeout_ms:60000}),
9
+ desktop_observe:Object.freeze({max_active:2,max_queue:4,queue_timeout_ms:10000}),
10
+ desktop_action:Object.freeze({max_active:1,max_queue:2,queue_timeout_ms:5000})
11
+ });
12
+ const DEADLINES=Object.freeze({
13
+ normal:Object.freeze({timeout:120000,maxTotalTimeout:180000}),
14
+ autonomous:Object.freeze({timeout:900000,maxTotalTimeout:1200000}),
15
+ desktop_observe:Object.freeze({timeout:30000,maxTotalTimeout:60000}),
16
+ desktop_action:Object.freeze({timeout:30000,maxTotalTimeout:45000})
17
+ });
18
+
19
+ function insist(condition,message){ if(!condition) throw new Error(message); }
20
+ function toolClass(name){
21
+ const value=String(name??'');
22
+ if(value==='autonomous_goal_run') return 'autonomous';
23
+ if(value==='desktop_action') return 'desktop_action';
24
+ if(value.startsWith('desktop_')) return 'desktop_observe';
25
+ return 'normal';
26
+ }
27
+ function estimateBase64Bytes(value){
28
+ if(typeof value!=='string') return 0;
29
+ const clean=value.replace(/\s/g,'');
30
+ if(clean.length===0) return 0;
31
+ const padding=clean.endsWith('==')?2:clean.endsWith('=')?1:0;
32
+ return Math.floor(clean.length*3/4)-padding;
33
+ }
34
+ function scanDesktopPayload(value,{maxPreviewBytes},path='result',seen=new Set()){
35
+ if(value===null||value===undefined) return;
36
+ if(typeof value==='string'||typeof value==='number'||typeof value==='boolean') return;
37
+ if(typeof value!=='object') return;
38
+ if(seen.has(value)) throw new Error('bridge desktop result contains cyclic value');
39
+ seen.add(value);
40
+ if(Array.isArray(value)){
41
+ for(let i=0;i<value.length;i++) scanDesktopPayload(value[i],{maxPreviewBytes},`${path}[${i}]`,seen);
42
+ seen.delete(value); return;
43
+ }
44
+ for(const [key,child] of Object.entries(value)){
45
+ const lower=key.toLowerCase();
46
+ if(DESKTOP_RAW_KEYS.has(lower)) throw new Error(`bridge desktop result contains forbidden raw frame field '${path}.${key}'`);
47
+ if((lower==='preview_png_base64'||lower==='preview_jpeg_base64')&&typeof child==='string'){
48
+ const bytes=estimateBase64Bytes(child);
49
+ if(bytes>maxPreviewBytes) throw new Error(`bridge desktop preview exceeds ${maxPreviewBytes} byte limit`);
50
+ }
51
+ if(lower==='data'&&value.type==='image'&&typeof child==='string'){
52
+ const bytes=estimateBase64Bytes(child);
53
+ if(bytes>maxPreviewBytes) throw new Error(`bridge MCP image content exceeds ${maxPreviewBytes} byte limit`);
54
+ }
55
+ scanDesktopPayload(child,{maxPreviewBytes},`${path}.${key}`,seen);
56
+ }
57
+ seen.delete(value);
58
+ }
59
+
60
+ export function bridgeToolClass(name){ return toolClass(name); }
61
+ export function bridgeDeadlineForTool(name){ return DEADLINES[toolClass(name)]; }
62
+ export function bridgeCatalogSha256(toolNames){
63
+ insist(Array.isArray(toolNames)&&toolNames.every(x=>typeof x==='string'),'bridge catalog names invalid');
64
+ const sorted=[...new Set(toolNames)].sort();
65
+ insist(sorted.length===toolNames.length,'bridge catalog contains duplicate tool name');
66
+ return createHash('sha256').update(JSON.stringify(sorted),'utf8').digest('hex');
67
+ }
68
+ export function verifyCompactCatalogAttestation(actualNames,toolResult){
69
+ insist(Array.isArray(actualNames)&&actualNames.every(x=>typeof x==='string'&&x.length>0),'actual bridge catalog invalid');
70
+ const actual=[...actualNames].sort();
71
+ insist(new Set(actual).size===actual.length,'actual bridge catalog contains duplicate tool name');
72
+ const envelope=toolResult?.structuredContent;
73
+ insist(envelope?.status==='ok'&&envelope?.op==='manifest','capability manifest tool result invalid');
74
+ const manifest=envelope.result;
75
+ insist(manifest?.schema==='deadbyte.capability-manifest.v2'||manifest?.schema==='deadbyte.capability-manifest.v3','capability manifest schema mismatch');
76
+ insist(manifest.profile==='compact','capability manifest profile mismatch');
77
+ insist(typeof manifest.ledger_sha256==='string'&&/^[0-9a-f]{64}$/.test(manifest.ledger_sha256),'capability manifest ledger hash invalid');
78
+ insist(Array.isArray(manifest.tool_catalog)&&manifest.tool_catalog.every(x=>typeof x==='string'&&x.length>0),'capability manifest tool_catalog invalid');
79
+ const declared=[...manifest.tool_catalog];
80
+ insist(declared.length===manifest.tool_count,'capability manifest tool_count mismatch');
81
+ insist(new Set(declared).size===declared.length,'capability manifest catalog contains duplicate tool name');
82
+ insist(JSON.stringify(declared)===JSON.stringify([...declared].sort()),'capability manifest catalog must be sorted');
83
+ const declaredSha=bridgeCatalogSha256(declared);
84
+ insist(declaredSha===manifest.catalog_sha256,'capability manifest catalog hash mismatch');
85
+ insist(JSON.stringify(actual)===JSON.stringify(declared),'bridge listTools/catalog attestation mismatch');
86
+ return Object.freeze({
87
+ ok:true,profile:'compact',tool_count:declared.length,catalog_sha256:declaredSha,ledger_sha256:manifest.ledger_sha256
88
+ });
89
+ }
90
+
91
+ export function enforceDesktopBridgeResult(toolName,result,{maxPreviewBytes=1024*1024}={}){
92
+ if(!String(toolName??'').startsWith('desktop_')) return result;
93
+ insist(Number.isInteger(maxPreviewBytes)&&maxPreviewBytes>=16*1024&&maxPreviewBytes<=4*1024*1024,'maxPreviewBytes invalid');
94
+ scanDesktopPayload(result,{maxPreviewBytes});
95
+ return result;
96
+ }
97
+
98
+ export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
99
+ const classes=['normal','autonomous','desktop_observe','desktop_action'];
100
+ for(const name of classes){
101
+ const cfg=limits[name];
102
+ insist(cfg&&Number.isInteger(cfg.max_active)&&cfg.max_active>=1&&cfg.max_active<=64,`bridge limit ${name}.max_active invalid`);
103
+ insist(Number.isInteger(cfg.max_queue)&&cfg.max_queue>=0&&cfg.max_queue<=256,`bridge limit ${name}.max_queue invalid`);
104
+ insist(Number.isInteger(cfg.queue_timeout_ms)&&cfg.queue_timeout_ms>=100&&cfg.queue_timeout_ms<=120000,`bridge limit ${name}.queue_timeout_ms invalid`);
105
+ }
106
+ const state=new Map(classes.map(name=>[name,{active:0,queue:[],admitted:0,completed:0,rejected:0,timed_out:0,cancelled:0}]));
107
+ let sequence=0;
108
+ let closed=false;
109
+ const drainWaiters=[];
110
+
111
+ function finishDrain(){
112
+ if(!closed||[...state.values()].some(item=>item.active>0||item.queue.some(waiter=>!waiter.done))) return;
113
+ while(drainWaiters.length) drainWaiters.shift()();
114
+ }
115
+
116
+ function dispatch(name){
117
+ const cfg=limits[name],s=state.get(name);
118
+ while(s.active<cfg.max_active&&s.queue.length){
119
+ const waiter=s.queue.shift();
120
+ if(waiter.done) continue;
121
+ waiter.done=true; clearTimeout(waiter.timer); waiter.cleanup(); s.active++; s.admitted++;
122
+ waiter.resolve(makeTicket(name,waiter.tool,waiter.id,waiter.queuedAt));
123
+ }
124
+ }
125
+ function makeTicket(name,tool,id,queuedAt){
126
+ let released=false;
127
+ return Object.freeze({
128
+ id,class:name,tool,queued_ms:Math.max(0,Date.now()-queuedAt),
129
+ release(){
130
+ if(released) return false;
131
+ released=true;
132
+ const s=state.get(name);
133
+ s.active=Math.max(0,s.active-1);s.completed++;
134
+ dispatch(name);
135
+ finishDrain();
136
+ return true;
137
+ }
138
+ });
139
+ }
140
+ async function acquire(tool,{signal}={}){
141
+ const name=toolClass(tool),cfg=limits[name],s=state.get(name),id=++sequence,queuedAt=Date.now();
142
+ if(closed){s.rejected++;throw new Error('bridge governor closed');}
143
+ if(signal?.aborted){s.cancelled++;throw signal.reason instanceof Error?signal.reason:new Error('bridge request aborted');}
144
+ if(s.active<cfg.max_active){
145
+ s.active++;s.admitted++;
146
+ return makeTicket(name,String(tool),id,queuedAt);
147
+ }
148
+ if(s.queue.length>=cfg.max_queue){s.rejected++;throw new Error(`bridge backpressure queue full for ${name}`);}
149
+ return await new Promise((resolve,reject)=>{
150
+ const waiter={id,tool:String(tool),queuedAt,resolve,reject,done:false,timer:null,cleanup:()=>{}};
151
+ const abort=()=>{
152
+ if(waiter.done)return;
153
+ waiter.done=true;clearTimeout(waiter.timer);waiter.cleanup();
154
+ const index=s.queue.indexOf(waiter);if(index>=0)s.queue.splice(index,1);
155
+ s.cancelled++;reject(signal?.reason instanceof Error?signal.reason:new Error('bridge request aborted'));finishDrain();
156
+ };
157
+ waiter.cleanup=()=>signal?.removeEventListener?.('abort',abort);
158
+ signal?.addEventListener?.('abort',abort,{once:true});
159
+ waiter.timer=setTimeout(()=>{
160
+ if(waiter.done)return;
161
+ waiter.done=true;waiter.cleanup();s.timed_out++;
162
+ const index=s.queue.indexOf(waiter); if(index>=0)s.queue.splice(index,1);
163
+ reject(new Error(`bridge backpressure queue timeout for ${name}`));
164
+ finishDrain();
165
+ },cfg.queue_timeout_ms);
166
+ s.queue.push(waiter);
167
+ });
168
+ }
169
+ function close(reason='bridge governor closed'){
170
+ if(!closed){
171
+ closed=true;
172
+ for(const s of state.values()){
173
+ for(const waiter of s.queue.splice(0)){
174
+ if(waiter.done)continue;
175
+ waiter.done=true;clearTimeout(waiter.timer);waiter.cleanup();s.cancelled++;
176
+ waiter.reject(new Error(String(reason)));
177
+ }
178
+ }
179
+ }
180
+ if([...state.values()].every(item=>item.active===0)) return Promise.resolve();
181
+ return new Promise(resolve=>drainWaiters.push(resolve));
182
+ }
183
+ function reconcile(reason='bridge downstream reconciling'){
184
+ if(closed) return 0;
185
+ let removed=0;
186
+ for(const s of state.values()){
187
+ for(const waiter of s.queue.splice(0)){
188
+ if(waiter.done)continue;
189
+ waiter.done=true;clearTimeout(waiter.timer);waiter.cleanup();s.cancelled++;removed++;
190
+ waiter.reject(new Error(String(reason)));
191
+ }
192
+ }
193
+ return removed;
194
+ }
195
+ function snapshot(){
196
+ return Object.freeze(Object.fromEntries(classes.map(name=>{
197
+ const s=state.get(name),cfg=limits[name];
198
+ return [name,Object.freeze({active:s.active,queued:s.queue.filter(x=>!x.done).length,max_active:cfg.max_active,max_queue:cfg.max_queue,
199
+ admitted:s.admitted,completed:s.completed,rejected:s.rejected,timed_out:s.timed_out,cancelled:s.cancelled,saturated:s.active>=cfg.max_active})];
200
+ })));
201
+ }
202
+ return Object.freeze({acquire,reconcile,close,snapshot});
203
+ }
204
+
205
+ export const BRIDGE_R40_DEFAULT_LIMITS=DEFAULT_LIMITS;
206
+
@@ -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()
@@ -683,11 +685,31 @@ function Stop-OwnedComponent([string]$Name) {
683
685
  Remove-Item -LiteralPath (Ledger-Path $Name) -Force -ErrorAction SilentlyContinue
684
686
  }
685
687
 
686
- function Test-LocalReady($Cfg) {
688
+ function Get-LocalHealth($Cfg) {
689
+ $response = $null
690
+ try {
691
+ $request = [System.Net.HttpWebRequest]::Create([string]$Cfg.LocalReadyUri)
692
+ $request.Timeout = [int]$Cfg.ProbeTimeoutSeconds * 1000
693
+ $request.ReadWriteTimeout = [int]$Cfg.ProbeTimeoutSeconds * 1000
694
+ $response = $request.GetResponse()
695
+ } catch [System.Net.WebException] {
696
+ $response = $_.Exception.Response
697
+ if ($null -eq $response) { return [pscustomobject]@{ State='UNREACHABLE'; StatusCode=0; Diagnostic='readiness endpoint unreachable' } }
698
+ } catch { return [pscustomobject]@{ State='UNREACHABLE'; StatusCode=0; Diagnostic='readiness probe failed' } }
687
699
  try {
688
- $r = Invoke-WebRequest -UseBasicParsing -Uri ([string]$Cfg.LocalReadyUri) -TimeoutSec ([int]$Cfg.ProbeTimeoutSeconds)
689
- return ($r.StatusCode -ge 200 -and $r.StatusCode -lt 300)
690
- } catch { return $false }
700
+ $status = [int]$response.StatusCode
701
+ $reader = New-Object System.IO.StreamReader($response.GetResponseStream())
702
+ try { $body = $reader.ReadToEnd() } finally { $reader.Dispose() }
703
+ try { $parsed = $body | ConvertFrom-Json } catch { return [pscustomobject]@{ State='INVALID'; StatusCode=$status; Diagnostic='readiness response JSON invalid' } }
704
+ if ($parsed.schema -ne 'deadbyte.bridge-health.v1' -or [string]$parsed.state -notin @('STARTING','READY','DEGRADED','RECONCILING','STOPPING')) {
705
+ return [pscustomobject]@{ State='INVALID'; StatusCode=$status; Diagnostic='readiness response schema invalid' }
706
+ }
707
+ return [pscustomobject]@{ State=[string]$parsed.state; StatusCode=$status; Diagnostic=[string]$parsed.diagnostic }
708
+ } finally { if ($null -ne $response) { $response.Dispose() } }
709
+ }
710
+ function Test-LocalReady($Cfg) {
711
+ $health = Get-LocalHealth $Cfg
712
+ return ($health.State -eq 'READY' -and $health.StatusCode -ge 200 -and $health.StatusCode -lt 300)
691
713
  }
692
714
  function Get-LocalReadyListenerOwners($Cfg) {
693
715
  try { $uri = [Uri]([string]$Cfg.LocalReadyUri) } catch { Fail 'LocalReadyUri is invalid' }
@@ -717,16 +739,43 @@ function Test-LocalReadyOwned($Cfg, $Bridge) {
717
739
  if ($owners.Count -ne 1 -or $owners[0] -ne [int]$Bridge.Ledger.pid) { return $false }
718
740
  return (Test-LocalReady $Cfg)
719
741
  }
742
+ function Get-LocalHealthOwned($Cfg, $Bridge) {
743
+ if (-not $Bridge -or -not $Bridge.Alive) { return [pscustomobject]@{ State='UNREACHABLE'; StatusCode=0; Diagnostic='bridge not alive' } }
744
+ $owners = @(Get-LocalReadyListenerOwners $Cfg)
745
+ if ($owners.Count -ne 1 -or $owners[0] -ne [int]$Bridge.Ledger.pid) { return [pscustomobject]@{ State='UNATTRIBUTED'; StatusCode=0; Diagnostic='readiness listener ownership mismatch' } }
746
+ return (Get-LocalHealth $Cfg)
747
+ }
720
748
 
721
749
  function Get-ObservedState($Cfg) {
722
750
  $bridge = Test-OwnedInstance 'Bridge'
723
751
  $cloud = Test-OwnedInstance 'Cloud'
724
- $ready = if ($bridge.Alive) { try { Test-LocalReadyOwned $Cfg $bridge } catch { $false } } else { $false }
752
+ $core = Get-DownstreamCoreObservation $Cfg $bridge
753
+ $health = if ($bridge.Alive -and $core.alive) { try { Get-LocalHealthOwned $Cfg $bridge } catch { [pscustomobject]@{ State='UNREACHABLE'; StatusCode=0; Diagnostic='readiness attribution failed' } } } else { [pscustomobject]@{ State='UNREACHABLE'; StatusCode=0; Diagnostic='core not alive' } }
754
+ $ready = $health.State -eq 'READY'
725
755
  $state = if (-not $bridge.Alive -and -not $cloud.Alive) { 'OFFLINE' }
726
756
  elseif (-not $bridge.Alive -and $cloud.Alive) { 'PARKED' }
727
757
  elseif ($bridge.Alive -and $cloud.Alive -and $ready) { 'ONLINE' }
728
- else { 'DEGRADED' }
729
- [pscustomobject]@{ State=$state; Bridge=$bridge; Cloud=$cloud; LocalReady=$ready }
758
+ elseif ($bridge.Alive -and $cloud.Alive -and $core.alive -and $health.State -eq 'DEGRADED') { 'DEGRADED' }
759
+ elseif ($bridge.Alive -and $core.reason -eq 'startup-zero-child') { 'STARTING' }
760
+ else { 'FAILED' }
761
+ [pscustomobject]@{ State=$state; Bridge=$bridge; Core=$core; Cloud=$cloud; LocalReady=$ready; LocalHealth=$health }
762
+ }
763
+
764
+ function Wait-LocalOperational($Cfg) {
765
+ $deadline = [DateTime]::UtcNow.AddSeconds([int]$Cfg.StartTimeoutSeconds)
766
+ do {
767
+ $bridge = Test-OwnedInstance 'Bridge'
768
+ if (-not $bridge.Alive) { return $null }
769
+ $core = Get-DownstreamCoreObservation $Cfg $bridge
770
+ if (-not $core.alive -and $core.reason -ne 'startup-zero-child') { return $null }
771
+ if ($core.alive) {
772
+ $health = Get-LocalHealthOwned $Cfg $bridge
773
+ if ($health.State -in @('READY','DEGRADED')) { return $health }
774
+ }
775
+ if ([DateTime]::UtcNow -ge $deadline) { return $null }
776
+ Start-Sleep -Milliseconds 250
777
+ } while ([DateTime]::UtcNow -lt $deadline)
778
+ return $null
730
779
  }
731
780
 
732
781
  function Wait-LocalReady($Cfg) {
@@ -734,7 +783,10 @@ function Wait-LocalReady($Cfg) {
734
783
  do {
735
784
  $bridge = Test-OwnedInstance 'Bridge'
736
785
  if (-not $bridge.Alive) { return $false }
737
- if (Test-LocalReadyOwned $Cfg $bridge) { return $true }
786
+ $core = Get-DownstreamCoreObservation $Cfg $bridge
787
+ if (-not $core.alive -and $core.reason -ne 'startup-zero-child') { return $false }
788
+ if ($core.alive -and (Test-LocalReadyOwned $Cfg $bridge)) { return $true }
789
+ if ([DateTime]::UtcNow -ge $deadline) { return $false }
738
790
  Start-Sleep -Milliseconds 250
739
791
  } while ([DateTime]::UtcNow -lt $deadline)
740
792
  return $false
@@ -835,17 +887,18 @@ function Invoke-CoreGate($Cfg, [string]$ScriptName, [string[]]$ExtraArguments =
835
887
 
836
888
  function Start-Deadbyte($Cfg) {
837
889
  $state = Get-ObservedState $Cfg
838
- if ($state.State -eq 'ONLINE') { return $state }
839
- if ($state.State -eq 'DEGRADED') { Fail 'runtime is DEGRADED; use status and stop only if identities remain verified' }
890
+ if ($state.State -in @('ONLINE','DEGRADED')) { return $state }
891
+ if ($state.State -in @('FAILED','STARTING')) { Fail "runtime is $($state.State); inspect status and reconcile verified owned components before restart" }
840
892
  $cloudWasAlive = [bool]$state.Cloud.Alive
841
893
  Assert-LocalReadyPortAvailable $Cfg
842
894
  try {
843
895
  Start-OwnedComponent 'Bridge' $Cfg.Bridge $Cfg | Out-Null
844
- if (-not (Wait-LocalReady $Cfg)) { Fail 'bridge started but owned local readiness gate failed' }
896
+ $localHealth = Wait-LocalOperational $Cfg
897
+ if ($null -eq $localHealth) { Fail 'bridge started but owned local readiness gate failed' }
845
898
  Start-OwnedComponent 'Cloud' $Cfg.Cloud $Cfg | Out-Null
846
899
  if (-not (Wait-CurrentUrl $Cfg)) { Fail 'public endpoint metadata did not become available before timeout' }
847
900
  $final = Get-ObservedState $Cfg
848
- if ($final.State -ne 'ONLINE') { Fail "start gate failed: observed $($final.State)" }
901
+ if ($final.State -notin @('ONLINE','DEGRADED')) { Fail "start gate failed: observed $($final.State)" }
849
902
  return $final
850
903
  } catch {
851
904
  try { Stop-OwnedComponent 'Bridge' } catch {}
@@ -872,6 +925,18 @@ function Stop-Deadbyte($Cfg) {
872
925
  return $s
873
926
  }
874
927
 
928
+ function Assert-PolicyRootsAvailable($Policy, [string]$Plane) {
929
+ $rootIds = @($Policy.roots.PSObject.Properties.Name)
930
+ if ($rootIds.Count -lt 1) { Fail "$Plane policy requires at least one root" }
931
+ foreach ($rootId in $rootIds) {
932
+ $raw = [string]$Policy.roots.$rootId.path
933
+ if ([string]::IsNullOrWhiteSpace($raw)) { Fail "$Plane policy root '$rootId' path missing" }
934
+ try { $full = [System.IO.Path]::GetFullPath($raw) } catch { Fail "$Plane policy root '$rootId' path invalid" }
935
+ if (-not (Test-Path -LiteralPath $full -PathType Container)) { Fail "$Plane policy root '$rootId' missing: $full" }
936
+ }
937
+ return $rootIds
938
+ }
939
+
875
940
  function Get-HostPolicyMetadata($Cfg) {
876
941
  if ([string]::IsNullOrWhiteSpace([string]$Cfg.HostPolicyFile)) { Fail 'privileged host plane is not configured' }
877
942
  $policyPath = [string]$Cfg.HostPolicyFile
@@ -881,6 +946,7 @@ function Get-HostPolicyMetadata($Cfg) {
881
946
  $armFile = [System.IO.Path]::GetFullPath([string]$policy.arm_file)
882
947
  $runtimeReal = [System.IO.Path]::GetFullPath($RuntimeDir).TrimEnd('\') + '\'
883
948
  if (-not $armFile.StartsWith($runtimeReal, [System.StringComparison]::OrdinalIgnoreCase)) { Fail 'host policy arm_file must live under controller runtime directory' }
949
+ Assert-PolicyRootsAvailable $policy 'host' | Out-Null
884
950
  [pscustomobject]@{
885
951
  Path = $policyPath
886
952
  Sha256 = Get-ExecutableHash $policyPath
@@ -943,7 +1009,7 @@ function Get-ProcessPolicyMetadata($Cfg) {
943
1009
  $runtimeReal = [System.IO.Path]::GetFullPath($RuntimeDir).TrimEnd('\') + '\'
944
1010
  if (-not $grantFile.StartsWith($runtimeReal, [System.StringComparison]::OrdinalIgnoreCase)) { Fail 'process policy grant_file must live under controller runtime directory' }
945
1011
  $profileIds = @($policy.profiles.PSObject.Properties.Name)
946
- $rootIds = @($policy.roots.PSObject.Properties.Name)
1012
+ $rootIds = @(Assert-PolicyRootsAvailable $policy 'process')
947
1013
  if ($profileIds.Count -lt 1 -or $rootIds.Count -lt 1) { Fail 'process policy requires profiles and roots' }
948
1014
  [pscustomobject]@{ Path=$policyPath; Sha256=Get-ExecutableHash $policyPath; GrantFile=$grantFile; ProfileIds=$profileIds; RootIds=$rootIds }
949
1015
  }
@@ -1003,8 +1069,7 @@ function Get-CodingPolicyMetadata($Cfg) {
1003
1069
  $leaseFile = [System.IO.Path]::GetFullPath([string]$policy.lease_file)
1004
1070
  $runtimeReal = [System.IO.Path]::GetFullPath($RuntimeDir).TrimEnd('\') + '\'
1005
1071
  if (-not $leaseFile.StartsWith($runtimeReal, [System.StringComparison]::OrdinalIgnoreCase)) { Fail 'coding policy lease_file must live under controller runtime directory' }
1006
- $rootIds = @($policy.roots.PSObject.Properties.Name)
1007
- if ($rootIds.Count -lt 1) { Fail 'coding policy requires at least one root' }
1072
+ $rootIds = @(Assert-PolicyRootsAvailable $policy 'coding')
1008
1073
  [pscustomobject]@{ Path=$policyPath; Sha256=Get-ExecutableHash $policyPath; LeaseFile=$leaseFile; RootIds=$rootIds }
1009
1074
  }
1010
1075
 
@@ -1265,6 +1330,73 @@ function Recover-AutonomousSupervisor($Cfg) {
1265
1330
  return [pscustomobject]@{ Runtime=$runtime; Supervisor=$supervisor; Process=$process; Coding=$coding; Autonomous=$autonomous; Desktop=$desktop; Host=$hostStatus }
1266
1331
  }
1267
1332
 
1333
+ function Get-BoundedObservationReason($Value) {
1334
+ $reason = [string]$Value
1335
+ if ($reason -cmatch '^[a-z][a-z0-9-]{0,63}$') { return $reason }
1336
+ return 'unverified'
1337
+ }
1338
+
1339
+ function Convert-OwnedObservation($Owned) {
1340
+ $pidValue = $null; $birth = $null
1341
+ if ($Owned.Alive -and $Owned.Ledger) {
1342
+ $pidValue = [int]$Owned.Ledger.pid
1343
+ $birth = [string]$Owned.Ledger.creation_time_utc
1344
+ }
1345
+ [ordered]@{ alive=[bool]$Owned.Alive; reason=(Get-BoundedObservationReason $Owned.Reason); pid=$pidValue; creation_time_utc=$birth }
1346
+ }
1347
+
1348
+ function Convert-AuthorityObservation($Authority) {
1349
+ [ordered]@{ configured=[bool]$Authority.Configured; armed=[bool]$Authority.Armed; reason=(Get-BoundedObservationReason $Authority.Reason) }
1350
+ }
1351
+
1352
+ function Get-DownstreamCoreObservation($Cfg, $Bridge) {
1353
+ $out = [ordered]@{ alive=$false; reason='bridge-unavailable'; pid=$null; parent_pid=$null; creation_time_utc=$null; identity_basis=$null }
1354
+ if (-not $Bridge.Alive) { return $out }
1355
+ $bridgePid = [int]$Bridge.Ledger.pid
1356
+ 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) {
1357
+ $out.reason='bridge-config-mismatch'; return $out
1358
+ }
1359
+ try {
1360
+ $children = @(Get-CimInstance Win32_Process -Filter ("ParentProcessId={0} AND Name='node.exe'" -f $bridgePid) -ErrorAction Stop)
1361
+ if ($children.Count -eq 0) { $out.reason='startup-zero-child'; return $out }
1362
+ if ($children.Count -ne 1) { $out.reason='ambiguous-core'; return $out }
1363
+ $child = $children[0]
1364
+ if ([int]$child.ParentProcessId -ne $bridgePid -or [int]$child.ProcessId -lt 1 -or $null -eq $child.CreationDate) { $out.reason='core-identity-incomplete'; return $out }
1365
+ 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 }
1366
+ $command = [string]$child.CommandLine
1367
+ $needle = (Join-Path ([string]$Cfg.CoreRoot) 'src\mcp-server.mjs').Replace('/','\').ToLowerInvariant()
1368
+ if ([string]::IsNullOrWhiteSpace($command)) { $basis='verified-bridge-single-opaque-node-child' }
1369
+ elseif ($command.Replace('/','\').ToLowerInvariant().Contains($needle)) { $basis='command-line' }
1370
+ else { $out.reason='wrong-core-generation'; return $out }
1371
+ $out.alive=$true; $out.reason='verified'; $out.pid=[int]$child.ProcessId; $out.parent_pid=$bridgePid
1372
+ $out.creation_time_utc=$child.CreationDate.ToUniversalTime().ToString('o'); $out.identity_basis=$basis
1373
+ return $out
1374
+ } catch { $out.reason='core-observation-failed'; return $out }
1375
+ }
1376
+
1377
+ function Get-StructuredObservation($Cfg) {
1378
+ $s = Get-ObservedState $Cfg
1379
+ $supervisor = Get-AutonomousSupervisorStatus $Cfg
1380
+ [ordered]@{
1381
+ schema='deadbyte.controller-observation.v1'
1382
+ observed_at_utc=[DateTime]::UtcNow.ToString('o')
1383
+ state=[string]$s.State
1384
+ core_root=[string]$Cfg.CoreRoot
1385
+ local_ready=[bool]$s.LocalReady
1386
+ bridge=(Convert-OwnedObservation $s.Bridge)
1387
+ core=$s.Core
1388
+ cloud=(Convert-OwnedObservation $s.Cloud)
1389
+ supervisor=[ordered]@{ configured=[bool]$supervisor.Configured; running=[bool]$supervisor.Running; reason=(Get-BoundedObservationReason $supervisor.Reason) }
1390
+ authority=[ordered]@{
1391
+ process=(Convert-AuthorityObservation (Get-ProcessGrantStatus $Cfg))
1392
+ coding=(Convert-AuthorityObservation (Get-CodingLeaseStatus $Cfg))
1393
+ autonomous=(Convert-AuthorityObservation (Get-AutonomousLeaseStatus $Cfg))
1394
+ desktop=(Convert-AuthorityObservation (Get-DesktopGrantStatus $Cfg))
1395
+ host=(Convert-AuthorityObservation (Get-HostArmStatus $Cfg))
1396
+ }
1397
+ }
1398
+ }
1399
+
1268
1400
  function Show-State($Cfg) {
1269
1401
  $s = Get-ObservedState $Cfg
1270
1402
  $bp = if ($s.Bridge.Alive) { $s.Bridge.Ledger.pid } else { '-' }
@@ -1272,6 +1404,7 @@ function Show-State($Cfg) {
1272
1404
  $url = Get-CurrentUrl $Cfg
1273
1405
  Write-Host ("DEADBYTE MCP = {0}" -f $s.State)
1274
1406
  Write-Host ("Bridge PID : {0} [{1}]" -f $bp, $s.Bridge.Reason)
1407
+ Write-Host ("Core PID : {0} [{1}]" -f $(if ($s.Core.alive) { $s.Core.pid } else { '-' }), $s.Core.reason)
1275
1408
  Write-Host ("Cloud PID : {0} [{1}]" -f $cp, $s.Cloud.Reason)
1276
1409
  Write-Host ("Local ready : {0}" -f $s.LocalReady)
1277
1410
  Write-Host ("URL : {0}" -f $(if ($url) { $url } else { '<unknown>' }))
@@ -1370,14 +1503,15 @@ function Clean-Stale {
1370
1503
  function Run-CommandCore([string]$Name) {
1371
1504
  $cfg = Get-Config
1372
1505
  Assert-ControllerRootBound $cfg
1373
- Ensure-Directory $RuntimeDir; Ensure-Directory $LogDir
1506
+ $readOnly = $Name -in @('status','url','hoststatus','processstatus','codingstatus','autonomousstatus','desktopstatus','supervisorstatus')
1507
+ if (-not $readOnly) { Ensure-Directory $RuntimeDir; Ensure-Directory $LogDir }
1374
1508
  switch ($Name) {
1375
1509
  'start' { Start-Deadbyte $cfg | Out-Null; if ([bool]$cfg.AutonomousSupervisorEnabled) { Start-AutonomousSupervisor $cfg | Out-Null }; Show-State $cfg | Out-Null }
1376
1510
  'resume' { Start-Deadbyte $cfg | Out-Null; if ([bool]$cfg.AutonomousSupervisorEnabled) { Start-AutonomousSupervisor $cfg | Out-Null }; Show-State $cfg | Out-Null }
1377
1511
  'park' { Park-Deadbyte $cfg | Out-Null; Show-State $cfg | Out-Null }
1378
1512
  'stop' { if ([bool]$cfg.AutonomousSupervisorEnabled) { Stop-AutonomousSupervisor $cfg | Out-Null }; Stop-Deadbyte $cfg | Out-Null; Show-State $cfg | Out-Null }
1379
1513
  '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 }
1514
+ 'status' { if ($Json) { Get-StructuredObservation $cfg | ConvertTo-Json -Depth 6 -Compress | Write-Output } else { Show-State $cfg | Out-Null } }
1381
1515
  'url' { $u=Get-CurrentUrl $cfg; if (-not $u) { Fail 'URL unavailable' }; Write-Output $u }
1382
1516
  'test' { Invoke-Smoke $cfg $false }
1383
1517
  '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.34-r57\\controller\\runtime\\process-grant.json",
5
- "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.34-r57\\controller\\runtime\\process-state",
4
+ "grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.36-r59\\controller\\runtime\\process-grant.json",
5
+ "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.36-r59\\controller\\runtime\\process-state",
6
6
  "native_host": {
7
- "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.34-r57\\bin\\deadbyte-process-host.exe",
7
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.36-r59\\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.34-r57",
12
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.36-r59",
13
13
  "deny_paths": [
14
14
  "node_modules",
15
15
  "controller/runtime",
@@ -0,0 +1,26 @@
1
+ # R59 Task Contract
2
+
3
+ - TASK_ID: deadbyte-r59-robust-runtime
4
+ - OBJECTIVE: Produce backward-compatible DEADBYTE MCP 0.15.36 with fault-isolated optional planes, live capability snapshots, resilient Bridge/Core lifecycle, and verified direct-cloudflared frontdoor operation.
5
+ - ACTIVE_SKILL: implement-controlled-software-changes; final verification uses verify-production-implementation without repair authority.
6
+ - LEAD_ROLE: runtime implementation
7
+ - REVIEW_ROLES: independent release verifier after the candidate is frozen
8
+ - SOURCES: owner-approved 0.15.35 to 0.15.36 plan; exact 0.15.35 tarball SHA-256 `8259e30946d28dd138c1e2ce2f483fe1370d1658544f2adbfebafa4db8875bba`; sealed parent manifest `1b5715b276facbc00f8e341a554472cb4829e5af60e221c357c41b66053af9d4`
9
+ - FIXED: existing public tool names/counts/input contracts; authority planes; no Wrangler; no generic shell/PID/executable/stdin authority; no mutation of sealed 0.15.35 bytes
10
+ - TARGETS: Core initialization, capability resolver/manifest, bundled Bridge/governor, controller diagnostics, frontdoor verification and release evidence
11
+ - BOUNDS: optional configured planes may degrade independently; signed ledger remains the authority ceiling; no transparent replay after dispatch
12
+ - CLASS_2_DISCRETION: bounded retry/backoff/TTL values inside owner-approved limits, reversible and test-bound
13
+ - CLASS_3_DISCRETION: internal module boundaries, helper names and test organization
14
+ - PROHIBITED: dynamic plugin loading; authority widening; Host/Desktop auto-arm; in-place production edits; Wrangler transport
15
+ - METHOD_LOCK: direct cloudflared frontdoor; state-machine Bridge/Core lifecycle; signed static capability ceiling with live reducing overlay; status METHOD_CLOSED by owner instruction
16
+ - PRODUCTION_LINEAGE: source parent 0.15.35 tarball; delivery target npm `deadbyte-mcp@0.15.36`; runtime representation signed release/generation slot
17
+ - DEPENDENCIES: Node.js/PowerShell/MSVC already pinned by the parent; no new dependencies
18
+ - CAPABILITY_CONTEXT: local Windows host with D: isolated test state; npm and production activation only after deterministic gates
19
+ - ASSURANCE_MODE: HIGH_RISK
20
+ - TESTS: focused RED/GREEN, full regression, Windows gate, isolated acceptance, four-hour soak, registry round-trip, activation/rollback/restore
21
+ - ACCEPTANCE_ORACLES: actual MCP protocol/catalog, Ed25519 ping verification, OS process identity, protected hashes, npm registry bytes and independent receipt verifier
22
+ - ACCEPTANCE_ENVIRONMENT: current production Windows host with isolated D: state; clean-machine proof is not claimed
23
+ - PASS_CONDITION: every mandatory gate passes with fresh evidence and final authority is disarmed
24
+ - STOP_CONDITION: protected parent bytes drift, authority widens, unknown mutation is replayed, mandatory gate fails, or credentials/human authentication are required
25
+ - ROLLBACK: exact signed 0.15.35 pointer plus owned compatibility junction
26
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.34",
3
+ "version": "0.15.36",
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-r57.ps1",
45
+ "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r59-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",
@@ -79,7 +79,11 @@
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",
85
+ "r59:focused:test": "node --test --test-concurrency=1 test/capability-snapshot-r59.test.mjs test/capability-resolver.test.mjs test/runtime-plane-registry-r59.test.mjs test/optional-plane-degraded-r59.test.mjs test/bridge-runtime-r59.test.mjs test/controller-policy-preflight-r59.test.mjs test/r59-tool-surface-compat.test.mjs test/r58-controller-state-coherence.test.mjs",
86
+ "r59:release:test": "node --test --test-concurrency=1 test/r59-release-contract.test.mjs test/r59-tool-surface-compat.test.mjs test/bridge-runtime-r59.test.mjs test/controller-policy-preflight-r59.test.mjs"
83
87
  },
84
88
  "bundleDependencies": [
85
89
  "@modelcontextprotocol/server",
@@ -0,0 +1,13 @@
1
+ {
2
+ "schema": "deadbyte.r59-full-regression-capture.v1",
3
+ "started_at_utc": "2026-10-02T18:38:13.917Z",
4
+ "finished_at_utc": "2026-10-02T18:43:52.171Z",
5
+ "exit_code": 0,
6
+ "signal": null,
7
+ "error": null,
8
+ "stdout_sha256": "36848d4d222085e1c7099ceb77261b91eb5daf42e540b5878c2e58024c81cf66",
9
+ "stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
10
+ "stdout_bytes": 113612,
11
+ "stderr_bytes": 0,
12
+ "pass": true
13
+ }
File without changes