deadbyte-mcp 0.10.0 → 0.11.0

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 (70) hide show
  1. package/MANIFEST.SHA256 +69 -55
  2. package/README.txt +13 -14
  3. package/bin/WORKER-REGISTRY.txt +3 -3
  4. package/bin/appcontainer-stage.exe +0 -0
  5. package/bin/appcontainer-stage.obj +0 -0
  6. package/bin/bootstrap-advapi32.exe +0 -0
  7. package/bin/bootstrap-advapi32.obj +0 -0
  8. package/bin/bootstrap-exitcode.exe +0 -0
  9. package/bin/bootstrap-exitcode.obj +0 -0
  10. package/bin/bootstrap-kernel32.exe +0 -0
  11. package/bin/bootstrap-kernel32.obj +0 -0
  12. package/bin/child-control-probe.exe +0 -0
  13. package/bin/child-control-probe.obj +0 -0
  14. package/bin/child-control-stage.exe +0 -0
  15. package/bin/child-control-stage.obj +0 -0
  16. package/bin/contained-reverse-worker.exe +0 -0
  17. package/bin/contained-reverse-worker.obj +0 -0
  18. package/bin/contained-transform-worker.exe +0 -0
  19. package/bin/contained-transform-worker.obj +0 -0
  20. package/bin/containment-probe.exe +0 -0
  21. package/bin/containment-probe.obj +0 -0
  22. package/bin/deadbyte-contain.exe +0 -0
  23. package/bin/deadbyte-contain.obj +0 -0
  24. package/bin/deadbyte-exec.exe +0 -0
  25. package/bin/deadbyte-exec.obj +0 -0
  26. package/bin/deadbyte-process-host.exe +0 -0
  27. package/bin/deadbyte-process-host.obj +0 -0
  28. package/bin/deadbyte-tunnel-host.exe +0 -0
  29. package/bin/deadbyte-tunnel-host.obj +0 -0
  30. package/controller/README.TXT +3 -3
  31. package/controller/deadbyte-controller.ps1 +1 -1
  32. package/controller/deadbyte-process-policy.json +1 -1
  33. package/docs/ARCHITECTURE.md +1 -1
  34. package/package.json +1 -1
  35. package/scripts/deferred-slot-operation.mjs +1 -1
  36. package/scripts/final-closure-r36.mjs +113 -0
  37. package/scripts/final-closure-verify-r36.mjs +208 -0
  38. package/scripts/final-closure-verify.mjs +48 -48
  39. package/scripts/final-closure.mjs +13 -13
  40. package/scripts/gate-windows-r36.ps1 +42 -0
  41. package/scripts/gate-windows.ps1 +3 -3
  42. package/scripts/release-parity-r36.mjs +200 -0
  43. package/scripts/release-parity-tests.ps1 +2 -2
  44. package/scripts/release-parity.mjs +37 -37
  45. package/scripts/windows-gate-evidence-r36.mjs +52 -0
  46. package/scripts/windows-gate-evidence.mjs +5 -5
  47. package/src/agent-memory-plane.mjs +98 -0
  48. package/src/autonomous-output-contracts.mjs +5 -2
  49. package/src/autonomous-runtime.mjs +155 -31
  50. package/src/autonomous-timeout-recovery.mjs +27 -0
  51. package/src/deadbyte-cli.mjs +37 -76
  52. package/src/effect-ledger.mjs +47 -0
  53. package/src/observation-lease.mjs +32 -0
  54. package/src/remote-live-log.mjs +59 -0
  55. package/src/remote-mcp-autonomous-smoke-client.mjs +15 -9
  56. package/src/version.mjs +1 -1
  57. package/src/worker-scheduler.mjs +53 -0
  58. package/test/autonomous-output-contract.test.mjs +1 -1
  59. package/test/core.test.mjs +1 -1
  60. package/test/production-docs.test.mjs +5 -5
  61. package/test/r33-closeout-regression.test.mjs +4 -4
  62. package/test/r33-finalization.test.mjs +6 -6
  63. package/test/r36-finalization.test.mjs +5 -5
  64. package/test/r36-release-identity.test.mjs +12 -19
  65. package/test/r37-agent-fabric.test.mjs +92 -0
  66. package/test/r37-autonomous-timeout-recovery.test.mjs +60 -0
  67. package/test/r37-finalization.test.mjs +74 -0
  68. package/test/release-version.test.mjs +42 -36
  69. package/test/remote-live-log-r37.test.mjs +47 -0
  70. package/test/remote-session-cli.test.mjs +27 -50
