deadbyte-mcp 0.15.0 → 0.15.1

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 (77) hide show
  1. package/MANIFEST.SHA256 +76 -41
  2. package/PROVENANCE.json +10 -0
  3. package/R45-PARENT.json +18 -0
  4. package/README.txt +14 -14
  5. package/RELEASE.json +37 -0
  6. package/SBOM.cdx.json +46 -0
  7. package/TEST-MATRIX.json +31 -0
  8. package/bin/deadbyte-hardware-observer-r45.exe +0 -0
  9. package/bin/deadbyte-hardware-observer-r45.obj +0 -0
  10. package/controller/README.TXT +2 -2
  11. package/controller/deadbyte-controller.ps1 +2 -2
  12. package/docs/ARCHITECTURE.md +1 -1
  13. package/native/deadbyte-hardware-observer.cpp +308 -0
  14. package/package.json +12 -7
  15. package/scripts/autonomous-tests.ps1 +2 -2
  16. package/scripts/build-hardware-r45.ps1 +71 -0
  17. package/scripts/deferred-slot-operation-r45.mjs +126 -0
  18. package/scripts/derive-r45-parent.mjs +24 -0
  19. package/scripts/derive-r45-release.mjs +72 -0
  20. package/scripts/derive-r45-tests.mjs +20 -0
  21. package/scripts/final-closure-r45.mjs +121 -0
  22. package/scripts/final-closure-verify-r45.mjs +220 -0
  23. package/scripts/finalize-r45.mjs +219 -0
  24. package/scripts/full-regression-r45.mjs +20 -0
  25. package/scripts/full-regression-summary-r45.mjs +14 -0
  26. package/scripts/gate-windows-r45.ps1 +44 -0
  27. package/scripts/init-host-policy.ps1 +39 -1
  28. package/scripts/inspect-active-release-r45.mjs +20 -0
  29. package/scripts/release-manifest.mjs +3 -1
  30. package/scripts/release-parity-r45.mjs +253 -0
  31. package/scripts/release-parity-tests-r45.ps1 +8 -0
  32. package/scripts/verify-r45-parent.mjs +142 -0
  33. package/scripts/windows-gate-evidence-r45.mjs +60 -0
  34. package/src/autonomous-runtime.mjs +12 -7
  35. package/src/capability-ledger.mjs +1 -0
  36. package/src/compact-gateway-mcp-tools.mjs +4 -2
  37. package/src/deadbyte-cli.mjs +17 -9
  38. package/src/doctor-r45.mjs +65 -0
  39. package/src/host-plane.mjs +133 -85
  40. package/src/mcp-server.mjs +64 -23
  41. package/src/native-diff-v2.mjs +9 -4
  42. package/src/native-diff.mjs +29 -7
  43. package/src/observation-mcp-tools.mjs +5 -1
  44. package/src/observation-output-contracts.mjs +8 -0
  45. package/src/observation-runtime.mjs +33 -2
  46. package/src/observation-smoke-client.mjs +6 -2
  47. package/src/output-contracts.mjs +27 -11
  48. package/src/r45-compact-disarmed-probe.mjs +74 -0
  49. package/src/r45-full-surface-probe.mjs +34 -0
  50. package/src/release-generation.mjs +1 -0
  51. package/src/remote-mcp-r45-parity-client.mjs +206 -0
  52. package/src/runtime-update.mjs +36 -8
  53. package/src/version.mjs +1 -1
  54. package/test/agent-runtime.test.mjs +1 -0
  55. package/test/autonomous-loop.test.mjs +24 -0
  56. package/test/autonomous-runtime.test.mjs +1 -0
  57. package/test/cli-entrypoint.test.mjs +4 -4
  58. package/test/coding-plane.test.mjs +1 -0
  59. package/test/compact-max-catalog-r45.test.mjs +99 -0
  60. package/test/contained.test.mjs +23 -11
  61. package/test/controller.test.mjs +5 -1
  62. package/test/core.test.mjs +1 -1
  63. package/test/full-max-catalog-r45.test.mjs +91 -0
  64. package/test/hardware-observation-r45.test.mjs +44 -0
  65. package/test/host-inline-r45.test.mjs +67 -0
  66. package/test/machine-mcp-integration.test.mjs +1 -0
  67. package/test/observation-mcp-tools.test.mjs +4 -3
  68. package/test/output-schema.test.mjs +1 -0
  69. package/test/package-boundary.test.mjs +1 -1
  70. package/test/production-docs.test.mjs +3 -3
  71. package/test/r33-closeout-regression.test.mjs +20 -19
  72. package/test/r33-finalization.test.mjs +3 -3
  73. package/test/r45-autonomous-quick-test.test.mjs +10 -0
  74. package/test/r45-finalization.test.mjs +84 -0
  75. package/test/release-generation.test.mjs +1 -0
  76. package/test/release-version.test.mjs +52 -41
  77. package/test/runtime-host-bootstrap-r45.test.mjs +46 -0
