deadbyte-mcp 0.15.44 → 0.15.45

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 (157) hide show
  1. package/MANIFEST.SHA256 +69 -131
  2. package/PROVENANCE.json +257 -243
  3. package/README.txt +18 -18
  4. package/RELEASE.json +348 -334
  5. package/SBOM.cdx.json +2 -2
  6. package/TEST-MATRIX.json +503 -491
  7. package/bridge/package.json +1 -1
  8. package/controller/deadbyte-controller.ps1 +1857 -1769
  9. package/controller/deadbyte-desktop-policy.json +6 -6
  10. package/controller/deadbyte-process-policy.json +4 -4
  11. package/docs/R68-COMPAT-HOST-EXEC-CANDIDATE.md +63 -0
  12. package/docs/R69-LIVE-OUTCOME-R70-POLICY-TRANSFER.md +136 -0
  13. package/docs/R70-CODING-DIGEST-SUPERVISOR-CHECKPOINT-20261013.md +42 -0
  14. package/docs/R70-FINITE-GRANT-OWNER-BOUNDARY-20261013.md +80 -0
  15. package/docs/R70-OWNER-BOOTSTRAP-CHECKPOINT-20261013.md +60 -0
  16. package/docs/R70-REFERENCE-MECHANISMS.json +95 -0
  17. package/docs/R70-TRUST-GUARD-EXPIRY-CHECKPOINT-20261013.md +47 -0
  18. package/package.json +2 -2
  19. package/scripts/benchmark-l0-r71.mjs +76 -0
  20. package/scripts/gate-windows-r71.ps1 +64 -0
  21. package/scripts/npm-release-r48.mjs +2 -0
  22. package/scripts/npm-release-readiness-r71.mjs +21 -0
  23. package/scripts/verify-r70-full-regression.ps1 +72 -0
  24. package/src/authority-continuity-r65.mjs +28 -8
  25. package/src/autonomous-mcp-tools.mjs +1 -1
  26. package/src/autonomous-output-contracts.mjs +4 -1
  27. package/src/autonomous-policy.mjs +54 -7
  28. package/src/capability-ledger.mjs +1 -1
  29. package/src/capability-resolver.mjs +2 -1
  30. package/src/commander-compat-runtime.mjs +30 -2
  31. package/src/deadbyte-cli.mjs +8 -6
  32. package/src/native-diff-v2.mjs +18 -5
  33. package/src/native-diff.mjs +21 -5
  34. package/src/r70-owner-approval.mjs +78 -0
  35. package/src/remote-live-log.mjs +48 -14
  36. package/src/remote-result-journal.mjs +1 -1
  37. package/src/runtime-update.mjs +2051 -1891
  38. package/src/tool-audit.mjs +2 -0
  39. package/src/version.mjs +1 -1
  40. package/test/autonomous-local-supervisor.test.mjs +2 -1
  41. package/test/autonomous-output-contract.test.mjs +17 -1
  42. package/test/autonomous-supervisor-integration.test.mjs +2 -1
  43. package/test/capability-resolver.test.mjs +17 -0
  44. package/test/codex-autonomous-r44.test.mjs +1 -1
  45. package/test/commander-compat-runtime.test.mjs +42 -0
  46. package/test/controller-policy-preflight-r59.test.mjs +1 -0
  47. package/test/native-diff-topology-r36.test.mjs +35 -2
  48. package/test/native-diff.test.mjs +83 -3
  49. package/test/r59-tool-surface-compat.test.mjs +9 -5
  50. package/test/r65-authority-runtime-epoch.test.mjs +9 -1
  51. package/test/r67-isolated-slot-rollback-restore.test.mjs +2 -1
  52. package/test/r67-npm-publish-gate.test.mjs +4 -2
  53. package/test/r67-release-contract.test.mjs +8 -7
  54. package/test/r69-live-outcome.test.mjs +137 -0
  55. package/test/r70-autonomous-grant-expiry.test.mjs +89 -0
  56. package/test/r70-autonomous-policy-bootstrap.test.mjs +166 -0
  57. package/test/r70-controller-autonomous-root.test.mjs +104 -0
  58. package/test/r70-controller-grant-subset.test.mjs +28 -0
  59. package/test/r70-controller-owner-issue-boundary.test.mjs +80 -0
  60. package/test/r70-controller-policy-snapshot.test.mjs +66 -0
  61. package/test/r70-owner-approval.test.mjs +67 -0
  62. package/test/r71-full-verifier-artifact.test.mjs +28 -0
  63. package/test/r71-isolated-slot-rollback-restore.test.mjs +62 -0
  64. package/test/r71-native-diff-mcp-wire.test.mjs +75 -0
  65. package/test/r71-publish-fence.test.mjs +38 -0
  66. package/test/r71-release-identity.test.mjs +31 -0
  67. package/test/remote-result-journal.test.mjs +12 -0
  68. package/test/remote-session-cli.test.mjs +2 -1
  69. package/test/standing-grants.test.mjs +2 -2
  70. package/test/tool-audit.test.mjs +14 -0
  71. package/bin/appcontainer-stage.obj +0 -0
  72. package/bin/bootstrap-advapi32.obj +0 -0
  73. package/bin/bootstrap-exitcode.obj +0 -0
  74. package/bin/bootstrap-kernel32.obj +0 -0
  75. package/bin/child-control-probe.obj +0 -0
  76. package/bin/child-control-stage.obj +0 -0
  77. package/bin/contained-reverse-worker.obj +0 -0
  78. package/bin/contained-transform-worker.obj +0 -0
  79. package/bin/containment-probe.obj +0 -0
  80. package/bin/deadbyte-contain.obj +0 -0
  81. package/bin/deadbyte-desktop-input-r40.obj +0 -0
  82. package/bin/deadbyte-desktop-observer-r40.obj +0 -0
  83. package/bin/deadbyte-desktop-uia-r40.obj +0 -0
  84. package/bin/deadbyte-exec.obj +0 -0
  85. package/bin/deadbyte-hardware-observer-r45.obj +0 -0
  86. package/bin/deadbyte-native-inspect-r67.obj +0 -0
  87. package/bin/deadbyte-process-host.obj +0 -0
  88. package/bin/deadbyte-tunnel-host.obj +0 -0
  89. package/conpty-input-observer.obj +0 -0
  90. package/miniconpty.obj +0 -0
  91. package/proof/CONTAINMENT-BUILD.txt +0 -163
  92. package/proof/MCP-SMOKE-STATUS.txt +0 -9
  93. package/proof/NODE-SYNTAX.txt +0 -4
  94. package/proof/PROOF.txt +0 -6
  95. package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +0 -29
  96. package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +0 -28
  97. package/proof/SECRET-SCAN.txt +0 -4
  98. package/proof/SOURCE-GATES.txt +0 -16
  99. package/proof/STATUS.txt +0 -11
  100. package/proof/TARGET-V0313-CONTAINMENT-PASS.sha256 +0 -1
  101. package/proof/TARGET-V0313-CONTAINMENT-PASS.txt +0 -215
  102. package/proof/TARGET-V040-CONTAINED-IPC-FAIL.sha256 +0 -1
  103. package/proof/TARGET-V040-CONTAINED-IPC-FAIL.txt +0 -299
  104. package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  105. package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.txt +0 -311
  106. package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  107. package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.txt +0 -313
  108. package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  109. package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.txt +0 -308
  110. package/proof/TARGET-V044-CONTAINED-PASS.sha256 +0 -1
  111. package/proof/TARGET-V044-CONTAINED-PASS.txt +0 -432
  112. package/proof/TARGET-V045-DUAL-OPERATION-PASS.sha256 +0 -1
  113. package/proof/TARGET-V045-DUAL-OPERATION-PASS.txt +0 -481
  114. package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.sha256 +0 -1
  115. package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.txt +0 -610
  116. package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.sha256 +0 -1
  117. package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.txt +0 -642
  118. package/proof/TARGET-V050-BATCH-GATE-PASS.sha256 +0 -1
  119. package/proof/TARGET-V050-BATCH-GATE-PASS.txt +0 -713
  120. package/proof/TESTS.txt +0 -686
  121. package/proof/TRUST-EPHEMERAL.txt +0 -4
  122. package/proof/V03-FREEZE.txt +0 -27
  123. package/proof/V041-IPC-HOTFIX.txt +0 -16
  124. package/proof/V042-ENV-HOTFIX.txt +0 -15
  125. package/proof/V043-DRIVE-CWD-HOTFIX.txt +0 -14
  126. package/proof/V044-LOCALAPPDATA-HOTFIX.txt +0 -18
  127. package/proof/V045-OPERATION-REGISTRY.txt +0 -7
  128. package/proof/V046-WORKER-REGISTRY.txt +0 -12
  129. package/proof/V047-WORKER-MANIFEST.txt +0 -18
  130. package/proof/V050-BATCH-TRUST-CLOSURE.txt +0 -21
  131. package/proof/V060-ACTIVE-NETWORK-AUTHORITY.txt +0 -29
  132. package/proof/V070-NODE-SYNTAX.txt +0 -36
  133. package/proof/V070-NODE-TESTS.txt +0 -752
  134. package/proof/V070-PACK-DRY-RUN.txt +0 -126
  135. package/proof/V070-SOURCE-GATE.txt +0 -30
  136. package/proof/V070-STATIC-SCAN.txt +0 -4
  137. package/proof/V070-WINDOWS-GATE-PENDING.txt +0 -25
  138. package/proof/V071-NODE-SYNTAX.txt +0 -1
  139. package/proof/V071-NODE-TESTS.txt +0 -796
  140. package/proof/V071-PACK-DRY-RUN.json +0 -656
  141. package/proof/V071-SOURCE-GATE.txt +0 -16
  142. package/proof/V071-WINDOWS-GATE-PENDING.txt +0 -24
  143. package/proof/V073-NODE-SYNTAX.txt +0 -4
  144. package/proof/V073-SOURCE-GATE.txt +0 -21
  145. package/proof/V073-STATIC-SCAN.txt +0 -10
  146. package/proof/V073-WINDOWS-GATE-PENDING.txt +0 -5
  147. package/proof/VERIFY.txt +0 -7
  148. package/proof/WINDOWS-CONTAINED-STATUS.txt +0 -5
  149. package/proof/WINDOWS-CONTAINMENT-STATUS.txt +0 -3
  150. package/proof/commander-closure-20260927/CONTINUATION.json +0 -43
  151. package/proof/commander-closure-20260927/RESULT.json +0 -30
  152. package/proof/commander-closure-20260927/SEARCH-CONTINUATION.json +0 -30
  153. package/proof/commander-closure-20260927/XLS-REFERENCE-PROBE.json +0 -13
  154. package/proof/commander-closure-20260928/DIFFERENTIAL-CHECKPOINT.json +0 -122
  155. package/proof/r59-full-regression-current.json +0 -13
  156. package/proof/r59-full-regression-current.stderr.log +0 -0
  157. package/proof/r59-full-regression-current.stdout.log +0 -1268