@@ -0,0 +1,208 @@
1
+ import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';
2
+ import { lstat, readFile, readdir } from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const HEX64=/^[0-9a-f]{64}$/;
8
+ const UPDATE_DOMAIN=Buffer.from('DEADBYTE-R27-SLOT-UPDATE-V1\0','utf8');
9
+ const CLOSURE_DOMAIN=Buffer.from('DEADBYTE-R36-FINAL-CLOSURE-V1\0','utf8');
10
+ const PING_DOMAIN=Buffer.from('DEADBYTE-MACHINE-PING-V1\0','utf8');
11
+ const R35_PREDECESSOR_RELEASE_ID='v0.9.0-b95e1ec1d9a7e26a';
12
+ const R35_PREDECESSOR_MANIFEST='b95e1ec1d9a7e26a96ef492306c1be4df18c883ff03ab3b6015f677d7429ec8d';
13
+ const R36_FULL_TOOL_COUNT=76;
14
+ const R36_COMPACT_TOOL_LIMIT=42;
15
+ const REQUIRED_PARITY_KEYS=['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface'];
16
+ const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
17
+ const canonical=value=>Array.isArray(value)?value.map(canonical):value&&typeof value==='object'
18
+ ?Object.fromEntries(Object.keys(value).sort().map(key=>[key,canonical(value[key])])):value;
19
+ const canonicalJson=value=>JSON.stringify(canonical(value));
20
+ const same=(a,b)=>canonicalJson(a)===canonicalJson(b);
21
+ function insist(ok,msg){if(!ok) throw new Error(msg);}
22
+ function samePath(a,b){return path.resolve(String(a)).toLowerCase()===path.resolve(String(b)).toLowerCase();}
23
+ function isCandidateIdentity(value,manifest){
24
+ return value?.version==='0.10.0'&&value?.manifest_sha256===manifest&&value?.release_id===`v0.10.0-${manifest.slice(0,16)}`;
25
+ }
26
+ function isR35Identity(value){
27
+ return value?.version==='0.9.0'&&value?.manifest_sha256===R35_PREDECESSOR_MANIFEST&&value?.release_id===R35_PREDECESSOR_RELEASE_ID;
28
+ }
29
+
30
+ function parseManifest(text){
31
+ const out=new Map();
32
+ for(const [i,line] of text.split(/\r?\n/).entries()){
33
+ if(!line) continue;
34
+ const m=/^([0-9a-f]{64}) ([^\0]+)$/.exec(line);insist(m,`manifest line ${i+1} malformed`);
35
+ insist(!path.posix.isAbsolute(m[2])&&!m[2].split('/').includes('..')&&!out.has(m[2]),`unsafe/duplicate manifest path ${m[2]}`);
36
+ out.set(m[2],m[1]);
37
+ }
38
+ return out;
39
+ }
40
+ async function walk(root,rel=''){
41
+ const dir=path.join(root,...(rel?rel.split('/'):[]));
42
+ const names=(await readdir(dir)).sort((a,b)=>a.localeCompare(b,'en'));
43
+ const files=[];
44
+ for(const name of names){
45
+ const childRel=rel?`${rel}/${name}`:name;
46
+ const full=path.join(root,...childRel.split('/'));
47
+ const st=await lstat(full);insist(!st.isSymbolicLink(),`symlink forbidden: ${childRel}`);
48
+ if(st.isDirectory()) files.push(...await walk(root,childRel));
49
+ else{insist(st.isFile(),`non-file forbidden: ${childRel}`);files.push(childRel);}
50
+ }
51
+ return files;
52
+ }
53
+ async function verifyTree(root,manifestName,expectedDigest){
54
+ const manifestBytes=await readFile(path.join(root,manifestName));
55
+ insist(sha256(manifestBytes)===expectedDigest,`${manifestName} digest mismatch`);
56
+ const entries=parseManifest(manifestBytes.toString('utf8'));
57
+ const actual=(await walk(root)).filter(rel=>rel!==manifestName).sort((a,b)=>a.localeCompare(b,'en'));
58
+ const expected=[...entries.keys()].sort((a,b)=>a.localeCompare(b,'en'));
59
+ insist(same(actual,expected),`${manifestName} exact tree mismatch`);
60
+ for(const [rel,digest] of entries) insist(sha256(await readFile(path.join(root,...rel.split('/'))))===digest,`${manifestName} file hash mismatch: ${rel}`);
61
+ return entries.size;
62
+ }
63
+ function publicKeyInfo(publicPem){
64
+ const key=createPublicKey(publicPem);insist(key.asymmetricKeyType==='ed25519','public key must be Ed25519');
65
+ const der=Buffer.from(key.export({type:'spki',format:'der'}));
66
+ return {key,key_id:sha256(der),spki_base64:der.toString('base64')};
67
+ }
68
+ function verifyUpdateEnvelope(env,keyInfo){
69
+ insist(env?.body&&env?.attestation,'update envelope malformed');
70
+ const bodyBytes=Buffer.from(canonicalJson(env.body),'utf8');
71
+ insist(sha256(bodyBytes)===env.body_sha256,'update body hash mismatch');
72
+ const {receipt_sha256,...unsigned}=env;
73
+ insist(sha256(Buffer.from(canonicalJson(unsigned),'utf8'))===receipt_sha256,'update receipt hash mismatch');
74
+ insist(env.attestation.algorithm==='ed25519'&&env.attestation.domain==='DEADBYTE-R27-SLOT-UPDATE-V1','update attestation contract mismatch');
75
+ insist(env.attestation.key_id===keyInfo.key_id,'update signer mismatch');
76
+ insist(cryptoVerify(null,Buffer.concat([UPDATE_DOMAIN,bodyBytes]),keyInfo.key,Buffer.from(env.attestation.signature_base64,'base64')),'update signature invalid');
77
+ return true;
78
+ }
79
+ function verifyPing(ping,status,pointer){
80
+ insist(ping?.status==='ok'&&ping.schema==='deadbyte.machine-ping.v1','machine ping malformed');
81
+ insist(status?.status==='ok'&&typeof status.public_key_spki_base64==='string','machine status malformed');
82
+ const der=Buffer.from(status.public_key_spki_base64,'base64');
83
+ insist(der.toString('base64')===status.public_key_spki_base64,'machine SPKI base64 non-canonical');
84
+ const machineKey=createPublicKey({key:der,format:'der',type:'spki'});insist(machineKey.asymmetricKeyType==='ed25519','machine key must be Ed25519');
85
+ const machineId=sha256(der);
86
+ insist(status.machine_id===machineId&&ping.machine_id===machineId&&ping.attestation?.key_id===machineId,'machine id/key mismatch');
87
+ insist(ping.release_id===pointer.release_id&&ping.release_manifest_sha256===pointer.manifest_sha256,'machine ping release binding mismatch');
88
+ insist(ping.generation_manifest_sha256===pointer.generation_manifest_sha256,'machine ping generation binding mismatch');
89
+ const {status:_s,attestation:_a,...body}=ping;
90
+ const bytes=Buffer.from(canonicalJson(body),'utf8');
91
+ insist(cryptoVerify(null,Buffer.concat([PING_DOMAIN,bytes]),machineKey,Buffer.from(ping.attestation.signature_base64,'base64')),'machine ping signature invalid');
92
+ }
93
+
94
+ export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.homedir(),'.deadbyte-mcp')}={}){
95
+ insist(envelope?.body?.schema==='deadbyte.r36-final-closure.v1','closure schema mismatch');
96
+ insist(envelope.body.version==='0.10.0','closure version mismatch');
97
+ insist(envelope.body.release_label==='R36 FINAL MACHINE BASELINE','closure release label mismatch');
98
+ const keyInfo=publicKeyInfo(await readFile(path.join(stateRoot,'trust','ed25519-public.pem')));
99
+ const bodyBytes=Buffer.from(canonicalJson(envelope.body),'utf8');
100
+ insist(sha256(bodyBytes)===envelope.body_sha256,'closure body hash mismatch');
101
+ const {closure_sha256,...unsigned}=envelope;
102
+ insist(sha256(Buffer.from(canonicalJson(unsigned),'utf8'))===closure_sha256,'closure envelope hash mismatch');
103
+ insist(envelope.attestation?.algorithm==='ed25519'&&envelope.attestation?.domain==='DEADBYTE-R36-FINAL-CLOSURE-V1','closure attestation contract mismatch');
104
+ insist(envelope.attestation.key_id===keyInfo.key_id,'closure signer mismatch');
105
+ insist(cryptoVerify(null,Buffer.concat([CLOSURE_DOMAIN,bodyBytes]),keyInfo.key,Buffer.from(envelope.attestation.signature_base64,'base64')),'closure signature invalid');
106
+
107
+ const pointer=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
108
+ insist(same(pointer,envelope.body.active_pointer),'active pointer drift');
109
+ insist(pointer.version==='0.10.0','active pointer version mismatch');
110
+ insist(isCandidateIdentity(pointer,pointer.manifest_sha256),'release id/content address mismatch');
111
+ const releaseFiles=await verifyTree(pointer.release_root,'MANIFEST.SHA256',pointer.manifest_sha256);
112
+ const generationFiles=await verifyTree(pointer.generation_root,'GENERATION.SHA256',pointer.generation_manifest_sha256);
113
+ insist(sha256(await readFile(path.join(stateRoot,'bin','DEADBYTE-MCP.ps1')))===pointer.launcher_sha256,'launcher hash mismatch');
114
+
115
+ const predecessor=envelope.body.predecessor;
116
+ insist(isR35Identity(predecessor),'closure predecessor is not exact sealed R35');
117
+ const immutable=envelope.body.immutable_slot;
118
+ insist(immutable?.protected===true,'closure immutable-slot protection missing');
119
+ insist(samePath(immutable.release_root,pointer.release_root),'closure immutable release_root mismatch');
120
+ insist(!samePath(immutable.development_root,immutable.release_root),'closure development_root aliases immutable release_root');
121
+
122
+ const surfaces=envelope.body.surfaces;
123
+ insist(surfaces?.local_full?.status==='passed'&&surfaces.local_full.tool_count===R36_FULL_TOOL_COUNT&&surfaces.local_full.strict_output_schemas===true,'closure local full 76-tool proof invalid');
124
+ insist(HEX64.test(surfaces.local_full.catalog_sha256??''),'closure local full catalog hash missing');
125
+ insist(surfaces?.public_compact?.status==='passed'&&surfaces.public_compact.tool_count<=R36_COMPACT_TOOL_LIMIT&&surfaces.public_compact.capability_closure===true,'closure public compact capability proof invalid');
126
+ insist(surfaces.public_compact.coding_armed===false&&surfaces.public_compact.autonomous_armed===false,'closure compact authority is not DISARMED');
127
+ insist(HEX64.test(surfaces.public_compact.catalog_sha256??'')&&HEX64.test(surfaces.public_compact.ledger_sha256??''),'closure compact catalog/ledger hash missing');
128
+
129
+ const evidence=envelope.body.evidence;
130
+ insist(evidence&&evidence.parity&&evidence.activation&&evidence.rollback&&evidence.restore&&evidence.windows_gate,'closure evidence set incomplete');
131
+ for(const [name,item] of Object.entries(evidence)){
132
+ insist(item?.path&&HEX64.test(item.sha256??''),`${name} evidence identity malformed`);
133
+ insist(sha256(await readFile(item.path))===item.sha256,`${name} evidence hash mismatch`);
134
+ }
135
+
136
+ const parity=JSON.parse(await readFile(evidence.parity.path,'utf8'));
137
+ insist(parity.schema==='deadbyte.r36-parity.v1'&&parity.status==='passed','R36 parity evidence invalid');
138
+ insist(parity.rdc_operation_count===0&&parity.execution_provider==='deadbyte_mcp','R36 parity execution provider mismatch');
139
+ insist(isCandidateIdentity(parity.candidate,pointer.manifest_sha256),'R36 parity candidate binding mismatch');
140
+ insist(isCandidateIdentity(parity.successor,pointer.manifest_sha256),'R36 parity successor binding mismatch');
141
+ insist(isR35Identity(parity.predecessor),'R36 parity predecessor binding mismatch');
142
+ insist(parity.local_full?.status==='passed'&&parity.local_full.tool_count===R36_FULL_TOOL_COUNT&&parity.local_full.strict_output_schemas===true,'R36 parity local full proof invalid');
143
+ insist(parity.local_full.catalog_sha256===surfaces.local_full.catalog_sha256,'R36 local full catalog drift between parity and closure');
144
+ insist(parity.public_compact?.status==='passed'&&parity.public_compact.tool_count<=R36_COMPACT_TOOL_LIMIT&&parity.public_compact.capability_closure===true&&parity.public_compact.gateway_count===5,'R36 parity public compact proof invalid');
145
+ insist(parity.successor_disarmed?.status==='passed'&&parity.successor_disarmed.tool_count<=R36_COMPACT_TOOL_LIMIT&&parity.successor_disarmed.capability_closure===true&&parity.successor_disarmed.coding_armed===false&&parity.successor_disarmed.autonomous_armed===false,'R36 parity successor disarmed proof invalid');
146
+ insist(parity.successor_disarmed.catalog_sha256===surfaces.public_compact.catalog_sha256,'R36 compact catalog drift between restore and closure');
147
+ insist(parity.successor_disarmed.ledger_sha256===surfaces.public_compact.ledger_sha256,'R36 capability ledger drift between restore and closure');
148
+ insist(parity.immutable_slot?.protected===true,'R36 parity immutable-slot proof missing');
149
+ insist(samePath(parity.immutable_slot.release_root,pointer.release_root),'R36 parity immutable release_root mismatch');
150
+ insist(samePath(parity.immutable_slot.development_root,immutable.development_root),'R36 parity/closure development_root mismatch');
151
+ insist(!samePath(parity.immutable_slot.development_root,pointer.release_root),'R36 mutable development_root aliases immutable release slot');
152
+ for(const key of REQUIRED_PARITY_KEYS) insist(parity.requirements?.[key]===true,`R36 parity requirement missing ${key}`);
153
+
154
+ const activation=JSON.parse(await readFile(evidence.activation.path,'utf8'));
155
+ const rollback=JSON.parse(await readFile(evidence.rollback.path,'utf8'));
156
+ const restore=JSON.parse(await readFile(evidence.restore.path,'utf8'));
157
+ verifyUpdateEnvelope(activation,keyInfo);verifyUpdateEnvelope(rollback,keyInfo);verifyUpdateEnvelope(restore,keyInfo);
158
+ insist(activation.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&activation.body.rollback_performed===false,'R36 activation receipt invalid');
159
+ insist(activation.body.release_version==='0.10.0'&&activation.body.candidate_manifest_sha256===pointer.manifest_sha256,'R36 activation candidate identity invalid');
160
+ insist(isCandidateIdentity(activation.body.active_pointer,pointer.manifest_sha256),'R36 activation active pointer invalid');
161
+ insist(isR35Identity(activation.body.prior_pointer),'R36 activation predecessor is not exact R35');
162
+ insist(samePath(activation.body.development_root,immutable.development_root),'R36 activation development_root mismatch');
163
+ insist(!samePath(activation.body.development_root,activation.body.active_pointer.release_root),'R36 activation development_root aliases release slot');
164
+
165
+ insist(rollback.body.schema==='deadbyte.r31-slot-rollback-receipt.v1'&&rollback.body.rollback_performed===true,'R36 rollback receipt invalid');
166
+ insist(isCandidateIdentity(rollback.body.from_pointer,pointer.manifest_sha256),'R36 rollback source is not exact candidate');
167
+ insist(isR35Identity(rollback.body.active_pointer),'R36 rollback target is not exact R35 predecessor');
168
+ insist(rollback.body.activation_receipt_sha256===activation.receipt_sha256,'R36 rollback not bound to activation receipt');
169
+
170
+ insist(restore.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&restore.body.rollback_performed===false,'R36 restore receipt invalid');
171
+ insist(restore.body.release_version==='0.10.0'&&restore.body.candidate_manifest_sha256===pointer.manifest_sha256,'R36 restore candidate identity invalid');
172
+ insist(isR35Identity(restore.body.prior_pointer),'R36 restore predecessor is not exact R35');
173
+ insist(isCandidateIdentity(restore.body.active_pointer,pointer.manifest_sha256)&&same(restore.body.active_pointer,pointer),'R36 restore/current pointer mismatch');
174
+ insist(samePath(restore.body.development_root,immutable.development_root),'R36 restore development_root mismatch');
175
+ insist(!samePath(restore.body.development_root,restore.body.active_pointer.release_root),'R36 restore development_root aliases release slot');
176
+
177
+ const windowsGate=JSON.parse(await readFile(evidence.windows_gate.path,'utf8'));
178
+ insist(windowsGate.schema==='deadbyte.r36-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'R36 Windows gate evidence invalid');
179
+ insist(windowsGate.version==='0.10.0'&&windowsGate.manifest_sha256===pointer.manifest_sha256,'R36 Windows gate manifest/version binding mismatch');
180
+ insist(windowsGate.marker==='DEADBYTE V0.10.0 / R36 WINDOWS BATCH GATE: PASS','R36 Windows gate PASS marker mismatch');
181
+
182
+ const machine=envelope.body.machine;
183
+ insist(machine?.status?.release_id===pointer.release_id&&machine.status.release_manifest_sha256===pointer.manifest_sha256&&machine.status.generation_manifest_sha256===pointer.generation_manifest_sha256,'machine status binding mismatch');
184
+ verifyPing(machine.ping,machine.status,pointer);
185
+ insist(machine.ping.nonce===machine.nonce,'machine ping nonce binding mismatch');
186
+
187
+ const grantNames=['process-grant.json','coding-grant.json','autonomous-grant.json','host-grant.json'];
188
+ insist(envelope.body.authority?.all_disarmed===true,'closure authority not disarmed');
189
+ for(const name of grantNames){
190
+ let exists=true;try{await lstat(path.join(stateRoot,'runtime',name));}catch(error){if(error?.code==='ENOENT') exists=false;else throw error;}
191
+ insist(!exists,`authority grant still present: ${name}`);
192
+ insist(envelope.body.authority.grants_absent?.[name]===true,`closure grant absence not recorded: ${name}`);
193
+ }
194
+ return {ok:true,status:'passed',release_id:pointer.release_id,manifest_sha256:pointer.manifest_sha256,
195
+ generation_manifest_sha256:pointer.generation_manifest_sha256,release_files:releaseFiles,generation_files:generationFiles,
196
+ machine_id:machine.status.machine_id,parity_sha256:evidence.parity.sha256,closure_sha256:envelope.closure_sha256,
197
+ full_tool_count:R36_FULL_TOOL_COUNT,compact_tool_count:surfaces.public_compact.tool_count};
198
+ }
199
+
200
+ const invoked=process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url);
201
+ if(invoked){
202
+ const file=process.argv[2];
203
+ if(!file) throw new Error('usage: node scripts/final-closure-verify.mjs <closure.json>');
204
+ try{
205
+ const envelope=JSON.parse(await readFile(path.resolve(file),'utf8'));
206
+ console.log(JSON.stringify(await verifyFinalClosureObject(envelope),null,2));
207
+ }catch(error){console.error(error instanceof Error?error.stack:String(error));process.exitCode=1;}
208
+ }
@@ -6,12 +6,12 @@ import { fileURLToPath } from 'node:url';
6
6
 
