deadbyte-mcp 0.15.43 → 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 (247) hide show
  1. package/MANIFEST.SHA256 +160 -161
  2. package/PROVENANCE.json +257 -232
  3. package/README.txt +18 -18
  4. package/RELEASE.json +348 -320
  5. package/SBOM.cdx.json +14 -2
  6. package/TEST-MATRIX.json +503 -460
  7. package/bin/deadbyte-native-inspect-r67.exe +0 -0
  8. package/bridge/package.json +1 -1
  9. package/controller/deadbyte-controller.ps1 +1857 -1769
  10. package/controller/deadbyte-desktop-policy.json +6 -6
  11. package/controller/deadbyte-process-policy.json +4 -4
  12. package/docs/R67-ALPHA-REFERENCE-DIFFERENTIAL.md +42 -0
  13. package/docs/R67-ALPHA-STATIC-COMPARISON.json +205 -0
  14. package/docs/R67-CANDIDATE-PARENT.json +10 -0
  15. package/docs/R67-EVIDENCE-RECONCILE-CLOSEOUT-20261011.md +64 -0
  16. package/docs/R67-FULL-REGRESSION-UNKNOWN.json +27 -0
  17. package/docs/R67-NATIVE-INSPECT-BINARY.json +11 -0
  18. package/docs/R67-NPM-EXDEV-PRESERVATION-20261011.md +39 -0
  19. package/docs/R67-OBSERVATION-TRUTH.md +82 -0
  20. package/docs/R67-REFERENCE-GAP-MATRIX.json +57 -0
  21. package/docs/R67-REGRESSION-CLOSURE-20261011.md +24 -0
  22. package/docs/R68-COMPAT-HOST-EXEC-CANDIDATE.md +63 -0
  23. package/docs/R69-LIVE-OUTCOME-R70-POLICY-TRANSFER.md +136 -0
  24. package/docs/R70-CODING-DIGEST-SUPERVISOR-CHECKPOINT-20261013.md +42 -0
  25. package/docs/R70-FINITE-GRANT-OWNER-BOUNDARY-20261013.md +80 -0
  26. package/docs/R70-OWNER-BOOTSTRAP-CHECKPOINT-20261013.md +60 -0
  27. package/docs/R70-REFERENCE-MECHANISMS.json +95 -0
  28. package/docs/R70-TRUST-GUARD-EXPIRY-CHECKPOINT-20261013.md +47 -0
  29. package/native/deadbyte-native-inspect-r67.cpp +252 -0
  30. package/package.json +6 -3
  31. package/scripts/benchmark-l0-r71.mjs +76 -0
  32. package/scripts/build-native-inspector-r67.ps1 +28 -0
  33. package/scripts/gate-windows-r67.ps1 +56 -0
  34. package/scripts/gate-windows-r71.ps1 +64 -0
  35. package/scripts/npm-preserve-artifact-r67.mjs +99 -0
  36. package/scripts/npm-release-r48.mjs +12 -2
  37. package/scripts/npm-release-readiness-r67.mjs +26 -0
  38. package/scripts/npm-release-readiness-r71.mjs +21 -0
  39. package/scripts/r67-acquire-alpha-reference.mjs +95 -0
  40. package/scripts/r67-audit-nonpass-source.mjs +39 -0
  41. package/scripts/r67-compare-desktop-alpha.mjs +48 -0
  42. package/scripts/r67-diagnose-failed-shard.mjs +23 -0
  43. package/scripts/r67-durable-batch.mjs +42 -0
  44. package/scripts/r67-focused-gate.mjs +58 -0
  45. package/scripts/r67-full-regression.mjs +28 -0
  46. package/scripts/r67-independent-observation-verify.mjs +36 -0
  47. package/scripts/r67-independent-runtime-observation-verify.mjs +63 -0
  48. package/scripts/r67-nonpass-adjudicate.mjs +20 -0
  49. package/scripts/r67-publish-boundary-audit.mjs +32 -0
  50. package/scripts/r67-regression-reconcile.mjs +10 -0
  51. package/scripts/r67-regression-shard-run.mjs +70 -0
  52. package/scripts/r67-run-shard-batch.mjs +18 -0
  53. package/scripts/r67-stage-candidate.mjs +30 -0
  54. package/scripts/r67-verify-parent-ping.mjs +22 -0
  55. package/scripts/release-manifest.mjs +1 -0
  56. package/scripts/verify-r70-full-regression.ps1 +72 -0
  57. package/src/activation-continuity-engine-r65.mjs +2 -1
  58. package/src/authority-continuity-r65.mjs +28 -8
  59. package/src/autonomous-mcp-tools.mjs +1 -1
  60. package/src/autonomous-output-contracts.mjs +4 -1
  61. package/src/autonomous-policy.mjs +54 -7
  62. package/src/autonomous-runtime.mjs +1 -1
  63. package/src/capability-ledger.mjs +1 -1
  64. package/src/capability-resolver.mjs +2 -1
  65. package/src/commander-compat-runtime.mjs +30 -2
  66. package/src/deadbyte-cli.mjs +41 -7
  67. package/src/machine-fs-smoke-client.mjs +13 -5
  68. package/src/machine-identity.mjs +59 -2
  69. package/src/machine-mcp-tools.mjs +8 -0
  70. package/src/mcp-server.mjs +11 -2
  71. package/src/native-diff-v2.mjs +18 -5
  72. package/src/native-diff.mjs +21 -5
  73. package/src/native-inspector-r67.mjs +66 -0
  74. package/src/r67-diagnostic-export.mjs +118 -0
  75. package/src/r67-diagnostics-verify.mjs +82 -0
  76. package/src/r67-evidence-reconcile.mjs +128 -0
  77. package/src/r67-native-observation-authority.mjs +45 -0
  78. package/src/r67-observation-receipt.mjs +43 -0
  79. package/src/r67-regression-shards.mjs +176 -0
  80. package/src/r70-owner-approval.mjs +78 -0
  81. package/src/remote-live-log.mjs +62 -24
  82. package/src/remote-result-journal.mjs +1 -1
  83. package/src/runtime-update.mjs +2051 -1891
  84. package/src/tool-audit.mjs +3 -1
  85. package/src/version.mjs +1 -1
  86. package/test/agent-runtime.test.mjs +1 -1
  87. package/test/autonomous-local-supervisor.test.mjs +2 -1
  88. package/test/autonomous-loop.test.mjs +11 -6
  89. package/test/autonomous-output-contract.test.mjs +17 -1
  90. package/test/autonomous-runtime.test.mjs +1 -1
  91. package/test/autonomous-supervisor-integration.test.mjs +2 -1
  92. package/test/capability-resolver.test.mjs +17 -0
  93. package/test/codex-autonomous-r44.test.mjs +1 -1
  94. package/test/coding-plane.test.mjs +1 -1
  95. package/test/commander-compat-runtime.test.mjs +42 -0
  96. package/test/controller-policy-preflight-r59.test.mjs +1 -0
  97. package/test/full-max-catalog-r46.test.mjs +1 -1
  98. package/test/native-diff-topology-r36.test.mjs +35 -2
  99. package/test/native-diff.test.mjs +83 -3
  100. package/test/output-schema.test.mjs +1 -1
  101. package/test/r51-live-log-polling.test.mjs +12 -0
  102. package/test/r53-release-contract.test.mjs +1 -1
  103. package/test/r54-release-contract.test.mjs +1 -1
  104. package/test/r55-release-contract.test.mjs +1 -1
  105. package/test/r56-release-contract.test.mjs +1 -1
  106. package/test/r57-release-contract.test.mjs +1 -1
  107. package/test/r58-bundled-bridge.test.mjs +1 -1
  108. package/test/r58-release-contract.test.mjs +2 -2
  109. package/test/r58-windows-gate.test.mjs +1 -1
  110. package/test/r59-tool-surface-compat.test.mjs +9 -5
  111. package/test/r60-release-contract.test.mjs +3 -3
  112. package/test/r61-release-contract.test.mjs +1 -1
  113. package/test/r62-release-contract.test.mjs +1 -1
  114. package/test/r63-release-contract.test.mjs +1 -1
  115. package/test/r64-release-contract.test.mjs +1 -1
  116. package/test/r65-authority-runtime-epoch.test.mjs +9 -1
  117. package/test/r65-epoch-native-activation-integration.test.mjs +4 -4
  118. package/test/r65-release-contract.test.mjs +1 -1
  119. package/test/r66-release-contract.test.mjs +2 -1
  120. package/test/r67-cli-integration.test.mjs +41 -0
  121. package/test/r67-diagnostics-cli.test.mjs +60 -0
  122. package/test/r67-diagnostics-verify.test.mjs +49 -0
  123. package/test/r67-diagnostics-zip-oracle.test.mjs +38 -0
  124. package/test/r67-diagnostics.test.mjs +60 -0
  125. package/test/r67-evidence-reconcile.test.mjs +186 -0
  126. package/test/r67-isolated-slot-rollback-restore.test.mjs +63 -0
  127. package/test/r67-live-log-secret-canary.test.mjs +44 -0
  128. package/test/r67-machine-fs-smoke-epoch.test.mjs +22 -0
  129. package/test/r67-native-inspector.test.mjs +131 -0
  130. package/test/r67-native-observation-authority.test.mjs +49 -0
  131. package/test/r67-npm-cross-volume.test.mjs +74 -0
  132. package/test/r67-npm-publish-gate.test.mjs +40 -0
  133. package/test/r67-regression-shards.test.mjs +184 -0
  134. package/test/r67-release-contract.test.mjs +45 -0
  135. package/test/r67-runtime-observation-binding.test.mjs +86 -0
  136. package/test/r67-server-observation-wiring.test.mjs +12 -0
  137. package/test/r67-signed-receipt.test.mjs +66 -0
  138. package/test/r67-skip-rationale.test.mjs +31 -0
  139. package/test/r67-tool-annotations.test.mjs +21 -0
  140. package/test/r67-windows-gate-argv.test.mjs +13 -0
  141. package/test/r69-live-outcome.test.mjs +137 -0
  142. package/test/r70-autonomous-grant-expiry.test.mjs +89 -0
  143. package/test/r70-autonomous-policy-bootstrap.test.mjs +166 -0
  144. package/test/r70-controller-autonomous-root.test.mjs +104 -0
  145. package/test/r70-controller-grant-subset.test.mjs +28 -0
  146. package/test/r70-controller-owner-issue-boundary.test.mjs +80 -0
  147. package/test/r70-controller-policy-snapshot.test.mjs +66 -0
  148. package/test/r70-owner-approval.test.mjs +67 -0
  149. package/test/r71-full-verifier-artifact.test.mjs +28 -0
  150. package/test/r71-isolated-slot-rollback-restore.test.mjs +62 -0
  151. package/test/r71-native-diff-mcp-wire.test.mjs +75 -0
  152. package/test/r71-publish-fence.test.mjs +38 -0
  153. package/test/r71-release-identity.test.mjs +31 -0
  154. package/test/release-version.test.mjs +1 -1
  155. package/test/remote-live-log-r36.test.mjs +10 -0
  156. package/test/remote-live-log-r37.test.mjs +29 -0
  157. package/test/remote-result-journal.test.mjs +12 -0
  158. package/test/remote-session-cli.test.mjs +2 -1
  159. package/test/semantic-multilang.test.mjs +1 -1
  160. package/test/standing-grants.test.mjs +2 -2
  161. package/test/tool-audit.test.mjs +14 -0
  162. package/bin/appcontainer-stage.obj +0 -0
  163. package/bin/bootstrap-advapi32.obj +0 -0
  164. package/bin/bootstrap-exitcode.obj +0 -0
  165. package/bin/bootstrap-kernel32.obj +0 -0
  166. package/bin/child-control-probe.obj +0 -0
  167. package/bin/child-control-stage.obj +0 -0
  168. package/bin/contained-reverse-worker.obj +0 -0
  169. package/bin/contained-transform-worker.obj +0 -0
  170. package/bin/containment-probe.obj +0 -0
  171. package/bin/deadbyte-contain.obj +0 -0
  172. package/bin/deadbyte-desktop-input-r40.obj +0 -0
  173. package/bin/deadbyte-desktop-observer-r40.obj +0 -0
  174. package/bin/deadbyte-desktop-uia-r40.obj +0 -0
  175. package/bin/deadbyte-exec.obj +0 -0
  176. package/bin/deadbyte-hardware-observer-r45.obj +0 -0
  177. package/bin/deadbyte-process-host.obj +0 -0
  178. package/bin/deadbyte-tunnel-host.obj +0 -0
  179. package/conpty-input-observer.obj +0 -0
  180. package/miniconpty.obj +0 -0
  181. package/proof/CONTAINMENT-BUILD.txt +0 -163
  182. package/proof/MCP-SMOKE-STATUS.txt +0 -9
  183. package/proof/NODE-SYNTAX.txt +0 -4
  184. package/proof/PROOF.txt +0 -6
  185. package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +0 -29
  186. package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +0 -28
  187. package/proof/SECRET-SCAN.txt +0 -4
  188. package/proof/SOURCE-GATES.txt +0 -16
  189. package/proof/STATUS.txt +0 -11
  190. package/proof/TARGET-V0313-CONTAINMENT-PASS.sha256 +0 -1
  191. package/proof/TARGET-V0313-CONTAINMENT-PASS.txt +0 -215
  192. package/proof/TARGET-V040-CONTAINED-IPC-FAIL.sha256 +0 -1
  193. package/proof/TARGET-V040-CONTAINED-IPC-FAIL.txt +0 -299
  194. package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  195. package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.txt +0 -311
  196. package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  197. package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.txt +0 -313
  198. package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
  199. package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.txt +0 -308
  200. package/proof/TARGET-V044-CONTAINED-PASS.sha256 +0 -1
  201. package/proof/TARGET-V044-CONTAINED-PASS.txt +0 -432
  202. package/proof/TARGET-V045-DUAL-OPERATION-PASS.sha256 +0 -1
  203. package/proof/TARGET-V045-DUAL-OPERATION-PASS.txt +0 -481
  204. package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.sha256 +0 -1
  205. package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.txt +0 -610
  206. package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.sha256 +0 -1
  207. package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.txt +0 -642
  208. package/proof/TARGET-V050-BATCH-GATE-PASS.sha256 +0 -1
  209. package/proof/TARGET-V050-BATCH-GATE-PASS.txt +0 -713
  210. package/proof/TESTS.txt +0 -686
  211. package/proof/TRUST-EPHEMERAL.txt +0 -4
  212. package/proof/V03-FREEZE.txt +0 -27
  213. package/proof/V041-IPC-HOTFIX.txt +0 -16
  214. package/proof/V042-ENV-HOTFIX.txt +0 -15
  215. package/proof/V043-DRIVE-CWD-HOTFIX.txt +0 -14
  216. package/proof/V044-LOCALAPPDATA-HOTFIX.txt +0 -18
  217. package/proof/V045-OPERATION-REGISTRY.txt +0 -7
  218. package/proof/V046-WORKER-REGISTRY.txt +0 -12
  219. package/proof/V047-WORKER-MANIFEST.txt +0 -18
  220. package/proof/V050-BATCH-TRUST-CLOSURE.txt +0 -21
  221. package/proof/V060-ACTIVE-NETWORK-AUTHORITY.txt +0 -29
  222. package/proof/V070-NODE-SYNTAX.txt +0 -36
  223. package/proof/V070-NODE-TESTS.txt +0 -752
  224. package/proof/V070-PACK-DRY-RUN.txt +0 -126
  225. package/proof/V070-SOURCE-GATE.txt +0 -30
  226. package/proof/V070-STATIC-SCAN.txt +0 -4
  227. package/proof/V070-WINDOWS-GATE-PENDING.txt +0 -25
  228. package/proof/V071-NODE-SYNTAX.txt +0 -1
  229. package/proof/V071-NODE-TESTS.txt +0 -796
  230. package/proof/V071-PACK-DRY-RUN.json +0 -656
  231. package/proof/V071-SOURCE-GATE.txt +0 -16
  232. package/proof/V071-WINDOWS-GATE-PENDING.txt +0 -24
  233. package/proof/V073-NODE-SYNTAX.txt +0 -4
  234. package/proof/V073-SOURCE-GATE.txt +0 -21
  235. package/proof/V073-STATIC-SCAN.txt +0 -10
  236. package/proof/V073-WINDOWS-GATE-PENDING.txt +0 -5
  237. package/proof/VERIFY.txt +0 -7
  238. package/proof/WINDOWS-CONTAINED-STATUS.txt +0 -5
  239. package/proof/WINDOWS-CONTAINMENT-STATUS.txt +0 -3
  240. package/proof/commander-closure-20260927/CONTINUATION.json +0 -43
  241. package/proof/commander-closure-20260927/RESULT.json +0 -30
  242. package/proof/commander-closure-20260927/SEARCH-CONTINUATION.json +0 -30
  243. package/proof/commander-closure-20260927/XLS-REFERENCE-PROBE.json +0 -13
  244. package/proof/commander-closure-20260928/DIFFERENTIAL-CHECKPOINT.json +0 -122
  245. package/proof/r59-full-regression-current.json +0 -13
  246. package/proof/r59-full-regression-current.stderr.log +0 -0
  247. package/proof/r59-full-regression-current.stdout.log +0 -1268