@@ -0,0 +1,89 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {mkdtemp,readFile,rm,writeFile} from 'node:fs/promises';
4
+ import {spawnSync} from 'node:child_process';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import * as auto from '../src/autonomous-policy.mjs';
8
+
9
+ const H=c=>c.repeat(64);
10
+ const controller=new URL('../controller/deadbyte-controller.ps1',import.meta.url);
11
+ const quote=s=>`'${String(s).replaceAll("'","''")}'`;
12
+ const issued=Date.parse('2026-10-13T03:00:00.000Z');
13
+ const when=n=>new Date(issued+n).toISOString();
14
+
15
+ test('R70 signed standing grant expiry is bounded, canonical and fail-closed before authority decision',()=>{
16
+ assert.equal(typeof auto.inspectAutonomousStandingWindow,'function');
17
+ const base={granted_at_utc:when(0),expires_at_utc:when(1_800_000)};
18
+ assert.deepEqual(auto.inspectAutonomousStandingWindow(base,new Date(when(300_000))),
19
+ {ok:true,reason:null,expires_at_utc:when(1_800_000),remaining_ms:1_500_000});
20
+ for(const [claim,reason,now] of [
21
+ [{...base,expires_at_utc:when(0)},'expiry-window-invalid',when(30_000)],
22
+ [{...base,expires_at_utc:when(3_600_001)},'expiry-window-invalid',when(30_000)],
23
+ [{...base,expires_at_utc:'bad'},'expiry-invalid',when(30_000)],
24
+ [{...base,expires_at_utc:when(1_800_000)},'expired',when(1_800_000)],
25
+ [{...base,granted_at_utc:when(700_000)},'not-yet-valid',when(300_000)]
26
+ ]){
27
+ const result=auto.inspectAutonomousStandingWindow(claim,new Date(now));
28
+ assert.equal(result.ok,false);
29
+ assert.equal(result.reason,reason);
30
+ }
31
+ assert.deepEqual(auto.inspectAutonomousStandingWindow({granted_at_utc:when(0)},new Date(when(300_000))),
32
+ {ok:true,reason:null,expires_at_utc:null,remaining_ms:null});
33
+ });
34
+
35
+ test('R70 runtime rejects a v2 grant whose Coding policy digest is missing or stale',async()=>{
36
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-coding-lease-'));
37
+ const leaseFile=path.join(root,'grant.json');
38
+ try{
39
+ const policy={policy_sha256:H('a'),coding_policy_sha256:H('b'),root_ids:['core'],
40
+ lease_file:leaseFile,policy_path:path.join(root,'autonomous-policy.json')};
41
+ const base={schema:'deadbyte.autonomous-grant.v2',policy_sha256:H('a'),
42
+ instance_nonce:H('c'),root_ids:['core'],granted_at_utc:when(0),
43
+ expires_at_utc:when(1_800_000)};
44
+ for(const candidate of [{...base,coding_policy_sha256:H('d')},base]){
45
+ await writeFile(leaseFile,JSON.stringify(candidate));
46
+ const status=await auto.autonomousSessionStatus(policy,new Date(when(300_000)));
47
+ assert.equal(status.armed,false);
48
+ assert.equal(status.reason,'coding-policy-digest');
49
+ await assert.rejects(auto.recheckAutonomousAuthority(policy,{
50
+ armed:true,instance_nonce:H('c'),root_ids:['core'],standing:true,expires_at_utc:when(1_800_000)
51
+ },'core',new Date(when(300_000))),/coding-policy-digest/);
52
+ }
53
+ }finally{await rm(root,{recursive:true,force:true});}
54
+ });
55
+
56
+ test('R70 controller must agree with runtime on expired and malformed signed standing grant',async()=>{
57
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-grant-expiry-'));
58
+ const grantFile=path.join(root,'autonomous-grant.json');
59
+ try{
60
+ const scriptText=await readFile(controller,'utf8');
61
+ const start=scriptText.indexOf('function Get-AutonomousLeaseStatus(');
62
+ const end=scriptText.indexOf('function Arm-Autonomous(',start);
63
+ assert.ok(start>=0&&end>start);
64
+ const block=scriptText.slice(start,end);
65
+ const now=Date.now();
66
+ const records=[
67
+ {name:'expired',grant:new Date(now-3_600_000),expires:new Date(now-1_800_000),reason:'expired',armed:false},
68
+ {name:'oversized',grant:new Date(now-300_000),expires:new Date(now+7_200_000),reason:'expiry-window-invalid',armed:false},
69
+ {name:'valid',grant:new Date(now-300_000),expires:new Date(now+900_000),reason:'standing-grant',armed:true}
70
+ ];
71
+ for(const c of records){
72
+ const lease={schema:'deadbyte.autonomous-grant.v2',policy_sha256:H('a'),coding_policy_sha256:H('b'),
73
+ instance_nonce:H('c'),root_ids:['core'],granted_at_utc:c.grant.toISOString(),
74
+ expires_at_utc:c.expires.toISOString()};
75
+ await writeFile(grantFile,JSON.stringify(lease));
76
+ const script=`$ErrorActionPreference='Stop';
77
+ function Get-AutonomousPolicyMetadata($Cfg){return [pscustomobject]@{LeaseFile=${quote(grantFile)};Sha256='${H('a')}';CodingPolicySha256='${H('b')}';RootIds=@('core')}}
78
+ function Get-CodingLeaseStatus($Cfg){return [pscustomobject]@{Armed=$true;RootIds=@('core')}}
79
+ function Get-AuthorityEpochStatus($Cfg,$Plane,$File,$Nonce){return [pscustomobject]@{Trusted=$true;Seq=1;EventSha256='${H('d')}'}}
80
+ ${block}
81
+ (Get-AutonomousLeaseStatus @{AutonomousPolicyFile='test-fixture'})|ConvertTo-Json -Compress`;
82
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
83
+ assert.equal(result.status,0,result.stderr);
84
+ const out=JSON.parse(result.stdout.trim());
85
+ assert.equal(out.Armed,c.armed,c.name);
86
+ assert.equal(out.Reason,c.reason,c.name);
87
+ }
88
+ }finally{await rm(root,{recursive:true,force:true});}
89
+ });
@@ -0,0 +1,166 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash,generateKeyPairSync,sign} from 'node:crypto';
4
+ import {mkdir,mkdtemp,readFile,realpath,rm,writeFile} from 'node:fs/promises';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import * as update from '../src/runtime-update.mjs';
8
+ import {canonicalJson} from '../src/canonical-json.mjs';
9
+ import {loadAutonomousPolicy} from '../src/autonomous-policy.mjs';
10
+
11
+ const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
12
+ const baseArgs=['--stage','stage','--development-root','dev','--expected-version','0.15.45',
13
+ '--expected-manifest','a'.repeat(64)];
14
+
15
+ test('R70 autonomous policy bootstrap is an exact path and SHA pair',()=>{
16
+ assert.throws(()=>update.parseUpdateArgs([...baseArgs,'--autonomous-policy','policy.json']),/autonomous policy bootstrap requires path plus SHA-256/);
17
+ assert.throws(()=>update.parseUpdateArgs([...baseArgs,'--autonomous-policy-sha256','a'.repeat(64)]),/autonomous policy bootstrap requires path plus SHA-256/);
18
+ const parsed=update.parseUpdateArgs([...baseArgs,'--autonomous-policy','policy.json','--autonomous-policy-sha256','b'.repeat(64),
19
+ '--owner-approval','approval.json','--owner-approval-sha256','c'.repeat(64)]);
20
+ assert.deepEqual(parsed.autonomousPolicyBootstrap,{path:path.resolve('policy.json'),sha256:'b'.repeat(64)});
21
+ assert.deepEqual(parsed.ownerApprovalBootstrap,{path:path.resolve('approval.json'),sha256:'c'.repeat(64)});
22
+ });
23
+
24
+ test('R70 autonomous policy bootstrap cannot be parsed without pinned owner approval',()=>{
25
+ assert.throws(()=>update.parseUpdateArgs([...baseArgs,'--autonomous-policy','policy.json',
26
+ '--autonomous-policy-sha256','b'.repeat(64)]),/owner approval/i);
27
+ assert.throws(()=>update.parseUpdateArgs([...baseArgs,'--owner-approval','approval.json',
28
+ '--owner-approval-sha256','c'.repeat(64)]),/autonomous policy/i);
29
+ });
30
+
31
+ test('R70 pinned autonomous policy rejects changed bytes and roots outside Coding policy',async()=>{
32
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-policy-'));
33
+ try{
34
+ const file=path.join(root,'autonomous-policy.json');
35
+ const bytes=Buffer.from(JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
36
+ lease_file:path.join(root,'grant.json'),evidence_dir:path.join(root,'evidence'),
37
+ coding_policy_sha256:'a'.repeat(64),root_ids:['gfx_project'],planner:{backend:'client_sampling',max_tokens:2048},
38
+ profiles:{},limits:{max_files_per_diff:8}}));
39
+ await writeFile(file,bytes);
40
+ const pinned={path:file,sha256:sha(bytes)};
41
+ const prepared=await update.prepareAutonomousPolicyBootstrap(pinned);
42
+ assert.deepEqual(prepared.policy.root_ids,['gfx_project']);
43
+ assert.doesNotThrow(()=>update.assertAutonomousBootstrapRoots(prepared.policy,{roots:{gfx_project:{path:root}}},'a'.repeat(64)));
44
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(prepared.policy,{roots:{core:{path:root}}},'a'.repeat(64)),/outside selected coding policy/);
45
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(prepared.policy,{roots:{gfx_project:{path:root}}},'b'.repeat(64)),/coding policy SHA-256 mismatch/);
46
+ await writeFile(file,Buffer.concat([bytes,Buffer.from('\n')]));
47
+ await assert.rejects(update.prepareAutonomousPolicyBootstrap(pinned),/SHA-256 mismatch/);
48
+ }finally{await rm(root,{recursive:true,force:true});}
49
+ });
50
+
51
+ test('R70 selected autonomous root must resolve to an existing real directory before update mutation',async()=>{
52
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-realroot-'));
53
+ try{
54
+ const policy={root_ids:['gfx_project'],coding_policy_sha256:'a'.repeat(64)};
55
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(policy,{roots:{gfx_project:{path:path.join(root,'missing')}}},'a'.repeat(64)),/real directory/);
56
+ }finally{await rm(root,{recursive:true,force:true});}
57
+ });
58
+
59
+ test('R70 autonomous bootstrap cannot treat a whole drive as a project root',()=>{
60
+ if(process.platform!=='win32') return;
61
+ const drive=path.parse('D:\\').root;
62
+ const policy={root_ids:['local_d'],coding_policy_sha256:'a'.repeat(64)};
63
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(policy,{roots:{local_d:{path:drive}}},'a'.repeat(64)),/project-scoped root/);
64
+ });
65
+
66
+ test('R70 project bootstrap rejects a Coding policy that still exposes a whole drive',async()=>{
67
+ if(process.platform!=='win32') return;
68
+ const project=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-narrow-policy-'));
69
+ try{
70
+ const autonomous={root_ids:['gfx_project'],coding_policy_sha256:'a'.repeat(64)};
71
+ const coding={roots:{
72
+ gfx_project:{path:project,read:true,write:true,exec:false,deny_paths:[]},
73
+ local_c:{path:'C:\\',read:true,write:true,exec:true,deny_paths:[]}
74
+ }};
75
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(autonomous,coding,'a'.repeat(64)),/coding policy contains a broad filesystem root/);
76
+ }finally{await rm(project,{recursive:true,force:true});}
77
+ });
78
+
79
+ test('R70 pinned JSON hash and parsed policy come from one read',async()=>{
80
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-single-read-'));
81
+ try{
82
+ const file=path.join(root,'policy.json');
83
+ const approved=Buffer.from('{"schema":"approved"}');
84
+ const replacement=Buffer.from('{"schema":"replacement"}');
85
+ await writeFile(file,approved);
86
+ let reads=0;
87
+ const prepared=await update.readPinnedJsonPolicy({path:file,sha256:sha(approved)},'test policy',async()=>{
88
+ reads++;
89
+ return reads===1?approved:replacement;
90
+ });
91
+ assert.equal(reads,1);
92
+ assert.equal(prepared.sha256,sha(approved));
93
+ assert.equal(prepared.policy.schema,'approved');
94
+ }finally{await rm(root,{recursive:true,force:true});}
95
+ });
96
+
97
+ test('R70 preflight and runtime reject profiles outside approved Autonomous roots',async()=>{
98
+ const state=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-profile-scope-'));
99
+ try{
100
+ const project=path.join(state,'project'),other=path.join(state,'other');
101
+ await mkdir(project);await mkdir(other);
102
+ const digest='a'.repeat(64);
103
+ const codingPolicy={policy_sha256:digest,roots:{gfx_project:{path:project},other_project:{path:other}},
104
+ commands:{script:{}}};
105
+ const bad={schema:'deadbyte.autonomous-policy.v1',enabled:true,lease_file:path.join(state,'grant.json'),
106
+ evidence_dir:path.join(state,'evidence'),coding_policy_sha256:digest,root_ids:['gfx_project'],
107
+ planner:{backend:'client_sampling',max_tokens:2048},
108
+ profiles:{unsafe:{kind:'command',root_id:'other_project',command_id:'script',
109
+ script_path:'verify.ps1',script_sha256:'f'.repeat(64)}}};
110
+ assert.throws(()=>update.assertAutonomousBootstrapRoots(bad,codingPolicy,digest),/profile|autonomous roots/i);
111
+ const file=path.join(state,'autonomous.json');
112
+ await writeFile(file,JSON.stringify(bad));
113
+ await assert.rejects(loadAutonomousPolicy(file,codingPolicy),/profile.*root invalid/i);
114
+ }finally{await rm(state,{recursive:true,force:true});}
115
+ });
116
+
117
+ test('R70 update preflight verifies pinned owner signature against the manifest and selected policies',async()=>{
118
+ const state=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-owner-bootstrap-'));
119
+ try{
120
+ const root=await realpath(path.join(state,'project').replace(/project$/,'')).then(async()=>{
121
+ const project=path.join(state,'project');await mkdir(project);return realpath(project);
122
+ });
123
+ const trust=path.join(state,'trust');await mkdir(trust);
124
+ const {privateKey,publicKey}=generateKeyPairSync('ed25519');
125
+ await writeFile(path.join(trust,'r70-owner-public.pem'),publicKey.export({type:'spki',format:'pem'}));
126
+ const manifest='c'.repeat(64),coding='a'.repeat(64),autonomous='b'.repeat(64);
127
+ const subject={schema:'deadbyte.project-authority-subject.r70.v1',scope:'coding_autonomous_native_diff',
128
+ root_id:'gfx_project',project_root:root,coding_policy_sha256:coding,autonomous_policy_sha256:autonomous,
129
+ reviewed_artifact_sha256:manifest,issued_at_utc:'2026-10-13T00:00:00.000Z',expires_at_utc:'2026-10-13T00:30:00.000Z'};
130
+ const subjectSha=sha(Buffer.from(canonicalJson(subject)));
131
+ const signed={schema:'deadbyte.project-owner-approval.r70.v1',subject_sha256:subjectSha,
132
+ owner_key_id:sha(publicKey.export({type:'spki',format:'der'}))};
133
+ const approval={...signed,subject,signature_base64:sign(null,Buffer.concat([
134
+ Buffer.from('DEADBYTE-R70-PROJECT-OWNER-APPROVAL\0'),Buffer.from(canonicalJson(signed))]),privateKey).toString('base64')};
135
+ const approvalPath=path.join(state,'approval.json'),bytes=Buffer.from(JSON.stringify(approval));
136
+ await writeFile(approvalPath,bytes);
137
+ const input={stateRoot:state,bootstrap:{path:approvalPath,sha256:sha(bytes)},
138
+ autonomousPolicy:{root_ids:['gfx_project'],coding_policy_sha256:coding},codingPolicy:{roots:{gfx_project:{path:root,read:true,write:true}}},
139
+ codingPolicySha256:coding,autonomousPolicySha256:autonomous,expectedManifest:manifest,
140
+ now:new Date('2026-10-13T00:05:00.000Z')};
141
+ const verified=await update.verifyAutonomousOwnerBootstrap(input);
142
+ assert.equal(verified.subject_sha256,subjectSha);
143
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap({...input,expectedManifest:'d'.repeat(64)}),/artifact/i);
144
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap({...input,now:new Date('2026-10-13T00:30:00.000Z')}),/expired/i);
145
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap({
146
+ ...input,codingPolicy:{roots:{...input.codingPolicy.roots,trust_writer:{path:trust,write:true}}}
147
+ }),/owner trust key is writable/i);
148
+ await assert.rejects(update.performSlotUpdate({
149
+ stage:path.join(state,'unverified-stage'),developmentRoot:path.join(state,'unverified-dev'),
150
+ expectedVersion:'0.15.45',expectedManifest:manifest,stateRoot:state,
151
+ autonomousPolicyBootstrap:{path:'not-loaded',sha256:autonomous}
152
+ }),/owner approval/i);
153
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap({
154
+ ...input,codingPolicy:{roots:{gfx_project:{...input.codingPolicy.roots.gfx_project,exec:true}}}
155
+ }),/unsandboxed Coding execution/i);
156
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap({
157
+ ...input,codingPolicy:{roots:{...input.codingPolicy.roots,
158
+ command_root:{path:root,read:true,write:false,exec:true}}}
159
+ }),/unsandboxed Coding execution/i);
160
+ const attacker=generateKeyPairSync('ed25519').publicKey;
161
+ await writeFile(path.join(trust,'r70-owner-public.pem'),attacker.export({type:'spki',format:'pem'}));
162
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap(input),/key identity|signature/i);
163
+ await writeFile(approvalPath,Buffer.concat([bytes,Buffer.from('\\n')]));
164
+ await assert.rejects(update.verifyAutonomousOwnerBootstrap(input),/SHA-256 mismatch/i);
165
+ }finally{await rm(state,{recursive:true,force:true});}
166
+ });
@@ -0,0 +1,104 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {mkdtemp,readFile,rm,symlink,unlink,writeFile} from 'node:fs/promises';
4
+ import {spawnSync} from 'node:child_process';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+
8
+ const controllerPath=new URL('../controller/deadbyte-controller.ps1',import.meta.url);
9
+ const quote=value=>`'${String(value).replaceAll("'","''")}'`;
10
+
11
+ test('R70 controller rejects Autonomous roots outside selected Coding roots',async()=>{
12
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-controller-root-'));
13
+ try{
14
+ const runtime=path.join(root,'runtime'),policyFile=path.join(root,'autonomous.json');
15
+ await writeFile(policyFile,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
16
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:'a'.repeat(64),root_ids:['outside']}));
17
+ const source=await readFile(controllerPath,'utf8');
18
+ const start=source.indexOf('function Get-AutonomousPolicyMetadata(');
19
+ const end=source.indexOf('function Get-AutonomousLeaseStatus(',start);
20
+ assert.ok(start>=0&&end>start);
21
+ const helperStart=source.indexOf('function Read-ControllerPolicySnapshot(');
22
+ const helperEnd=source.indexOf('function Get-CodingPolicyMetadata(',helperStart);
23
+ assert.ok(helperStart>=0&&helperEnd>helperStart);
24
+ const block=source.slice(helperStart,helperEnd)+source.slice(start,end);
25
+ const script=`$ErrorActionPreference='Stop';$RuntimeDir=${quote(runtime)};function Fail([string]$m){throw $m};function Get-ExecutableHash($p){return 'b'.PadLeft(64,'b')};function Get-CodingPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='a'.PadLeft(64,'a');RootIds=@('project');RootPaths=@{project=${quote(root)}};RootAccess=@{project=@{read=$true;write=$true;exec=$false}}}};${block};try{Get-AutonomousPolicyMetadata @{AutonomousPolicyFile=${quote(policyFile)}}|Out-Null;Write-Output 'UNEXPECTED_PASS'}catch{Write-Output $_.Exception.Message}`;
26
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
27
+ assert.equal(result.status,0,result.stderr);
28
+ assert.match(result.stdout,/autonomous policy root 'outside' outside coding policy/);
29
+ await writeFile(policyFile,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
30
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:'a'.repeat(64),root_ids:['project']}));
31
+ const accepted=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
32
+ assert.equal(accepted.status,0,accepted.stderr);
33
+ assert.match(accepted.stdout,/UNEXPECTED_PASS/);
34
+ assert.doesNotMatch(accepted.stdout,/outside coding policy/);
35
+ }finally{await rm(root,{recursive:true,force:true});}
36
+ });
37
+
38
+ test('R70 controller refuses a direct Autonomous whole-drive policy root',async()=>{
39
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-controller-drive-'));
40
+ try{
41
+ const runtime=path.join(root,'runtime'),policyFile=path.join(root,'autonomous.json');
42
+ const drive=path.parse(root).root;
43
+ await writeFile(policyFile,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
44
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:'a'.repeat(64),root_ids:['project']}));
45
+ const source=await readFile(controllerPath,'utf8');
46
+ const helperStart=source.indexOf('function Read-ControllerPolicySnapshot(');
47
+ const helperEnd=source.indexOf('function Get-CodingPolicyMetadata(',helperStart);
48
+ const start=source.indexOf('function Get-AutonomousPolicyMetadata(');
49
+ const end=source.indexOf('function Get-AutonomousLeaseStatus(',start);
50
+ assert.ok(helperStart>=0&&helperEnd>helperStart&&start>=0&&end>start);
51
+ const block=source.slice(helperStart,helperEnd)+source.slice(start,end);
52
+ const script=`$ErrorActionPreference='Stop';$RuntimeDir=${quote(runtime)};function Fail([string]$m){throw $m};function Get-CodingPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='a'.PadLeft(64,'a');RootIds=@('project');RootPaths=@{project=${quote(drive)}};RootAccess=@{project=@{read=$true;write=$true;exec=$false}}}};${block};try{Get-AutonomousPolicyMetadata @{AutonomousPolicyFile=${quote(policyFile)}}|Out-Null;Write-Output 'UNEXPECTED_PASS'}catch{Write-Output $_.Exception.Message}`;
53
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
54
+ assert.equal(result.status,0,result.stderr);
55
+ assert.match(result.stdout,/project-scoped root/);
56
+ assert.doesNotMatch(result.stdout,/UNEXPECTED_PASS/);
57
+ }finally{await rm(root,{recursive:true,force:true});}
58
+ });
59
+
60
+ test('R70 controller refuses a project-looking junction to a whole drive',async()=>{
61
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-controller-junction-'));
62
+ const link=path.join(root,'project-link');
63
+ try{
64
+ const runtime=path.join(root,'runtime'),policyFile=path.join(root,'autonomous.json');
65
+ await symlink(path.parse(root).root,link,'junction');
66
+ await writeFile(policyFile,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
67
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:'a'.repeat(64),root_ids:['project']}));
68
+ const source=await readFile(controllerPath,'utf8');
69
+ const helperStart=source.indexOf('function Read-ControllerPolicySnapshot(');
70
+ const helperEnd=source.indexOf('function Get-CodingPolicyMetadata(',helperStart);
71
+ const start=source.indexOf('function Get-AutonomousPolicyMetadata(');
72
+ const end=source.indexOf('function Get-AutonomousLeaseStatus(',start);
73
+ const block=source.slice(helperStart,helperEnd)+source.slice(start,end);
74
+ const script=`$ErrorActionPreference='Stop';$RuntimeDir=${quote(runtime)};function Fail([string]$m){throw $m};function Get-CodingPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='a'.PadLeft(64,'a');RootIds=@('project');RootPaths=@{project=${quote(link)}};RootAccess=@{project=@{read=$true;write=$true;exec=$false}}}};${block};try{Get-AutonomousPolicyMetadata @{AutonomousPolicyFile=${quote(policyFile)}}|Out-Null;Write-Output 'UNEXPECTED_PASS'}catch{Write-Output $_.Exception.Message}`;
75
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
76
+ assert.equal(result.status,0,result.stderr);
77
+ assert.match(result.stdout,/real project directory/);
78
+ assert.doesNotMatch(result.stdout,/UNEXPECTED_PASS/);
79
+ }finally{
80
+ await unlink(link).catch(error=>{if(error.code!=='ENOENT')throw error;});
81
+ await rm(root,{recursive:true,force:true});
82
+ }
83
+ });
84
+
85
+ test('R70 controller refuses a narrow Autonomous root when Coding still empowers a whole drive',async()=>{
86
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-controller-coding-drive-'));
87
+ try{
88
+ const runtime=path.join(root,'runtime'),policyFile=path.join(root,'autonomous.json');
89
+ const drive=path.parse(root).root;
90
+ await writeFile(policyFile,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
91
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:'a'.repeat(64),root_ids:['project']}));
92
+ const source=await readFile(controllerPath,'utf8');
93
+ const helperStart=source.indexOf('function Read-ControllerPolicySnapshot(');
94
+ const helperEnd=source.indexOf('function Get-CodingPolicyMetadata(',helperStart);
95
+ const start=source.indexOf('function Get-AutonomousPolicyMetadata(');
96
+ const end=source.indexOf('function Get-AutonomousLeaseStatus(',start);
97
+ const block=source.slice(helperStart,helperEnd)+source.slice(start,end);
98
+ const script=`$ErrorActionPreference='Stop';$RuntimeDir=${quote(runtime)};function Fail([string]$m){throw $m};function Get-CodingPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='a'.PadLeft(64,'a');RootIds=@('project','local_drive');RootPaths=@{project=${quote(root)};local_drive=${quote(drive)}};RootAccess=@{project=@{read=$true;write=$true;exec=$false};local_drive=@{read=$true;write=$true;exec=$true}}}};${block};try{Get-AutonomousPolicyMetadata @{AutonomousPolicyFile=${quote(policyFile)}}|Out-Null;Write-Output 'UNEXPECTED_PASS'}catch{Write-Output $_.Exception.Message}`;
99
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
100
+ assert.equal(result.status,0,result.stderr);
101
+ assert.match(result.stdout,/coding policy contains a broad filesystem root/);
102
+ assert.doesNotMatch(result.stdout,/UNEXPECTED_PASS/);
103
+ }finally{await rm(root,{recursive:true,force:true});}
104
+ });
@@ -0,0 +1,28 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {mkdtemp,readFile,rm,writeFile} from 'node:fs/promises';
4
+ import {spawnSync} from 'node:child_process';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+
8
+ const controllerPath=new URL('../controller/deadbyte-controller.ps1',import.meta.url);
9
+ const quote=value=>`'${String(value).replaceAll("'","''")}'`;
10
+
11
+ test('R70 Autonomous status cannot exceed effective Coding grant roots',async()=>{
12
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-grant-subset-'));
13
+ try{
14
+ const grant=path.join(root,'autonomous-grant.json');
15
+ await writeFile(grant,JSON.stringify({schema:'deadbyte.autonomous-grant.v2',policy_sha256:'a'.repeat(64),
16
+ coding_policy_sha256:'b'.repeat(64),instance_nonce:'c'.repeat(64),root_ids:['other']}));
17
+ const source=await readFile(controllerPath,'utf8');
18
+ const start=source.indexOf('function Get-AutonomousLeaseStatus('),end=source.indexOf('function Arm-Autonomous(',start);
19
+ assert.ok(start>=0&&end>start);
20
+ const block=source.slice(start,end);
21
+ const script=`$ErrorActionPreference='Stop';function Get-AutonomousPolicyMetadata($Cfg){return [pscustomobject]@{LeaseFile=${quote(grant)};Sha256='a'.PadLeft(64,'a');CodingPolicySha256='b'.PadLeft(64,'b');RootIds=@('project','other')}};function Get-CodingLeaseStatus($Cfg){return [pscustomobject]@{Armed=$true;RootIds=@('project')}};function Get-AuthorityEpochStatus($Cfg,$Plane,$Grant,$Nonce){return [pscustomobject]@{Trusted=$true;Seq=1;EventSha256='d'.PadLeft(64,'d')}};${block};$s=Get-AutonomousLeaseStatus @{AutonomousPolicyFile='fixture'};$s|ConvertTo-Json -Compress`;
22
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
23
+ assert.equal(result.status,0,result.stderr);
24
+ const state=JSON.parse(result.stdout.trim());
25
+ assert.equal(state.Armed,false);
26
+ assert.equal(state.Reason,'coding-roots');
27
+ }finally{await rm(root,{recursive:true,force:true});}
28
+ });
@@ -0,0 +1,80 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {mkdtemp,readFile,rm} from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import {spawnSync} from 'node:child_process';
7
+
8
+ const controllerPath=new URL('../controller/deadbyte-controller.ps1',import.meta.url);
9
+ const LEGACY='6274492644c303b38117541cc22a59e88e6ff5fdef7051a5d57ad336f45765f5';
10
+ const H=c=>c.repeat(64);
11
+
12
+ async function probe(policySha,rootId){
13
+ const source=await readFile(controllerPath,'utf8');
14
+ const start=source.indexOf('function Arm-Autonomous(');
15
+ const end=source.indexOf('function Disarm-Autonomous(',start);
16
+ assert.ok(start>=0&&end>start,'controller arm function must be present');
17
+ const slice=source.slice(start,end);
18
+ const script=`$ErrorActionPreference='Stop';
19
+ function Fail([string]$m){throw $m}
20
+ function Get-CodingLeaseStatus($Cfg){return [pscustomobject]@{Armed=$true;RootIds=@('core','gfx_project')}}
21
+ function Get-AutonomousPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='${policySha}';RootIds=@('${rootId}');CodingPolicySha256='${H('a')}'}}
22
+ function Ensure-Directory($d){Write-Output 'MUTATION_REACHED';throw 'TEST_STUB_NO_GRANT'}
23
+ $RuntimeDir='fixture-only'
24
+ ${slice}
25
+ try{Arm-Autonomous @{};Write-Output 'UNEXPECTED_PASS'}catch{Write-Output ('GATE_ERROR '+$_.Exception.Message)}
26
+ `;
27
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
28
+ assert.equal(result.status,0,result.stderr);
29
+ return result.stdout;
30
+ }
31
+
32
+ test('R70 controller must reject unapproved successor Autonomous policy before grant I/O',async()=>{
33
+ for(const [sha,id] of [[H('b'),'gfx_project'],[H('b'),'core'],[LEGACY,'gfx_project']]){
34
+ const output=await probe(sha,id);
35
+ assert.match(output,/R70_OWNER_ENROLLMENT_REQUIRED/,output);
36
+ assert.doesNotMatch(output,/MUTATION_REACHED|UNEXPECTED_PASS/,output);
37
+ }
38
+ });
39
+
40
+ test('R70 newly issued legacy-core grant includes bounded expiry before signing',async()=>{
41
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-finite-grant-'));
42
+ const leaseFile=path.join(root,'grant.json');
43
+ const quote=s=>`'${s.replaceAll("'","''")}'`;
44
+ try{
45
+ const source=await readFile(controllerPath,'utf8');
46
+ const start=source.indexOf('function Arm-Autonomous(');
47
+ const end=source.indexOf('function Disarm-Autonomous(',start);
48
+ assert.ok(start>=0&&end>start);
49
+ const script=`$ErrorActionPreference='Stop';
50
+ function Fail([string]$m){throw $m}
51
+ function Get-CodingLeaseStatus($Cfg){return [pscustomobject]@{Armed=$true;RootIds=@('core')}}
52
+ function Get-AutonomousPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='${LEGACY}';RootIds=@('core');CodingPolicySha256='${H('a')}';LeaseFile=${quote(leaseFile)}}}
53
+ function Ensure-Directory($p){}
54
+ function Invoke-AuthorityEpochCommand($Cfg,$Plane,$Action,$File){return 'TEST_ONLY_EPOCH'}
55
+ $RuntimeDir=${quote(root)}
56
+ ${source.slice(start,end)}
57
+ Arm-Autonomous @{};
58
+ `;
59
+ const before=Date.now();
60
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
61
+ const after=Date.now();
62
+ assert.equal(result.status,0,result.stderr);
63
+ const grant=JSON.parse((await readFile(leaseFile,'utf8')).replace(/^\uFEFF/,''));
64
+ assert.equal(grant.schema,'deadbyte.autonomous-grant.v2');
65
+ assert.equal(grant.policy_sha256,LEGACY);
66
+ assert.equal(grant.coding_policy_sha256,H('a'));
67
+ assert.deepEqual(grant.root_ids,['core']);
68
+ const issued=Date.parse(grant.granted_at_utc),expires=Date.parse(grant.expires_at_utc);
69
+ assert.ok(Number.isFinite(issued)&&Number.isFinite(expires),'grant must include valid UTC times');
70
+ assert.ok(issued>=before-1000&&issued<=after+1000,'signed grant issued_at must be current');
71
+ assert.equal(expires-issued,3_600_000,'new grant must expire within exactly one hour');
72
+ }finally{await rm(root,{recursive:true,force:true});}
73
+ });
74
+
75
+ test('R70 exact known-good core policy keeps existing explicit manual arm route',async()=>{
76
+ const output=await probe(LEGACY,'core');
77
+ assert.match(output,/MUTATION_REACHED/,output);
78
+ assert.match(output,/TEST_STUB_NO_GRANT/,output);
79
+ assert.doesNotMatch(output,/UNEXPECTED_PASS/,output);
80
+ });
@@ -0,0 +1,66 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash} from 'node:crypto';
4
+ import {mkdtemp,mkdir,readFile,rm,writeFile} from 'node:fs/promises';
5
+ import {spawnSync} from 'node:child_process';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+
9
+ const controllerPath=new URL('../controller/deadbyte-controller.ps1',import.meta.url);
10
+ const quote=value=>"'"+String(value).replaceAll("'","''")+"'";
11
+ const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
12
+
13
+ test('R70 controller policy digest binds the same bytes used for root decisions',async()=>{
14
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-policy-snapshot-'));
15
+ try{
16
+ const runtime=path.join(root,'runtime'),workspace=path.join(root,'project');
17
+ await mkdir(workspace);
18
+ const file=path.join(root,'coding.json');
19
+ const bytes=Buffer.from(JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,
20
+ lease_file:path.join(runtime,'coding-grant.json'),roots:{gfx_project:{path:workspace}},
21
+ commands:{}}));
22
+ await writeFile(file,bytes);
23
+ const source=await readFile(controllerPath,'utf8');
24
+ const begin=source.indexOf('function Get-CodingPolicyMetadata(');
25
+ const end=source.indexOf('function Get-CodingLeaseStatus(',begin);
26
+ assert.ok(begin>=0&&end>begin);
27
+ const helperBegin=source.indexOf('function Read-ControllerPolicySnapshot(');
28
+ const helper=helperBegin>=0?source.slice(helperBegin,source.indexOf('function Get-CodingPolicyMetadata(',helperBegin)):'';
29
+ const block=source.slice(begin,end);
30
+ const script="$ErrorActionPreference='Stop';$RuntimeDir="+quote(runtime)+";function Fail([string]$m){throw $m};function Get-ExecutableHash($p){return 'a'.PadLeft(64,'a')};function Assert-PolicyRootsAvailable($p,$n){return @('gfx_project')};"+helper+";"+block+";$m=Get-CodingPolicyMetadata @{CodingPolicyFile="+quote(file)+"};$m|ConvertTo-Json -Compress";
31
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
32
+ assert.equal(result.status,0,result.stderr);
33
+ const metadata=JSON.parse(result.stdout.trim());
34
+ assert.equal(metadata.Sha256,sha(bytes));
35
+ assert.deepEqual(metadata.RootIds,['gfx_project']);
36
+ }finally{await rm(root,{recursive:true,force:true});}
37
+ });
38
+
39
+ test('R70 Autonomous metadata binds parsed policy and Coding digest to one snapshot',async()=>{
40
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-autonomous-snapshot-'));
41
+ try{
42
+ const runtime=path.join(root,'runtime'),file=path.join(root,'autonomous.json');
43
+ const codingSha='b'.repeat(64);
44
+ const bytes=Buffer.from(JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,
45
+ lease_file:path.join(runtime,'autonomous-grant.json'),coding_policy_sha256:codingSha,
46
+ root_ids:['gfx_project']}));
47
+ await writeFile(file,bytes);
48
+ const source=await readFile(controllerPath,'utf8');
49
+ const helperBegin=source.indexOf('function Read-ControllerPolicySnapshot(');
50
+ const helperEnd=source.indexOf('function Get-CodingPolicyMetadata(',helperBegin);
51
+ const begin=source.indexOf('function Get-AutonomousPolicyMetadata(');
52
+ const end=source.indexOf('function Get-AutonomousLeaseStatus(',begin);
53
+ assert.ok(helperBegin>=0&&helperEnd>helperBegin&&begin>=0&&end>begin);
54
+ const helper=source.slice(helperBegin,helperEnd),block=source.slice(begin,end);
55
+ const script="$ErrorActionPreference='Stop';$RuntimeDir="+quote(runtime)+
56
+ ";function Fail([string]$m){throw $m};function Get-ExecutableHash($p){return 'a'.PadLeft(64,'a')}"+
57
+ ";function Get-CodingPolicyMetadata($Cfg){return [pscustomobject]@{Sha256='b'.PadLeft(64,'b');RootIds=@('gfx_project');RootPaths=@{gfx_project="+quote(root)+"};RootAccess=@{gfx_project=@{read=$true;write=$true;exec=$false}}}};"+
58
+ helper+";"+block+";$m=Get-AutonomousPolicyMetadata @{AutonomousPolicyFile="+quote(file)+"};$m|ConvertTo-Json -Compress";
59
+ const result=spawnSync('powershell',['-NoLogo','-NoProfile','-NonInteractive','-Command',script],{encoding:'utf8',timeout:15000});
60
+ assert.equal(result.status,0,result.stderr);
61
+ const metadata=JSON.parse(result.stdout.trim());
62
+ assert.equal(metadata.Sha256,sha(bytes));
63
+ assert.equal(metadata.CodingPolicySha256,codingSha);
64
+ assert.deepEqual(metadata.RootIds,['gfx_project']);
65
+ }finally{await rm(root,{recursive:true,force:true});}
66
+ });
@@ -0,0 +1,67 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash,generateKeyPairSync,sign} from 'node:crypto';
4
+ import {mkdtemp,realpath,rm} from 'node:fs/promises';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import {canonicalJson} from '../src/canonical-json.mjs';
8
+ import {verifyProjectOwnerApproval} from '../src/r70-owner-approval.mjs';
9
+
10
+ const H=c=>c.repeat(64);
11
+ const domain=Buffer.from('DEADBYTE-R70-PROJECT-OWNER-APPROVAL\0','utf8');
12
+ const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
13
+
14
+ async function fixture(){
15
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r70-owner-'));
16
+ const projectRoot=await realpath(root);
17
+ const {privateKey,publicKey}=generateKeyPairSync('ed25519');
18
+ const keyId=sha(publicKey.export({type:'spki',format:'der'}));
19
+ const subject={schema:'deadbyte.project-authority-subject.r70.v1',scope:'coding_autonomous_native_diff',
20
+ root_id:'gfx_project',project_root:projectRoot,coding_policy_sha256:H('a'),
21
+ autonomous_policy_sha256:H('b'),reviewed_artifact_sha256:H('c'),
22
+ issued_at_utc:'2026-10-13T00:00:00.000Z',expires_at_utc:'2026-10-13T00:30:00.000Z'};
23
+ const subjectSha=sha(Buffer.from(canonicalJson(subject),'utf8'));
24
+ const signed={schema:'deadbyte.project-owner-approval.r70.v1',subject_sha256:subjectSha,owner_key_id:keyId};
25
+ const approval={...signed,subject,signature_base64:sign(null,Buffer.concat([domain,Buffer.from(canonicalJson(signed),'utf8')]),privateKey).toString('base64')};
26
+ const expected={rootId:'gfx_project',projectRoot,codingPolicySha256:H('a'),autonomousPolicySha256:H('b'),reviewedArtifactSha256:H('c')};
27
+ return {root,projectRoot,publicKey,approval,expected,subjectSha};
28
+ }
29
+
30
+ test('R70 owner signature binds exact reviewed project, policy pair, scope and bounded lifetime',async()=>{
31
+ const f=await fixture();
32
+ try{
33
+ const proof=await verifyProjectOwnerApproval({approval:f.approval,ownerPublicKey:f.publicKey,expected:f.expected,
34
+ now:new Date('2026-10-13T00:05:00.000Z')});
35
+ assert.equal(proof.approved,true);
36
+ assert.equal(proof.subject_sha256,f.subjectSha);
37
+ assert.equal(proof.expires_at_utc,'2026-10-13T00:30:00.000Z');
38
+ }finally{await rm(f.root,{recursive:true,force:true});}
39
+ });
40
+
41
+ test('R70 signed owner approval fails closed on artifact, policy, root and signature drift',async()=>{
42
+ const f=await fixture();
43
+ try{
44
+ const now=new Date('2026-10-13T00:05:00.000Z');
45
+ for(const changed of [
46
+ {reviewedArtifactSha256:H('d')},{codingPolicySha256:H('d')},{autonomousPolicySha256:H('d')},{rootId:'other'}
47
+ ]){
48
+ await assert.rejects(verifyProjectOwnerApproval({approval:f.approval,ownerPublicKey:f.publicKey,
49
+ expected:{...f.expected,...changed},now}),/subject|scope|root|artifact|policy/i);
50
+ }
51
+ await assert.rejects(verifyProjectOwnerApproval({approval:{...f.approval,signature_base64:Buffer.alloc(64).toString('base64')},
52
+ ownerPublicKey:f.publicKey,expected:f.expected,now}),/signature/i);
53
+ await assert.rejects(verifyProjectOwnerApproval({approval:{...f.approval,unreviewed_extra:true},
54
+ ownerPublicKey:f.publicKey,expected:f.expected,now}),/unknown field/i);
55
+ }finally{await rm(f.root,{recursive:true,force:true});}
56
+ });
57
+
58
+ test('R70 owner approval expires and cannot survive a changed lifetime field',async()=>{
59
+ const f=await fixture();
60
+ try{
61
+ await assert.rejects(verifyProjectOwnerApproval({approval:f.approval,ownerPublicKey:f.publicKey,expected:f.expected,
62
+ now:new Date('2026-10-13T00:30:00.000Z')}),/expired/i);
63
+ const altered={...f.approval,subject:{...f.approval.subject,expires_at_utc:'2026-10-13T01:00:00.000Z'}};
64
+ await assert.rejects(verifyProjectOwnerApproval({approval:altered,ownerPublicKey:f.publicKey,expected:f.expected,
65
+ now:new Date('2026-10-13T00:05:00.000Z')}),/subject|signature/i);
66
+ }finally{await rm(f.root,{recursive:true,force:true});}
67
+ });
@@ -0,0 +1,28 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash} from 'node:crypto';
4
+ import {readFile} from 'node:fs/promises';
5
+ import {spawnSync} from 'node:child_process';
6
+ import path from 'node:path';
7
+ import {fileURLToPath} from 'node:url';
8
+
9
+ const root=path.dirname(path.dirname(fileURLToPath(import.meta.url)));
10
+ const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
11
+
12
+ test('R71 full verifier persists the complete stdout bytes beside its no-clobber result',async t=>{
13
+ if(process.platform!=='win32'){t.skip('Windows PowerShell verifier only');return;}
14
+ const run=spawnSync('powershell.exe',['-NoProfile','-ExecutionPolicy','Bypass','-File',
15
+ path.join(root,'scripts','verify-r70-full-regression.ps1'),'-SelfTest'],
16
+ {cwd:root,encoding:'utf8',windowsHide:true,timeout:30_000});
17
+ assert.equal(run.status,0,run.stderr||run.stdout);
18
+ const resultPath=/R70_FULL_TEST_ARTIFACT=([^\r\n]+)/.exec(run.stdout)?.[1];
19
+ assert.ok(resultPath,'durable result path missing');
20
+ const result=JSON.parse(await readFile(resultPath,'utf8'));
21
+ assert.equal(result.mode,'synthetic-selftest');
22
+ assert.equal(result.exit_code,1);
23
+ assert.equal(typeof result.stdout_path,'string');
24
+ const output=await readFile(result.stdout_path);
25
+ assert.equal(sha(output),result.stdout_sha256);
26
+ assert.match(output.toString('utf8'),/hash mismatch: SYNTHETIC_TEST/);
27
+ assert.equal(output.toString('utf8').trimEnd().split('\n').length,result.total_line_count);
28
+ });