7
7
  const HEX64=/^[0-9a-f]{64}$/;
8
8
  const UPDATE_DOMAIN=Buffer.from('DEADBYTE-R27-SLOT-UPDATE-V1\0','utf8');
9
- const CLOSURE_DOMAIN=Buffer.from('DEADBYTE-R36-FINAL-CLOSURE-V1\0','utf8');
9
+ const CLOSURE_DOMAIN=Buffer.from('DEADBYTE-R37-FINAL-CLOSURE-V1\0','utf8');
10
10
  const PING_DOMAIN=Buffer.from('DEADBYTE-MACHINE-PING-V1\0','utf8');
11
- const R35_PREDECESSOR_RELEASE_ID='v0.9.0-b95e1ec1d9a7e26a';
12
- const R35_PREDECESSOR_MANIFEST='b95e1ec1d9a7e26a96ef492306c1be4df18c883ff03ab3b6015f677d7429ec8d';
13
- const R36_FULL_TOOL_COUNT=76;
14
- const R36_COMPACT_TOOL_LIMIT=42;
11
+ const R36_PREDECESSOR_RELEASE_ID='v0.10.0-8d1e5f09745e7647';
12
+ const R36_PREDECESSOR_MANIFEST='8d1e5f09745e764796b60e0a8a0168be7334ed4bf834fad5974a80eba295b4e8';
13
+ const R37_FULL_TOOL_COUNT=76;
14
+ const R37_COMPACT_TOOL_LIMIT=42;
15
15
  const REQUIRED_PARITY_KEYS=['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface'];