@@ -0,0 +1,219 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { spawn, spawnSync } from 'node:child_process';
3
+ import { lstat, mkdir, readFile, realpath, rename, writeFile } from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { parseActivePointer } from '../src/release-slot.mjs';
8
+ import { loadPowerShellDataFile, parseControllerStatus, runSlotUpdateCli, windowsPowerShellEnvironment } from '../src/runtime-update.mjs';
9
+ import { verifyR45Parent } from './verify-r45-parent.mjs';
10
+ import { runReleaseParity } from './release-parity-r45.mjs';
11
+ import { writeFinalClosure } from './final-closure-r45.mjs';
12
+ import { verifyFinalClosureObject } from './final-closure-verify-r45.mjs';
13
+
14
+ const HEX64=/^[0-9a-f]{64}$/;
15
+ const EXPECTED_VERSION='0.15.1';
16
+ const PARENT_RELEASE_ID='v0.15.0-c15fa41719be61b3';
17
+ const PARENT_MANIFEST='c15fa41719be61b3186e49b2367a5f4c057365cfb465102dbefb7d7355f45483';
18
+ const PARENT_FINAL_CLOSURE='533b7e0ff9ded04086dd90ed34e3b87bc427acc3c55c25bb9f4ec66cb448e667';
19
+ const here=path.dirname(fileURLToPath(import.meta.url));
20
+ const packageRoot=path.resolve(here,'..');
21
+ const stateRoot=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
22
+ const evidenceRoot=path.join(stateRoot,'evidence','release','r45-finalization');
23
+ const launcher=path.join(stateRoot,'bin','DEADBYTE-MCP.ps1');
24
+ const ps=path.join(process.env.SystemRoot||'C:\\Windows','System32','WindowsPowerShell','v1.0','powershell.exe');
25
+ const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
26
+ const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
27
+ const insist=(ok,message)=>{if(!ok)throw new Error(message);};
28
+
29
+ async function atomicJson(file,value){
30
+ await mkdir(path.dirname(file),{recursive:true});
31
+ const bytes=Buffer.from(`${JSON.stringify(value,null,2)}\n`,'utf8');
32
+ const temp=`${file}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;
33
+ await writeFile(temp,bytes,{flag:'wx'});
34
+ await rename(temp,file);
35
+ return {path:file,sha256:sha256(bytes)};
36
+ }
37
+ async function activePointer(){
38
+ return parseActivePointer(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
39
+ }
40
+ async function bridgeArgs(){
41
+ const pointer=await activePointer();
42
+ const config=await loadPowerShellDataFile(pointer.config_path);
43
+ const raw=config?.Bridge?.WorkingDirectory;
44
+ insist(typeof raw==='string'&&path.isAbsolute(raw),'active Bridge.WorkingDirectory must be absolute');
45
+ const root=await realpath(path.resolve(raw));
46
+ const pkg=JSON.parse(await readFile(path.join(root,'package.json'),'utf8'));
47
+ insist(pkg?.name==='deadbyte-chatgpt-bridge','active Bridge package identity mismatch');
48
+ const script=path.join(root,'src','bridge.mjs');
49
+ return ['--bridge-root',root,'--bridge-script-sha256',sha256(await readFile(script))];
50
+ }
51
+ async function activationArgs(manifestSha256){
52
+ insist(HEX64.test(manifestSha256??''),'R45 finalizer manifest must be lowercase SHA-256');
53
+ const processPolicy=path.join(packageRoot,'controller','deadbyte-process-policy.json');
54
+ const hostPolicy=path.join(packageRoot,'controller','deadbyte-host-policy.json');
55
+ const desktopPolicy=path.join(packageRoot,'controller','deadbyte-desktop-policy.json');
56
+ const semantic=path.join(packageRoot,'controller','deadbyte-semantic-lsp-config.json');
57
+ return [
58
+ '--stage',packageRoot,'--development-root',packageRoot,'--expected-version',EXPECTED_VERSION,
59
+ '--expected-manifest',manifestSha256,
60
+ '--process-policy',processPolicy,'--process-policy-sha256',sha256(await readFile(processPolicy)),
61
+ '--host-policy',hostPolicy,'--host-policy-sha256',sha256(await readFile(hostPolicy)),
62
+ '--desktop-policy',desktopPolicy,'--desktop-policy-sha256',sha256(await readFile(desktopPolicy)),
63
+ '--semantic-lsp-config',semantic,'--semantic-lsp-config-sha256',sha256(await readFile(semantic)),
64
+ '--enable-machine-fs','--enable-observation','--enable-desktop','--enable-autonomous-supervisor',
65
+ '--restore-standing-grants',
66
+ ...await bridgeArgs()
67
+ ];
68
+ }
69
+ export function validateFinalizerAuthorityStatus(status){
70
+ insist(status?.process_armed===true,'R45 finalizer requires Process standing grant');
71
+ insist(status?.coding_armed===true,'R45 finalizer requires Coding standing grant');
72
+ insist(status?.autonomous_armed===true,'R45 finalizer requires Autonomous standing grant');
73
+ insist(status?.desktop_armed===false,'R45 finalizer requires Desktop DISARMED');
74
+ insist(status?.host_armed===false,'R45 finalizer requires Host DISARMED');
75
+ return true;
76
+ }
77
+ function currentAuthorityStatus(){
78
+ const result=spawnSync(ps,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',launcher,'status'],
79
+ {encoding:'utf8',windowsHide:true,timeout:20000,env:windowsPowerShellEnvironment()});
80
+ if(result.error) throw result.error;
81
+ if(result.status!==0) throw new Error(`R45 finalizer controller status failed: ${result.stderr||result.stdout}`);
82
+ return parseControllerStatus(result.stdout??'');
83
+ }
84
+ export function validateWindowsGateEvidence(value,manifestSha256,parent){
85
+ insist(value?.schema==='deadbyte.r45-windows-gate.v1'&&value.status==='passed'&&value.exit_code===0,'R45 Windows gate evidence invalid');
86
+ insist(value.version===EXPECTED_VERSION&&value.manifest_sha256===manifestSha256,'R45 Windows gate candidate mismatch');
87
+ insist(value.marker==='DEADBYTE V0.15.1 / R45 MACHINE FREEDOM WINDOWS BATCH GATE: PASS','R45 Windows gate marker mismatch');
88
+ insist(value.parent?.release_id===parent.release_id&&value.parent?.manifest_sha256===parent.manifest_sha256,'R45 Windows gate parent mismatch');
89
+ insist(value.parent?.generation_manifest_sha256===parent.generation_manifest_sha256,'R45 Windows gate parent generation mismatch');
90
+ insist(value.parent?.final_closure_sha256===PARENT_FINAL_CLOSURE&&value.parent?.final_closure_sha256===parent.closure_sha256,'R45 Windows gate parent final closure mismatch');
91
+ for(const key of ['skill_integrity','agent_backend_persistence','codex_protocol_contract','remote_device_identity','durable_job_supervisor','real_external_supervisor_smoke','full_regression_required','host_inline_native','native_hardware_observation','doctor_release_truth']) {
92
+ insist(value.features?.[key]===true,`R45 Windows gate feature contract missing ${key}`);
93
+ }
94
+ return true;
95
+ }
96
+ function disarmFailClosed(){
97
+ const results=[];
98
+ for(const command of ['disarmdesktop','disarmautonomous','disarmcoding','disarmprocess','disarmhost']){
99
+ const result=spawnSync(ps,['-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',launcher,command],
100
+ {encoding:'utf8',windowsHide:true,timeout:20000,env:windowsPowerShellEnvironment()});
101
+ results.push({command,status:result.status,signal:result.signal??null});
102
+ }
103
+ return results;
104
+ }
105
+ async function mirrorRoot(){
106
+ const pointer=await activePointer();
107
+ const policy=JSON.parse(await readFile(path.join(pointer.generation_root,'coding-policy.json'),'utf8'));
108
+ const raw=policy?.roots?.parity_scratch?.path??policy?.roots?.parity_scratch?.real_path;
109
+ if(typeof raw!=='string'||!path.isAbsolute(raw)) throw new Error('active generation parity_scratch root unavailable');
110
+ const stat=await lstat(raw);
111
+ if(!stat.isDirectory()||stat.isSymbolicLink()) throw new Error('parity_scratch root must be a real directory');
112
+ return raw;
113
+ }
114
+ async function writeMirror(manifestSha256,value){
115
+ const root=await mirrorRoot();
116
+ const file=path.join(root,`r45-final-${manifestSha256.slice(0,16)}.json`);
117
+ return atomicJson(file,value);
118
+ }
119
+ async function verifyInputs(manifestSha256){
120
+ insist(HEX64.test(manifestSha256??''),'R45 finalizer manifest invalid');
121
+ const manifestBytes=await readFile(path.join(packageRoot,'MANIFEST.SHA256'));
122
+ insist(sha256(manifestBytes)===manifestSha256,'R45 finalizer manifest drift');
123
+ const pkg=JSON.parse(await readFile(path.join(packageRoot,'package.json'),'utf8'));
124
+ insist(pkg?.name==='deadbyte-mcp'&&pkg?.version===EXPECTED_VERSION,'R45 finalizer package identity mismatch');
125
+ const parent=await verifyR45Parent(path.join(packageRoot,'R45-PARENT.json'));
126
+ const authorityStatus=currentAuthorityStatus();
127
+ validateFinalizerAuthorityStatus(authorityStatus);
128
+ const before=await activePointer();
129
+ insist(before.release_id===PARENT_RELEASE_ID&&before.manifest_sha256===PARENT_MANIFEST,'R45 finalizer must start from exact sealed R44 parent');
130
+ const windowsGatePath=path.join(stateRoot,'evidence','release',`r45-windows-gate-${manifestSha256.slice(0,16)}.json`);
131
+ const windowsGateBytes=await readFile(windowsGatePath);
132
+ const windowsGate=JSON.parse(windowsGateBytes.toString('utf8').replace(/^\uFEFF/,''));
133
+ validateWindowsGateEvidence(windowsGate,manifestSha256,parent);
134
+ return {parent,before,authorityStatus,windowsGatePath,windowsGateFileSha256:sha256(windowsGateBytes)};
135
+ }
136
+ async function runWorker(manifestSha256,operationId){
137
+ const statePath=path.join(evidenceRoot,`${operationId}.json`);
138
+ let activation=null;
139
+ let parity=null;
140
+ try{
141
+ await atomicJson(statePath,{schema:'deadbyte.r45-finalization-state.v1',operation_id:operationId,status:'running',
142
+ manifest_sha256:manifestSha256,started_at_utc:new Date().toISOString()});
143
+ const inputs=await verifyInputs(manifestSha256);
144
+ activation=await runSlotUpdateCli(await activationArgs(manifestSha256),{stateRoot});
145
+ insist(activation?.pointer?.version===EXPECTED_VERSION&&activation.pointer.manifest_sha256===manifestSha256,'R45 activation result mismatch');
146
+ insist(activation?.final_authority?.process_armed===true&&activation?.final_authority?.coding_armed===true&&activation?.final_authority?.autonomous_armed===true,
147
+ 'R45 activation must restore prior Process+Coding+Autonomous standing grants for detached parity');
148
+ insist(activation?.final_authority?.desktop_armed===false&&activation?.final_authority?.host_armed===false,
149
+ 'R45 activation must keep Desktop+Host disarmed');
150
+
151
+ parity=await runReleaseParity(activation.receipt_path);
152
+ insist(parity?.evidence?.status==='passed'&&parity.evidence?.candidate?.manifest_sha256===manifestSha256,'R45 parity result mismatch');
153
+
154
+ const closure=await writeFinalClosure({parityPath:parity.evidence_path,activationPath:activation.receipt_path,
155
+ windowsGatePath:inputs.windowsGatePath});
156
+ const envelope=JSON.parse(await readFile(closure.path,'utf8'));
157
+ const verified=await verifyFinalClosureObject(envelope,{stateRoot});
158
+ insist(verified?.ok===true&&verified.status==='passed'&&verified.manifest_sha256===manifestSha256,'R45 independent final closure verification failed');
159
+
160
+ const pointer=await activePointer();
161
+ const result={schema:'deadbyte.r45-finalization-result.v1',status:'passed',verified:true,
162
+ completed_at_utc:new Date().toISOString(),release_id:pointer.release_id,version:pointer.version,
163
+ manifest_sha256:pointer.manifest_sha256,generation_manifest_sha256:pointer.generation_manifest_sha256,
164
+ activation_receipt_sha256:activation.receipt_sha256,
165
+ parity_sha256:parity.evidence_sha256,windows_gate_sha256:inputs.windowsGateFileSha256,
166
+ closure_file_sha256:closure.sha256,closure_sha256:closure.closure_sha256,
167
+ full_tool_count:verified.full_tool_count,compact_tool_count:verified.compact_tool_count,
168
+ parent_release_id:inputs.parent.release_id,parent_manifest_sha256:inputs.parent.manifest_sha256};
169
+ const mirror=await writeMirror(manifestSha256,result);
170
+ await atomicJson(statePath,{...result,operation_id:operationId,mirror_path:mirror.path,mirror_sha256:mirror.sha256,
171
+ activation_receipt_path:activation.receipt_path,parity_path:parity.evidence_path,closure_path:closure.path});
172
+ return result;
173
+ }catch(error){
174
+ let rollback=null;
175
+ try{
176
+ if(activation?.receipt_path){
177
+ const pointer=await activePointer().catch(()=>null);
178
+ if(pointer?.version===EXPECTED_VERSION&&pointer?.manifest_sha256===manifestSha256){
179
+ rollback=await runSlotUpdateCli(['--rollback-receipt',activation.receipt_path],{stateRoot});
180
+ }
181
+ }
182
+ }catch(rollbackError){rollback={error:String(rollbackError?.message??rollbackError)};}
183
+ const disarm=disarmFailClosed();
184
+ const failed={schema:'deadbyte.r45-finalization-result.v1',status:'failed',verified:false,
185
+ completed_at_utc:new Date().toISOString(),manifest_sha256:manifestSha256,
186
+ error:String(error?.message??error),rollback:rollback?{ok:rollback?.ok===true,error:rollback?.error??null}:null,disarm};
187
+ await atomicJson(statePath,{...failed,operation_id:operationId}).catch(()=>{});
188
+ await writeMirror(manifestSha256,failed).catch(()=>{});
189
+ throw error;
190
+ }
191
+ }
192
+ export async function scheduleFinalization(manifestSha256){
193
+ insist(HEX64.test(manifestSha256??''),'R45 finalizer manifest invalid');
194
+ const operationId=`r45-${manifestSha256.slice(0,16)}-${randomBytes(8).toString('hex')}`;
195
+ const statePath=path.join(evidenceRoot,`${operationId}.json`);
196
+ await atomicJson(statePath,{schema:'deadbyte.r45-finalization-state.v1',operation_id:operationId,status:'scheduled',
197
+ manifest_sha256:manifestSha256,scheduled_at_utc:new Date().toISOString()});
198
+ const child=spawn(process.execPath,[fileURLToPath(import.meta.url),manifestSha256,'--worker',operationId],{
199
+ cwd:packageRoot,detached:true,stdio:'ignore',windowsHide:true,env:{...process.env,DEADBYTE_STATE_ROOT:stateRoot}
200
+ });
201
+ child.unref();
202
+ return {status:'scheduled',operation_id:operationId,state_path:statePath,manifest_sha256:manifestSha256,
203
+ execution_provider:'deadbyte_mcp',rdc_operation_count:0};
204
+ }
205
+
206
+ const invoked=process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url);
207
+ if(invoked){
208
+ const [manifestSha256,flag,operationId]=process.argv.slice(2);
209
+ try{
210
+ if(flag==='--worker'){
211
+ insist(/^r45-[0-9a-f]{16}-[0-9a-f]{16}$/.test(operationId??''),'R45 finalizer worker operation id invalid');
212
+ await sleep(4000);
213
+ await runWorker(manifestSha256,operationId);
214
+ }else{
215
+ insist(flag===undefined&&operationId===undefined,'usage: node scripts/finalize-r45.mjs <manifest_sha256>');
216
+ console.log(JSON.stringify(await scheduleFinalization(manifestSha256)));
217
+ }
218
+ }catch(error){console.error(error instanceof Error?error.stack:String(error));process.exitCode=1;}
219
+ }
@@ -0,0 +1,20 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readdir } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const here=path.dirname(fileURLToPath(import.meta.url));
7
+ const root=path.resolve(here,'..');
8
+ const testDir=path.join(root,'test');
9
+ const files=(await readdir(testDir,{withFileTypes:true}))
10
+ .filter(entry=>entry.isFile()&&entry.name.endsWith('.test.mjs')&&entry.name!=='full-max-catalog-r44.test.mjs')
11
+ .map(entry=>path.join('test',entry.name))
12
+ .sort((a,b)=>a.localeCompare(b,'en'));
13
+ if(files.length<1) throw new Error('R45 full regression found no test files');
14
+ console.log(`R45-FULL-REGRESSION files=${files.length}`);
15
+ const result=spawnSync(process.execPath,['--test','--test-concurrency=1',...files],{
16
+ cwd:root,stdio:'inherit',windowsHide:true,shell:false
17
+ });
18
+ if(result.error) throw result.error;
19
+ if(result.signal) throw new Error(`R45 full regression terminated by ${result.signal}`);
20
+ process.exitCode=Number.isInteger(result.status)?result.status:1;
@@ -0,0 +1,14 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readdir } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
6
+ const files=(await readdir(path.join(root,'test'),{withFileTypes:true})).filter(e=>e.isFile()&&e.name.endsWith('.test.mjs')).map(e=>path.join('test',e.name)).sort();
7
+ const r=spawnSync(process.execPath,['--test','--test-reporter=spec',...files],{cwd:root,encoding:'utf8',windowsHide:true,shell:false,maxBuffer:64*1024*1024});
8
+ if(r.error) throw r.error;
9
+ const lines=(String(r.stdout||'')+'\n'+String(r.stderr||'')).split(/\r?\n/);
10
+ for(let i=0;i<lines.length;i++){
11
+ if(lines[i].startsWith('✖ ')||/^ℹ fail /.test(lines[i])||/^test at /.test(lines[i])) console.log(lines[i]);
12
+ }
13
+ console.log('EXIT='+String(r.status));
14
+ process.exitCode=Number.isInteger(r.status)?r.status:1;
@@ -0,0 +1,44 @@
1
+ $ErrorActionPreference = 'Stop'
2
+ Set-StrictMode -Version 2.0
3
+ function Invoke-GateStep {
4
+ param([Parameter(Mandatory = $true)][string]$Name,[Parameter(Mandatory = $true)][string[]]$NpmArgs)
5
+ Write-Host "==== $Name ===="
6
+ & npm.cmd @NpmArgs
7
+ if ($LASTEXITCODE -ne 0) { throw "DEADBYTE V0.15.1 / R45 gate failed at $Name with exit code $LASTEXITCODE" }
8
+ }
9
+ Invoke-GateStep -Name 'r45-parent-verify' -NpmArgs @('run','r45:parent:verify')
10
+ Invoke-GateStep -Name 'containment-build' -NpmArgs @('run','containment:build')
11
+ Invoke-GateStep -Name 'process-policy-refresh' -NpmArgs @('run','process:policy:refresh')
12
+ Invoke-GateStep -Name 'desktop-policy-refresh' -NpmArgs @('run','desktop:policy:refresh')
13
+ Invoke-GateStep -Name 'hardware-build' -NpmArgs @('run','hardware:build')
14
+ Write-Host '==== host-policy-hermetic-clean ===='
15
+ $HostPolicyPath = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\controller\deadbyte-host-policy.json'))
16
+ Remove-Item -LiteralPath $HostPolicyPath -Force -ErrorAction SilentlyContinue
17
+ if (Test-Path -LiteralPath $HostPolicyPath) { throw "DEADBYTE V0.15.1 / R45 gate could not remove machine-local Host policy before hermetic regression" }
18
+ Write-Host 'HOST_POLICY_HERMETIC_ABSENT'
19
+ Write-Host '==== r45-feature-focused ===='
20
+ & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'release-parity-tests-r45.ps1')
21
+ if ($LASTEXITCODE -ne 0) { throw "DEADBYTE V0.15.1 / R45 gate failed at r45-feature-focused with exit code $LASTEXITCODE" }
22
+ Invoke-GateStep -Name 'full-regression' -NpmArgs @('run','r45:full:test')
23
+ Invoke-GateStep -Name 'mcp-smoke' -NpmArgs @('run','mcp:smoke')
24
+ Invoke-GateStep -Name 'mcp-agent-smoke' -NpmArgs @('run','mcp:agent:smoke')
25
+ Invoke-GateStep -Name 'mcp-coding-smoke' -NpmArgs @('run','mcp:coding:smoke')
26
+ Invoke-GateStep -Name 'mcp-machine-fs-smoke' -NpmArgs @('run','mcp:machine-fs:smoke')
27
+ Invoke-GateStep -Name 'mcp-observation-smoke' -NpmArgs @('run','mcp:observation:smoke')
28
+ Invoke-GateStep -Name 'mcp-process-smoke' -NpmArgs @('run','mcp:process:smoke')
29
+ Invoke-GateStep -Name 'mcp-autonomous-smoke' -NpmArgs @('run','mcp:autonomous:smoke')
30
+ Invoke-GateStep -Name 'tunnel-stdio-compat-smoke' -NpmArgs @('run','mcp:tunnel-compat:smoke')
31
+ Invoke-GateStep -Name 'containment-smoke' -NpmArgs @('run','containment:smoke')
32
+ Invoke-GateStep -Name 'contained-smoke' -NpmArgs @('run','contained:smoke')
33
+ Invoke-GateStep -Name 'mcp-contained-smoke' -NpmArgs @('run','mcp:contained:smoke')
34
+ Invoke-GateStep -Name 'host-policy-refresh' -NpmArgs @('run','host:policy:init')
35
+ Invoke-GateStep -Name 'release-manifest-write' -NpmArgs @('run','manifest:write')
36
+ Invoke-GateStep -Name 'release-manifest' -NpmArgs @('run','manifest:verify')
37
+ Invoke-GateStep -Name 'doctor' -NpmArgs @('run','doctor')
38
+ Invoke-GateStep -Name 'mcp-host-smoke' -NpmArgs @('run','mcp:host:smoke')
39
+ Invoke-GateStep -Name 'authority-smoke' -NpmArgs @('run','authority:smoke')
40
+ Invoke-GateStep -Name 'release-manifest-final' -NpmArgs @('run','manifest:verify')
41
+ Write-Host '==== windows-gate-evidence ===='
42
+ & node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence-r45.mjs')
43
+ if ($LASTEXITCODE -ne 0) { throw "DEADBYTE V0.15.1 / R45 gate failed at windows-gate-evidence with exit code $LASTEXITCODE" }
44
+ Write-Host '==== DEADBYTE V0.15.1 / R45 MACHINE FREEDOM WINDOWS BATCH GATE: PASS ===='
@@ -93,16 +93,54 @@ $commands = [ordered]@{
93
93
  timeout_ms = 120000
94
94
  max_output_bytes = 1048576
95
95
  }
96
+ powershell_inline = [ordered]@{
97
+ kind = 'inline'
98
+ executable = $powerShellExe
99
+ executable_sha256 = Get-Sha256Lower $powerShellExe
100
+ root_ids = $rootIds
101
+ prefix_args = @('-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-Command')
102
+ timeout_ms = 120000
103
+ max_output_bytes = 1048576
104
+ max_command_chars = 32768
105
+ }
106
+ cmd_inline = [ordered]@{
107
+ kind = 'inline'
108
+ executable = $cmdExe
109
+ executable_sha256 = Get-Sha256Lower $cmdExe
110
+ root_ids = $rootIds
111
+ prefix_args = @('/D','/S','/C')
112
+ timeout_ms = 120000
113
+ max_output_bytes = 1048576
114
+ max_command_chars = 32768
115
+ }
116
+ node_inline = [ordered]@{
117
+ kind = 'inline'
118
+ executable = $nodeExe
119
+ executable_sha256 = Get-Sha256Lower $nodeExe
120
+ root_ids = $rootIds
121
+ prefix_args = @('-e')
122
+ timeout_ms = 120000
123
+ max_output_bytes = 1048576
124
+ max_command_chars = 32768
125
+ }
96
126
  }
97
127
 
98
128
  $policy = [ordered]@{
99
- schema = 'deadbyte.host-policy.v1'
129
+ schema = 'deadbyte.host-policy.v2'
100
130
  enabled = $true
101
131
  arm_file = $armFile
102
132
  max_read_bytes = 262144
103
133
  max_write_bytes = 1048576
104
134
  roots = $roots
105
135
  commands = $commands
136
+ native_exec = [ordered]@{
137
+ enabled = $true
138
+ root_ids = $rootIds
139
+ timeout_ms = 120000
140
+ max_output_bytes = 1048576
141
+ max_args = 64
142
+ max_arg_chars = 8192
143
+ }
106
144
  }
107
145
 
108
146
  $parent = Split-Path -Parent $PolicyPath
@@ -0,0 +1,20 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFile } from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ const sha256=b=>createHash('sha256').update(b).digest('hex');
6
+ const root=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
7
+ const pointer=JSON.parse(await readFile(path.join(root,'active-release.json'),'utf8'));
8
+ const finalPath=path.join(root,'evidence','release',`r44-final-${pointer.manifest_sha256.slice(0,16)}.json`);
9
+ const finalBytes=await readFile(finalPath);
10
+ const releaseManifest=await readFile(path.join(pointer.release_root,'MANIFEST.SHA256'),'utf8');
11
+ const generationManifest=await readFile(path.join(pointer.generation_root,'GENERATION.SHA256'),'utf8');
12
+ const count=s=>s.split(/\r?\n/).filter(Boolean).length;
13
+ console.log(JSON.stringify({
14
+ pointer,
15
+ final_path:finalPath,
16
+ final_file_sha256:sha256(finalBytes),
17
+ final_closure_sha256:JSON.parse(finalBytes).closure_sha256,
18
+ release_manifest_file_count:count(releaseManifest),
19
+ generation_manifest_file_count:count(generationManifest)
20
+ },null,2));
@@ -26,6 +26,8 @@ const requiredBundledDependencyRoots = [
26
26
  'node_modules/@modelcontextprotocol/client/package.json',
27
27
  'node_modules/zod/package.json'
28
28
  ];
29
+ const excludedPackagePrefixes = ['tmp/','.deadbyte-machine-fs-recovery/'];
30
+ const excludedPackagePaths = new Set(['controller/deadbyte-host-policy.json']);
29
31
  const allowedWorkspacePayload = new Set([
30
32
  'workspaces/autonomous-live/fixture.txt',
31
33
  'workspaces/demo/input.txt'
@@ -57,7 +59,7 @@ function npmPackFiles() {
57
59
  const raw = item?.path;
58
60
  if (typeof raw !== 'string' || raw.length < 1) throw new Error('npm pack file path invalid');
59
61
  const rel = raw.replaceAll('\\','/');
60
- if (rel === manifestName) continue;
62
+ if (rel === manifestName || excludedPackagePaths.has(rel) || excludedPackagePrefixes.some(prefix => rel.startsWith(prefix))) continue;
61
63
  if (path.posix.isAbsolute(rel) || rel.split('/').includes('..') || rel.includes('\0')) {
62
64
  throw new Error(`unsafe package path '${rel}'`);
63
65
  }