deadbyte-mcp 0.15.45 → 0.15.46

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 (35) hide show
  1. package/MANIFEST.SHA256 +34 -24
  2. package/PROVENANCE.json +260 -257
  3. package/README.txt +22 -21
  4. package/RELEASE.json +367 -346
  5. package/SBOM.cdx.json +2 -2
  6. package/TEST-MATRIX.json +501 -503
  7. package/bridge/package.json +1 -1
  8. package/controller/deadbyte-controller.ps1 +20 -6
  9. package/controller/deadbyte-process-policy.json +4 -4
  10. package/package.json +2 -2
  11. package/scripts/gate-windows-r72.ps1 +76 -0
  12. package/scripts/npm-release-r48.mjs +2 -0
  13. package/scripts/npm-release-readiness-r72.mjs +76 -0
  14. package/src/deadbyte-cli.mjs +722 -721
  15. package/src/launcher-isolation.mjs +58 -0
  16. package/src/remote-authority.mjs +75 -75
  17. package/src/remote-mcp-machine-smoke-client.mjs +84 -84
  18. package/src/runtime-update.mjs +2056 -2008
  19. package/src/staging-input-isolation.mjs +79 -0
  20. package/src/version.mjs +1 -1
  21. package/test/deferred-slot-operation-behavior.test.mjs +2 -2
  22. package/test/r58-cleanup-retention.test.mjs +3 -3
  23. package/test/r58-concurrent-recovery.test.mjs +3 -3
  24. package/test/r58-stale-owner.test.mjs +1 -1
  25. package/test/r59-tool-surface-compat.test.mjs +2 -2
  26. package/test/r60-authority-coherence.test.mjs +10 -2
  27. package/test/r71-isolated-slot-rollback-restore.test.mjs +11 -11
  28. package/test/r71-release-identity.test.mjs +12 -10
  29. package/test/r72-launcher-isolation.test.mjs +99 -0
  30. package/test/r72-publication-fence.test.mjs +56 -0
  31. package/test/r72-publication-output-integrity.test.mjs +110 -0
  32. package/test/r72-remote-safe-contract.test.mjs +101 -0
  33. package/test/r72-staging-input-isolation.test.mjs +87 -0
  34. package/test/r72-staging-workspace-isolation.test.mjs +114 -0
  35. package/test/remote-session-cli.test.mjs +110 -64
@@ -12,6 +12,15 @@ const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
12
12
  const cliPath=path.join(root,'src','deadbyte-cli.mjs');
13
13
  const isWindows=process.platform==='win32';
14
14
  const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
15
+ const fixtureTimeoutMs=30000;
16
+ async function boundedCompletion(promise,timeoutMs=fixtureTimeoutMs){
17
+ let timer;
18
+ try{return await Promise.race([promise,new Promise(resolve=>{
19
+ timer=setTimeout(()=>resolve({timeout:true}),timeoutMs);
20
+ timer.unref?.();
21
+ })]);}
22
+ finally{clearTimeout(timer);}
23
+ }
15
24
 
16
25
  async function fixture({failCommand='',statusOnline=false}={}){
17
26
  const dir=await mkdtemp(path.join(os.tmpdir(),'deadbyte-remote-session-'));
@@ -45,7 +54,7 @@ async function traceCommands(file,{read=readFile,retryDelayMs=10,maxAttempts=20}
45
54
  }
46
55
  return [];
47
56
  }