16
16
  const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
17
17
  const canonical=value=>Array.isArray(value)?value.map(canonical):value&&typeof value==='object'
@@ -21,10 +21,10 @@ const same=(a,b)=>canonicalJson(a)===canonicalJson(b);
21
21
  function insist(ok,msg){if(!ok) throw new Error(msg);}
22
22
  function samePath(a,b){return path.resolve(String(a)).toLowerCase()===path.resolve(String(b)).toLowerCase();}
23
23
  function isCandidateIdentity(value,manifest){
24
- return value?.version==='0.10.0'&&value?.manifest_sha256===manifest&&value?.release_id===`v0.10.0-${manifest.slice(0,16)}`;
24
+ return value?.version==='0.11.0'&&value?.manifest_sha256===manifest&&value?.release_id===`v0.11.0-${manifest.slice(0,16)}`;
25
25
  }
26
- function isR35Identity(value){
27
- return value?.version==='0.9.0'&&value?.manifest_sha256===R35_PREDECESSOR_MANIFEST&&value?.release_id===R35_PREDECESSOR_RELEASE_ID;
26
+ function isR36Identity(value){
27
+ return value?.version==='0.10.0'&&value?.manifest_sha256===R36_PREDECESSOR_MANIFEST&&value?.release_id===R36_PREDECESSOR_RELEASE_ID;
28
28
  }
29
29
 
30
30
  function parseManifest(text){
@@ -92,37 +92,37 @@ function verifyPing(ping,status,pointer){
92
92
  }
93
93
 
94
94
  export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.homedir(),'.deadbyte-mcp')}={}){
95
- insist(envelope?.body?.schema==='deadbyte.r36-final-closure.v1','closure schema mismatch');
96
- insist(envelope.body.version==='0.10.0','closure version mismatch');
97
- insist(envelope.body.release_label==='R36 FINAL MACHINE BASELINE','closure release label mismatch');
95
+ insist(envelope?.body?.schema==='deadbyte.r37-final-closure.v1','closure schema mismatch');
96
+ insist(envelope.body.version==='0.11.0','closure version mismatch');
97
+ insist(envelope.body.release_label==='R37 FINAL MACHINE BASELINE','closure release label mismatch');
98
98
  const keyInfo=publicKeyInfo(await readFile(path.join(stateRoot,'trust','ed25519-public.pem')));
99
99
  const bodyBytes=Buffer.from(canonicalJson(envelope.body),'utf8');
100
100
  insist(sha256(bodyBytes)===envelope.body_sha256,'closure body hash mismatch');
101
101
  const {closure_sha256,...unsigned}=envelope;
102
102
  insist(sha256(Buffer.from(canonicalJson(unsigned),'utf8'))===closure_sha256,'closure envelope hash mismatch');
103
- insist(envelope.attestation?.algorithm==='ed25519'&&envelope.attestation?.domain==='DEADBYTE-R36-FINAL-CLOSURE-V1','closure attestation contract mismatch');
103
+ insist(envelope.attestation?.algorithm==='ed25519'&&envelope.attestation?.domain==='DEADBYTE-R37-FINAL-CLOSURE-V1','closure attestation contract mismatch');
104
104
  insist(envelope.attestation.key_id===keyInfo.key_id,'closure signer mismatch');
105
105
  insist(cryptoVerify(null,Buffer.concat([CLOSURE_DOMAIN,bodyBytes]),keyInfo.key,Buffer.from(envelope.attestation.signature_base64,'base64')),'closure signature invalid');
106
106
 
107
107
  const pointer=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
108
108
  insist(same(pointer,envelope.body.active_pointer),'active pointer drift');
109
- insist(pointer.version==='0.10.0','active pointer version mismatch');
109
+ insist(pointer.version==='0.11.0','active pointer version mismatch');
110
110
  insist(isCandidateIdentity(pointer,pointer.manifest_sha256),'release id/content address mismatch');
111
111
  const releaseFiles=await verifyTree(pointer.release_root,'MANIFEST.SHA256',pointer.manifest_sha256);
112
112
  const generationFiles=await verifyTree(pointer.generation_root,'GENERATION.SHA256',pointer.generation_manifest_sha256);
113
113
  insist(sha256(await readFile(path.join(stateRoot,'bin','DEADBYTE-MCP.ps1')))===pointer.launcher_sha256,'launcher hash mismatch');
114
114
 
115
115
  const predecessor=envelope.body.predecessor;
116
- insist(isR35Identity(predecessor),'closure predecessor is not exact sealed R35');
116
+ insist(isR36Identity(predecessor),'closure predecessor is not exact sealed R36');
117
117
  const immutable=envelope.body.immutable_slot;
118
118
  insist(immutable?.protected===true,'closure immutable-slot protection missing');
119
119
  insist(samePath(immutable.release_root,pointer.release_root),'closure immutable release_root mismatch');
120
120
  insist(!samePath(immutable.development_root,immutable.release_root),'closure development_root aliases immutable release_root');
121
121
 
122
122
  const surfaces=envelope.body.surfaces;
123
- insist(surfaces?.local_full?.status==='passed'&&surfaces.local_full.tool_count===R36_FULL_TOOL_COUNT&&surfaces.local_full.strict_output_schemas===true,'closure local full 76-tool proof invalid');
123
+ insist(surfaces?.local_full?.status==='passed'&&surfaces.local_full.tool_count===R37_FULL_TOOL_COUNT&&surfaces.local_full.strict_output_schemas===true,'closure local full 76-tool proof invalid');
124
124
  insist(HEX64.test(surfaces.local_full.catalog_sha256??''),'closure local full catalog hash missing');
125
- insist(surfaces?.public_compact?.status==='passed'&&surfaces.public_compact.tool_count<=R36_COMPACT_TOOL_LIMIT&&surfaces.public_compact.capability_closure===true,'closure public compact capability proof invalid');
125
+ insist(surfaces?.public_compact?.status==='passed'&&surfaces.public_compact.tool_count<=R37_COMPACT_TOOL_LIMIT&&surfaces.public_compact.capability_closure===true,'closure public compact capability proof invalid');
126
126
  insist(surfaces.public_compact.coding_armed===false&&surfaces.public_compact.autonomous_armed===false,'closure compact authority is not DISARMED');
127
127
  insist(HEX64.test(surfaces.public_compact.catalog_sha256??'')&&HEX64.test(surfaces.public_compact.ledger_sha256??''),'closure compact catalog/ledger hash missing');
128
128
 
@@ -134,50 +134,50 @@ export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.
134
134
  }