@@ -0,0 +1,45 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ const sealedRoot=path.join(os.homedir(),'.deadbyte-mcp','releases','v0.15.44-9f500af433df3e77');
7
+ const get=async rel=>JSON.parse(await readFile(path.join(sealedRoot,rel),'utf8'));
8
+ const parent={
9
+ release_id:'v0.15.43-4c4a64a4c8e9f5a6',
10
+ manifest_sha256:'4c4a64a4c8e9f5a6e9eecce85fd0007ebcac99121b29c07f1a1fc81d1643cd33',
11
+ generation_manifest_sha256:'ef3b041e2a87c2e143d4733a98a52d9db80cd16ad7007e112fcb5202e70c77c3'
12
+ };
13
+ test('sealed R67 predecessor preserves its release version, lineage and prepublish evidence',async()=>{
14
+ const [pkg,bridge,release,prov,matrix,sbom,version]=await Promise.all([
15
+ get('package.json'),get('bridge/package.json'),
16
+ get('RELEASE.json'),get('PROVENANCE.json'),get('TEST-MATRIX.json'),get('SBOM.cdx.json'),
17
+ readFile(path.join(sealedRoot,'src','version.mjs'),'utf8')
18
+ ]);
19
+ assert.equal(pkg.version,'0.15.44');
20
+ assert.equal(bridge.version,pkg.version);
21
+ assert.match(version,/DEADBYTE_VERSION = '0\.15\.44'/);
22
+ assert.equal(release.version,pkg.version);
23
+ assert.equal(release.train,'R67');
24
+ assert.equal(release.parent.version,'0.15.43');
25
+ assert.equal(release.parent.release_id,parent.release_id);
26
+ assert.equal(release.parent.manifest_sha256,parent.manifest_sha256);
27
+ assert.equal(release.parent.generation_manifest_sha256,parent.generation_manifest_sha256);
28
+ assert.deepEqual(release.runtime_predecessor,parent);
29
+ assert.equal(prov.version,pkg.version);
30
+ assert.equal(prov.parent_release_id,parent.release_id);
31
+ assert.equal(prov.parent_manifest_sha256,parent.manifest_sha256);
32
+ assert.equal(prov.parent_generation_manifest_sha256,parent.generation_manifest_sha256);
33
+ assert.equal(matrix.version,pkg.version);
34
+ assert.equal(matrix.train,'R67');
35
+ assert.equal(sbom.metadata.component.version,pkg.version);
36
+ assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r67:0.15.44');
37
+ assert.equal(release.r67_native_observation.status,'CANDIDATE_SEALED');
38
+ assert.equal(release.r67_native_observation.new_public_tools,0);
39
+ assert.equal(release.r67_native_observation.full_release_gate,'PASS');
40
+ assert.equal(release.r67_native_observation.current_source_full_shards,'PASS');
41
+ assert.equal(release.r67_native_observation.isolated_activation_rollback_restore,'PASS');
42
+ assert.ok(matrix.required.some(x=>x.id==='r67-sharded-full'));
43
+ assert.match(pkg.scripts['gate:windows'],/gate-windows-r67\.ps1/);
44
+ assert.match(pkg.scripts['r67:focused:test'],/r67-focused-gate\.mjs/);
45
+ });
@@ -0,0 +1,86 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash} from 'node:crypto';
4
+ import {mkdtemp,mkdir,writeFile,rm} from 'node:fs/promises';
5
+ import path from 'node:path';
6
+ import os from 'node:os';
7
+ import {createMachineRuntime} from '../src/machine-identity.mjs';
8
+ import {independentlyVerifyR67RuntimeObservation} from '../scripts/r67-independent-runtime-observation-verify.mjs';
9
+ const sha=b=>createHash('sha256').update(b).digest('hex');
10
+ const POLICY='a'.repeat(64),GRANT='r67-fixture-grant-1';
11
+ async function fixture(callback){
12
+ const stateRoot=await mkdtemp(path.join(os.tmpdir(),'r67-owned-observation-'));
13
+ const release=path.join(stateRoot,'releases','r67'),generation=path.join(stateRoot,'generations','r67');
14
+ await mkdir(release,{recursive:true});await mkdir(generation,{recursive:true});
15
+ const releaseBytes=Buffer.from('candidate-r67-release\n'),generationBytes=Buffer.from('candidate-r67-generation\n');
16
+ await writeFile(path.join(release,'MANIFEST.SHA256'),releaseBytes);
17
+ await writeFile(path.join(generation,'GENERATION.SHA256'),generationBytes);
18
+ const releaseHash=sha(releaseBytes),generationHash=sha(generationBytes);
19
+ const pointer={
20
+ schema:'deadbyte.active-release.v1',release_id:'v0.15.43-'+releaseHash.slice(0,16),version:'0.15.43',
21
+ manifest_sha256:releaseHash,release_root:release,generation_root:generation,
22
+ generation_manifest_sha256:generationHash,launcher_sha256:'1'.repeat(64),
23
+ config_path:path.join(generation,'controller-config.psd1')
24
+ };
25
+ const activePointerPath=path.join(stateRoot,'active-release.json');
26
+ await writeFile(activePointerPath,JSON.stringify(pointer)+'\n');
27
+ const runtime=await createMachineRuntime({stateRoot,activePointerPath,assertObservationAuthority:callback});
28
+ return {runtime,stateRoot,cleanup:()=>rm(stateRoot,{recursive:true,force:true})};
29
+ }
30
+ const grant=()=>({grant_id:GRANT,policy_sha256:POLICY,scope:'native-observe-readonly',authority_generation:4});
31
+ test('R67 isolated machine-owned observation signs actual Windows native process data with generation and scoped standing-grant',async()=>{
32
+ const phases=[];
33
+ const x=await fixture(async({phase,operation})=>{phases.push(phase);assert.equal(operation,'process');return grant();});
34
+ try{
35
+ const before=await x.runtime.status();
36
+ const output=await x.runtime.observeNative({args:['process','4']});
37
+ assert.equal(output.result.status,'ok');
38
+ assert.equal(output.receipt.machine_id,before.machine_id);
39
+ assert.equal(output.receipt.generation_manifest_sha256,before.generation_manifest_sha256);
40
+ assert.equal(output.receipt.authority.grant_id,GRANT);
41
+ assert.deepEqual(phases,['pre','post']);
42
+ const check=independentlyVerifyR67RuntimeObservation({
43
+ receipt:output.receipt,result:output.result,requestArgs:['process','4'],
44
+ machinePublicSpkiBase64:before.public_key_spki_base64,
45
+ expectedMachineStatus:before,expectedPolicySha256:POLICY,expectedGrantId:GRANT
46
+ });
47
+ assert.equal(check.ok,true,check.reason);
48
+ assert.equal(check.signature_valid,true);
49
+ }finally{await x.cleanup();}
50
+ });
51
+ test('R67 runtime observer denies missing authority, changing lease and revoked grant before signing',async()=>{
52
+ const noAuthority=await fixture(null);
53
+ try{await assert.rejects(()=>noAuthority.runtime.observeNative({args:['process','4']}),/authority/i);}
54
+ finally{await noAuthority.cleanup();}
55
+ let armed=true,rotate=false;
56
+ const x=await fixture(async({phase})=>{
57
+ if(phase==='post'&&rotate)armed=false;
58
+ if(!armed)throw new Error('LOCAL_AUTHORITY_REVOKED');
59
+ return grant();
60
+ });
61
+ try{
62
+ rotate=true;
63
+ await assert.rejects(()=>x.runtime.observeNative({args:['process','4']}),/LOCAL_AUTHORITY_REVOKED/);
64
+ assert.equal(armed,false);
65
+ }finally{await x.cleanup();}
66
+ });
67
+ test('R67 runtime observation verifier rejects changed result, request, generation, grant and signature',async()=>{
68
+ const x=await fixture(async()=>grant());
69
+ try{
70
+ const before=await x.runtime.status();
71
+ const xResult=await x.runtime.observeNative({args:['process','4']});
72
+ const verify=(receipt,result,args=['process','4'],status=before)=>independentlyVerifyR67RuntimeObservation({
73
+ receipt,result,requestArgs:args,machinePublicSpkiBase64:before.public_key_spki_base64,
74
+ expectedMachineStatus:status,expectedPolicySha256:POLICY,expectedGrantId:GRANT
75
+ }).ok;
76
+ assert.equal(verify(xResult.receipt,xResult.result),true);
77
+ const corrupt=structuredClone(xResult.result);corrupt.data.processes[0].name+='INJECTED';
78
+ assert.equal(verify(xResult.receipt,corrupt),false);
79
+ assert.equal(verify(xResult.receipt,xResult.result,['process','8']),false);
80
+ assert.equal(verify({...xResult.receipt,generation_manifest_sha256:'0'.repeat(64)},xResult.result),false);
81
+ assert.equal(verify({...xResult.receipt,authority:{...xResult.receipt.authority,grant_id:'wrong'}},xResult.result),false);
82
+ assert.equal(verify({...xResult.receipt,attestation:{...xResult.receipt.attestation,signature_base64:'AA=='}},xResult.result),false);
83
+ const after={...before,identity_generation:before.identity_generation+1};
84
+ assert.equal(verify(xResult.receipt,xResult.result,['process','4'],after),false);
85
+ }finally{await x.cleanup();}
86
+ });
@@ -0,0 +1,12 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ test('R67 server-owned Native Observer is wired to live Coding standing epoch and explicitly opted in',async()=>{
5
+ const source=await readFile(new URL('../src/mcp-server.mjs',import.meta.url),'utf8');
6
+ assert.match(source,/import \{ createR67NativeObservationAuthority \} from '\.\/r67-native-observation-authority\.mjs'/);
7
+ assert.match(source,/let codingPolicy=null;/);
8
+ assert.match(source,/DEADBYTE_R67_NATIVE_OBSERVE \?\? '0'/);
9
+ assert.match(source,/getCodingPolicy:\(\)=>codingPolicy,enabled:nativeObserveMode==='1'/);
10
+ assert.match(source,/createMachineRuntime\(\{stateRoot:runtimeStateRoot,assertObservationAuthority:assertNativeObservationAuthority\}\)/);
11
+ assert.equal((source.match(/let codingPolicy=null;/g)??[]).length,1);
12
+ });
@@ -0,0 +1,66 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {generateKeyPairSync,createHash} from 'node:crypto';
4
+ import {signR67Observation} from '../src/r67-observation-receipt.mjs';
5
+ import {independentlyVerifyR67Receipt} from '../scripts/r67-independent-observation-verify.mjs';
6
+ import {runNativeInspect} from '../src/native-inspector-r67.mjs';
7
+
8
+ const sha=s=>createHash('sha256').update(s).digest('hex');
9
+ const pair=generateKeyPairSync('ed25519');
10
+ const trustedPublicSpkiBase64=pair.publicKey.export({type:'spki',format:'der'}).toString('base64');
11
+ const other=generateKeyPairSync('ed25519');
12
+ const otherSpki=other.publicKey.export({type:'spki',format:'der'}).toString('base64');
13
+ const requestSha256=sha(Buffer.from(JSON.stringify(['process','4']),'utf8'));
14
+ const executableSha256='c814771dddac8bfb184250b868ddb6ab9f5e0e43613c04c3ed8abe09324ec4db';
15
+
16
+ test('R67 signs a real Windows native observation and independently verifies exact result bytes',async()=>{
17
+ const result=await runNativeInspect(['process','4']);
18
+ assert.equal(result.status,'ok');
19
+ const receipt=signR67Observation({privateKey:pair.privateKey,publicKey:pair.publicKey,operation:'process',requestSha256,executableSha256,result});
20
+ const verified=independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256});
21
+ assert.equal(verified.ok,true,verified.reason);
22
+ assert.equal(verified.signature_valid,true);
23
+ assert.equal(verified.signer_key_id,sha(Buffer.from(trustedPublicSpkiBase64,'base64')));
24
+ });
25
+
26
+ test('R67 independent verifier rejects changed result, changed receipt, alternate signer and malformed encoding',async()=>{
27
+ const result=await runNativeInspect(['process','4']);
28
+ const receipt=signR67Observation({privateKey:pair.privateKey,publicKey:pair.publicKey,operation:'process',requestSha256,executableSha256,result});
29
+ const changedResult=structuredClone(result);
30
+ changedResult.data.processes[0].name+='INJECTED';
31
+ assert.equal(independentlyVerifyR67Receipt({receipt,result:changedResult,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256}).ok,false);
32
+ const changedReceipt={...receipt,executable_sha256:sha(Buffer.from('ATTACK'))};
33
+ assert.equal(independentlyVerifyR67Receipt({receipt:changedReceipt,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256}).ok,false);
34
+ assert.equal(independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64:otherSpki,requestArgs:['process','4'],expectedExecutableSha256:executableSha256}).ok,false);
35
+ const forged=signR67Observation({privateKey:other.privateKey,publicKey:other.publicKey,operation:'process',requestSha256,executableSha256,result});
36
+ assert.equal(independentlyVerifyR67Receipt({receipt:forged,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256}).ok,false);
37
+ const badSig={...receipt,attestation:{...receipt.attestation,signature_base64:'AAA='}};
38
+ assert.equal(independentlyVerifyR67Receipt({receipt:badSig,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256}).ok,false);
39
+ });
40
+
41
+ test('R67 signing fails closed without trusted caller signer or on mismatched public/private key and corrupt data SHA',async()=>{
42
+ const result=await runNativeInspect(['process','4']);
43
+ assert.throws(()=>signR67Observation({operation:'process',requestSha256,executableSha256,result}),/trusted runtime/);
44
+ assert.throws(()=>signR67Observation({privateKey:pair.privateKey,publicKey:other.publicKey,operation:'process',requestSha256,executableSha256,result}),/mismatch/);
45
+ const altered={...result,data_sha256:sha(Buffer.from('forged'))};
46
+ assert.throws(()=>signR67Observation({privateKey:pair.privateKey,publicKey:pair.publicKey,operation:'process',requestSha256,executableSha256,result:altered}),/digest invalid/);
47
+ });
48
+
49
+ test('R67 trusted caller signing is integrated into actual native process inspection, not implicit CLI authority',async()=>{
50
+ const {result,receipt}=await runNativeInspect(['process','4'],{trustedSigner:{privateKey:pair.privateKey,publicKey:pair.publicKey}});
51
+ assert.equal(result.status,'ok');
52
+ assert.equal(receipt.operation,'process');
53
+ const check=independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:executableSha256});
54
+ assert.equal(check.ok,true,check.reason);
55
+ const untrusted=await runNativeInspect(['process','4']);
56
+ assert.equal(untrusted.status,'ok');
57
+ assert.equal(Object.hasOwn(untrusted,'attestation'),false);
58
+ });
59
+
60
+ test('R67 independent verifier requires exact request argv and trusted executable pin',async()=>{
61
+ const result=await runNativeInspect(['process','4']);
62
+ const receipt=signR67Observation({privateKey:pair.privateKey,publicKey:pair.publicKey,operation:'process',requestSha256,executableSha256,result});
63
+ assert.equal(independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64,requestArgs:['process','8'],expectedExecutableSha256:executableSha256}).ok,false);
64
+ assert.equal(independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64,requestArgs:['process','4'],expectedExecutableSha256:sha(Buffer.from('WRONG EXE'))}).ok,false);
65
+ assert.equal(independentlyVerifyR67Receipt({receipt,result,trustedPublicSpkiBase64}).ok,false);
66
+ });
@@ -0,0 +1,31 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {spawnSync} from 'node:child_process';
4
+ import {fileURLToPath} from 'node:url';
5
+ import path from 'node:path';
6
+ import {parseR67NonpassCases,parseR67TapSummary} from '../src/r67-regression-shards.mjs';
7
+ const root=path.dirname(path.dirname(fileURLToPath(import.meta.url)));
8
+ const historical=[
9
+ 'test/r53-release-contract.test.mjs','test/r54-release-contract.test.mjs','test/r55-release-contract.test.mjs',
10
+ 'test/r56-release-contract.test.mjs','test/r57-release-contract.test.mjs','test/r58-release-contract.test.mjs',
11
+ 'test/r58-windows-gate.test.mjs','test/r58-bundled-bridge.test.mjs','test/r60-release-contract.test.mjs',
12
+ 'test/r61-release-contract.test.mjs','test/r62-release-contract.test.mjs','test/r63-release-contract.test.mjs',
13
+ 'test/r64-release-contract.test.mjs','test/r65-release-contract.test.mjs','test/semantic-multilang.test.mjs'
14
+ ];
15
+ test('R67 real TAP from historical release and R35 fixture skips has individual source-derived reasons',()=>{
16
+ const r=spawnSync(process.execPath,['--test','--test-reporter=tap','--test-concurrency=2',...historical],{
17
+ cwd:root,encoding:'utf8',windowsHide:true,shell:false,timeout:90000,maxBuffer:16*1024*1024,
18
+ env:Object.fromEntries(Object.entries(process.env).filter(([key])=>key!=='NODE_TEST_CONTEXT'))
19
+ });
20
+ assert.equal(r.error,undefined,r.error?.message);
21
+ assert.equal(r.status,0,'selected regression exit '+r.status+' output tail '+r.stdout?.slice(-1500));
22
+ const tap=parseR67TapSummary(r.stdout);
23
+ assert.ok(tap,'valid full TAP totals; stdout-tail='+String(r.stdout).slice(-1600)+'; stderr-tail='+String(r.stderr).slice(-500));
24
+ assert.equal(tap.fail,0);
25
+ const ledger=parseR67NonpassCases(r.stdout);
26
+ assert.ok(ledger,'nonpass parser output');
27
+ assert.ok(ledger.expected_nonpass>0,'must exercise real skip path');
28
+ assert.equal(ledger.fully_classified,true,JSON.stringify(ledger.cases.filter(x=>!x.reason)));
29
+ assert.equal(ledger.cases.length,ledger.expected_nonpass);
30
+ for(const c of ledger.cases)assert.match(c.reason,/Historical|historical|fixture|R35|R\d+/);
31
+ });
@@ -0,0 +1,21 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {registerMachineTools} from '../src/machine-mcp-tools.mjs';
4
+ test('R67 MCP annotations classify pure observation distinctly from machine revoke, without granting authority',async()=>{
5
+ const catalog=new Map();
6
+ const server={registerTool:(name,config,fn)=>catalog.set(name,{config,fn})};
7
+ let granted=false;
8
+ const runtime={list:async()=>({status:'ok',machines:[]}),status:async()=>({status:'ok'}),ping:async()=>({status:'ok'}),revoke:async()=>({status:'revoked'})};
9
+ registerMachineTools(server,{runtime,assertRevokeAuthority:async()=>{if(!granted)throw new Error('LOCAL_DENY');}});
10
+ for(const name of ['machine_list','machine_status','machine_ping']){
11
+ const hint=catalog.get(name).config.annotations;
12
+ assert.equal(hint.readOnlyHint,true,name);
13
+ assert.equal(hint.destructiveHint,false,name);
14
+ assert.equal(hint.openWorldHint,false,name);
15
+ }
16
+ const rev=catalog.get('machine_revoke');
17
+ assert.deepEqual(rev.config.annotations,{readOnlyHint:false,destructiveHint:true,idempotentHint:false,openWorldHint:false});
18
+ const denial=await rev.fn({reason:'check'});
19
+ assert.ok(denial.isError||denial.structuredContent?.status==='denied','annotations cannot grant revocation');
20
+ assert.equal(granted,false);
21
+ });
@@ -0,0 +1,13 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import {fileURLToPath} from 'node:url';
6
+ const root=path.dirname(path.dirname(fileURLToPath(import.meta.url)));
7
+
8
+ test('R67 Windows release gate must not shadow automatic PowerShell $Args when passing node script argv',async()=>{
9
+ const source=await readFile(path.join(root,'scripts','gate-windows-r67.ps1'),'utf8');
10
+ assert.doesNotMatch(source,/\[string\[\]\]\$Args\b/i,'PowerShell automatic $Args silently discards function parameters');
11
+ assert.match(source,/\[string\[\]\]\$NodeArgs\b/);
12
+ assert.match(source,/\& node @NodeArgs/);
13
+ });
@@ -0,0 +1,137 @@
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 {classifyRemoteAuditOutcome,createLiveTimelineTracker,createLiveTimelineFilter,createLiveTimelineWriter,formatCompactAuditEvent} from '../src/remote-live-log.mjs';
6
+
7
+ function pair(status,is_error=false,side_effect_state=null){
8
+ const tracker=createLiveTimelineTracker({clock:()=>1000,displayMode:'ascii',rootPaths:{local_d:'D:\\'}});
9
+ const args={root_id:'local_d',path:'TECHNICAL/ProgramingLangPJ/tmp/gfx_r3_dev/runtime/gfx/dbyte_gfx3d.dby'};
10
+ const start=tracker.observe({event_type:'tool.request',tool:'coding_file_write',request_id:'r69-example-1',args});
11
+ const done=tracker.observe({event_type:'tool.result',tool:'coding_file_write',request_id:'r69-example-1',
12
+ outcome:{status,is_error,side_effect_state,duration_ms:1}});
13
+ return {tracker,start,done};
14
+ }
15
+
16
+ test('R69 failed, denied and observed_failure never produce a false SUCCEEDED line',()=>{
17
+ for(const status of ['failed','denied','rejected','blocked','observed_failure','cancelled']){
18
+ const {tracker,done}=pair(status);
19
+ assert.match(done,/ERR status=/,status);
20
+ assert.doesNotMatch(done,/SUCCEEDED|\bOK\b/,status);
21
+ assert.match(tracker.summary(),/0 ok \| 1 error/,status);
22
+ }
23
+ });
24
+
25
+ test('R69 unavailable and unsupported result envelopes never print mutation SUCCEEDED',()=>{
26
+ for(const status of ['unavailable','unsupported']){
27
+ const {tracker,done}=pair(status);
28
+ assert.match(done,/ERR status=/,status);
29
+ assert.doesNotMatch(done,/SUCCEEDED/,status);
30
+ assert.match(tracker.summary(),/0 ok \| 1 error/,status);
31
+ }
32
+ });
33
+
34
+ test('R69 pending tool result requires continuation, never implies effect committed',()=>{
35
+ for(const status of ['pending','running','input_required','paused','processing','accepted']){
36
+ const {tracker,done}=pair(status);
37
+ assert.match(done,/PENDING status=/,status);
38
+ assert.doesNotMatch(done,/SUCCEEDED|\bOK\b/,status);
39
+ assert.match(tracker.summary(),/0 ok \| 0 errors \| 0 unknown \| 1 pending/,status);
40
+ }
41
+ });
42
+
43
+ test('R69 unknown side-effect outranks every status; no retry claim',()=>{
44
+ const {done,tracker}=pair('committed',false,'unknown');
45
+ assert.match(done,/FAILED_AFTER_UNKNOWN_EFFECT/);
46
+ assert.match(tracker.summary(),/1 unknown/);
47
+ });
48
+
49
+ test('R69 human console always retains the operation location in terminal result',()=>{
50
+ const {start,done}=pair('denied');
51
+ const absolute='D:\\TECHNICAL\\ProgramingLangPJ\\tmp\\gfx_r3_dev\\runtime\\gfx\\dbyte_gfx3d.dby [root=local_d]';
52
+ assert.ok(start.includes(absolute));
53
+ assert.ok(done.includes(absolute));
54
+ assert.match(done,/ERR status=denied/);
55
+ assert.doesNotMatch(done,/SUCCEEDED/);
56
+ });
57
+
58
+ test('R69 compact audit flags status failure or pending even with is_error=false',()=>{
59
+ assert.match(formatCompactAuditEvent({event_type:'tool.result',tool:'host_exec',outcome:{is_error:false,status:'denied'}}),/ERR/);
60
+ assert.match(formatCompactAuditEvent({event_type:'tool.result',tool:'host_exec',outcome:{is_error:false,status:'input_required'}}),/PENDING/);
61
+ });
62
+
63
+ test('R69 TTY writer obeys runtime terminal resize without rewriting a wrapped start line',()=>{
64
+ const writes=[];
65
+ const stream={isTTY:true,columns:32,write(value){writes.push(value);return true;}};
66
+ const writer=createLiveTimelineWriter({stream,displayMode:'ascii'});
67
+ writer.write('START',{event_type:'tool.call',request_id:'resize'});
68
+ stream.columns=5;
69
+ writer.write('TOO LONG RESULT',{event_type:'tool.result',request_id:'resize'});
70
+ assert.deepEqual(writes,['START','\n','TOO LONG RESULT\n']);
71
+ assert.equal(writer.pending(),null);
72
+ stream.columns=80;
73
+ writer.write('RUN',{event_type:'tool.call',request_id:'wide'});
74
+ writer.write('OK',{event_type:'tool.result',request_id:'wide'});
75
+ assert.equal(writes.at(-1),'\r\x1b[2KOK\n');
76
+ });
77
+
78
+
79
+ test('R69 live latency uses fractional milliseconds instead of printing a false 0ms',()=>{
80
+ const tracker=createLiveTimelineTracker({clock:()=>1000,displayMode:'ascii'});
81
+ tracker.observe({event_type:'tool.request',tool:'machine_status',request_id:'subms'});
82
+ const done=tracker.observe({event_type:'tool.result',tool:'machine_status',request_id:'subms',
83
+ outcome:{is_error:false,duration_ms:0.125}});
84
+ assert.ok(done.includes('0.125ms'));
85
+ assert.doesNotMatch(done,/ 0ms /);
86
+ });
87
+
88
+ test('R69 latency summary includes p99 and discloses bounded sample coverage',()=>{
89
+ const tracker=createLiveTimelineTracker({clock:()=>1000,displayMode:'ascii'});
90
+ for(let i=1;i<=100;i++){
91
+ const id='sample-'+i;
92
+ tracker.observe({event_type:'tool.request',tool:'machine_status',request_id:id});
93
+ tracker.observe({event_type:'tool.result',tool:'machine_status',request_id:id,
94
+ outcome:{is_error:false,duration_ms:i}});
95
+ }
96
+ const summary=tracker.summary();
97
+ assert.ok(summary.includes('p50 51ms'));
98
+ assert.ok(summary.includes('p95 95ms'));
99
+ assert.ok(summary.includes('p99 99ms'));
100
+ assert.ok(summary.includes('sample 100/100'));
101
+ });
102
+
103
+ test('R69 filter matches status-only errors independent of is_error=false',()=>{
104
+ const filter=createLiveTimelineFilter('status=error');
105
+ filter.accept({event_type:'tool.request',tool:'host_exec',request_id:'r69-e',args:{}});
106
+ assert.equal(filter.accept({event_type:'tool.result',tool:'host_exec',request_id:'r69-e',outcome:{status:'denied',is_error:false}}),true);
107
+ });
108
+
109
+ test('R69 mismatched terminal tool cannot inherit a mutating START or claim success',()=>{
110
+ const tracker=createLiveTimelineTracker({clock:()=>1000,displayMode:'ascii'});
111
+ const start=tracker.observe({event_type:'tool.request',tool:'coding_file_write',request_id:'r69-mismatch',args:{root_id:'core',path:'scratch.txt'}});
112
+ assert.match(start,/START/);
113
+ const terminal=tracker.observe({event_type:'tool.result',tool:'machine_ping',request_id:'r69-mismatch',
114
+ outcome:{status:'ok',is_error:false,duration_ms:1,receipt_sha256s:['a'.repeat(64)]}});
115
+ assert.match(terminal,/CORRELATION_MISMATCH/);
116
+ assert.doesNotMatch(terminal,/SUCCEEDED|RECEIPT=/);
117
+ assert.match(tracker.summary(),/0 ok \| 0 errors \| 1 unknown/);
118
+ });
119
+
120
+ test('R69 status filter cannot hide a mismatched terminal identity as successful',()=>{
121
+ const unknown=createLiveTimelineFilter('status=unknown');
122
+ unknown.accept({event_type:'tool.request',tool:'coding_file_write',request_id:'r69-filter-mismatch',args:{}});
123
+ assert.equal(unknown.accept({event_type:'tool.result',tool:'machine_ping',request_id:'r69-filter-mismatch',
124
+ outcome:{status:'ok',is_error:false}}),true);
125
+ });
126
+
127
+ test('R69 remote replay projection does not record unavailable as ok or input_required as complete',async()=>{
128
+ const source=await readFile(new URL('../src/deadbyte-cli.mjs',import.meta.url),'utf8');
129
+ const start=source.indexOf('function auditTimelineRecord(');
130
+ const end=source.indexOf('async function replayRemoteResults(',start);
131
+ assert.ok(start>=0&&end>start);
132
+ const record=new Function('createHash','parseAuditLogLine','classifyRemoteAuditOutcome',`${source.slice(start,end)};return auditTimelineRecord;`)(createHash,()=>null,classifyRemoteAuditOutcome);
133
+ const base={event_type:'tool.result',request_id:'r69-projection',tool:'coding_file_write',ts:'2026-10-13T00:00:00.000Z'};
134
+ assert.equal(record('audit.log','bounded-line',{...base,outcome:{status:'unavailable',is_error:false}}).status,'error');
135
+ assert.equal(record('audit.log','bounded-line',{...base,outcome:{status:'input_required',is_error:false}}).status,'pending');
136
+ });
137
+
@@ -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
+ });