48
- async function waitFor(file,predicate,{timeoutMs=12000}={}){
57
+ async function waitFor(file,predicate,{timeoutMs=fixtureTimeoutMs}={}){
49
58
  const deadline=Date.now()+timeoutMs;
50
59
  while(Date.now()<deadline){
51
60
  const commands=await traceCommands(file);
@@ -73,6 +82,17 @@ async function collect(child){
73
82
  const closed=new Promise(resolve=>child.once('close',(code,signal)=>resolve({code,signal})));
74
83
  return {closed,get stdout(){return stdout;},get stderr(){return stderr;}};
75
84
  }
85
+ // Windows: SIGKILL leaves PowerShell child holding a handle on the .ps1 fixture
86
+ // for a short window; retry rm() until it succeeds or gives up.
87
+ async function safeRm(dir,{maxAttempts=10,retryDelayMs=200}={}){
88
+ for(let i=0;i<maxAttempts;i++){
89
+ try{await rm(dir,{recursive:true,force:true});return;}
90
+ catch(err){
91
+ if(err?.code==='EBUSY'&&i<maxAttempts-1){await sleep(retryDelayMs);continue;}
92
+ throw err;
93
+ }
94
+ }
95
+ }
76
96
 
77
97
  const winTest=isWindows?test:test.skip;
78
98
 
@@ -80,14 +100,14 @@ winTest('bare remote reuses a fully verified ONLINE runtime without invoking blo
80
100
  const fx=await fixture({failCommand:'start',statusOnline:true});
81
101
  let child=null;
82
102
  try{
83
- child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
103
+ child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
84
104
  const output=await collect(child);
85
- const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=3,{timeoutMs:8000});
105
+ const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=3,{timeoutMs:fixtureTimeoutMs});
86
106
  assert.deepEqual(ready.slice(0,6),['status','status','armprocess','armcoding','armautonomous','status'],output.stderr);
87
107
  assert.doesNotMatch(ready.join(','),/(^|,)start(,|$)/);
88
108
  assert.equal(child.exitCode,null,'remote session must remain foreground after reusing ONLINE runtime');
89
109
  assert.match(output.stdout,/Runtime already ONLINE; reusing verified bridge\/cloud\/supervisor/);
90
- const authDeadline=Date.now()+3000;
110
+ const authDeadline=Date.now()+fixtureTimeoutMs;
91
111
  while(Date.now()<authDeadline&&!/\[AUTH\] process ARMED \| coding ARMED \| autonomous ARMED \| desktop DISARMED \| host DISARMED/.test(output.stdout)) await sleep(50);
92
112
  assert.match(output.stdout,/\[DISPLAY\] ASCII fallback: stdout_not_tty/);
93
113
  assert.match(output.stdout,/\[AUTH\] process ARMED \| coding ARMED \| autonomous ARMED \| desktop DISARMED \| host DISARMED/);
@@ -95,7 +115,31 @@ winTest('bare remote reuses a fully verified ONLINE runtime without invoking blo
95
115
  await output.closed;
96
116
  }finally{
97
117
  if(child&&child.exitCode===null) child.kill('SIGKILL');
98
- await rm(fx.dir,{recursive:true,force:true});
118
+ await safeRm(fx.dir);
119
+ }
120
+ });
121
+
122
+ winTest('R72 bare remote reaches READY with every authority disarmed and never arms a plane',async()=>{
123
+ const fx=await fixture({statusOnline:true});
124
+ let child=null;
125
+ try{
126
+ child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
127
+ const output=await collect(child);
128
+ const deadline=Date.now()+fixtureTimeoutMs;
129
+ while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)&&child.exitCode===null)await sleep(50);
130
+ assert.match(output.stdout,/\[READY\]/,output.stderr);
131
+ assert.match(output.stdout,/\[AUTH\] process DISARMED \| coding DISARMED \| autonomous DISARMED \| desktop DISARMED \| host DISARMED/);
132
+ const before=await traceCommands(fx.trace);
133
+ assert.deepEqual(before.slice(0,6),['status','status','disarmautonomous','disarmcoding','disarmprocess','status']);
134
+ assert.equal(before.filter(x=>/^arm(?:process|coding|autonomous|host|desktop)$/.test(x)).length,0,'bare remote must issue zero ARM commands');
135
+ child.stdin.end();
136
+ const ended=await boundedCompletion(output.closed);
137
+ assert.equal(ended.timeout,undefined,'bare remote did not stop');
138
+ assert.equal(ended.code,0,output.stderr);
139
+ assert.equal((await traceCommands(fx.trace)).at(-1),'park');
140
+ }finally{
141
+ if(child?.exitCode===null)child.kill('SIGKILL');
142
+ await safeRm(fx.dir);
99
143
  }
100
144
  });
101
145
 
@@ -106,16 +150,16 @@ winTest('bounded remote disarms a stale standing Host grant before READY',async(
106
150
  try{
107
151
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
108
152
  const output=await collect(child);
109
- const commands=await waitFor(fx.trace,items=>items.filter(x=>x==='status').length>=3,{timeoutMs:8000});
153
+ const commands=await waitFor(fx.trace,items=>items.filter(x=>x==='status').length>=3,{timeoutMs:fixtureTimeoutMs});
110
154
  assert.ok(commands.indexOf('disarmhost')>commands.indexOf('status'));
111
- const deadline=Date.now()+3000;
155
+ const deadline=Date.now()+fixtureTimeoutMs;
112
156
  while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)) await sleep(50);
113
157
  assert.match(output.stdout,/\[READY\]/,output.stderr);
114
158
  child.stdin.end();
115
159
  assert.equal((await output.closed).code,0,output.stderr);
116
160
  }finally{
117
161
  if(child&&child.exitCode===null) child.kill('SIGKILL');
118
- await rm(fx.dir,{recursive:true,force:true});
162
+ await safeRm(fx.dir);
119
163
  }