135
135
 
136
136
  const parity=JSON.parse(await readFile(evidence.parity.path,'utf8'));
137
- insist(parity.schema==='deadbyte.r36-parity.v1'&&parity.status==='passed','R36 parity evidence invalid');
138
- insist(parity.rdc_operation_count===0&&parity.execution_provider==='deadbyte_mcp','R36 parity execution provider mismatch');
139
- insist(isCandidateIdentity(parity.candidate,pointer.manifest_sha256),'R36 parity candidate binding mismatch');
140
- insist(isCandidateIdentity(parity.successor,pointer.manifest_sha256),'R36 parity successor binding mismatch');
141
- insist(isR35Identity(parity.predecessor),'R36 parity predecessor binding mismatch');
142
- insist(parity.local_full?.status==='passed'&&parity.local_full.tool_count===R36_FULL_TOOL_COUNT&&parity.local_full.strict_output_schemas===true,'R36 parity local full proof invalid');
137
+ insist(parity.schema==='deadbyte.r37-parity.v1'&&parity.status==='passed','R37 parity evidence invalid');
138
+ insist(parity.rdc_operation_count===0&&parity.execution_provider==='deadbyte_mcp','R37 parity execution provider mismatch');
139
+ insist(isCandidateIdentity(parity.candidate,pointer.manifest_sha256),'R37 parity candidate binding mismatch');
140
+ insist(isCandidateIdentity(parity.successor,pointer.manifest_sha256),'R37 parity successor binding mismatch');
141
+ insist(isR36Identity(parity.predecessor),'R37 parity predecessor binding mismatch');
142
+ insist(parity.local_full?.status==='passed'&&parity.local_full.tool_count===R37_FULL_TOOL_COUNT&&parity.local_full.strict_output_schemas===true,'R37 parity local full proof invalid');
143
143
  insist(parity.local_full.catalog_sha256===surfaces.local_full.catalog_sha256,'R36 local full catalog drift between parity and closure');
144
- insist(parity.public_compact?.status==='passed'&&parity.public_compact.tool_count<=R36_COMPACT_TOOL_LIMIT&&parity.public_compact.capability_closure===true&&parity.public_compact.gateway_count===5,'R36 parity public compact proof invalid');
145
- insist(parity.successor_disarmed?.status==='passed'&&parity.successor_disarmed.tool_count<=R36_COMPACT_TOOL_LIMIT&&parity.successor_disarmed.capability_closure===true&&parity.successor_disarmed.coding_armed===false&&parity.successor_disarmed.autonomous_armed===false,'R36 parity successor disarmed proof invalid');
144
+ insist(parity.public_compact?.status==='passed'&&parity.public_compact.tool_count<=R37_COMPACT_TOOL_LIMIT&&parity.public_compact.capability_closure===true&&parity.public_compact.gateway_count===5,'R37 parity public compact proof invalid');
145
+ insist(parity.successor_disarmed?.status==='passed'&&parity.successor_disarmed.tool_count<=R37_COMPACT_TOOL_LIMIT&&parity.successor_disarmed.capability_closure===true&&parity.successor_disarmed.coding_armed===false&&parity.successor_disarmed.autonomous_armed===false,'R37 parity successor disarmed proof invalid');
146
146
  insist(parity.successor_disarmed.catalog_sha256===surfaces.public_compact.catalog_sha256,'R36 compact catalog drift between restore and closure');
