deadbyte-mcp 0.15.37 → 0.15.38

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.
@@ -4,24 +4,39 @@ const DESKTOP_RAW_KEYS=new Set([
4
4
  'pixels','pixel_bytes','frame_bytes','raw_bgra','raw_rgba','raw_image','screenshot_bytes','bitmap_bytes'
5
5
  ]);
6
6
  const DEFAULT_LIMITS=Object.freeze({
7
+ control:Object.freeze({max_active:8,max_queue:16,queue_timeout_ms:5000}),
7
8
  normal:Object.freeze({max_active:8,max_queue:32,queue_timeout_ms:30000}),
9
+ bulk:Object.freeze({max_active:8,max_queue:16,queue_timeout_ms:30000}),
8
10
  autonomous:Object.freeze({max_active:2,max_queue:8,queue_timeout_ms:60000}),
9
11
  desktop_observe:Object.freeze({max_active:2,max_queue:4,queue_timeout_ms:10000}),
10
12
  desktop_action:Object.freeze({max_active:1,max_queue:2,queue_timeout_ms:5000})
11
13
  });
14
+ const DEFAULT_SHARED_LIMITS=Object.freeze({max_active:9,max_non_control_active:8});
12
15
  const DEADLINES=Object.freeze({
16
+ control:Object.freeze({timeout:10000,maxTotalTimeout:15000}),
13
17
  normal:Object.freeze({timeout:120000,maxTotalTimeout:180000}),
18
+ bulk:Object.freeze({timeout:120000,maxTotalTimeout:180000}),
14
19
  autonomous:Object.freeze({timeout:900000,maxTotalTimeout:1200000}),
15
20
  desktop_observe:Object.freeze({timeout:30000,maxTotalTimeout:60000}),
16
21
  desktop_action:Object.freeze({timeout:30000,maxTotalTimeout:45000})
17
22
  });
18
23
 
19
24
  function insist(condition,message){ if(!condition) throw new Error(message); }
