deadbyte-mcp 0.11.1 → 0.11.2

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.
@@ -5,7 +5,7 @@ import { mkdtemp, mkdir, readFile, rm, writeFile, readdir } from 'node:fs/promis
5
5
  import os from 'node:os';
6
6
  import path from 'node:path';
7
7
  import { spawn } from 'node:child_process';
8
- import * as parity from '../scripts/release-parity.mjs';
8
+ import * as parity from '../scripts/release-parity-r38.mjs';
9
9
  import { createToolAudit } from '../src/tool-audit.mjs';
10
10
  import { verifyAuditChain } from '../src/audit-verify.mjs';
11
11
  import { generateTrustKeypair } from '../src/trust.mjs';
@@ -86,12 +86,12 @@ test('audit restart reconciles an orphan request with an explicit interrupted re
86
86
  }finally{await rm(stateRoot,{recursive:true,force:true});}
87
87
  });
88
88
 
89
- test('Windows R37 gate emits manifest-bound machine-readable evidence outside the candidate tree', async()=>{
89
+ test('Windows R38 gate emits manifest-bound machine-readable evidence outside the candidate tree', async()=>{
90
90
  const stateRoot=await temp('deadbyte-r33-windows-evidence-');
91
91
  try{
92
- const gate=await readFile(path.join(root,'scripts','gate-windows.ps1'),'utf8');
93
- assert.match(gate,/windows-gate-evidence\.mjs/,'gate-windows.ps1 must invoke the evidence writer');
94
- const result=await run(process.execPath,[path.join(root,'scripts','windows-gate-evidence.mjs')],{
92
+ const gate=await readFile(path.join(root,'scripts','gate-windows-r38.ps1'),'utf8');
93
+ assert.match(gate,/windows-gate-evidence-r38\.mjs/,'gate-windows-r38.ps1 must invoke the evidence writer');
94
+ const result=await run(process.execPath,[path.join(root,'scripts','windows-gate-evidence-r38.mjs')],{
95
95
  cwd:root,env:{...process.env,DEADBYTE_STATE_ROOT:stateRoot}
96
96
  });
97
97
  assert.equal(result.code,0,result.stderr||result.stdout);
@@ -99,12 +99,12 @@ test('Windows R37 gate emits manifest-bound machine-readable evidence outside th
99
99
  assert.equal(summary.status,'written');
100
100
  const evidence=JSON.parse(await readFile(summary.path,'utf8'));
101
101
  const manifestSha=sha256(await readFile(path.join(root,'MANIFEST.SHA256')));
102
- assert.equal(evidence.schema,'deadbyte.r37-windows-gate.v1');
102
+ assert.equal(evidence.schema,'deadbyte.r38-windows-gate.v1');
103
103
  assert.equal(evidence.status,'passed');
104
104
  assert.equal(evidence.exit_code,0);
105
- assert.equal(evidence.version,'0.11.1');
105
+ assert.equal(evidence.version,'0.11.2');
106
106
  assert.equal(evidence.manifest_sha256,manifestSha);
107
- assert.equal(evidence.marker,'DEADBYTE V0.11.1 / R37 WINDOWS BATCH GATE: PASS');
107
+ assert.equal(evidence.marker,'DEADBYTE V0.11.2 / R38 WINDOWS BATCH GATE: PASS');
108
108
  assert.ok(summary.path.startsWith(path.join(stateRoot,'evidence','release')));
109
109
  }finally{await rm(stateRoot,{recursive:true,force:true});}
110
110
  });
@@ -2,8 +2,8 @@ import test from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { R34_EXPECTED_TOOLS } from '../src/remote-mcp-r34-parity-client.mjs';
5
- import { validateParityEvidence } from '../scripts/release-parity.mjs';
6
- import { verifyFinalClosureObject } from '../scripts/final-closure-verify.mjs';
5
+ import { validateParityEvidence } from '../scripts/release-parity-r38.mjs';
6
+ import { verifyFinalClosureObject } from '../scripts/final-closure-verify-r38.mjs';
7
7
 
8
8
  const root = new URL('../', import.meta.url);
9
9
  const text = rel => readFile(new URL(rel, root), 'utf8');
@@ -19,28 +19,28 @@ test('R34 public parity catalog is exact, unique, and includes production coding
19
19
 
20
20
  test('release parity and final verifier are package entry points', async () => {
21
21
  const pkg = JSON.parse(await text('package.json'));
22
- assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity.mjs');
23
- assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure.mjs');
24
- assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify.mjs');
22
+ assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity-r38.mjs');
23
+ assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure-r38.mjs');
24
+ assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify-r38.mjs');
25
25
  assert.equal(typeof validateParityEvidence, 'function');
26
26
  assert.equal(typeof verifyFinalClosureObject, 'function');
27
27
  });
28
28
 
29
- test('R37 final closure verifier is implementation-independent from production helpers', async () => {
30
- const verifier = await text('scripts/final-closure-verify.mjs');
31
- const writer = await text('scripts/final-closure.mjs');
29
+ test('R38 final closure verifier is implementation-independent from production helpers', async () => {
30
+ const verifier = await text('scripts/final-closure-verify-r38.mjs');
31
+ const writer = await text('scripts/final-closure-r38.mjs');
32
32
  assert.doesNotMatch(verifier, /from ['"]\.\.\/src\//);
33
33
  assert.match(verifier, /DEADBYTE-R27-SLOT-UPDATE-V1/);
34
34
  assert.match(verifier, /DEADBYTE-MACHINE-PING-V1/);
35
- assert.match(verifier, /DEADBYTE-R37-FINAL-CLOSURE-V1/);
36
- assert.match(writer, /pointer\.version==='0\.11\.1'/);
37
- assert.match(verifier, /envelope\.body\.version==='0\.11\.1'/);
38
- assert.match(verifier, /release_label==='R37 FINAL MACHINE BASELINE'/);
39
- assert.match(verifier, /08c2a0008b1f84c90f7ce7faa1e3decbd03f33612bc0fdc7d1ba591b548798e8/);
35
+ assert.match(verifier, /DEADBYTE-R38-FINAL-CLOSURE-V1/);
36
+ assert.match(writer, /pointer\.version==='0\.11\.2'/);
37
+ assert.match(verifier, /envelope\.body\.version==='0\.11\.2'/);
38
+ assert.match(verifier, /release_label==='R38 FINAL MACHINE BASELINE'/);
39
+ assert.match(verifier, /220fac89dd82cdcdddb82cd7d0b71b768f84a5c87d57ebaca0f5383f33d97a76/);
40
40
  });
41
41
 
42
42
  test('final closure verifier canonicalizes traversal order before exact-tree comparison', async () => {
43
- const verifier = await text('scripts/final-closure-verify.mjs');
43
+ const verifier = await text('scripts/final-closure-verify-r38.mjs');
44
44
  assert.match(verifier, /const actual=\(await walk\(root\)\)\.filter\(rel=>rel!==manifestName\)\.sort\(\(a,b\)=>a\.localeCompare\(b,'en'\)\);/);
45
45
  assert.match(verifier, /const expected=\[\.\.\.entries\.keys\(\)\]\.sort\(\(a,b\)=>a\.localeCompare\(b,'en'\)\);/);
46
46
  });
@@ -0,0 +1,74 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { validateParityEvidence, R38_PREDECESSOR_RELEASE_ID, R38_PREDECESSOR_MANIFEST } from '../scripts/release-parity-r38.mjs';
5
+ import { verifyFinalClosureObject } from '../scripts/final-closure-verify-r38.mjs';
6
+
7
+ const root=new URL('../',import.meta.url);
8
+ const text=rel=>readFile(new URL(rel,root),'utf8');
9
+
10
+ function parityFixture(){
11
+ const manifest='a'.repeat(64);
12
+ return {
13
+ schema:'deadbyte.r38-parity.v1',status:'passed',execution_provider:'deadbyte_mcp',rdc_operation_count:0,
14
+ candidate:{release_id:`v0.11.2-${manifest.slice(0,16)}`,version:'0.11.2',manifest_sha256:manifest},
15
+ immutable_slot:{protected:true,release_root:'C:/immutable/r38',development_root:'D:/Projects/deadbyte-mcp-r36-dev'},
16
+ local_full:{status:'passed',tool_count:76,strict_output_schemas:true},
17
+ public_compact:{status:'passed',tool_count:41,capability_closure:true,gateway_count:5},
18
+ autonomous:{status:'passed',signed_release_verified:true,observed_failure_before_replan:true},
19
+ before_rollback_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false},
20
+ rollback:{state:'completed'},stage_restore:{status:'restored',manifest_sha256:manifest},restore:{state:'completed'},
21
+ predecessor:{release_id:R38_PREDECESSOR_RELEASE_ID,version:'0.11.1',manifest_sha256:R38_PREDECESSOR_MANIFEST},
22
+ predecessor_disarmed:{status:'passed',tool_count:41,capability_closure:true},
23
+ successor:{release_id:`v0.11.2-${manifest.slice(0,16)}`,version:'0.11.2',manifest_sha256:manifest},
24
+ successor_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false},
25
+ requirements:Object.fromEntries(['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface'].map(key=>[key,true]))
26
+ };
27
+ }
28
+
29
+ test('R38 parity validator requires full-76, compact closure, exact public 0.11.1 predecessor and immutable-slot separation',()=>{
30
+ const good=parityFixture();
31
+ assert.equal(validateParityEvidence(good),true);
32
+ assert.throws(()=>validateParityEvidence({...good,local_full:{...good.local_full,tool_count:75}}),/full 76/i);
33
+ assert.throws(()=>validateParityEvidence({...good,public_compact:{...good.public_compact,capability_closure:false}}),/compact closure/i);
34
+ assert.throws(()=>validateParityEvidence({...good,predecessor:{...good.predecessor,manifest_sha256:'b'.repeat(64)}}),/predecessor/i);
35
+ assert.throws(()=>validateParityEvidence({...good,immutable_slot:{...good.immutable_slot,development_root:good.immutable_slot.release_root}}),/immutable-slot/i);
36
+ assert.throws(()=>validateParityEvidence({...good,stage_restore:{status:'missing',manifest_sha256:good.candidate.manifest_sha256}}),/stage restore/i);
37
+ });
38
+
39
+ test('R38 parity captures R38 bridge, exact public 0.11.1 predecessor, stage reseed and successor restore',async()=>{
40
+ const parity=await text('scripts/release-parity-r38.mjs');
41
+ assert.match(parity,/R38_PREDECESSOR_RELEASE_ID='v0\.11\.1-220fac89dd82cdcd'/);
42
+ assert.match(parity,/220fac89dd82cdcdddb82cd7d0b71b768f84a5c87d57ebaca0f5383f33d97a76/);
43
+ assert.match(parity,/const stageRestore=await restoreFrozenStage/);
44
+ assert.match(parity,/publicR38Disarmed/);
45
+ assert.match(parity,/scheduleDeferred\('activate',candidateManifest,\{bridgeRoot:successorBridge\.root,bridgeScriptSha256:successorBridge\.sha256\}\)/);
46
+ });
47
+
48
+ test('R38 current final closure writer and independent verifier bind R38 domains and public 0.11.1 predecessor',async()=>{
49
+ const [writer,verifier]=await Promise.all([text('scripts/final-closure-r38.mjs'),text('scripts/final-closure-verify-r38.mjs')]);
50
+ assert.equal(typeof verifyFinalClosureObject,'function');
51
+ assert.match(writer,/DEADBYTE-R38-FINAL-CLOSURE-V1/);
52
+ assert.match(writer,/deadbyte\.r38-final-closure\.v1/);
53
+ assert.match(writer,/pointer\.version==='0\.11\.2'/);
54
+ assert.match(writer,/R38 FINAL MACHINE BASELINE/);
55
+ assert.match(writer,/deadbyte\.r38-parity\.v1/);
56
+ assert.match(writer,/deadbyte\.r38-windows-gate\.v1/);
57
+ assert.match(writer,/R38_PREDECESSOR_RELEASE_ID/);
58
+ assert.doesNotMatch(verifier,/from ['"]\.\.\/src\//);
59
+ assert.match(verifier,/DEADBYTE-R38-FINAL-CLOSURE-V1/);
60
+ assert.match(verifier,/deadbyte\.r38-final-closure\.v1/);
61
+ assert.match(verifier,/envelope\.body\.version==='0\.11\.2'/);
62
+ assert.match(verifier,/R38 FINAL MACHINE BASELINE/);
63
+ assert.match(verifier,/deadbyte\.r38-parity\.v1/);
64
+ assert.match(verifier,/deadbyte\.r38-windows-gate\.v1/);
65
+ assert.match(verifier,/220fac89dd82cdcdddb82cd7d0b71b768f84a5c87d57ebaca0f5383f33d97a76/);
66
+ });
67
+
68
+ test('R38 bounded public parity suite covers current release identity and agent fabric',async()=>{
69
+ const script=await text('scripts/release-parity-tests-r38.ps1');
70
+ assert.match(script,/r38-finalization\.test\.mjs/);
71
+ assert.match(script,/release-version\.test\.mjs/);
72
+ assert.match(script,/r37-agent-fabric\.test\.mjs/);
73
+ assert.match(script,/remote-live-log-r37\.test\.mjs/);
74
+ });
@@ -30,16 +30,23 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
30
30
  ]},
31
31
  LocalReadyUri:'http://127.0.0.1:8787/healthz',UrlRegex:'https://x',McpUrlFile:'C:/mcp-url.txt',McpUrlFileSha256:EXE,McpPathFile:'C:/token.txt',StartTimeoutSeconds:30,ProbeTimeoutSeconds:3};
32
32
  const coding={schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:'C:/old/coding.json',evidence_dir:'C:/old/evidence',
33
- roots:{core:{path:'C:/old/core',read:true,write:true,exec:true,deny_paths:['node_modules']}},commands:{tests:command()},max_read_bytes:524288,max_write_bytes:2097152};
33
+ roots:{core:{path:'C:/old/core',read:true,write:true,exec:true,deny_paths:['node_modules']}},commands:{tests:command(),powershell_script:command()},max_read_bytes:524288,max_write_bytes:2097152};
34
34
  const autonomous={schema:'deadbyte.autonomous-policy.v1',enabled:true,lease_file:'C:/old/auto.json',evidence_dir:'C:/old/auto-evidence',coding_policy_sha256:'0'.repeat(64),root_ids:['core'],planner:{backend:'client_sampling',max_tokens:4096},
35
- profiles:{gate:{kind:'command',root_id:'core',command_id:'tests',script_path:'scripts/gate.ps1',script_sha256:'0'.repeat(64),args:[],cwd:'.',timeout_ms:120000,expect_exit_code:0,required_for_release:true,run_after_mutation:true,description:'gate'}},
35
+ profiles:{
36
+ gate:{kind:'command',root_id:'core',command_id:'tests',script_path:'scripts/gate.ps1',script_sha256:'0'.repeat(64),args:[],cwd:'.',timeout_ms:120000,expect_exit_code:0,required_for_release:true,run_after_mutation:true,description:'gate'},
37
+ 'windows-release':{kind:'command',root_id:'core',command_id:'powershell_script',script_path:'scripts/gate-windows-old.ps1',script_sha256:'0'.repeat(64),args:[],cwd:'.',timeout_ms:300000,expect_exit_code:0,required_for_release:true,run_after_mutation:false,description:'historical Windows release gate'}
38
+ },
36
39
  limits:{max_iterations:12,max_mutations:24,max_wall_ms:1800000,max_context_bytes:1048576,max_diff_bytes:1048576,max_files_per_diff:8}};
37
40
  const host={schema:'deadbyte.host-policy.v1',enabled:true,arm_file:'C:/old/host.json',roots:{core:{path:'C:/old/core',read:true,write:true,exec:true}},commands:{tests:command()},max_read_bytes:262144,max_write_bytes:1048576};
38
41
  const processPolicy={schema:'deadbyte.process-policy.v1',enabled:true,grant_file:'C:/old/process-grant.json',state_dir:'C:/old/process-state',
39
42
  native_host:{path:'C:/old/deadbyte-process-host.exe',sha256:'0'.repeat(64)},
40
43
  roots:{core:{path:'C:/old/core',deny_paths:['node_modules']}},
41
44
  profiles:{probe:{executable:'C:/Windows/System32/ping.exe',executable_sha256:EXE,root_ids:['core'],prefix_args:['127.0.0.1','-n','2'],max_args:0,max_arg_bytes:256,max_sessions:1,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}}}};
42
- const development=path.join(base,'development'); await mkdir(development,{recursive:true}); await mkdir(path.join(development,'scripts'),{recursive:true}); await writeFile(path.join(development,'scripts','gate.ps1'),'Write-Output gate\n');
45
+ const development=path.join(base,'development'); await mkdir(development,{recursive:true}); await mkdir(path.join(development,'scripts'),{recursive:true});
46
+ await writeFile(path.join(development,'scripts','gate.ps1'),'Write-Output gate\n');
47
+ await writeFile(path.join(development,'scripts','gate-windows-old.ps1'),'Write-Output old-gate\n');
48
+ await writeFile(path.join(development,'scripts','gate-windows-current.ps1'),'Write-Output current-gate\n');
49
+ await writeFile(path.join(development,'package.json'),JSON.stringify({scripts:{'gate:windows':'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-current.ps1'}}));
43
50
  const result=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy});
44
51
  const verified=await verifyGenerationBundle(result.generation_root,result.generation_manifest_sha256);
45
52
  assert.equal(verified.files,6);
@@ -62,6 +69,9 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
62
69
  assert.equal(generatedAuto.coding_policy_sha256,sha(codingBytes));
63
70
  assert.equal(generatedAuto.lease_file,path.join(path.resolve(state),'runtime','autonomous-grant.json'));
64
71
  assert.equal(generatedAuto.profiles.gate.script_sha256,sha(Buffer.from('Write-Output gate\n')));
72
+ assert.equal(generatedAuto.profiles['windows-release'].script_path,'scripts/gate-windows-current.ps1');
73
+ assert.equal(generatedAuto.profiles['windows-release'].script_sha256,sha(Buffer.from('Write-Output current-gate\n')));
74
+ assert.equal(generatedAuto.profiles['windows-release'].description,'Full Windows target release gate; runs only when finish is requested.');
65
75
  const generatedHost=JSON.parse(await readFile(result.host_policy_path,'utf8'));
66
76
  assert.equal(generatedHost.roots.core.path,path.resolve(development));
67
77
  assert.notEqual(generatedHost.roots.core.path,path.resolve(release));
@@ -5,40 +5,59 @@ import { createHash } from 'node:crypto';
5
5
 
6
6
  const root=new URL('../',import.meta.url);
7
7
  const text=rel=>readFile(new URL(rel,root),'utf8');
8
- const R37_PREDECESSOR_RELEASE_ID='v0.11.0-08c2a0008b1f84c9';
9
- const R37_PREDECESSOR_MANIFEST='08c2a0008b1f84c90f7ce7faa1e3decbd03f33612bc0fdc7d1ba591b548798e8';
8
+ const R38_PREDECESSOR_RELEASE_ID='v0.11.1-220fac89dd82cdcd';
9
+ const R38_PREDECESSOR_MANIFEST='220fac89dd82cdcdddb82cd7d0b71b768f84a5c87d57ebaca0f5383f33d97a76';
10
10
 
11
- test('R37 patch release authority agrees on V0.11.1 and preserves exact public 0.11.0 predecessor',async()=>{
11
+ test('R38 hotfix authority agrees on V0.11.2 and preserves exact public 0.11.1 predecessor',async()=>{
12
12
  const pkg=JSON.parse(await text('package.json'));
13
13
  const [version,controller,gate,readme,architecture,controllerReadme,deferred,parity,closure,closureVerify,windowsGate,semanticConfig]=await Promise.all([
14
- text('src/version.mjs'),text('controller/deadbyte-controller.ps1'),text('scripts/gate-windows.ps1'),
14
+ text('src/version.mjs'),text('controller/deadbyte-controller.ps1'),text('scripts/gate-windows-r38.ps1'),
15
15
  text('README.txt'),text('docs/ARCHITECTURE.md'),text('controller/README.TXT'),
16
- text('scripts/deferred-slot-operation.mjs'),text('scripts/release-parity.mjs'),text('scripts/final-closure.mjs'),
17
- text('scripts/final-closure-verify.mjs'),text('scripts/windows-gate-evidence.mjs'),
16
+ text('scripts/deferred-slot-operation-r38.mjs'),text('scripts/release-parity-r38.mjs'),text('scripts/final-closure-r38.mjs'),
17
+ text('scripts/final-closure-verify-r38.mjs'),text('scripts/windows-gate-evidence-r38.mjs'),
18
18
  text('controller/deadbyte-semantic-lsp-config.json')
19
19
  ]);
20
- assert.equal(pkg.version,'0.11.1');
21
- assert.match(version,/DEADBYTE_VERSION = '0\.11\.1'/);
22
- assert.match(controller,/CONTROLLER V0\.11\.1 \/ R37/);
23
- assert.match(gate,/DEADBYTE V0\.11\.1 \/ R37 WINDOWS BATCH GATE: PASS/);
24
- assert.match(readme,/^DEADBYTE MCP V0\.11\.1 \/ R37 PRODUCTION BASELINE$/m);
25
- assert.match(architecture,/^# DEADBYTE MCP V0\.11\.1 \/ R37 ARCHITECTURE$/m);
26
- assert.match(controllerReadme,/^DEADBYTE MCP V0\.11\.1 \/ R37 CONTROLLER$/m);
27
- assert.match(deferred,/--expected-version','0\.11\.1'/);
28
- assert.match(parity,/R37_PREDECESSOR_RELEASE_ID='v0\.11\.0-08c2a0008b1f84c9'/);
29
- assert.match(parity,new RegExp(R37_PREDECESSOR_MANIFEST));
30
- assert.match(parity,/version==='0\.11\.1'|version:'0\.11\.1'/);
31
- assert.match(closure,/version:'0\.11\.1'/);
32
- assert.match(closureVerify,/DEADBYTE V0\.11\.1 \/ R37 WINDOWS BATCH GATE: PASS/);
33
- assert.match(windowsGate,/version:'0\.11\.1'/);
20
+ assert.equal(pkg.version,'0.11.2');
21
+ assert.equal(pkg.scripts['gate:windows'],'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r38.ps1');
22
+ assert.equal(pkg.scripts['self-update:deferred'],'node scripts/deferred-slot-operation-r38.mjs');
23
+ assert.equal(pkg.scripts['release:parity'],'node scripts/release-parity-r38.mjs');
24
+ assert.equal(pkg.scripts['release:final:write'],'node scripts/final-closure-r38.mjs');
25
+ assert.equal(pkg.scripts['release:final:verify'],'node scripts/final-closure-verify-r38.mjs');
26
+ assert.match(version,/DEADBYTE_VERSION = '0\.11\.2'/);
27
+ assert.match(controller,/CONTROLLER V0\.11\.2 \/ R38/);
28
+ assert.match(gate,/DEADBYTE V0\.11\.2 \/ R38 WINDOWS BATCH GATE: PASS/);
29
+ assert.match(readme,/^DEADBYTE MCP V0\.11\.2 \/ R38 HOTFIX BASELINE$/m);
30
+ assert.match(architecture,/^# DEADBYTE MCP V0\.11\.2 \/ R38 ARCHITECTURE$/m);
31
+ assert.match(controllerReadme,/^DEADBYTE MCP V0\.11\.2 \/ R38 CONTROLLER$/m);
32
+ assert.match(deferred,/--expected-version','0\.11\.2'/);
33
+ assert.match(parity,/R38_PREDECESSOR_RELEASE_ID='v0\.11\.1-220fac89dd82cdcd'/);
34
+ assert.match(parity,new RegExp(R38_PREDECESSOR_MANIFEST));
35
+ assert.match(parity,/version==='0\.11\.2'|version:'0\.11\.2'/);
36
+ assert.match(closure,/version:'0\.11\.2'/);
37
+ assert.match(closureVerify,/DEADBYTE V0\.11\.2 \/ R38 WINDOWS BATCH GATE: PASS/);
38
+ assert.match(windowsGate,/version:'0\.11\.2'/);
34
39
  assert.equal(createHash('sha256').update(Buffer.from(semanticConfig,'utf8')).digest('hex'),'d274b099a298c1033fea8f1e8849751693bbc0448778d619400acb82d4f53a3b');
40
+ assert.equal(R38_PREDECESSOR_RELEASE_ID,'v0.11.1-220fac89dd82cdcd');
35
41
  });
36
42
 
37
- test('R37 patch keeps capability surface and fixes ONLINE remote startup without restoring verbose mode',async()=>{
38
- const [parity,cli]=await Promise.all([text('src/remote-mcp-r36-parity-client.mjs'),text('src/deadbyte-cli.mjs')]);
39
- assert.match(parity,/R36_EXPECTED_TOOLS\.length !== 76/);
40
- assert.match(parity,/R36_COMPACT_TOOL_LIMIT=42/);
43
+ test('R38 hotfix keeps ONLINE reuse and fixes PowerShell $Host recovery collision',async()=>{
44
+ const [cli,controller]=await Promise.all([text('src/deadbyte-cli.mjs'),text('controller/deadbyte-controller.ps1')]);
41
45
  assert.match(cli,/controllerRuntimeReady/);
42
46
  assert.match(cli,/Runtime already ONLINE; reusing verified bridge\/cloud\/supervisor/);
43
- assert.doesNotMatch(cli,/remote --verbose/);
47
+ const start=controller.indexOf('function Recover-AutonomousSupervisor');
48
+ const end=controller.indexOf('function Show-State',start);
49
+ assert.ok(start>=0&&end>start,'supervisor recovery block missing');
50
+ const block=controller.slice(start,end);
51
+ assert.doesNotMatch(block,/\$host\s*=/i);
52
+ assert.match(block,/\$hostStatus\s*=\s*Get-HostArmStatus/);
53
+ });
54
+
55
+ test('sealed R37 tooling remains historical 0.11.1 authority',async()=>{
56
+ const [parity,gate,closure]=await Promise.all([
57
+ text('scripts/release-parity.mjs'),text('scripts/gate-windows.ps1'),text('scripts/final-closure.mjs')
58
+ ]);
59
+ assert.match(parity,/R37_PREDECESSOR_RELEASE_ID='v0\.11\.0-08c2a0008b1f84c9'/);
60
+ assert.match(parity,/version==='0\.11\.1'|version:'0\.11\.1'/);
61
+ assert.match(gate,/DEADBYTE V0\.11\.1 \/ R37 WINDOWS BATCH GATE: PASS/);
62
+ assert.match(closure,/version:'0\.11\.1'/);
44
63
  });