deadbyte-mcp 0.15.26 → 0.15.28

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.
@@ -0,0 +1,56 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFile } from 'node:fs/promises';
4
+
5
+ const root=new URL('../',import.meta.url);
6
+ const read=rel=>readFile(new URL(rel,root),'utf8');
7
+ const json=rel=>read(rel).then(JSON.parse);
8
+
9
+ test('R51 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
10
+ const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
11
+ json('package.json'),json('package-lock.json'),json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs')
12
+ ]);
13
+ assert.equal(pkg.version,'0.15.28');
14
+ assert.equal(lock.version,pkg.version);
15
+ assert.equal(lock.packages[''].version,pkg.version);
16
+ assert.match(versionSource,/DEADBYTE_VERSION = '0\.15\.28'/);
17
+ assert.equal(release.version,pkg.version);
18
+ assert.equal(release.train,'R51');
19
+ assert.equal(provenance.version,pkg.version);
20
+ assert.equal(matrix.version,pkg.version);
21
+ assert.equal(matrix.train,'R51');
22
+ assert.equal(sbom.metadata.component.version,pkg.version);
23
+ assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r51:0.15.28');
24
+ assert.match(pkg.scripts['gate:windows'],/gate-windows-r51\.ps1/);
25
+ });
26
+
27
+ test('R51 lineage binds exact immutable published 0.15.27 parent',async()=>{
28
+ const [release,provenance]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json')]);
29
+ const expected={
30
+ release_id:'v0.15.27-1b1dbe24b45ad06a',
31
+ manifest_sha256:'1b1dbe24b45ad06a62771d15f510662952f3d7c3e5aa08053c6c61511c523e47',
32
+ generation_manifest_sha256:'f87a1637b3c55ba050d079d8a5e0862a2244b306be7e985880708e0d8ded3db0'
33
+ };
34
+ assert.deepEqual(release.parent,expected);
35
+ assert.equal(release.source_predecessor.version,'0.15.27');
36
+ assert.equal(release.source_predecessor.tarball_sha256,'e728031d097d8678dfef80f8648cce65e72a96611052c31969c80f884506d1d7');
37
+ assert.equal(release.source_predecessor.manifest_file_sha256,expected.manifest_sha256);
38
+ assert.equal(provenance.parent_release_id,expected.release_id);
39
+ assert.equal(provenance.parent_manifest_sha256,expected.manifest_sha256);
40
+ assert.equal(provenance.parent_generation_manifest_sha256,expected.generation_manifest_sha256);
41
+ assert.equal(provenance.source_predecessor_tarball_sha256,release.source_predecessor.tarball_sha256);
42
+ });
43
+
44
+ test('R51 release advertises only implemented coherence single-flight authority and livelog hardening',async()=>{
45
+ const release=await json('RELEASE.json');
46
+ for(const key of [
47
+ 'runtime_package_auto_coherence',
48
+ 'coding_command_singleflight',
49
+ 'coding_command_result_dedup_cache',
50
+ 'foreground_desktop_host_fail_closed',
51
+ 'human_livelog_slow_call_marker',
52
+ 'human_livelog_peak_inflight',
53
+ 'human_livelog_bounded_discovery',
54
+ 'human_livelog_single_parse'
55
+ ]) assert.equal(release.capabilities[key],true,key);
56
+ });
@@ -0,0 +1,59 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { ensureRuntimeCoherence } from '../src/runtime-coherence.mjs';
4
+
5
+ const hex=value=>value.repeat(64).slice(0,64);
6
+
7
+ test('R51 runtime coherence upgrades older active slot exactly once and verifies final identity',async()=>{
8
+ let active={version:'0.15.27',manifest_sha256:hex('1'),release_id:'old'};
9
+ let disarms=0,activations=0;
10
+ const events=[];
11
+ const result=await ensureRuntimeCoherence({
12
+ cliVersion:'0.15.28',packageManifestSha256:hex('2'),
13
+ readActive:async()=>active,
14
+ disarmPrivileged:async()=>{disarms++;},
15
+ activateCurrentPackage:async()=>{activations++;active={version:'0.15.28',manifest_sha256:hex('2'),release_id:'new'};},
16
+ onEvent:event=>events.push(event)
17
+ });
18
+ assert.equal(result.status,'upgraded');
19
+ assert.equal(result.active.version,'0.15.28');
20
+ assert.equal(disarms,1);assert.equal(activations,1);
21
+ assert.deepEqual(events.map(event=>event.phase),['upgrade_start','upgrade_complete']);
22
+ });
23
+
24
+ test('R51 runtime coherence is non-mutating when version and manifest already match',async()=>{
25
+ let mutations=0;
26
+ const active={version:'0.15.28',manifest_sha256:hex('a'),release_id:'same'};
27
+ const result=await ensureRuntimeCoherence({cliVersion:'0.15.28',packageManifestSha256:hex('a'),readActive:async()=>active,
28
+ disarmPrivileged:async()=>{mutations++;},activateCurrentPackage:async()=>{mutations++;}});
29
+ assert.equal(result.status,'coherent');assert.equal(mutations,0);
30
+ });
31
+
32
+ test('R51 runtime coherence refuses downgrade and same-version manifest drift',async()=>{
33
+ await assert.rejects(()=>ensureRuntimeCoherence({cliVersion:'0.15.28',packageManifestSha256:hex('a'),
34
+ readActive:async()=>({version:'0.15.29',manifest_sha256:hex('b')}),disarmPrivileged:async()=>{},activateCurrentPackage:async()=>{}}),/newer than CLI/i);
35
+ await assert.rejects(()=>ensureRuntimeCoherence({cliVersion:'0.15.28',packageManifestSha256:hex('a'),
36
+ readActive:async()=>({version:'0.15.28',manifest_sha256:hex('b')}),disarmPrivileged:async()=>{},activateCurrentPackage:async()=>{}}),/manifest skew/i);
37
+ });
38
+
39
+
40
+ test('R51 bare remote wires coherence before live generation binding and deploy honors state root override',async()=>{
41
+ const {readFile}=await import('node:fs/promises');
42
+ const cli=await readFile(new URL('../src/deadbyte-cli.mjs',import.meta.url),'utf8');
43
+ const deploy=await readFile(new URL('../scripts/deploy-r48.mjs',import.meta.url),'utf8');
44
+ assert.match(cli,/ensureRuntimeCoherence/);
45
+ assert.match(cli,/synchronizeForegroundRuntime/);
46
+ const syncAt=cli.indexOf('await synchronizeForegroundRuntime');
47
+ const rootsAt=cli.indexOf('await readLiveRootPaths');
48
+ assert.ok(syncAt>=0&&rootsAt>syncAt,'runtime coherence must complete before binding generation root paths');
49
+ assert.match(deploy,/process\.env\.DEADBYTE_STATE_ROOT/);
50
+ });
51
+
52
+
53
+ test('R51 foreground authority contract explicitly verifies and cleans desktop plus host',async()=>{
54
+ const {readFile}=await import('node:fs/promises');
55
+ const cli=await readFile(new URL('../src/deadbyte-cli.mjs',import.meta.url),'utf8');
56
+ assert.match(cli,/\['desktopstatus',\/\^Desktop plane/);
57
+ assert.match(cli,/SESSION_CLEANUP=.*disarmdesktop.*disarmhost/s);
58
+ assert.match(cli,/desktop, host DISARMED/);
59
+ });
@@ -204,3 +204,17 @@ test('expanded session summary reports outcome classes latency and slowest tool'
204
204
  assert.match(summary,/p50 75ms \| p95 200ms/);
205
205
  assert.match(summary,/slowest host_exec 200ms/);
206
206
  });