120
164
  });
121
165
 
@@ -125,7 +169,7 @@ winTest('remote --full verifies all five planes before READY and revokes them on
125
169
  try{
126
170
  child=spawn(process.execPath,[cliPath,'remote','--full'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
127
171
  const output=await collect(child);
128
- const deadline=Date.now()+8000;
172
+ const deadline=Date.now()+fixtureTimeoutMs;
129
173
  while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)) await sleep(50);
130
174
  assert.match(output.stdout,/\[AUTH\] process ARMED \| coding ARMED \| autonomous ARMED \| desktop ARMED \| host ARMED/,output.stderr);
131
175
  assert.match(output.stdout,/\[READY\]/);
@@ -137,7 +181,7 @@ winTest('remote --full verifies all five planes before READY and revokes them on
137
181
  assert.deepEqual(after.slice(-8),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','status','machinetest','park']);
138
182
  }finally{
139
183
  if(child?.exitCode===null) child.kill('SIGKILL');
140
- await rm(fx.dir,{recursive:true,force:true});
184
+ await safeRm(fx.dir);
141
185
  }
142
186
  });
143
187
 
@@ -148,7 +192,7 @@ for(const [flag,armedPlane,disarmedPlane] of [['--desktop','desktop','host'],['-
148
192
  try{
149
193
  child=spawn(process.execPath,[cliPath,'remote',flag],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
150
194
  const output=await collect(child);
151
- const deadline=Date.now()+8000;
195
+ const deadline=Date.now()+fixtureTimeoutMs;
152
196
  while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)) await sleep(50);
153
197
  assert.match(output.stdout,/\[READY\]/,output.stderr);
154
198
  assert.match(output.stdout,new RegExp(`${armedPlane} ARMED`));
@@ -160,7 +204,7 @@ for(const [flag,armedPlane,disarmedPlane] of [['--desktop','desktop','host'],['-
160
204
  assert.equal((await output.closed).code,0,output.stderr);
161
205
  }finally{
162
206
  if(child?.exitCode===null) child.kill('SIGKILL');
163
- await rm(fx.dir,{recursive:true,force:true});
207
+ await safeRm(fx.dir);
164
208
  }
165
209
  });
166
210
  }
@@ -173,7 +217,7 @@ winTest('conflicting remote authority modes fail before controller mutation',asy
173
217
  assert.notEqual((await output.closed).code,0);
174
218
  assert.match(output.stderr,/mutually exclusive/);
175
219
  assert.deepEqual(await traceCommands(fx.trace),[]);
176
- }finally{await rm(fx.dir,{recursive:true,force:true});}
220
+ }finally{await safeRm(fx.dir);}
177
221
  });
178
222
 
179
223
  winTest('remote refuses READY when public signed MCP execution probe fails',async()=>{
@@ -182,14 +226,14 @@ winTest('remote refuses READY when public signed MCP execution probe fails',asyn
182
226
  try{
183
227
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
184
228
  const output=await collect(child);
185
- const ended=await Promise.race([output.closed,sleep(12000).then(()=>({timeout:true}))]);
229
+ const ended=await boundedCompletion(output.closed);
186
230
  assert.equal(ended.timeout,undefined,'remote did not fail closed after execution probe failure');
187
231
  assert.notEqual(ended.code,0);
188
232
  assert.doesNotMatch(output.stdout,/\[READY\]|\[OK\] ONLINE/);
189
233
  assert.match(output.stderr,/machinetest|execution probe/i);
190
234
  }finally{
191
235
  if(child?.exitCode===null) child.kill('SIGKILL');
192
- await rm(fx.dir,{recursive:true,force:true});
236
+ await safeRm(fx.dir);
193
237
  }
194
238
  });
195
239
 
@@ -201,14 +245,14 @@ winTest('remote refuses READY when controller snapshot lies about Host enforceme
201
245
  try{
202
246
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
203
247
  const output=await collect(child);
204
- const ended=await Promise.race([output.closed,sleep(12000).then(()=>({timeout:true}))]);
248
+ const ended=await boundedCompletion(output.closed);
205
249
  assert.equal(ended.timeout,undefined,`remote did not reject split authority truth; stdout=${output.stdout.slice(-1200)} stderr=${output.stderr.slice(-1200)} trace=${(await traceCommands(fx.trace)).join(',')}`);
206
250
  assert.notEqual(ended.code,0);
207
251
  assert.doesNotMatch(output.stdout,/\[READY\]|\[OK\] ONLINE/);
208
252
  assert.match(output.stderr,/machinetest|enforcement/i);
209
253
  }finally{
210
254
  if(child?.exitCode===null) child.kill('SIGKILL');
211
- await rm(fx.dir,{recursive:true,force:true});
255
+ await safeRm(fx.dir);
212
256
  }
213
257
  });