20
- function toolClass(name){
25
+ function toolClass(name,args={}){
21
26
  const value=String(name??'');
22
27
  if(value==='autonomous_goal_run') return 'autonomous';
23
- if(value==='desktop_action') return 'desktop_action';
28
+ if(value==='desktop_action'||(value==='desktop_control'&&['action','target'].includes(args?.op))) return 'desktop_action';
24
29
  if(value.startsWith('desktop_')) return 'desktop_observe';
30
+ if(value==='desktop_control') return 'desktop_observe';
31
+ if(['machine_ping','machine_status','machine_revoke','machine_list','capability_manifest',
32
+ 'autonomous_session_status','coding_session_status'].includes(value))return 'control';
33
+ if(value==='machine_observe'&&['machine_ping','machine_status','machine_list'].includes(args?.op))return 'control';
34
+ if(['coding_search','coding_command_run','coding_benchmark_run','coding_task_run',
35
+ 'process_session_start','process_session_read','process_session_action',
36
+ 'machine_search_start','machine_search_page'].includes(value))return 'bulk';
37
+ if(value==='coding_inspect'&&['search','symbol_references','symbol_implementations'].includes(args?.op))return 'bulk';
38
+ if(value==='process_session'&&['start','read','action'].includes(args?.op))return 'bulk';
39
+ if(value==='machine_observe'&&['search_start','search_page','process_list'].includes(args?.op))return 'bulk';
25
40
  return 'normal';
26
41
  }
27
42
  function estimateBase64Bytes(value){
@@ -57,8 +72,8 @@ function scanDesktopPayload(value,{maxPreviewBytes},path='result',seen=new Set()
57
72
  seen.delete(value);
58
73
  }
59
74
 
60
- export function bridgeToolClass(name){ return toolClass(name); }
61
- export function bridgeDeadlineForTool(name){ return DEADLINES[toolClass(name)]; }
75
+ export function bridgeToolClass(name,args){ return toolClass(name,args); }
76
+ export function bridgeDeadlineForTool(name,args){ return DEADLINES[toolClass(name,args)]; }
62
77
  export function bridgeCatalogSha256(toolNames){
63
78
  insist(Array.isArray(toolNames)&&toolNames.every(x=>typeof x==='string'),'bridge catalog names invalid');
64
79
  const sorted=[...new Set(toolNames)].sort();
@@ -95,8 +110,12 @@ export function enforceDesktopBridgeResult(toolName,result,{maxPreviewBytes=1024
95
110
  return result;
96
111
  }
97
112
 
98
- export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
99
- const classes=['normal','autonomous','desktop_observe','desktop_action'];
113
+ export function createBridgeGovernor({limits:overrides={},shared:sharedOverrides={}}={}){
114
+ const limits={...DEFAULT_LIMITS,...overrides};
115
+ const shared={...DEFAULT_SHARED_LIMITS,...sharedOverrides};
116
+ insist(Number.isInteger(shared.max_active)&&shared.max_active>=2&&shared.max_active<=64,'bridge shared max_active invalid');
117
+ insist(Number.isInteger(shared.max_non_control_active)&&shared.max_non_control_active>=1&&shared.max_non_control_active<shared.max_active,'bridge shared max_non_control_active invalid');
118
+ const classes=['control','normal','bulk','autonomous','desktop_observe','desktop_action'];
100
119
  for(const name of classes){
101
120
  const cfg=limits[name];
102
121
  insist(cfg&&Number.isInteger(cfg.max_active)&&cfg.max_active>=1&&cfg.max_active<=64,`bridge limit ${name}.max_active invalid`);
@@ -104,6 +123,7 @@ export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
104
123
  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
124
  }
106
125
  const state=new Map(classes.map(name=>[name,{active:0,queue:[],admitted:0,completed:0,rejected:0,timed_out:0,cancelled:0}]));
126
+ let sharedActive=0,sharedNonControlActive=0;
107
127
  let sequence=0;
108
128
  let closed=false;
109
129
  const drainWaiters=[];
@@ -113,13 +133,75 @@ export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
113
133
  while(drainWaiters.length) drainWaiters.shift()();
114
134
  }
115
135
 
116
- function dispatch(name){
136
+ function canAdmit(name){
117
137
  const cfg=limits[name],s=state.get(name);
118
- while(s.active<cfg.max_active&&s.queue.length){
138
+ if(s.active>=cfg.max_active)return false;
139
+ if(sharedActive>=shared.max_active)return false;
140
+ if(name!=='control'&&sharedNonControlActive>=shared.max_non_control_active)return false;
141
+ return true;
142
+ }
143
+
144
+ function noteAdmit(name){
145
+ sharedActive++;
146
+ if(name!=='control')sharedNonControlActive++;
147
+ }
148
+
149
+ function noteRelease(name){
150
+ sharedActive=Math.max(0,sharedActive-1);
151
+ if(name!=='control')sharedNonControlActive=Math.max(0,sharedNonControlActive-1);
152
+ }
153
+
154
+ function dispatchOne(name){
155
+ const s=state.get(name);
156
+ if(!canAdmit(name))return false;
157
+
158
+ while(s.queue.length){
119
159
  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));
160
+ if(waiter.done)continue;
161
+
162
+ waiter.done=true;
163
+ clearTimeout(waiter.timer);
164
+ waiter.cleanup();
165
+
166
+ s.active++;
167
+ noteAdmit(name);
168
+ s.admitted++;
169
+
170
+ waiter.resolve(
171
+ makeTicket(name,waiter.tool,waiter.id,waiter.queuedAt)
172
+ );
173
+
174
+ return true;
175
+ }
176
+
177
+ return false;
178
+ }
179
+
180
+ function oldestAdmissibleQueuedClass(){
181
+ let selected=null;
182
+
183
+ for(const name of classes){
184
+ if(!canAdmit(name))continue;
185
+
186
+ const s=state.get(name);
187
+ const waiter=s.queue.find(item=>!item.done);
188
+
189
+ if(!waiter)continue;
190
+
191
+ if(selected===null||waiter.id<selected.id){
192
+ selected={name,id:waiter.id};
193
+ }
194
+ }
195
+
196
+ return selected?.name??null;
197
+ }
198
+
199
+ function dispatchAvailable(){
200
+ while(true){
201
+ const name=oldestAdmissibleQueuedClass();
202
+
203
+ if(name===null)break;
204
+ if(!dispatchOne(name))break;
123
205
  }
124
206
  }
125
207
  function makeTicket(name,tool,id,queuedAt){
@@ -130,19 +212,19 @@ export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
130
212
  if(released) return false;
131
213
  released=true;
132
214
  const s=state.get(name);
133
- s.active=Math.max(0,s.active-1);s.completed++;
134
- dispatch(name);
215
+ s.active=Math.max(0,s.active-1);noteRelease(name);s.completed++;
216
+ dispatchAvailable();
135
217
  finishDrain();
136
218
  return true;
137
219
  }
138
220
  });
139
221
  }
140
- async function acquire(tool,{signal}={}){
141
- const name=toolClass(tool),cfg=limits[name],s=state.get(name),id=++sequence,queuedAt=Date.now();
222
+ async function acquire(tool,{signal,arguments:args}={}){
223
+ const name=toolClass(tool,args),cfg=limits[name],s=state.get(name),id=++sequence,queuedAt=Date.now();
142
224
  if(closed){s.rejected++;throw new Error('bridge governor closed');}
143
225
  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++;
226
+ if(canAdmit(name)){
227
+ s.active++;noteAdmit(name);s.admitted++;
146
228
  return makeTicket(name,String(tool),id,queuedAt);
147
229
  }
148
230
  if(s.queue.length>=cfg.max_queue){s.rejected++;throw new Error(`bridge backpressure queue full for ${name}`);}
@@ -193,14 +275,22 @@ export function createBridgeGovernor({limits=DEFAULT_LIMITS}={}){
193
275
  return removed;
194
276
  }
195
277
  function snapshot(){
196
- return Object.freeze(Object.fromEntries(classes.map(name=>{
278
+ const lanes=Object.fromEntries(classes.map(name=>{
197
279
  const s=state.get(name),cfg=limits[name];
198
280
  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
281
  admitted:s.admitted,completed:s.completed,rejected:s.rejected,timed_out:s.timed_out,cancelled:s.cancelled,saturated:s.active>=cfg.max_active})];
200
- })));
282
+ }));
283
+ return Object.freeze({...lanes,shared:Object.freeze({
284
+ active:sharedActive,
285
+ non_control_active:sharedNonControlActive,
286
+ max_active:shared.max_active,
287
+ max_non_control_active:shared.max_non_control_active,
288
+ saturated:sharedActive>=shared.max_active
289
+ })});
201
290
  }