147
147
  insist(parity.successor_disarmed.ledger_sha256===surfaces.public_compact.ledger_sha256,'R36 capability ledger drift between restore and closure');
148
- insist(parity.immutable_slot?.protected===true,'R36 parity immutable-slot proof missing');
149
- insist(samePath(parity.immutable_slot.release_root,pointer.release_root),'R36 parity immutable release_root mismatch');
150
- insist(samePath(parity.immutable_slot.development_root,immutable.development_root),'R36 parity/closure development_root mismatch');
148
+ insist(parity.immutable_slot?.protected===true,'R37 parity immutable-slot proof missing');
149
+ insist(samePath(parity.immutable_slot.release_root,pointer.release_root),'R37 parity immutable release_root mismatch');
150
+ insist(samePath(parity.immutable_slot.development_root,immutable.development_root),'R37 parity/closure development_root mismatch');
151
151
  insist(!samePath(parity.immutable_slot.development_root,pointer.release_root),'R36 mutable development_root aliases immutable release slot');
152
- for(const key of REQUIRED_PARITY_KEYS) insist(parity.requirements?.[key]===true,`R36 parity requirement missing ${key}`);
152
+ for(const key of REQUIRED_PARITY_KEYS) insist(parity.requirements?.[key]===true,`R37 parity requirement missing ${key}`);
153
153
 
154
154
  const activation=JSON.parse(await readFile(evidence.activation.path,'utf8'));
155
155
  const rollback=JSON.parse(await readFile(evidence.rollback.path,'utf8'));
156
156
  const restore=JSON.parse(await readFile(evidence.restore.path,'utf8'));
157
157
  verifyUpdateEnvelope(activation,keyInfo);verifyUpdateEnvelope(rollback,keyInfo);verifyUpdateEnvelope(restore,keyInfo);
158
- insist(activation.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&activation.body.rollback_performed===false,'R36 activation receipt invalid');
159
- insist(activation.body.release_version==='0.10.0'&&activation.body.candidate_manifest_sha256===pointer.manifest_sha256,'R36 activation candidate identity invalid');
160
- insist(isCandidateIdentity(activation.body.active_pointer,pointer.manifest_sha256),'R36 activation active pointer invalid');
161
- insist(isR35Identity(activation.body.prior_pointer),'R36 activation predecessor is not exact R35');
162
- insist(samePath(activation.body.development_root,immutable.development_root),'R36 activation development_root mismatch');
163
- insist(!samePath(activation.body.development_root,activation.body.active_pointer.release_root),'R36 activation development_root aliases release slot');
158
+ insist(activation.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&activation.body.rollback_performed===false,'R37 activation receipt invalid');
159
+ insist(activation.body.release_version==='0.11.0'&&activation.body.candidate_manifest_sha256===pointer.manifest_sha256,'R37 activation candidate identity invalid');
160
+ insist(isCandidateIdentity(activation.body.active_pointer,pointer.manifest_sha256),'R37 activation active pointer invalid');
161
+ insist(isR36Identity(activation.body.prior_pointer),'R37 activation predecessor is not exact R35');
162
+ insist(samePath(activation.body.development_root,immutable.development_root),'R37 activation development_root mismatch');
163
+ insist(!samePath(activation.body.development_root,activation.body.active_pointer.release_root),'R37 activation development_root aliases release slot');
164
164
 
165
- insist(rollback.body.schema==='deadbyte.r31-slot-rollback-receipt.v1'&&rollback.body.rollback_performed===true,'R36 rollback receipt invalid');
166
- insist(isCandidateIdentity(rollback.body.from_pointer,pointer.manifest_sha256),'R36 rollback source is not exact candidate');
167
- insist(isR35Identity(rollback.body.active_pointer),'R36 rollback target is not exact R35 predecessor');
168
- insist(rollback.body.activation_receipt_sha256===activation.receipt_sha256,'R36 rollback not bound to activation receipt');
165
+ insist(rollback.body.schema==='deadbyte.r31-slot-rollback-receipt.v1'&&rollback.body.rollback_performed===true,'R37 rollback receipt invalid');
166
+ insist(isCandidateIdentity(rollback.body.from_pointer,pointer.manifest_sha256),'R37 rollback source is not exact candidate');
167
+ insist(isR36Identity(rollback.body.active_pointer),'R37 rollback target is not exact R35 predecessor');
168
+ insist(rollback.body.activation_receipt_sha256===activation.receipt_sha256,'R37 rollback not bound to activation receipt');
169
169
 
170
- insist(restore.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&restore.body.rollback_performed===false,'R36 restore receipt invalid');
171
- insist(restore.body.release_version==='0.10.0'&&restore.body.candidate_manifest_sha256===pointer.manifest_sha256,'R36 restore candidate identity invalid');
172
- insist(isR35Identity(restore.body.prior_pointer),'R36 restore predecessor is not exact R35');
173
- insist(isCandidateIdentity(restore.body.active_pointer,pointer.manifest_sha256)&&same(restore.body.active_pointer,pointer),'R36 restore/current pointer mismatch');
174
- insist(samePath(restore.body.development_root,immutable.development_root),'R36 restore development_root mismatch');
175
- insist(!samePath(restore.body.development_root,restore.body.active_pointer.release_root),'R36 restore development_root aliases release slot');
170
+ insist(restore.body.schema==='deadbyte.r27-slot-update-receipt.v1'&&restore.body.rollback_performed===false,'R37 restore receipt invalid');
171
+ insist(restore.body.release_version==='0.11.0'&&restore.body.candidate_manifest_sha256===pointer.manifest_sha256,'R37 restore candidate identity invalid');
172
+ insist(isR36Identity(restore.body.prior_pointer),'R37 restore predecessor is not exact R35');
173
+ insist(isCandidateIdentity(restore.body.active_pointer,pointer.manifest_sha256)&&same(restore.body.active_pointer,pointer),'R37 restore/current pointer mismatch');
174
+ insist(samePath(restore.body.development_root,immutable.development_root),'R37 restore development_root mismatch');
175
+ insist(!samePath(restore.body.development_root,restore.body.active_pointer.release_root),'R37 restore development_root aliases release slot');
176
176
 
177
177
  const windowsGate=JSON.parse(await readFile(evidence.windows_gate.path,'utf8'));