214
258
 
@@ -220,7 +264,7 @@ winTest('foreground cleanup retains ownership when status lies about a no-op Hos
220
264
  try{
221
265
  child=spawn(process.execPath,[cliPath,'remote','--full'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
222
266
  const output=await collect(child);
223
- const deadline=Date.now()+8000;
267
+ const deadline=Date.now()+fixtureTimeoutMs;
224
268
  while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)) await sleep(50);
225
269
  assert.match(output.stdout,/\[READY\]/,output.stderr);
226
270
  child.stdin.end();
@@ -230,7 +274,7 @@ winTest('foreground cleanup retains ownership when status lies about a no-op Hos
230
274
  assert.ok(!(await traceCommands(fx.trace)).includes('park'));
231
275
  }finally{
232
276
  if(child?.exitCode===null) child.kill('SIGKILL');
233
- await rm(fx.dir,{recursive:true,force:true});
277
+ await safeRm(fx.dir);
234
278
  }
235
279
  });
236
280
 
@@ -240,26 +284,28 @@ winTest('bare remote PARKED startup does not wait for a long-lived child holding
240
284
  let child=null;
241
285
  try{
242
286
  const startedAt=Date.now();
243
- child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
287
+ child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
244
288
  const output=await collect(child);
245
- const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=4,{timeoutMs:8000});
289
+ const afterStart=await waitFor(fx.trace,commands=>commands.length>=3,{timeoutMs:15000});
246
290
  const elapsed=Date.now()-startedAt;
291
+ assert.deepEqual(afterStart.slice(0,3),['status','start','status']);
292
+ assert.ok(elapsed<12000,`PARKED startup waited on inherited child pipe handles: ${elapsed}ms`);
293
+ const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=4,{timeoutMs:fixtureTimeoutMs});
247
294
  assert.deepEqual(ready.slice(0,8),['status','start','status','status','armprocess','armcoding','armautonomous','status']);
248
- assert.ok(elapsed<7000,`PARKED startup waited on inherited child pipe handles: ${elapsed}ms`);
249
295
  assert.equal(child.exitCode,null,'remote session must remain foreground after PARKED startup');
250
296
  assert.match(output.stdout,/\[BOOT\] Starting bridge\/runtime\.\.\./);
251
- const readyDeadline=Date.now()+3000;
297
+ const readyDeadline=Date.now()+fixtureTimeoutMs;
252
298
  while(Date.now()<readyDeadline&&!/\[OK\] ONLINE/.test(output.stdout)) await sleep(50);
253
299
  assert.match(output.stdout,/\[OK\] ONLINE/);
254
300
  child.stdin.end();
255
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
301
+ const ended=await boundedCompletion(output.closed);
256
302
  assert.equal(ended.timeout,undefined,'remote session did not exit after PARKED startup proof');
257
303
  assert.equal(ended.code,0,output.stderr);
258
304
  }finally{
259
305
  if(child?.exitCode===null) child.kill('SIGKILL');
260
306
  try{const pid=Number((await readFile(fx.spawnedPid,'utf8')).trim());if(Number.isInteger(pid)&&pid>0) process.kill(pid,'SIGKILL');}catch{}
261
307
  await sleep(100);
262
- await rm(fx.dir,{recursive:true,force:true});
308
+ await safeRm(fx.dir);
263
309
  }
264
310
  });
265
311
 
@@ -267,12 +313,12 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
267
313
  const fx=await fixture();
268
314
  let child=null;
269
315
  try{
270
- child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
316
+ child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
271
317
  const output=await collect(child);
272
318
  const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=4);
273
319
  assert.deepEqual(ready.slice(0,8),['status','start','status','status','armprocess','armcoding','armautonomous','status']);
274
320
  assert.equal(child.exitCode,null,'remote session must remain foreground after becoming ready');
275
- const tailDeadline=Date.now()+3000;
321
+ const tailDeadline=Date.now()+fixtureTimeoutMs;
276
322
  while(Date.now()<tailDeadline&&(!/\[AUTH\] process ARMED \| coding ARMED \| autonomous ARMED \| desktop DISARMED \| host DISARMED/.test(output.stdout)||
277
323
  !/\[READY\] DEADBYTE MCP online/.test(output.stdout))) await sleep(50);