207
+
208
+
209
+ test('R51 live timeline marks slow calls and reports peak in-flight concurrency',()=>{
210
+ let now=1000;
211
+ const tracker=createLiveTimelineTracker({clock:()=>now,slowCallMs:1000});
212
+ tracker.observe({event_type:'tool.request',tool:'coding_command_run',request_id:'slow-a-12345678',args:{root_id:'core',command_id:'node_script',script_path:'a.mjs'}});
213
+ tracker.observe({event_type:'tool.request',tool:'coding_file_read',request_id:'slow-b-12345678',args:{root_id:'core',path:'b.txt'}});
214
+ now=2500;
215
+ const line=tracker.observe({event_type:'tool.result',tool:'coding_command_run',request_id:'slow-a-12345678',outcome:{is_error:false,duration_ms:1500}});
216
+ assert.match(line,/1500ms|1\.50s/);
217
+ assert.match(line,/\[SLOW\]/);
218
+ tracker.observe({event_type:'tool.result',tool:'coding_file_read',request_id:'slow-b-12345678',outcome:{is_error:false,duration_ms:5}});
219
+ assert.match(tracker.summary(),/peak in-flight 2/);
220
+ });
@@ -23,7 +23,7 @@ async function fixture({failCommand='',statusOnline=false}={}){
23
23
  const spawnedPid=path.join(dir,'spawned.pid');
24
24
  await mkdir(bin,{recursive:true});
25
25
  const launcher=path.join(bin,'DEADBYTE-MCP.ps1');
26
- const ps1=`param([string]$Command)\n$ErrorActionPreference='Stop'\nfor($i=0;$i -lt 20;$i++){ try { [IO.File]::AppendAllText($env:DEADBYTE_REMOTE_TEST_TRACE,(\"$Command\" + [Environment]::NewLine),[Text.Encoding]::UTF8); break } catch { if($i -eq 19){ throw }; Start-Sleep -Milliseconds 10 } }\nif ($env:DEADBYTE_REMOTE_TEST_FAIL -and $Command -eq $env:DEADBYTE_REMOTE_TEST_FAIL) { $runtime=Join-Path $env:DEADBYTE_STATE_ROOT 'runtime'; New-Item -ItemType Directory -Path $runtime -Force | Out-Null; $failure=@{ schema='deadbyte.controller-start-failure.v1'; command=$Command; failed_at_utc='2026-09-26T00:00:00.000Z'; message='fixture controller evidence detail' } | ConvertTo-Json -Compress; [IO.File]::WriteAllText((Join-Path $runtime 'controller-start-failure.json'),$failure,[Text.Encoding]::UTF8); Write-Error \"forced $Command failure\"; exit 9 }\nswitch ($Command) {\n 'start' { if ($env:DEADBYTE_REMOTE_TEST_SPAWN_CHILD -eq '1') { $node=(Get-Command node.exe).Source; $spawned=Start-Process -FilePath $node -ArgumentList @('-e','setTimeout(()=>process.exit(0),10000)') -PassThru -WindowStyle Hidden -RedirectStandardOutput $env:DEADBYTE_REMOTE_TEST_SPAWN_STDOUT -RedirectStandardError $env:DEADBYTE_REMOTE_TEST_SPAWN_STDERR; if ($env:DEADBYTE_REMOTE_TEST_SPAWN_PID) { [IO.File]::WriteAllText($env:DEADBYTE_REMOTE_TEST_SPAWN_PID,[string]$spawned.Id,[Text.Encoding]::UTF8) } }; if ($env:DEADBYTE_REMOTE_TEST_STARTED) { [IO.File]::WriteAllText($env:DEADBYTE_REMOTE_TEST_STARTED,'1',[Text.Encoding]::UTF8) }; Write-Host 'DEADBYTE MCP = ONLINE' }\n 'status' { if ($env:DEADBYTE_REMOTE_TEST_STATUS_ONLINE -eq '1' -or ($env:DEADBYTE_REMOTE_TEST_STARTED -and (Test-Path -LiteralPath $env:DEADBYTE_REMOTE_TEST_STARTED))) { Write-Host 'DEADBYTE MCP = ONLINE'; Write-Host 'Bridge PID : 1001 [verified]'; Write-Host 'Cloud PID : 1002 [verified]'; Write-Host 'Local ready : True'; Write-Host 'Loop supervisor: RUNNING [verified]' } else { Write-Host 'DEADBYTE MCP = OFFLINE' } }\n 'processstatus' { Write-Host 'Process plane : ARMED [standing-grant]' }\n 'codingstatus' { Write-Host 'Coding plane : ARMED [standing-grant]' }\n 'autonomousstatus' { Write-Host 'Autonomous : ARMED [standing-grant]' }\n 'hoststatus' { Write-Host 'Host plane : DISARMED [disarmed]' }\n 'park' { if ($env:DEADBYTE_REMOTE_TEST_STARTED) { Remove-Item -LiteralPath $env:DEADBYTE_REMOTE_TEST_STARTED -Force -ErrorAction SilentlyContinue }; Write-Host 'DEADBYTE MCP = PARKED' }\n default { Write-Host \"$Command OK\" }\n}\nexit 0\n`;
26
+ const ps1=`param([string]$Command)\n$ErrorActionPreference='Stop'\nfor($i=0;$i -lt 20;$i++){ try { [IO.File]::AppendAllText($env:DEADBYTE_REMOTE_TEST_TRACE,(\"$Command\" + [Environment]::NewLine),[Text.Encoding]::UTF8); break } catch { if($i -eq 19){ throw }; Start-Sleep -Milliseconds 10 } }\nif ($env:DEADBYTE_REMOTE_TEST_FAIL -and $Command -eq $env:DEADBYTE_REMOTE_TEST_FAIL) { $runtime=Join-Path $env:DEADBYTE_STATE_ROOT 'runtime'; New-Item -ItemType Directory -Path $runtime -Force | Out-Null; $failure=@{ schema='deadbyte.controller-start-failure.v1'; command=$Command; failed_at_utc='2026-09-26T00:00:00.000Z'; message='fixture controller evidence detail' } | ConvertTo-Json -Compress; [IO.File]::WriteAllText((Join-Path $runtime 'controller-start-failure.json'),$failure,[Text.Encoding]::UTF8); Write-Error \"forced $Command failure\"; exit 9 }\nswitch ($Command) {\n 'start' { if ($env:DEADBYTE_REMOTE_TEST_SPAWN_CHILD -eq '1') { $node=(Get-Command node.exe).Source; $spawned=Start-Process -FilePath $node -ArgumentList @('-e','setTimeout(()=>process.exit(0),10000)') -PassThru -WindowStyle Hidden -RedirectStandardOutput $env:DEADBYTE_REMOTE_TEST_SPAWN_STDOUT -RedirectStandardError $env:DEADBYTE_REMOTE_TEST_SPAWN_STDERR; if ($env:DEADBYTE_REMOTE_TEST_SPAWN_PID) { [IO.File]::WriteAllText($env:DEADBYTE_REMOTE_TEST_SPAWN_PID,[string]$spawned.Id,[Text.Encoding]::UTF8) } }; if ($env:DEADBYTE_REMOTE_TEST_STARTED) { [IO.File]::WriteAllText($env:DEADBYTE_REMOTE_TEST_STARTED,'1',[Text.Encoding]::UTF8) }; Write-Host 'DEADBYTE MCP = ONLINE' }\n 'status' { if ($env:DEADBYTE_REMOTE_TEST_STATUS_ONLINE -eq '1' -or ($env:DEADBYTE_REMOTE_TEST_STARTED -and (Test-Path -LiteralPath $env:DEADBYTE_REMOTE_TEST_STARTED))) { Write-Host 'DEADBYTE MCP = ONLINE'; Write-Host 'Bridge PID : 1001 [verified]'; Write-Host 'Cloud PID : 1002 [verified]'; Write-Host 'Local ready : True'; Write-Host 'Loop supervisor: RUNNING [verified]' } else { Write-Host 'DEADBYTE MCP = OFFLINE' } }\n 'processstatus' { Write-Host 'Process plane : ARMED [standing-grant]' }\n 'codingstatus' { Write-Host 'Coding plane : ARMED [standing-grant]' }\n 'autonomousstatus' { Write-Host 'Autonomous : ARMED [standing-grant]' }\n 'desktopstatus' { Write-Host 'Desktop plane : DISARMED [disarmed]' }\n 'hoststatus' { Write-Host 'Host plane : DISARMED [disarmed]' }\n 'park' { if ($env:DEADBYTE_REMOTE_TEST_STARTED) { Remove-Item -LiteralPath $env:DEADBYTE_REMOTE_TEST_STARTED -Force -ErrorAction SilentlyContinue }; Write-Host 'DEADBYTE MCP = PARKED' }\n default { Write-Host \"$Command OK\" }\n}\nexit 0\n`;
27
27
  await writeFile(launcher,ps1,'utf8');
28
28
  return {dir,state,trace,env:{...process.env,DEADBYTE_STATE_ROOT:state,DEADBYTE_REMOTE_TEST_TRACE:trace,DEADBYTE_REMOTE_TEST_FAIL:failCommand,DEADBYTE_REMOTE_TEST_STATUS_ONLINE:statusOnline?'1':'0',DEADBYTE_REMOTE_TEST_STARTED:startedMarker,DEADBYTE_REMOTE_TEST_SPAWN_STDOUT:spawnedStdout,DEADBYTE_REMOTE_TEST_SPAWN_STDERR:spawnedStderr,DEADBYTE_REMOTE_TEST_SPAWN_PID:spawnedPid},spawnedPid};
29
29
  }