178
- insist(windowsGate.schema==='deadbyte.r36-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'R36 Windows gate evidence invalid');
179
- insist(windowsGate.version==='0.10.0'&&windowsGate.manifest_sha256===pointer.manifest_sha256,'R36 Windows gate manifest/version binding mismatch');
180
- insist(windowsGate.marker==='DEADBYTE V0.10.0 / R36 WINDOWS BATCH GATE: PASS','R36 Windows gate PASS marker mismatch');
178
+ insist(windowsGate.schema==='deadbyte.r37-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'R37 Windows gate evidence invalid');
179
+ insist(windowsGate.version==='0.11.0'&&windowsGate.manifest_sha256===pointer.manifest_sha256,'R37 Windows gate manifest/version binding mismatch');
180
+ insist(windowsGate.marker==='DEADBYTE V0.11.0 / R37 WINDOWS BATCH GATE: PASS','R37 Windows gate PASS marker mismatch');
181
181
 
182
182
  const machine=envelope.body.machine;
183
183
  insist(machine?.status?.release_id===pointer.release_id&&machine.status.release_manifest_sha256===pointer.manifest_sha256&&machine.status.generation_manifest_sha256===pointer.generation_manifest_sha256,'machine status binding mismatch');
@@ -194,7 +194,7 @@ export async function verifyFinalClosureObject(envelope,{stateRoot=path.join(os.
194
194
  return {ok:true,status:'passed',release_id:pointer.release_id,manifest_sha256:pointer.manifest_sha256,
195
195
  generation_manifest_sha256:pointer.generation_manifest_sha256,release_files:releaseFiles,generation_files:generationFiles,
196
196
  machine_id:machine.status.machine_id,parity_sha256:evidence.parity.sha256,closure_sha256:envelope.closure_sha256,
197
- full_tool_count:R36_FULL_TOOL_COUNT,compact_tool_count:surfaces.public_compact.tool_count};
197
+ full_tool_count:R37_FULL_TOOL_COUNT,compact_tool_count:surfaces.public_compact.tool_count};
198
198
  }
199
199
 
200
200
  const invoked=process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url);
@@ -7,11 +7,11 @@ import { probeR36FullSurface } from '../src/r36-full-surface-probe.mjs';
7
7
  import { probeR36CompactDisarmed } from '../src/r36-compact-disarmed-probe.mjs';
8
8
  import {
9
9
  validateParityEvidence,
10
- R35_PREDECESSOR_RELEASE_ID,
11
- R35_PREDECESSOR_MANIFEST
10
+ R36_PREDECESSOR_RELEASE_ID,
11
+ R36_PREDECESSOR_MANIFEST
12
12
  } from './release-parity.mjs';
13
13
 
14
- const DOMAIN=Buffer.from('DEADBYTE-R36-FINAL-CLOSURE-V1\0','utf8');
14
+ const DOMAIN=Buffer.from('DEADBYTE-R37-FINAL-CLOSURE-V1\0','utf8');
15
15
  const stateRoot=path.resolve(process.env.DEADBYTE_STATE_ROOT||path.join(os.homedir(),'.deadbyte-mcp'));
16
16
  const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
17
17
  const canonical=value=>Array.isArray(value)?value.map(canonical):value&&typeof value==='object'
@@ -42,24 +42,24 @@ async function atomicCreate(file,bytes){
42
42
 
43
43
  export async function writeFinalClosure({parityPath,activationPath,windowsGatePath}){
44
44
  const pointer=JSON.parse(await readFile(path.join(stateRoot,'active-release.json'),'utf8'));
45
- insist(pointer.version==='0.10.0','final closure requires V0.10.0 active release');
45
+ insist(pointer.version==='0.11.0','final closure requires V0.11.0 active release');
46
46
  insist(pointer.release_id===`v${pointer.version}-${pointer.manifest_sha256.slice(0,16)}`,'final closure release id/content address mismatch');
47
47
 
48
48
  const parity=JSON.parse(await readFile(path.resolve(parityPath),'utf8'));
49
- insist(parity.schema==='deadbyte.r36-parity.v1','R36 parity schema mismatch at final closure');
49
+ insist(parity.schema==='deadbyte.r37-parity.v1','R37 parity schema mismatch at final closure');
50
50
  validateParityEvidence(parity);
51
51
  insist(parity.candidate?.release_id===pointer.release_id&&parity.candidate?.manifest_sha256===pointer.manifest_sha256,'parity candidate/current release mismatch');
52
52
  insist(parity.successor?.release_id===pointer.release_id&&parity.successor?.manifest_sha256===pointer.manifest_sha256,'parity successor/current release mismatch');
53
- insist(parity.predecessor?.release_id===R35_PREDECESSOR_RELEASE_ID&&parity.predecessor?.manifest_sha256===R35_PREDECESSOR_MANIFEST,'parity predecessor identity mismatch');
53
+ insist(parity.predecessor?.release_id===R36_PREDECESSOR_RELEASE_ID&&parity.predecessor?.manifest_sha256===R36_PREDECESSOR_MANIFEST,'parity predecessor identity mismatch');
54
54
  insist(parity.rollback?.receipt_path&&parity.restore?.receipt_path,'parity rollback/restore receipt paths missing');
55
55
  insist(parity.immutable_slot?.protected===true,'parity immutable-slot proof missing');
56
56
  insist(samePath(parity.immutable_slot.release_root,pointer.release_root),'parity immutable release root mismatch');
57
57
  insist(!samePath(parity.immutable_slot.development_root,pointer.release_root),'development_root must differ from immutable release_root');
58
58
 
59
59
  const windowsGate=JSON.parse(await readFile(path.resolve(windowsGatePath),'utf8'));
60
- insist(windowsGate.schema==='deadbyte.r36-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'R36 Windows gate evidence invalid');
61
- insist(windowsGate.version==='0.10.0'&&windowsGate.manifest_sha256===pointer.manifest_sha256,'R36 Windows gate/current release mismatch');
62
- insist(windowsGate.marker==='DEADBYTE V0.10.0 / R36 WINDOWS BATCH GATE: PASS','R36 Windows gate marker mismatch');
60
+ insist(windowsGate.schema==='deadbyte.r37-windows-gate.v1'&&windowsGate.status==='passed'&&windowsGate.exit_code===0,'R37 Windows gate evidence invalid');
61
+ insist(windowsGate.version==='0.11.0'&&windowsGate.manifest_sha256===pointer.manifest_sha256,'R37 Windows gate/current release mismatch');
62
+ insist(windowsGate.marker==='DEADBYTE V0.11.0 / R37 WINDOWS BATCH GATE: PASS','R37 Windows gate marker mismatch');
63
63
 
64
64
  const localFull=await probeR36FullSurface({packageRoot:pointer.release_root,generationRoot:pointer.generation_root,stateRoot});
65
65
  insist(localFull.status==='passed'&&localFull.tool_count===76&&localFull.strict_output_schemas===true,'final local full 76-tool proof failed');
@@ -76,9 +76,9 @@ export async function writeFinalClosure({parityPath,activationPath,windowsGatePa
76
76
  windows_gate:await fileEvidence(windowsGatePath)
77
77
  };
78
78
  const body={
79
- schema:'deadbyte.r36-final-closure.v1',version:'0.10.0',release_label:'R36 FINAL MACHINE BASELINE',
79
+ schema:'deadbyte.r37-final-closure.v1',version:'0.11.0',release_label:'R37 FINAL MACHINE BASELINE',
80
80
  completed_at_utc:new Date().toISOString(),active_pointer:pointer,
81
- predecessor:{release_id:R35_PREDECESSOR_RELEASE_ID,version:'0.9.0',manifest_sha256:R35_PREDECESSOR_MANIFEST},
81
+ predecessor:{release_id:R36_PREDECESSOR_RELEASE_ID,version:'0.10.0',manifest_sha256:R36_PREDECESSOR_MANIFEST},
82
82
  immutable_slot:{protected:true,release_root:path.resolve(pointer.release_root),development_root:path.resolve(parity.immutable_slot.development_root)},
83
83
  surfaces:{
84
84
  local_full:{status:localFull.status,profile:localFull.profile,tool_count:localFull.tool_count,catalog_sha256:localFull.catalog_sha256,strict_output_schemas:localFull.strict_output_schemas,protocol_revision:localFull.protocol_revision},
@@ -94,10 +94,10 @@ export async function writeFinalClosure({parityPath,activationPath,windowsGatePa
94
94
  const keyId=sha256(Buffer.from(publicKey.export({type:'spki',format:'der'})));
95
95
  const bodyBytes=Buffer.from(canonicalJson(body),'utf8');
96
96
  const signature=cryptoSign(null,Buffer.concat([DOMAIN,bodyBytes]),privateKey);
97
- const envelope={body,body_sha256:sha256(bodyBytes),attestation:{algorithm:'ed25519',domain:'DEADBYTE-R36-FINAL-CLOSURE-V1',key_id:keyId,signature_base64:signature.toString('base64')}};
97
+ const envelope={body,body_sha256:sha256(bodyBytes),attestation:{algorithm:'ed25519',domain:'DEADBYTE-R37-FINAL-CLOSURE-V1',key_id:keyId,signature_base64:signature.toString('base64')}};
98
98
  envelope.closure_sha256=sha256(Buffer.from(canonicalJson(envelope),'utf8'));
99
99
  const dir=path.join(stateRoot,'evidence','release');
100
- const file=path.join(dir,`r36-final-${pointer.manifest_sha256.slice(0,16)}.json`);
100
+ const file=path.join(dir,`r37-final-${pointer.manifest_sha256.slice(0,16)}.json`);
101
101
  const bytes=Buffer.from(`${JSON.stringify(envelope,null,2)}\n`,'utf8');
102
102
  await atomicCreate(file,bytes);
103
103
  return {status:'written',path:file,sha256:sha256(bytes),closure_sha256:envelope.closure_sha256,release_id:pointer.release_id};
@@ -0,0 +1,42 @@
1
+ $ErrorActionPreference = 'Stop'
2
+ Set-StrictMode -Version 2.0
3
+
4
+ function Invoke-GateStep {
5
+ param(
6
+ [Parameter(Mandatory = $true)][string]$Name,
7
+ [Parameter(Mandatory = $true)][string[]]$NpmArgs
8
+ )
9
+ Write-Host "==== $Name ===="
10
+ & npm.cmd @NpmArgs
11
+ if ($LASTEXITCODE -ne 0) {
12
+ throw "DEADBYTE V0.10.0 / R36 gate failed at $Name with exit code $LASTEXITCODE"
13
+ }
14
+ }
15
+
16
+ Invoke-GateStep -Name 'containment-build' -NpmArgs @('run', 'containment:build')
17
+ Invoke-GateStep -Name 'process-policy-refresh' -NpmArgs @('run', 'process:policy:refresh')
18
+ Invoke-GateStep -Name 'release-manifest-write' -NpmArgs @('run', 'manifest:write')
19
+ Invoke-GateStep -Name 'release-manifest' -NpmArgs @('run', 'manifest:verify')
20
+ Invoke-GateStep -Name 'tests' -NpmArgs @('test')
21
+ Invoke-GateStep -Name 'mcp-smoke' -NpmArgs @('run', 'mcp:smoke')
22
+ Invoke-GateStep -Name 'mcp-agent-smoke' -NpmArgs @('run', 'mcp:agent:smoke')
23
+ Invoke-GateStep -Name 'mcp-coding-smoke' -NpmArgs @('run', 'mcp:coding:smoke')
24
+ Invoke-GateStep -Name 'mcp-machine-fs-smoke' -NpmArgs @('run', 'mcp:machine-fs:smoke')
25
+ Invoke-GateStep -Name 'mcp-observation-smoke' -NpmArgs @('run', 'mcp:observation:smoke')
26
+ Invoke-GateStep -Name 'mcp-process-smoke' -NpmArgs @('run', 'mcp:process:smoke')
27
+ Invoke-GateStep -Name 'mcp-autonomous-smoke' -NpmArgs @('run', 'mcp:autonomous:smoke')
28
+ Invoke-GateStep -Name 'tunnel-stdio-compat-smoke' -NpmArgs @('run', 'mcp:tunnel-compat:smoke')
29
+ Invoke-GateStep -Name 'mcp-host-smoke' -NpmArgs @('run', 'mcp:host:smoke')
30
+ Invoke-GateStep -Name 'authority-smoke' -NpmArgs @('run', 'authority: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 'release-manifest-final' -NpmArgs @('run', 'manifest:verify')
35
+
36
+ Write-Host '==== windows-gate-evidence ===='
37
+ & node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence.mjs')
38
+ if ($LASTEXITCODE -ne 0) {
39
+ throw "DEADBYTE V0.10.0 / R36 gate failed at windows-gate-evidence with exit code $LASTEXITCODE"
40
+ }
41
+
42
+ Write-Host '==== DEADBYTE V0.10.0 / R36 WINDOWS BATCH GATE: PASS ===='
@@ -9,7 +9,7 @@ function Invoke-GateStep {
9
9
  Write-Host "==== $Name ===="
10
10
  & npm.cmd @NpmArgs
11
11
  if ($LASTEXITCODE -ne 0) {
12
- throw "DEADBYTE V0.10.0 / R36 gate failed at $Name with exit code $LASTEXITCODE"
12
+ throw "DEADBYTE V0.11.0 / R37 gate failed at $Name with exit code $LASTEXITCODE"
13
13
  }
14
14
  }
15
15
 
@@ -36,7 +36,7 @@ Invoke-GateStep -Name 'release-manifest-final' -NpmArgs @('run', 'manifest:verif
36
36
  Write-Host '==== windows-gate-evidence ===='
37
37
  & node.exe (Join-Path $PSScriptRoot 'windows-gate-evidence.mjs')
38
38
  if ($LASTEXITCODE -ne 0) {
39
- throw "DEADBYTE V0.10.0 / R36 gate failed at windows-gate-evidence with exit code $LASTEXITCODE"
39
+ throw "DEADBYTE V0.11.0 / R37 gate failed at windows-gate-evidence with exit code $LASTEXITCODE"
40
40
  }
41
41
 
42
- Write-Host '==== DEADBYTE V0.10.0 / R36 WINDOWS BATCH GATE: PASS ===='
42
+ Write-Host '==== DEADBYTE V0.11.0 / R37 WINDOWS BATCH GATE: PASS ===='