278
324
  assert.match(output.stdout,/\[DISPLAY\] ASCII fallback: stdout_not_tty/);
@@ -306,7 +352,7 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
306
352
  '[TOOL OUT] 2026-09-16T00:00:00.001Z #000001 coding_tree {"is_error":false}',
307
353
  '[TOOL OUT] 2026-09-16T00:00:00.002Z #000002 coding_file_read {"is_error":true}'
308
354
  ].join('\n')+'\n','utf8');
309
- const logDeadline=Date.now()+3000;
355
+ const logDeadline=Date.now()+fixtureTimeoutMs;
310
356
  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);
311
357
  assert.doesNotMatch(output.stdout,/\| Arguments:/,'default human view must not print request JSON');
312
358
  assert.match(output.stdout,/^S .*#2 \[abcdef12\] coding_tree projects:src 42ms OK$/m);
@@ -326,7 +372,7 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
326
372
  assert.doesNotMatch(output.stdout,/\[TOOL IN \]|\[TOOL OUT\]/);
327
373
  assert.doesNotMatch(output.stdout,/payload bytes=/);
328
374
  child.stdin.end();
329
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
375
+ const ended=await boundedCompletion(output.closed);
330
376
  assert.equal(ended.timeout,undefined,'remote session did not exit after foreground input closed');
331
377
  const commands=await traceCommands(fx.trace);
332
378
  assert.deepEqual(commands.slice(-8),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','status','machinetest','park']);
@@ -337,7 +383,7 @@ winTest('bare remote uses one unified live timeline, keeps authority semantics,
337
383
  assert.doesNotMatch(output.stdout,/\p{Extended_Pictographic}/u,'piped Windows fallback must remain ASCII-safe');
338
384
  }finally{
339
385
  if(child?.exitCode===null) child.kill();
340
- await rm(fx.dir,{recursive:true,force:true});
386
+ await safeRm(fx.dir);
341
387
  }
342
388
  });
343
389
 
@@ -374,7 +420,7 @@ winTest('remote --resume replays sanitized tool-call and terminal result events
374
420
  deadline=Date.now()+3000;
375
421
  while(Date.now()<deadline&&!/^R .*#4 \[resume-r\] coding_file_read projects:src\/deadbyte-cli\.mjs.*OK$/m.test(firstOutput.stdout)) await sleep(50);
376
422
  first.stdin.end();
377
- const firstEnded=await Promise.race([firstOutput.closed,sleep(6000).then(()=>({timeout:true}))]);
423
+ const firstEnded=await boundedCompletion(firstOutput.closed);
378
424
  assert.equal(firstEnded.timeout,undefined);
379
425
 
380
426
  second=spawn(process.execPath,[cliPath,'remote','--resume',cursor1],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
@@ -395,12 +441,12 @@ winTest('remote --resume replays sanitized tool-call and terminal result events
395
441
  const liveIndex=secondOutput.stdout.indexOf('[LOG] Human live timeline');
396
442
  assert.ok(callReplayIndex>=0&&resultReplayIndex>callReplayIndex&&liveIndex>resultReplayIndex,'resume ordering must be call -> result -> live tail');
397
443
  second.stdin.end();
398
- const secondEnded=await Promise.race([secondOutput.closed,sleep(12000).then(()=>({timeout:true}))]);
444
+ const secondEnded=await boundedCompletion(secondOutput.closed);
399
445
  assert.equal(secondEnded.timeout,undefined);
400
446
  assert.equal(secondEnded.code,0,secondOutput.stderr);
401
447
  }finally{
402
448
  if(first?.exitCode===null) first.kill();if(second?.exitCode===null) second.kill();
403
- await rm(fx.dir,{recursive:true,force:true});
449
+ await safeRm(fx.dir);
404
450
  }
405
451
  });
406
452
 
@@ -424,14 +470,14 @@ winTest('remote --verbose enables sanitized request detail while preserving fore
424
470
  assert.match(output.stdout,/coding_tree\s+\| Arguments: .*"path":"src".*"root_id":"projects"/);
425
471
  assert.doesNotMatch(output.stdout,/DO_NOT_PRINT_VERBOSE_SECRET/);
426
472
  child.stdin.end();
427
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
473
+ const ended=await boundedCompletion(output.closed);
428
474
  assert.equal(ended.timeout,undefined);
429
475
  assert.equal(ended.code,0,output.stderr);
430
476
  const commands=await traceCommands(fx.trace);
431
477
  assert.deepEqual(commands.slice(-8),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','status','machinetest','park']);
432
478
  }finally{
433
479
  if(child?.exitCode===null) child.kill('SIGKILL');
434
- await rm(fx.dir,{recursive:true,force:true});
480
+ await safeRm(fx.dir);
435
481
  }
436
482
  });