@@ -77,17 +77,17 @@ winTest('bare remote reuses a fully verified ONLINE runtime without invoking blo
77
77
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
78
78
  const output=await collect(child);
79
79
  const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'),{timeoutMs:8000});
80
- assert.deepEqual(ready.slice(0,8),[
80
+ assert.deepEqual(ready.slice(0,9),[
81
81
  'status','armprocess','armcoding','armautonomous',
82
- 'processstatus','codingstatus','autonomousstatus','hoststatus'
82
+ 'processstatus','codingstatus','autonomousstatus','desktopstatus','hoststatus'
83
83
  ]);
84
84
  assert.doesNotMatch(ready.join(','),/(^|,)start(,|$)/);
85
85
  assert.equal(child.exitCode,null,'remote session must remain foreground after reusing ONLINE runtime');
86
86
  assert.match(output.stdout,/Runtime already ONLINE; reusing verified bridge\/cloud\/supervisor/);
87
87
  const authDeadline=Date.now()+3000;
88
- while(Date.now()<authDeadline&&!/\[AUTH\] ARMED: process, coding, autonomous \| host DISARMED/.test(output.stdout)) await sleep(50);
88
+ while(Date.now()<authDeadline&&!/\[AUTH\] ARMED: process, coding, autonomous \| desktop, host DISARMED/.test(output.stdout)) await sleep(50);
89
89
  assert.match(output.stdout,/\[DISPLAY\] ASCII fallback: stdout_not_tty/);
90
- assert.match(output.stdout,/\[AUTH\] ARMED: process, coding, autonomous \| host DISARMED/);
90
+ assert.match(output.stdout,/\[AUTH\] ARMED: process, coding, autonomous \| desktop, host DISARMED/);
91
91
  child.kill('SIGINT');
92
92
  await output.closed;
93
93
  }finally{
@@ -106,9 +106,9 @@ winTest('bare remote PARKED startup does not wait for a long-lived child holding
106
106
  const output=await collect(child);
107
107
  const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'),{timeoutMs:8000});
108
108
  const elapsed=Date.now()-startedAt;
109
- assert.deepEqual(ready.slice(0,10),[
109
+ assert.deepEqual(ready.slice(0,11),[
110
110
  'status','start','status','armprocess','armcoding','armautonomous',
111
- 'processstatus','codingstatus','autonomousstatus','hoststatus'
111
+ 'processstatus','codingstatus','autonomousstatus','desktopstatus','hoststatus'
112
112
  ]);
113
113
  assert.ok(elapsed<7000,`PARKED startup waited on inherited child pipe handles: ${elapsed}ms`);
114
114
  assert.equal(child.exitCode,null,'remote session must remain foreground after PARKED startup');
@@ -133,13 +133,13 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
133
133
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
134
134
  const output=await collect(child);
135
135
  const ready=await waitFor(fx.trace,commands=>commands.slice(0,10).join(',')==='status,start,status,armprocess,armcoding,armautonomous,processstatus,codingstatus,autonomousstatus,hoststatus');
136
- assert.deepEqual(ready.slice(0,10),[
136
+ assert.deepEqual(ready.slice(0,11),[
137
137
  'status','start','status','armprocess','armcoding','armautonomous',
138
- 'processstatus','codingstatus','autonomousstatus','hoststatus'
138
+ 'processstatus','codingstatus','autonomousstatus','desktopstatus','hoststatus'
139
139
  ]);
140
140
  assert.equal(child.exitCode,null,'remote session must remain foreground after becoming ready');
141
141
  const tailDeadline=Date.now()+3000;
142
- while(Date.now()<tailDeadline&&!/\[AUTH\] ARMED: process, coding, autonomous \| host DISARMED/.test(output.stdout)) await sleep(50);
142
+ while(Date.now()<tailDeadline&&!/\[AUTH\] ARMED: process, coding, autonomous \| desktop, host DISARMED/.test(output.stdout)) await sleep(50);
143
143
  assert.match(output.stdout,/\[DISPLAY\] ASCII fallback: stdout_not_tty/);
144
144
  assert.match(output.stdout,/\[DEVICE\] Starting DEADBYTE MCP/);
145
145
  assert.match(output.stdout,/\[BRIDGE\] Local bridge connected/);
@@ -148,7 +148,7 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
148
148
  assert.match(output.stdout,/\[BOOT\] Starting local \+ remote runtime/);
149
149
  assert.match(output.stdout,/\[OK\] ONLINE/);
150
150
  assert.match(output.stdout,/\[READY\] DEADBYTE MCP online/);
151
- assert.match(output.stdout,/\[AUTH\] ARMED: process, coding, autonomous \| host DISARMED/);
151
+ assert.match(output.stdout,/\[AUTH\] ARMED: process, coding, autonomous \| desktop, host DISARMED/);
152
152
  assert.match(output.stdout,/\[LOG\] Human live timeline\. Transport IN\/OUT hidden; full replay\/audit detail remains on disk\./);
153
153
  assert.doesNotMatch(output.stdout,/Process plane\s*:/);
154
154
  assert.doesNotMatch(output.stdout,/Coding plane\s*:/);
@@ -172,10 +172,10 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
172
172
  '[TOOL OUT] 2026-09-16T00:00:00.002Z #000002 coding_file_read {"is_error":true}'
173
173
  ].join('\n')+'\n','utf8');
174
174
  const logDeadline=Date.now()+3000;
175
- while(Date.now()<logDeadline&&!/^R .*#4 \[fedcba98\] coding_file_read projects:src\/deadbyte-cli\.mjs 1\.73s ERR$/m.test(output.stdout)) await sleep(50);
175
+ while(Date.now()<logDeadline&&!/^R .*#4 \[fedcba98\] coding_file_read projects:src\/deadbyte-cli\.mjs 1\.73s \[SLOW\] ERR$/m.test(output.stdout)) await sleep(50);
176
176
  assert.doesNotMatch(output.stdout,/\| Arguments:/,'default human view must not print request JSON');
177
177
  assert.match(output.stdout,/^S .*#2 \[abcdef12\] coding_tree projects:src 42ms OK$/m);
178
- assert.match(output.stdout,/^R .*#4 \[fedcba98\] coding_file_read projects:src\/deadbyte-cli\.mjs 1\.73s ERR$/m);
178
+ assert.match(output.stdout,/^R .*#4 \[fedcba98\] coding_file_read projects:src\/deadbyte-cli\.mjs 1\.73s \[SLOW\] ERR$/m);
179
179
  assert.equal((output.stdout.match(/\[abcdef12\].*coding_tree.*42ms.*OK/g)||[]).length,1,'duplicate terminal result must print once');
180
180
  assert.doesNotMatch(output.stdout,/\[cursor r1:/,'full replay cursor belongs in the journal, not every human line');
181
181
  const resultJournal=JSON.parse(await readFile(path.join(fx.state,'runtime','remote-results',`${marker.result_session_id}.json`),'utf8'));
@@ -194,11 +194,11 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
194
194
  const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
195
195
  assert.equal(ended.timeout,undefined,'remote session did not exit after foreground input closed');
196
196
  const commands=await traceCommands(fx.trace);
197
- assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
197
+ assert.deepEqual(commands.slice(-6),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','park']);
198
198
  assert.match(output.stdout,/^DEADBYTE MCP$/m);
199
199
  assert.match(output.stdout,/Human live timeline/i);
200
200
  assert.match(output.stdout,/\[AUTH\] Revoking session authority/);
201
- assert.doesNotMatch(output.stdout,/disarmautonomous OK|disarmcoding OK|disarmprocess OK|disarmhost OK|DEADBYTE MCP = PARKED/);
201
+ assert.doesNotMatch(output.stdout,/disarmautonomous OK|disarmcoding OK|disarmprocess OK|disarmdesktop OK|disarmhost OK|DEADBYTE MCP = PARKED/);
202
202
  assert.doesNotMatch(output.stdout,/\p{Extended_Pictographic}/u,'piped Windows fallback must remain ASCII-safe');
203
203
  }finally{
204
204
  if(child?.exitCode===null) child.kill();
@@ -293,7 +293,7 @@ winTest('remote --verbose enables sanitized request detail while preserving fore
293
293
  assert.equal(ended.timeout,undefined);
294
294
  assert.equal(ended.code,0,output.stderr);
295
295
  const commands=await traceCommands(fx.trace);
296
- assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
296
+ assert.deepEqual(commands.slice(-6),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','park']);
297
297
  }finally{
298
298
  if(child?.exitCode===null) child.kill('SIGKILL');
299
299
  await rm(fx.dir,{recursive:true,force:true});
@@ -307,9 +307,9 @@ winTest('detached guardian revokes authority, parks, and removes the session mar
307
307
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
308
308
  const output=await collect(child);
309
309
  const ready=await waitFor(fx.trace,commands=>commands.slice(0,10).join(',')==='status,start,status,armprocess,armcoding,armautonomous,processstatus,codingstatus,autonomousstatus,hoststatus');
310
- assert.deepEqual(ready.slice(0,10),[
310
+ assert.deepEqual(ready.slice(0,11),[
311
311
  'status','start','status','armprocess','armcoding','armautonomous',
312
- 'processstatus','codingstatus','autonomousstatus','hoststatus'
312
+ 'processstatus','codingstatus','autonomousstatus','desktopstatus','hoststatus'
313
313
  ]);
314
314
  const markerPath=path.join(fx.state,'runtime','remote-session.json');
315
315
  const markerDeadline=Date.now()+3000;
@@ -327,8 +327,8 @@ winTest('detached guardian revokes authority, parks, and removes the session mar
327
327
  assert.equal(killed,true,'failed to hard-kill remote owner');
328
328
  await Promise.race([output.closed,sleep(3000)]);
329
329
 
330
- const cleaned=await waitFor(fx.trace,commands=>commands.slice(-5).join(',')==='disarmautonomous,disarmcoding,disarmprocess,disarmhost,park',{timeoutMs:10000});
331
- assert.deepEqual(cleaned.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
330
+ const cleaned=await waitFor(fx.trace,commands=>commands.slice(-6).join(',')==='disarmautonomous,disarmcoding,disarmprocess,disarmhost,park',{timeoutMs:10000});
331
+ assert.deepEqual(cleaned.slice(-6),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','park']);
332
332
  const markerGoneDeadline=Date.now()+3000;
333
333
  let markerGone=false;
334
334
  while(Date.now()<markerGoneDeadline){
@@ -352,7 +352,7 @@ winTest('bare remote rolls back authority and parks if one plane fails to arm',a
352
352
  assert.notEqual(ended.code,0);
353
353
  const commands=await traceCommands(fx.trace);
354
354
  assert.deepEqual(commands.slice(0,5),['status','start','status','armprocess','armcoding']);
355
- assert.deepEqual(commands.slice(-5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
355
+ assert.deepEqual(commands.slice(-6),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','park']);
356
356
  assert.doesNotMatch(output.stdout,/Live logs/i);
357
357
  }finally{await rm(fx.dir,{recursive:true,force:true});}
358
358
  });
@@ -367,9 +367,9 @@ winTest('bare remote recovers a stale crashed session before arming a new one',a
367
367
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
368
368
  const output=await collect(child);
369
369
  const ready=await waitFor(fx.trace,commands=>commands.includes('hoststatus'));
370
- assert.deepEqual(ready.slice(0,5),['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park']);
371
- assert.equal(ready[5],'status');
372
- assert.equal(ready[6],'start');
370
+ assert.deepEqual(ready.slice(0,6),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','park']);
371
+ assert.equal(ready[6],'status');
372
+ assert.equal(ready[7],'start');
373
373
  assert.match(output.stdout,/\[RECOVERY\] Stale remote session pid=2147483000; revoking authority before restart\./);
374
374
  child.stdin.end();
375
375
  const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);