202
291
  return Object.freeze({acquire,reconcile,close,snapshot});
203
292
  }
204
293
 
205
294
  export const BRIDGE_R40_DEFAULT_LIMITS=DEFAULT_LIMITS;
295
+ export const BRIDGE_R61_SHARED_LIMITS=DEFAULT_SHARED_LIMITS;
206
296
 
@@ -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.37-r60\\controller\\runtime\\process-grant.json",
5
- "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.37-r60\\controller\\runtime\\process-state",
4
+ "grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.38-r61\\controller\\runtime\\process-grant.json",
5
+ "state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.38-r61\\controller\\runtime\\process-state",
6
6
  "native_host": {
7
- "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.37-r60\\bin\\deadbyte-process-host.exe",
7
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.38-r61\\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.37-r60",
12
+ "path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.38-r61",
13
13
  "deny_paths": [
14
14
  "node_modules",
15
15
  "controller/runtime",
@@ -0,0 +1,11 @@
1
+ # R61 LIVELOG and multi-workload resilience
2
+
3
+ - Source: a byte-verified copy of the non-Git R60 development tree at `D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.38-r61`, retaining its three intentional LIVELOG edits. The old R60 path remains a compatibility dependency of the live 0.15.37 generation and is not an R61 edit target.
4
+ - Sealed predecessor: `v0.15.37-1cfecd7889419da7`; release manifest `1cfecd7889419da7800814e3a2a4ffa93d48dfdb0c344a5b7b91fe8d093230aa`; generation manifest `54842021c75f01bf7ecbd5b10ab8a482ecf107765b45c46f9d39b12bab65eac4`.
5
+ - Target: `deadbyte-mcp@0.15.38`, R61, unchanged 43-tool compact catalog and zero new authority scopes.
6
+ - Mechanism decisions and license observations: [r61-reference-evidence.md](r61-reference-evidence.md). No donor source was copied.
7
+ - RED: eight admitted `coding_search` jobs blocked `machine_ping` at the governor boundary; 12,000 filtered LIVELOG requests grew an unbounded identity map; a historical schema differential test referenced a moved external source despite byte-identical canonical reference content; the active 0.15.37 generation pinned Bridge source/dependency hashes to the mutable R60 development path, so the first R61 edits caused read-only controller status/doctor to fail.
8
+ - Fix: existing Bridge governor now separates bounded control/ordinary/bulk admission; LIVELOG presentation and filter identities are bounded and audit-sequence-aware; the historical schema test reads the canonical reference corpus and retains the exact pinned SHA-256 check. The R61 updater verifies the development Bridge input but binds the generated runtime config to the manifest-verified immutable release slot. The two trusted R60 Bridge files were restored byte-for-byte from the sealed 0.15.37 slot after R61 was copied to its own path; live status returned ONLINE without restart, revoke, or slot mutation.
9
+ - Performance evidence: `D:\Projects\deadbyte-mcp\testing\0.15.38\r61-ab-nine-rounds.json` (SHA-256 `3f10010654f08b4347c8e22e0f7ec3c521a69872878934770a0d2c0fd5b16ef7`) and 15-round 1/8 follow-up `r61-ab-single-and-eight.json` (SHA-256 `b16143ff7cb8aeced0e685352ffebeeeb74116d648d5b3509af2c66bd1f3b8a0a`). At 32-way mixed governor load, median throughput changed 790.1 → 903.75 ops/s, control p95 31.54 → 21.82 ms, and maximum observed queue depth 23 → 14. All 108 full-matrix runs had zero errors and unknown outcomes. At 1-way follow-up, throughput 244.78 → 246.82 ops/s and total p95 46.03 → 45.93 ms. This is a direct-governor/scratch-I/O benchmark, **not** full MCP transport, signed audit, or production-load proof.
10
+ - R61 focused gate after identity change: 47/47 PASS, 0 skip. Isolated Bridge/Core cold start, public MCP status, Core recovery and stop: PASS in one run; not a multi-workload transport benchmark.
11
+ - Final full regression, Windows gate, release manifest/doctor, package boundary after final bytes, registry, activation, rollback and restore remain separate required gates. This document is not a release PASS claim.
@@ -0,0 +1,18 @@
1
+ # R61 reference-mechanism decisions
2
+
3
+ This is a source-inspection record, not authority to copy donor code. R61 uses
4
+ patterns reimplemented inside existing DEADBYTE components. No donor source
5
+ bytes or dependencies are imported.
6
+
7
+ | Reference | Inspected source | Mechanism and comparison with DEADBYTE | License/decision |
8
+ | --- | --- | --- | --- |
9
+ | Better Remote Commander | `references/better-remote-commander/packages/relay/src/device-hub.ts`, `mcp/invoke.ts`, `NOTICE` | Replaces stale sockets, correlates call/result and uses a pong watchdog. DEADBYTE already has a single guarded Bridge dispatch and bounded reconnect; test half-open detection and shared recovery, but do not add a fleet or new relay. | Root package declares MIT; NOTICE identifies derived Desktop Commander code. ADAPT watchdog tests only; KEEP current dispatch. |
10
+ | CUA | `references/cua/rfcs/3007-cua-driver-lifecycle-sessions.md`, `3682-typed-native-window-sdk.md`, `libs/cua-driver/rust/crates/cua-driver-core/tests/session_lifecycle.rs` | Accepted lifecycle sessions separate cleanup from authority; typed window actions distinguish snapshot target and post-action verification. DEADBYTE already has native Desktop and stale-frame controls. Add adversarial lifecycle/fresh-observation tests only if missing. RFC 2447 is superseded and not an architecture guide. | Top-level Python metadata declares MIT; component licenses must be checked before any copying. KEEP native/adapter split; ADAPT tests. |
11
+ | Desktop Commander | `references/desktop-commander/dist/utils/toolHistory.js`, process handlers | History caps entries, stored output bytes and file size. DEADBYTE already bounds process retained output via policy, repairs PATHEXT, supports offset reads, cancellation and bounded operation history. LIVELOG completed identity set is unbounded presentation state. | Package declares MIT. ADAPT LIVELOG retention; KEEP process runtime. |
12
+ | Open Remote MCP | `references/open-remote-mcp/docs/ARCHITECTURE.md`, `apps/agent/src/index.ts`, `NOTICE.md` | Relay policy narrows, never widens local device capability. DEADBYTE signed ledger and separate local planes are stronger; add a focused relay/local enforcement test, not a second permission system. | Root package has no license field in inspected metadata; no source copying. KEEP local authority; ADAPT test. |
13
+ | ReMCP | `references/remcp/docs/TOOL_SELECTION_EVAL.md`, `scripts/check-distribution.mjs`, `docs/DISTRIBUTION.md` | Golden positive/negative tool-selection cases and cross-distribution identity checks. DEADBYTE already has exact catalog, release manifest and npm closure; add a small golden routing test without a new runtime dependency. | Package declares MIT. ADAPT evaluation; KEEP release machinery. |
14
+ | Secure Host MCP | `references/secure-host-mcp/src/workspace.ts`, `src/executor.ts`, `test/workspace.test.ts` | Rejects broad workspace roots, resolves symlink parents and bounds executor time. DEADBYTE already has explicit roots, policy-pinned profiles and native containment. Probe equivalent boundary cases; do not expose generic shell or change root policy without RED evidence. | Package declares MIT. KEEP architecture; ADAPT adversarial cases if missing. |
15
+ | WinRemote MCP | `references/winremote-mcp/src/winremote/security.py`, `tiers.py`, `tests/test_security_hardening.py` | Capability tiers and URL/OAuth hardening. DEADBYTE authority planes are narrower and independently revocable; OCR/tier expansion would add scope. Compare URL and Windows privilege boundary tests where current interfaces overlap. | Python metadata declares MIT. KEEP planes; REJECT OCR and tier expansion. |
16
+
17
+ Acceptance remains based on DEADBYTE's observed behavior, not donor popularity.
18
+ Any newly found donor gap requires a focused RED and a narrow local fix.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.37",
3
+ "version": "0.15.38",
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-r60-prepublish.ps1",
45
+ "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r61-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",
@@ -85,7 +85,8 @@
85
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
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",
87
87
  "r60:focused:test": "node --test --test-concurrency=1 test/r60-authority-coherence.test.mjs test/r60-authority-enforcement.test.mjs test/r60-bridge-dispatch.test.mjs test/r60-clock-discipline.test.mjs test/r60-live-timeline.test.mjs test/r60-reconnect-errors.test.mjs test/r60-reconnect-jitter.test.mjs test/r60-remote-call-recovery.test.mjs test/r60-windows-log-decode.test.mjs test/r60-release-contract.test.mjs",
88
- "r60:full:test": "node scripts/full-regression-r60.mjs"
88
+ "r60:full:test": "node scripts/full-regression-r60.mjs",
89
+ "r61:focused:test": "node --test --test-concurrency=1 test/r61-release-contract.test.mjs test/r61-release-bridge-binding.test.mjs test/r61-control-lane.test.mjs test/r61-live-timeline-bounds.test.mjs test/r61-npm-artifact-identity.test.mjs test/remote-live-log-r37.test.mjs test/bridge-runtime-r59.test.mjs test/commander-schema-differential-r48.test.mjs test/package-boundary.test.mjs test/r60-bridge-dispatch.test.mjs test/r60-authority-enforcement.test.mjs"
89
90
  },
90
91
  "bundleDependencies": [
91
92
  "@modelcontextprotocol/server",
@@ -0,0 +1,45 @@
1
+ param(
2
+ [ValidateSet('all','preflight','focused','full','manifest','doctor')]
3
+ [string]$Stage='all'
4
+ )
5
+
6
+ $ErrorActionPreference='Stop'
7
+ Set-StrictMode -Version 3.0
8
+ $root=Split-Path $PSScriptRoot -Parent
9
+ Set-Location -LiteralPath $root
10
+
11
+ function Invoke-Npm([string]$Name,[string[]]$NpmArgs){
12
+ Write-Host "==== $Name ===="
13
+ & npm.cmd @NpmArgs
14
+ if($LASTEXITCODE -ne 0){ throw "R61 prepublish gate failed at $Name exit=$LASTEXITCODE" }
15
+ }
16
+
17
+ $stateRoot=if(-not [string]::IsNullOrWhiteSpace($env:DEADBYTE_STATE_ROOT)){
18
+ [IO.Path]::GetFullPath($env:DEADBYTE_STATE_ROOT)
19
+ }else{ Join-Path $env:USERPROFILE '.deadbyte-mcp' }
20
+ $pointer=Join-Path $stateRoot 'active-release.json'
21
+ if(-not (Test-Path -LiteralPath $pointer -PathType Leaf)){ throw "R61 predecessor pointer missing: $pointer" }
22
+ $active=Get-Content -LiteralPath $pointer -Raw | ConvertFrom-Json
23
+ if($active.release_id -ne 'v0.15.37-1cfecd7889419da7'){ throw "R61 predecessor release mismatch: $($active.release_id)" }
24
+ if($active.manifest_sha256 -ne '1cfecd7889419da7800814e3a2a4ffa93d48dfdb0c344a5b7b91fe8d093230aa'){ throw 'R61 predecessor manifest mismatch' }
25
+ if($active.generation_manifest_sha256 -ne '54842021c75f01bf7ecbd5b10ab8a482ecf107765b45c46f9d39b12bab65eac4'){ throw 'R61 predecessor generation mismatch' }
26
+ if($Stage -eq 'preflight'){Write-Host '==== R61 WINDOWS GATE: PASS preflight ====';return}
27
+
28
+ if($Stage -eq 'all' -or $Stage -eq 'focused'){
29
+ Invoke-Npm 'r61-focused' @('run','r61:focused:test')
30
+ if($Stage -eq 'focused'){Write-Host '==== R61 WINDOWS GATE: PASS focused ====';return}
31
+ }
32
+ if($Stage -eq 'all' -or $Stage -eq 'full'){
33
+ Invoke-Npm 'full-regression' @('test')
34
+ if($Stage -eq 'full'){Write-Host '==== R61 WINDOWS GATE: PASS full ====';return}
35
+ }
36
+ if($Stage -eq 'all' -or $Stage -eq 'manifest'){
37
+ Invoke-Npm 'manifest-write' @('run','manifest:write')
38
+ Invoke-Npm 'manifest-verify' @('run','manifest:verify')
39
+ if($Stage -eq 'manifest'){Write-Host '==== R61 WINDOWS GATE: PASS manifest ====';return}
40
+ }
41
+ if($Stage -eq 'all' -or $Stage -eq 'doctor'){
42
+ Invoke-Npm 'doctor' @('run','doctor')
43
+ if($Stage -eq 'doctor'){Write-Host '==== R61 WINDOWS GATE: PASS doctor ====';return}
44
+ }
45
+ Write-Host '==== R61 PREPUBLISH WINDOWS GATE: PASS ===='
@@ -0,0 +1,22 @@
1
+ import {createHash} from 'node:crypto';
2
+
3
+ const digest=(name,bytes,encoding='hex')=>createHash(name).update(bytes).digest(encoding);
4
+
5
+ export function verifyPublishedTarballIdentity({version,localBytes,registryBytes,published,tags}){
6
+ if(typeof version!=='string'||!/^\d+\.\d+\.\d+$/.test(version)||!Buffer.isBuffer(localBytes)||!Buffer.isBuffer(registryBytes)){
7
+ throw new Error('npm artifact identity inputs invalid');
8
+ }
9
+ const tarballSha256=digest('sha256',localBytes);
10
+ const integrity='sha512-'+digest('sha512',localBytes,'base64');
11
+ const shasum=digest('sha1',localBytes);
12
+ const dist=published?.dist??published;
13
+ if(published?.version!==version||dist?.integrity!==integrity||dist?.shasum!==shasum||
14
+ dist?.tarball!==`https://registry.npmjs.org/deadbyte-mcp/-/deadbyte-mcp-${version}.tgz`){
15
+ throw new Error('published registry metadata does not match the exact local tarball');
16
+ }
17
+ if(tags?.latest!==version)throw new Error(`npm latest tag mismatch: expected ${version}, got ${tags?.latest??'<missing>'}`);
18
+ if(digest('sha256',registryBytes)!==tarballSha256||'sha512-'+digest('sha512',registryBytes,'base64')!==integrity){
19
+ throw new Error('registry tarball bytes differ from the exact published local artifact');
20
+ }
21
+ return Object.freeze({tarball_sha256:tarballSha256,npm_integrity:integrity,shasum});
22
+ }
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import { verifyPublishedTarballIdentity } from './npm-artifact-identity-r61.mjs';
2
3
  import { mkdtemp, readFile, rm, unlink } from 'node:fs/promises';
3
4
  import path from 'node:path';
4
5
  import os from 'node:os';
@@ -58,6 +59,8 @@ const allowedUnmanifested = new Set([
58
59
 
59
60
  async function main() {
60
61
  const isVerifyOnly = process.argv.includes('--verify-only') || process.argv.includes('--dry-run');
62
+ const publishOnly = process.argv.includes('--publish-only');
63
+ if (isVerifyOnly && publishOnly) throw new Error('--publish-only conflicts with verify-only mode');
61
64
 
62
65
  console.log(`[1/7] Reading package.json and checking registry publication status... ${isVerifyOnly ? '(MODE: VERIFY-ONLY / DRY-RUN)' : '(MODE: PUBLISH)'}`);
63
66
  const pkg = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
@@ -180,6 +183,8 @@ async function main() {
180
183
  return;
181
184
  }
182
185
 
186
+ const localBytes = await readFile(tarball);
187
+
183
188
  console.log('[6/7] Publishing artifact to npm registry...');
184
189
  publishAttempted = true;
185
190
  let publishOut;
@@ -193,8 +198,15 @@ async function main() {
193
198
  }
194
199
  throw publishError;
195
200
  }
196
- const published = parseJson(runNpm(['view', `deadbyte-mcp@${version}`, 'version', 'dist.integrity', 'dist.tarball', '--json'], { timeout: 120000 }));
201
+ const viewed = parseJson(runNpm(['view', `deadbyte-mcp@${version}`, 'version', 'dist.integrity', 'dist.shasum', 'dist.tarball', '--json'], { timeout: 120000 }));
202
+ const published = Array.isArray(viewed) ? viewed[0] : viewed;
203
+ const dist = published?.dist ?? published;
204
+ if(typeof dist?.tarball !== 'string')throw new Error('published registry tarball URL missing');
205
+ const registryResponse = await fetch(dist.tarball,{signal:AbortSignal.timeout(120000)});
206
+ if(!registryResponse.ok) throw new Error(`registry tarball fetch failed status=${registryResponse.status}`);
207
+ const registryBytes = Buffer.from(await registryResponse.arrayBuffer());
197
208
  const tags = parseJson(runNpm(['view', 'deadbyte-mcp', 'dist-tags', '--json'], { timeout: 120000 }));
209
+ const identity=verifyPublishedTarballIdentity({version,localBytes,registryBytes,published,tags});
198
210
 
199
211
  console.log('[7/7] Post-publish external registry smoke test (executed outside repo in temp)...');
200
212
  const tempDir = os.tmpdir();
@@ -211,16 +223,20 @@ async function main() {
211
223
  timeout: 300000,
212
224
  });
213
225
 
214
- console.log('[8/8] Activating the published release into the live immutable slot and waiting for verified handoff...');
215
- run(node, [path.join(root, 'scripts', 'deploy-r48.mjs')], { cwd: root, timeout: 900000 });
226
+ if(!publishOnly){
227
+ console.log('[8/8] Activating the published release into the live immutable slot and waiting for verified handoff...');
228
+ run(node, [path.join(root, 'scripts', 'deploy-r48.mjs')], { cwd: root, timeout: 900000 });
229
+ }else console.log('[8/8] Publication verified; activation deliberately deferred to the separate production gate.');
216
230
 
217
231
  releaseSucceeded = true;
218
232
  console.log('\nRELEASE SUCCESSFUL:');
219
233
  console.log(JSON.stringify({
220
- status: 'published',
234
+ status: publishOnly?'published_verified_activation_pending':'published',
221
235
  name: pkg.name,
222
236
  version,
223
237
  tarball: filename,
238
+ tarball_sha256: identity.tarball_sha256,
239
+ npm_integrity: identity.npm_integrity,
224
240
  published,
225
241
  published_output_tail: publishOut.slice(-2000),
226
242
  dist_tags: tags,
@@ -231,7 +247,7 @@ async function main() {
231
247
  }, null, 2));
232
248
 
233
249
  } finally {
234
- if (releaseSucceeded || !publishAttempted) {
250
+ if ((releaseSucceeded && !publishOnly) || !publishAttempted) {
235
251
  await unlink(tarball).catch(() => {});
236
252
  } else {
237
253
  console.error('Release artifact preserved after failure: ' + tarball);
@@ -0,0 +1,98 @@
1
+ import {mkdtemp,mkdir,readFile,readdir,stat,writeFile,open,rm} from 'node:fs/promises';
2
+ import {spawn} from 'node:child_process';
3
+ import {createHash} from 'node:crypto';
4
+ import {monitorEventLoopDelay,performance} from 'node:perf_hooks';
5
+ import {pathToFileURL} from 'node:url';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+
9
+ const roots=process.argv.slice(2);
10
+ if(roots.length!==2||roots.some(item=>!path.isAbsolute(item)))throw new Error('two absolute governor module paths required');
11
+ const levels=(process.env.DEADBYTE_R61_BENCH_LEVELS??'1,2,4,8,16,32').split(',').map(Number);
12
+ if(!levels.length||levels.some(level=>![1,2,4,8,16,32].includes(level))||new Set(levels).size!==levels.length)throw new Error('benchmark levels invalid');
13
+ const ROUNDS=Number(process.env.DEADBYTE_R61_BENCH_ROUNDS??3),OPS=160;
14
+ if(!Number.isInteger(ROUNDS)||ROUNDS<3||ROUNDS>15)throw new Error('benchmark rounds must be 3..15');
15
+ const scratchRoot=process.env.DEADBYTE_R61_SCRATCH_ROOT;
16
+ if(!scratchRoot||!path.isAbsolute(scratchRoot))throw new Error('explicit absolute DEADBYTE_R61_SCRATCH_ROOT required');
17
+ const quant=(values,p)=>{const ordered=[...values].sort((a,b)=>a-b);return ordered[Math.max(0,Math.ceil(ordered.length*p)-1)]};
18
+ const sha=value=>createHash('sha256').update(value).digest('hex');
19
+
20
+ async function childOutput(){
21
+ const child=spawn(process.execPath,['-e','process.stdout.write("R61_CHILD_OK")'],{windowsHide:true,stdio:['ignore','pipe','pipe']});
22
+ let output='';for await(const chunk of child.stdout)output+=chunk;
23
+ const exit=await new Promise(resolve=>child.once('close',resolve));
24
+ if(exit!==0||output!=='R61_CHILD_OK')throw new Error('bounded child process oracle failed');
25
+ }
26
+
27
+ async function runCase(modulePath,level,round){
28
+ const {createBridgeGovernor}=await import(pathToFileURL(modulePath).href);
29
+ await mkdir(scratchRoot,{recursive:true});
30
+ const scratch=await mkdtemp(path.join(scratchRoot,'deadbyte-r61-bench-'));
31
+ const fixture=path.join(scratch,'fixture'),audit=path.join(scratch,'presentation.jsonl');
32
+ await mkdir(fixture);
33
+ const sample='deadbyte bounded corpus สวัสดี\n'.repeat(512);
34
+ for(let i=0;i<16;i++)await writeFile(path.join(fixture,`f${i}.txt`),sample);
35
+ const governor=createBridgeGovernor();
36
+ const calls=[],control=[],counts={error:0,unknown:0},peak={rss:process.memoryUsage().rss,queue:0,active:0};
37
+ const delay=monitorEventLoopDelay({resolution:20});delay.enable();
38
+ let next=0;
39
+ const started=performance.now();
40
+ async function worker(){
41
+ while(next<OPS){
42
+ const i=next++;
43
+ const kind=i%16;
44
+ const tool=kind<3?(kind===0?'machine_ping':'machine_status'):
45
+ kind<5?'capability_manifest':kind<8?'machine_fs_read':kind<10?'coding_search':
46
+ kind<12?'machine_fs_write':kind===12?'process_session_start':kind<15?'coding_file_read':'machine_process_list';
47
+ const t=performance.now();let ticket;
48
+ try{
49
+ ticket=await governor.acquire(tool);
50
+ if(tool==='machine_ping')sha(`nonce-${round}-${i}`);
51
+ else if(tool==='machine_status')await stat(fixture);
52
+ else if(tool==='capability_manifest')sha(await readFile(roots[0]));
53
+ else if(tool==='coding_search'){
54
+ const names=await readdir(fixture);
55
+ for(const name of names)if((await readFile(path.join(fixture,name),'utf8')).includes('bounded'))break;
56
+ }else if(tool==='machine_fs_write')await writeFile(path.join(scratch,`out-${i}.txt`),sample.slice(0,128));
57
+ else if(tool==='process_session_start')await childOutput();
58
+ else if(tool==='machine_process_list')os.cpus().length;
59
+ else await readFile(path.join(fixture,`f${i%16}.txt`));
60
+ const line=JSON.stringify({kind,at:i,hash:sha(String(i))})+'\n';
61
+ const handle=await open(audit,'a');try{await handle.writeFile(line);await handle.sync();}finally{await handle.close();}
62
+ }catch(error){counts.error++;throw error;}
63
+ finally{
64
+ ticket?.release();
65
+ const elapsed=performance.now()-t;
66
+ calls.push(elapsed);if(kind<3)control.push(elapsed);
67
+ const state=governor.snapshot();
68
+ peak.rss=Math.max(peak.rss,process.memoryUsage().rss);
69
+ peak.queue=Math.max(peak.queue,...Object.values(state).map(value=>value.queued));
70
+ peak.active=Math.max(peak.active,...Object.values(state).map(value=>value.active));
71
+ }
72
+ }
73
+ }
74
+ try{
75
+ await Promise.all(Array.from({length:level},()=>worker()));
76
+ await governor.close();
77
+ const total=performance.now()-started;
78
+ return {level,round,n:calls.length,throughput_ops_s:OPS*1000/total,p50_ms:quant(calls,.5),p95_ms:quant(calls,.95),
79
+ p99_ms:quant(calls,.99),max_ms:Math.max(...calls),control_p95_ms:quant(control,.95),
80
+ event_loop_p95_ms:delay.percentile(95)/1e6,peak_rss_bytes:peak.rss,peak_queue:peak.queue,
81
+ peak_active:peak.active,errors:counts.error,unknown:counts.unknown};
82
+ }finally{delay.disable();await rm(scratch,{recursive:true,force:true});}
83
+ }
84
+
85
+ const results=[];
86
+ for(const level of levels)for(let round=0;round<ROUNDS;round++){
87
+ const order=round%2===0?[0,1]:[1,0];
88
+ for(const index of order)results.push({target:index,...await runCase(roots[index],level,round)});
89
+ }
90
+ const report={schema:'deadbyte.r61.mixed-lane-benchmark.v1',node:process.version,platform:process.platform,
91
+ governor_sha256:await Promise.all(roots.map(async value=>sha(await readFile(value)))),levels,rounds:ROUNDS,operations_per_run:OPS,
92
+ limitations:['direct governor and real scratch I/O, not full MCP transport','presentation traffic is fsynced fixture data, not signed audit'],results};
93
+ const outputPath=process.env.DEADBYTE_R61_BENCH_OUTPUT;
94
+ if(outputPath){
95
+ if(!path.isAbsolute(outputPath))throw new Error('benchmark output must be absolute');
96
+ await writeFile(outputPath,JSON.stringify(report,null,2)+'\n',{flag:'wx'});
97
+ console.log(JSON.stringify({schema:report.schema,output_path:outputPath,result_count:results.length,governor_sha256:report.governor_sha256}));
98
+ }else console.log(JSON.stringify(report,null,2));
@@ -226,12 +226,12 @@ function parseAuditLogLine(file,line){
226
226
  if(!/^segment-\d{8}\.jsonl$/.test(path.basename(file))||!line) return null;
227
227
  try{return JSON.parse(line);}catch{return null;}
228
228
  }
229
- function formatLogLine(file,line,{auditEvent=null,activityTracker=null,sequence=null,verbose=false,displayMode='unicode'}={}){
229
+ function formatLogLine(file,line,{auditEvent=null,activityTracker=null,sequence=null,sourceSequence=null,verbose=false,displayMode='unicode'}={}){
230
230
  if(!line) return null;
231
231
  if(/^segment-\d{8}\.jsonl$/.test(path.basename(file))){
232
232
  const event=auditEvent??parseAuditLogLine(file,line);
233
233
  if(!event) return null;
234
- return activityTracker?activityTracker.observe(event,{sequence}):formatCompactAuditEvent(event);
234
+ return activityTracker?activityTracker.observe(event,{sequence,sourceSequence}):formatCompactAuditEvent(event);
235
235
  }
236
236
  return formatRuntimeDiagnosticLine(file,line,{verbose,displayMode});
237
237
  }
@@ -328,7 +328,7 @@ function timelineFilterEvent(timeline){
328
328
  async function tailRemoteLogs(root,signal,{journal=null,offsets=null,activityTracker=null,timelineFilter=null,timelineWriter=null,verbose=false,displayMode='unicode'}={}){
329
329
  process.stdout.write(verbose
330
330
  ? '[LOG] Verbose live timeline. Full sanitized request detail enabled; Ctrl+C disconnects and revokes authority.\n'
331
- : '[LOG] Human live timeline. Transport IN/OUT hidden; full replay/audit detail remains on disk. Ctrl+C disconnects and revokes authority.\n');
331
+ : '[LOG] Human live timeline. Transport IN/OUT hidden; full replay/audit detail remains on disk. START/DONE retained; heartbeat bursts folded; Ctrl+C disconnects and revokes authority.\n');
332
332
  const activeOffsets=offsets??await snapshotRemoteLogOffsets(root);
333
333
  const partialLines=new Map();
334
334
  let liveFiles=[...activeOffsets.keys()];
@@ -358,7 +358,8 @@ async function tailRemoteLogs(root,signal,{journal=null,offsets=null,activityTra
358
358
  : await journal.recordTerminal(timeline);
359
359
  if(recorded?.duplicate) continue;
360
360
  const accepted=timelineFilter&&timeline?timelineFilter.accept(timelineFilterEvent(timeline)):true;
361
- const formatted=formatLogLine(file,line,{auditEvent,activityTracker,sequence:recorded?.event?.seq??null,verbose,displayMode});
361
+ const formatted=formatLogLine(file,line,{auditEvent,activityTracker,sequence:recorded?.event?.seq??null,
362
+ sourceSequence:Number.isSafeInteger(auditEvent?.seq)?auditEvent.seq:null,verbose,displayMode});
362
363
  if(!formatted||!accepted) continue;
363
364
  const output=Array.isArray(formatted)?formatted:[formatted];
364
365
  for(const item of output) if(item){
@@ -512,9 +513,9 @@ async function runRemoteSession({resumeCursor=null,verbose=false,trace=false,fil
512
513
  filePath:remoteResultJournalPath(ctx.root,marker.result_session_id),sessionId:marker.result_session_id,maxEntries:2048
513
514
  });
514
515
  const rootPaths=await readLiveRootPaths(ctx.root);
515
- const activityTracker=createLiveTimelineTracker({verbose,displayMode,rootPaths,trace});
516
+ const activityTracker=createLiveTimelineTracker({verbose,displayMode,rootPaths,trace,foldHeartbeats:!verbose});
516
517
  const timelineFilter=filterExpression?createLiveTimelineFilter(filterExpression):null;
517
- const timelineWriter=createLiveTimelineWriter({stream:process.stdout,displayMode,rewrite:!verbose});
518
+ const timelineWriter=createLiveTimelineWriter({stream:process.stdout,displayMode,rewrite:false});
518
519
  const aborter=new AbortController();
519
520
  const abort=()=>aborter.abort();
520
521
  const watchStdin=!process.stdin.isTTY;
@@ -588,6 +589,8 @@ async function runRemoteSession({resumeCursor=null,verbose=false,trace=false,fil
588
589
  if(logTask) await logTask.catch(()=>{});
589
590
  timelineWriter.flush();
590
591
  for(const line of activityTracker.reconcileInterrupted('session_end')) process.stdout.write(`${line}\n`);
592
+ const filterRetention=timelineFilter?.retention();
593
+ if(filterRetention?.evicted>0) process.stdout.write(`[WARN] LIVELOG filter evicted ${filterRetention.evicted} presentation identities; full audit remains on disk.\n`);
591
594
  process.stdout.write(`${activityTracker.summary()}\n`);
592
595
  process.removeListener('SIGINT',abort);process.removeListener('SIGTERM',abort);
593
596
  if(watchStdin){process.stdin.removeListener('end',abort);process.stdin.removeListener('close',abort);process.stdin.pause();}