437
483
 
@@ -439,7 +485,7 @@ winTest('detached guardian revokes authority, parks, and removes the session mar
439
485
  const fx=await fixture();
440
486
  let child=null;
441
487
  try{
442
- child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
488
+ child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
443
489
  const output=await collect(child);
444
490
  const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=4);
445
491
  assert.deepEqual(ready.slice(0,8),['status','start','status','status','armprocess','armcoding','armautonomous','status']);
@@ -470,7 +516,7 @@ winTest('detached guardian revokes authority, parks, and removes the session mar
470
516
  assert.equal(markerGone,true,'guardian left stale remote-session marker after hard kill');
471
517
  }finally{
472
518
  if(child?.exitCode===null) child.kill();
473
- await rm(fx.dir,{recursive:true,force:true});
519
+ await safeRm(fx.dir);
474
520
  }
475
521
  });
476
522
 
@@ -481,12 +527,12 @@ winTest('guardian retains ownership marker when disarm exits zero but Host remai
481
527
  try{
482
528
  child=spawn(process.execPath,[cliPath,'remote','--full'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
483
529
  const output=await collect(child);
484
- const deadline=Date.now()+8000;
530
+ const deadline=Date.now()+fixtureTimeoutMs;
485
531
  while(Date.now()<deadline&&!/\[READY\]/.test(output.stdout)) await sleep(50);
486
532
  assert.match(output.stdout,/\[READY\]/,output.stderr);
487
533
  child.kill('SIGKILL');
488
534
  await output.closed;
489
- await waitFor(fx.trace,commands=>commands.includes('disarmhost'),{timeoutMs:8000});
535
+ await waitFor(fx.trace,commands=>commands.includes('disarmhost'),{timeoutMs:fixtureTimeoutMs});
490
536
  await sleep(750);
491
537
  const marker=JSON.parse(await readFile(path.join(fx.state,'runtime','remote-session.json'),'utf8'));
492
538
  assert.equal(marker.schema,'deadbyte.remote-session.v2');
@@ -494,23 +540,23 @@ winTest('guardian retains ownership marker when disarm exits zero but Host remai
494
540
  assert.ok(!commands.includes('park'),'guardian must not park after unverified revocation');
495
541
  }finally{
496
542
  if(child?.exitCode===null) child.kill('SIGKILL');
497
- await rm(fx.dir,{recursive:true,force:true});
543
+ await safeRm(fx.dir);
498
544
  }
499
545
  });
500
546
 
501
547
  winTest('bare remote rolls back authority and parks if one plane fails to arm',async()=>{
502
548
  const fx=await fixture({failCommand:'armcoding'});
503
549
  try{
504
- const child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
550
+ const child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
505
551
  const output=await collect(child);
506
- const ended=await Promise.race([output.closed,sleep(12000).then(()=>({timeout:true}))]);
552
+ const ended=await boundedCompletion(output.closed);
507
553
  assert.equal(ended.timeout,undefined,`failed startup did not terminate; stdout=${output.stdout.slice(-1200)} stderr=${output.stderr.slice(-1200)} trace=${(await traceCommands(fx.trace)).join(',')}`);
508
554
  assert.notEqual(ended.code,0);
509
555
  const commands=await traceCommands(fx.trace);
510
556
  assert.deepEqual(commands.slice(0,6),['status','start','status','status','armprocess','armcoding']);
511
557
  assert.deepEqual(commands.slice(-8),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','status','machinetest','park']);
512
558
  assert.doesNotMatch(output.stdout,/Live logs/i);
513
- }finally{await rm(fx.dir,{recursive:true,force:true});}
559
+ }finally{await safeRm(fx.dir);}
514
560
  });
515
561
 
516
562
  winTest('bare remote recovers a stale crashed session before arming a new one',async()=>{
@@ -522,18 +568,18 @@ winTest('bare remote recovers a stale crashed session before arming a new one',a
522
568
  await writeFile(path.join(runtime,'remote-session.json'),JSON.stringify({schema:'deadbyte.remote-session.v1',pid:2147483000,started_at_utc:'2026-01-01T00:00:00.000Z'}),'utf8');
523
569
  child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
524
570
  const output=await collect(child);
525
- const ready=await waitFor(fx.trace,commands=>commands.filter(x=>x==='status').length>=5);
571
+ const ready=await waitFor(fx.trace,commands=>commands.length>=10&&commands[9]==='start');
526
572
  assert.deepEqual(ready.slice(0,8),['disarmautonomous','disarmcoding','disarmprocess','disarmdesktop','disarmhost','status','machinetest','park']);
527
573
  assert.equal(ready[8],'status');
528
574
  assert.equal(ready[9],'start');
529
575
  assert.match(output.stdout,/\[RECOVERY\] Stale remote session pid=2147483000; revoking authority before restart\./);
530
576
  child.stdin.end();
531
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
577
+ const ended=await boundedCompletion(output.closed);
532
578
  assert.equal(ended.timeout,undefined);
533
579
  assert.equal(ended.code,0,output.stderr);
534
580
  }finally{
535
581
  if(child?.exitCode===null) child.kill();
536
- await rm(fx.dir,{recursive:true,force:true});
582
+ await safeRm(fx.dir);
537
583
  }
538
584
  });
539
585
 
@@ -547,13 +593,13 @@ winTest('remote warning lines use deterministic ASCII fallback on piped Windows
547
593
  const markerPath=path.join(fx.state,'runtime','remote-session.json');
548
594
  await writeFile(markerPath,'{invalid-json\n','utf8');
549
595
  child.stdin.end();
550
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
596
+ const ended=await boundedCompletion(output.closed);
551
597
  assert.equal(ended.timeout,undefined,'remote session did not exit after warning fixture');
552
598
  assert.match(output.stderr,/^\[WARN\] remote session marker cleanup:/m);
553
599
  assert.doesNotMatch(output.stderr,/\p{Extended_Pictographic}/u);
554
600
  }finally{
555
601
  if(child?.exitCode===null) child.kill();
556
- await rm(fx.dir,{recursive:true,force:true});
602
+ await safeRm(fx.dir);
557
603
  }
558
604
  });
559
605
 
@@ -561,7 +607,7 @@ winTest('R58 concurrent cold remote claims have one winner and no loser cleanup'
561
607
  const fx=await fixture({statusOnline:true});const children=[],outputs=[];
562
608
  try{
563
609
  for(let i=0;i<3;i++){
564
- const child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
610
+ const child=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
565
611
  children.push(child);outputs.push(await collect(child));
566
612
  }
567
613
  const commands=await waitFor(fx.trace,items=>items.filter(x=>x==='status').length>=3);
@@ -579,18 +625,18 @@ winTest('R58 concurrent cold remote claims have one winner and no loser cleanup'
579
625
  live[0].stdin.end();assert.equal((await outputs[children.indexOf(live[0])].closed).code,0);
580
626
  }finally{
581
627
  for(const child of children)if(child.exitCode===null)child.kill();
582
- await rm(fx.dir,{recursive:true,force:true});
628
+ await safeRm(fx.dir);
583
629
  }
584
630
  });
585
631
 
586
632
  winTest('R58 duplicate remote verifies the real live owner and leaves its authority untouched',async()=>{
587
633
  const fx=await fixture({statusOnline:true});let first=null,second=null;
588
634
  try{
589
- first=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
635
+ first=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
590
636
  const firstOutput=await collect(first);
591
637
  const commands=await waitFor(fx.trace,items=>items.filter(x=>x==='status').length>=3);
592
638
  assert.ok(commands.filter(x=>x==='status').length>=3,firstOutput.stderr);
593
- const ownerReadyDeadline=Date.now()+3000;
639
+ const ownerReadyDeadline=Date.now()+fixtureTimeoutMs;
594
640
  while(Date.now()<ownerReadyDeadline&&!/\[READY\]/.test(firstOutput.stdout)) await sleep(50);
595
641
  assert.match(firstOutput.stdout,/\[READY\]/,firstOutput.stderr);
596
642
  const before=await traceCommands(fx.trace);
@@ -598,7 +644,7 @@ winTest('R58 duplicate remote verifies the real live owner and leaves its author
598
644
  const marker=JSON.parse(await readFile(markerPath,'utf8'));
599
645
  assert.equal(marker.owner_identity.pid,first.pid);
600
646
  assert.equal(marker.guardian_identity.parent_pid,first.pid);
601
- second=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
647
+ second=spawn(process.execPath,[cliPath,'remote','--operator'],{env:fx.env,stdio:['pipe','pipe','pipe'],windowsHide:true});
602
648
  const secondOutput=await collect(second);
603
649
  const stopped=await secondOutput.closed;
604
650
  assert.notEqual(stopped.code,0);
@@ -609,7 +655,7 @@ winTest('R58 duplicate remote verifies the real live owner and leaves its author
609
655
  first.stdin.end();assert.equal((await firstOutput.closed).code,0,firstOutput.stderr);
610
656
  }finally{
611
657
  if(first?.exitCode===null)first.kill();if(second?.exitCode===null)second.kill();
612
- await rm(fx.dir,{recursive:true,force:true});
658
+ await safeRm(fx.dir);
613
659
  }
614
660
  });
615
661
 
@@ -624,14 +670,14 @@ winTest('bare remote refuses unverified legacy ownership without touching author
624
670
  const output=await collect(child);
625
671
  await sleep(500);
626
672
  if(child.exitCode===null) child.stdin.end();
627
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
673
+ const ended=await boundedCompletion(output.closed);
628
674
  assert.equal(ended.timeout,undefined);
629
675
  assert.notEqual(ended.code,0);
630
676
  assert.deepEqual(await traceCommands(fx.trace),[]);
631
677
  assert.match(output.stderr,/remote session ownership unverified/i);
632
678
  }finally{
633
679
  if(child?.exitCode===null) child.kill();
634
- await rm(fx.dir,{recursive:true,force:true});
680
+ await safeRm(fx.dir);
635
681
  }
636
682
  });
637
683
 
@@ -640,11 +686,11 @@ winTest('explicit remote status remains a one-shot controller command',async()=>
640
686
  try{
641
687
  const child=spawn(process.execPath,[cliPath,'remote','status'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
642
688
  const output=await collect(child);
643
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
689
+ const ended=await boundedCompletion(output.closed);
644
690
  assert.equal(ended.timeout,undefined);
645
691
  assert.equal(ended.code,0,output.stderr);
646
692
  assert.deepEqual(await traceCommands(fx.trace),['status']);
647
- }finally{await rm(fx.dir,{recursive:true,force:true});}
693
+ }finally{await safeRm(fx.dir);}
648
694
  });
649
695
 
650
696
  winTest('explicit remote status keeps the coherent runtime one-shot and silent',async()=>{
@@ -659,12 +705,12 @@ winTest('explicit remote status keeps the coherent runtime one-shot and silent',
659
705
  }),'utf8');
660
706
  const child=spawn(process.execPath,[cliPath,'remote','status'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
661
707
  const output=await collect(child);
662
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
708
+ const ended=await boundedCompletion(output.closed);
663
709
  assert.equal(ended.timeout,undefined);
664
710
  assert.equal(ended.code,0,output.stderr);
665
711
  assert.doesNotMatch(output.stderr,/VERSION SKEW/);
666
712
  assert.deepEqual(await traceCommands(fx.trace),['status']);
667
- }finally{await rm(fx.dir,{recursive:true,force:true});}
713
+ }finally{await safeRm(fx.dir);}
668
714
  });
669
715
 
670
716
  winTest('bare remote surfaces bounded controller-start-failure evidence instead of only exit code',async()=>{
@@ -672,12 +718,12 @@ winTest('bare remote surfaces bounded controller-start-failure evidence instead
672
718
  try{
673
719
  const child=spawn(process.execPath,[cliPath,'remote'],{env:fx.env,stdio:['ignore','pipe','pipe'],windowsHide:true});
674
720
  const output=await collect(child);
675
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
721
+ const ended=await boundedCompletion(output.closed);
676
722
  assert.equal(ended.timeout,undefined,'failed start did not terminate');
677
723
  assert.notEqual(ended.code,0);
678
724
  assert.match(output.stderr,/fixture controller evidence detail/);
679
725
  assert.match(output.stderr,/controller-start-failure/i);
680
- }finally{await rm(fx.dir,{recursive:true,force:true});}
726
+ }finally{await safeRm(fx.dir);}
681
727
  });
682
728
 
683
729
 
@@ -711,11 +757,11 @@ winTest('remote --trace --filter selects presentation without dropping journaled
711
757
  const journal=JSON.parse(await readFile(path.join(fx.state,'runtime','remote-results',marker.result_session_id+'.json'),'utf8'));
712
758
  assert.equal(journal.events.length,4,'presentation filter must not remove journal evidence');
713
759
  child.stdin.end();
714
- const ended=await Promise.race([output.closed,sleep(6000).then(()=>({timeout:true}))]);
760
+ const ended=await boundedCompletion(output.closed);
715
761
  assert.equal(ended.timeout,undefined);
716
762
  assert.equal(ended.code,0,output.stderr);
717
763
  }finally{
718
764
  if(child?.exitCode===null) child.kill('SIGKILL');
719
- await rm(fx.dir,{recursive:true,force:true});
765
+ await safeRm(fx.dir);
720
766
  }
721
767
  });