deadbyte-mcp 0.15.71 → 0.15.74

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 (82) hide show
  1. package/MANIFEST.SHA256 +81 -28
  2. package/PROVENANCE.json +56 -16
  3. package/README.txt +24 -18
  4. package/RELEASE.json +67 -18
  5. package/SBOM.cdx.json +14 -2
  6. package/TEST-MATRIX.json +44 -2
  7. package/bin/deadbyte-owner-token-r193.exe +0 -0
  8. package/bridge/package.json +1 -1
  9. package/controller/deadbyte-process-policy.json +4 -4
  10. package/docs/R184-package-lock.json +2 -2
  11. package/docs/R192-LIVE-LOG-HARDENING.txt +39 -0
  12. package/native/deadbyte-owner-token-r193.cpp +156 -0
  13. package/package.json +2 -2
  14. package/scripts/gate-windows-r193.ps1 +108 -0
  15. package/scripts/gate-windows-r194.ps1 +112 -0
  16. package/scripts/npm-interactive-r194.mjs +13 -0
  17. package/scripts/npm-publication-r65.mjs +64 -4
  18. package/scripts/npm-release-r48.mjs +58 -11
  19. package/scripts/npm-release-readiness-r193.mjs +80 -0
  20. package/scripts/npm-release-readiness-r194.mjs +80 -0
  21. package/scripts/r188-owner-uac-review.ps1 +91 -0
  22. package/scripts/r188-uac-review-preview.mjs +65 -0
  23. package/scripts/r192-focused.mjs +10 -0
  24. package/scripts/r192-release-tests.mjs +8 -0
  25. package/scripts/r193-compile-token.ps1 +22 -0
  26. package/scripts/r193-evidence-relocate.ps1 +12 -0
  27. package/scripts/r193-focused-gate.mjs +20 -0
  28. package/scripts/r193-import-r188-scripts.ps1 +14 -0
  29. package/scripts/r193-limited-subject-probe.ps1 +25 -0
  30. package/scripts/r193-migrate-runtime-limited.ps1 +103 -0
  31. package/scripts/r193-owner-keygen.mjs +43 -0
  32. package/scripts/r193-owner-request-live.mjs +50 -0
  33. package/scripts/r193-owner-uac-approve.ps1 +42 -0
  34. package/scripts/r193-owner-uac-broker.mjs +139 -0
  35. package/scripts/r193-owner-uac-enroll-and-approve.ps1 +62 -0
  36. package/scripts/r193-test-limited-token.ps1 +49 -0
  37. package/scripts/r193-toolchain-inventory.ps1 +7 -0
  38. package/scripts/r193-uac-bridge-focused.mjs +21 -0
  39. package/src/deadbyte-cli.mjs +2 -1
  40. package/src/r188-owner-uac.mjs +105 -0
  41. package/src/r188-uac-boundary.mjs +21 -0
  42. package/src/r193-live-owner-subject.mjs +110 -0
  43. package/src/r193-owner-secret-acl.mjs +67 -0
  44. package/src/r193-owner-uac-broker.mjs +85 -0
  45. package/src/r193-uac-r70-bridge.mjs +54 -0
  46. package/src/remote-live-log.mjs +22 -1
  47. package/src/version.mjs +1 -1
  48. package/test/process-policy-refresh.test.mjs +1 -1
  49. package/test/r130-release-security-contract.test.mjs +8 -8
  50. package/test/r132-release-identity.test.mjs +7 -7
  51. package/test/r153-prepublish-identity.test.mjs +1 -1
  52. package/test/r160-release-contract.test.mjs +3 -3
  53. package/test/r165-live-cli-skew.test.mjs +1 -1
  54. package/test/r167-release-contract.test.mjs +11 -11
  55. package/test/r168-release-contract.test.mjs +4 -2
  56. package/test/r172-release-contract.test.mjs +6 -6
  57. package/test/r173-release-contract.test.mjs +16 -16
  58. package/test/r179-release-contract.test.mjs +11 -11
  59. package/test/r188-owner-uac.test.mjs +48 -0
  60. package/test/r188-uac-boundary.test.mjs +42 -0
  61. package/test/r190-release-contract.test.mjs +10 -10
  62. package/test/r191-release-contract.test.mjs +12 -12
  63. package/test/r192-live-log-hardening.test.mjs +50 -0
  64. package/test/r192-release-identity.test.mjs +40 -0
  65. package/test/r193-limited-migration-contract.test.mjs +26 -0
  66. package/test/r193-live-owner-subject.test.mjs +61 -0
  67. package/test/r193-native-process-observer.test.mjs +36 -0
  68. package/test/r193-native-token.test.mjs +43 -0
  69. package/test/r193-owner-enrollment-entrypoint.test.mjs +38 -0
  70. package/test/r193-owner-secret-acl.test.mjs +23 -0
  71. package/test/r193-owner-uac-broker.test.mjs +82 -0
  72. package/test/r193-owner-uac-entrypoint.test.mjs +36 -0
  73. package/test/r193-release-identity.test.mjs +56 -0
  74. package/test/r193-release-readiness.test.mjs +87 -0
  75. package/test/r193-uac-r70-bridge.test.mjs +88 -0
  76. package/test/r193-windows-gate.test.mjs +30 -0
  77. package/test/r194-npm-auth-recovery.test.mjs +77 -0
  78. package/test/r194-npm-preauth.test.mjs +57 -0
  79. package/test/r194-release-identity.test.mjs +43 -0
  80. package/test/r194-release-readiness.test.mjs +87 -0
  81. package/test/r194-windows-gate.test.mjs +21 -0
  82. package/test/r59-tool-surface-compat.test.mjs +1 -1
@@ -13,8 +13,10 @@ const predecessorTarball='fc3ae5b1505e316bc9dfedf8d063cb00641754c8f5f1306a31f8cc
13
13
 
14
14
  test('R172 preserves the immutable R168 publication lineage separately from current identity',async()=>{
15
15
  const release=await read('RELEASE.json');
16
- assert.equal(release.runtime_predecessor.version,'0.15.68');
17
- assert.equal(release.parent.version,'0.15.68');
16
+ assert.equal(release.runtime_predecessor.version,'0.15.72');
17
+ assert.equal(release.parent.version,'0.15.72');
18
+ assert.equal(release.runtime_predecessor.release_id,'v0.15.72-0a5d9436e06e2d9e');
19
+ assert.equal(release.parent.release_id,'v0.15.72-0a5d9436e06e2d9e');
18
20
  assert.notEqual(release.runtime_predecessor.release_id,parent);
19
21
  assert.notEqual(release.parent.release_id,parent);
20
22
  assert.equal(release.r168.scope,'REMOTE_VERSION_SKEW_FAIL_CLOSED_AND_READONLY_RECONCILIATION');
@@ -16,12 +16,12 @@ test('R190 binds the published source predecessor separately from the active run
16
16
  const versions=[pkg.version,bridge.version,release.version,provenance.version,matrix.version,
17
17
  bom.metadata.component.version,DEADBYTE_VERSION];
18
18
  if(lock)versions.push(lock.version,lock.packages[''].version);
19
- for(const value of versions)assert.equal(value,'0.15.71');
20
- assert.equal(release.train,'R191'); assert.equal(matrix.train,'R191');
21
- assert.equal(release.source_predecessor.version,'0.15.70');
22
- assert.equal(release.source_predecessor.manifest_sha256,'df15db35c7ddddd769650f5c86557159d10d99e9eef4dd232cae67faeb8ad6e3');
23
- assert.equal(release.source_predecessor.tarball_sha256,'1a5f5f30bf4781ed951d6d201b8a972d088b2091555d7f4cc2e2bb899ed5707e');
24
- assert.equal(release.runtime_predecessor.release_id,'v0.15.68-ff29dbb2fbb89862');
19
+ for(const value of versions)assert.equal(value,'0.15.74');
20
+ assert.equal(release.train,'R194'); assert.equal(matrix.train,'R194');
21
+ assert.equal(release.source_predecessor.version,'0.15.73');
22
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
23
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
24
+ assert.equal(release.runtime_predecessor.release_id,'v0.15.72-0a5d9436e06e2d9e');
25
25
  assert.equal(release.r173.public_tool_delta,0); assert.equal(release.r173.authority_scope_delta,0);
26
26
  });
27
27
 
@@ -13,21 +13,21 @@ test('R190 package identity binds the exact published R179 source and live runti
13
13
  json('package.json'),readReleaseLock(root),json('bridge/package.json'),json('RELEASE.json'),
14
14
  json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json')
15
15
  ]);
16
- assert.equal(pkg.version,'0.15.71');
17
- assert.equal(lock.version,'0.15.71');
18
- assert.equal(lock.packages[''].version,'0.15.71');
19
- assert.equal(bridge.version,'0.15.71');
20
- assert.equal(release.version,'0.15.71');
21
- assert.equal(release.train,'R191');
22
- assert.equal(matrix.version,'0.15.71');
23
- assert.equal(matrix.train,'R191');
24
- assert.equal(sbom.metadata.component.version,'0.15.71');
25
- assert.equal(release.source_predecessor.version,'0.15.70');
26
- assert.equal(release.source_predecessor.train,'R190');
27
- assert.equal(release.source_predecessor.manifest_sha256,'df15db35c7ddddd769650f5c86557159d10d99e9eef4dd232cae67faeb8ad6e3');
28
- assert.equal(release.source_predecessor.tarball_sha256,'1a5f5f30bf4781ed951d6d201b8a972d088b2091555d7f4cc2e2bb899ed5707e');
29
- assert.equal(release.runtime_predecessor.version,'0.15.68');
30
- assert.equal(provenance.version,'0.15.71');
31
- assert.equal(provenance.parent_tarball_sha256,release.source_predecessor.tarball_sha256);
16
+ assert.equal(pkg.version,'0.15.74');
17
+ assert.equal(lock.version,'0.15.74');
18
+ assert.equal(lock.packages[''].version,'0.15.74');
19
+ assert.equal(bridge.version,'0.15.74');
20
+ assert.equal(release.version,'0.15.74');
21
+ assert.equal(release.train,'R194');
22
+ assert.equal(matrix.version,'0.15.74');
23
+ assert.equal(matrix.train,'R194');
24
+ assert.equal(sbom.metadata.component.version,'0.15.74');
25
+ assert.equal(release.source_predecessor.version,'0.15.73');
26
+ assert.equal(release.source_predecessor.train,'R193');
27
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
28
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
29
+ assert.equal(release.runtime_predecessor.version,'0.15.72');
30
+ assert.equal(provenance.version,'0.15.74');
31
+ assert.equal(provenance.parent_tarball_sha256,'15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d');
32
32
  assert.equal(provenance.source_predecessor_manifest_file_sha256,release.source_predecessor.manifest_sha256);
33
33
  });
@@ -7,26 +7,26 @@ import {DEADBYTE_VERSION} from '../src/version.mjs';
7
7
  import {readReleaseLock} from './helpers/release-lock.mjs';
8
8
  const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
9
9
  const read=async file=>JSON.parse(await readFile(path.join(root,file),'utf8'));
10
- const parent='v0.15.68-ff29dbb2fbb89862';
11
- const manifest='ff29dbb2fbb898625592afb47835a4a62ef289429f1e0a89a83242398cd98885';
12
- const generation='2887d4a8d54ea6fc6b28869072f72491c892dfe28178b3537936dce958147bd2';
10
+ const parent='v0.15.72-0a5d9436e06e2d9e';
11
+ const manifest='0a5d9436e06e2d9e7cf9179417465955d8ca5ba88655b13dd019190243c1cc90';
12
+ const generation='aec7b998306a3bbbcc59088648e7bc46ca7e203d749d4550b5b5f372032f92b0';
13
13
  const tarball='1a7f1fe05a06178b8d772a140be6e0470790b743cef690c3f8f8165cc61075bf';
14
14
  test('R190 version, lock snapshot, bridge, matrix, SBOM and provenance identify exact 0.15.70 successor',async()=>{
15
15
  const [pkg,lock,bridge,release,provenance,matrix,sbom]=await Promise.all([
16
16
  read('package.json'),readReleaseLock(root),read('bridge/package.json'),read('RELEASE.json'),
17
17
  read('PROVENANCE.json'),read('TEST-MATRIX.json'),read('SBOM.cdx.json')]);
18
18
  for(const version of [pkg.version,lock.version,lock.packages[''].version,bridge.version,release.version,provenance.version,
19
- matrix.version,sbom.metadata.component.version,DEADBYTE_VERSION])assert.equal(version,'0.15.71');
20
- assert.equal(release.train,'R191');assert.equal(matrix.train,'R191');
21
- assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r191:0.15.71');
19
+ matrix.version,sbom.metadata.component.version,DEADBYTE_VERSION])assert.equal(version,'0.15.74');
20
+ assert.equal(release.train,'R194');assert.equal(matrix.train,'R194');
21
+ assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r194:0.15.74');
22
22
  assert.equal(release.parent.release_id,parent);assert.equal(release.parent.manifest_sha256,manifest);
23
23
  assert.equal(release.parent.generation_manifest_sha256,generation);
24
- assert.equal(release.source_predecessor.version,'0.15.70');
25
- assert.equal(release.source_predecessor.manifest_sha256,'df15db35c7ddddd769650f5c86557159d10d99e9eef4dd232cae67faeb8ad6e3');
26
- assert.equal(release.source_predecessor.tarball_sha256,'1a5f5f30bf4781ed951d6d201b8a972d088b2091555d7f4cc2e2bb899ed5707e');
24
+ assert.equal(release.source_predecessor.version,'0.15.73');
25
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
26
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
27
27
  assert.equal(release.runtime_predecessor.release_id,parent);
28
28
  assert.equal(provenance.runtime_predecessor.release_id,parent);
29
- assert.equal(provenance.parent_tarball_sha256,release.source_predecessor.tarball_sha256);
29
+ assert.equal(provenance.parent_tarball_sha256,'15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d');
30
30
  assert.equal(provenance.source_predecessor_tarball_sha256,release.source_predecessor.tarball_sha256);
31
31
  });
32
32
  test('R179 does not misrepresent owner Autonomous enrollment, protected regression or publication as finished',async()=>{
@@ -48,7 +48,7 @@ test('R190 retains historical R179 and R173 source evidence without promoting it
48
48
  assert.equal(release.r173.source_predecessor_version,'0.15.67');
49
49
  assert.equal(release.r173.source_predecessor_manifest_sha256,'4fd7bfc76b1de6401c142b607cc84e847434b28c888bc99ceb09c9e8e5adc8f8');
50
50
  assert.equal(prov.r173.source_predecessor_version,'0.15.67');
51
- assert.equal(release.source_predecessor.version,'0.15.70');
51
+ assert.equal(release.source_predecessor.version,'0.15.73');
52
52
  assert.notEqual(release.source_predecessor.tarball_sha256,release.r173.source_predecessor_tarball_sha256);
53
53
  });
54
54
  test('R184 ships a semantic lock snapshot matching installed package identity and dependencies',async()=>{
@@ -0,0 +1,48 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createR188OwnerUacRequest,verifyR188OwnerUacRequest} from '../src/r188-owner-uac.mjs';
4
+ const h=c=>c.repeat(64);
5
+ const issued=new Date('2026-10-28T06:00:00.000Z');
6
+ const fixture={
7
+ machineEpoch:h('e'),releaseManifestSha256:h('a'),
8
+ codingPolicySha256:h('b'),autonomousPolicySha256:h('c'),
9
+ rootId:'core',projectRoot:'D:\\Projects\\deadbyte-mcp',
10
+ maxSeconds:600,now:issued,expiresInMs:120000
11
+ };
12
+ test('R188 no-Windows-Hello UAC review is project-scoped, short lived and not a grant',()=>{
13
+ const a=createR188OwnerUacRequest(fixture),b=createR188OwnerUacRequest(fixture);
14
+ assert.equal(a.schema,'deadbyte.r188-owner-uac-request.v1');
15
+ assert.equal(a.subject.root_id,'core');
16
+ assert.equal(a.subject.operation,'autonomous_goal_run');
17
+ assert.equal(a.subject.max_seconds,600);
18
+ assert.equal(a.subject.expires_at_utc,'2026-10-28T06:02:00.000Z');
19
+ assert.notEqual(a.challenge,b.challenge);
20
+ assert.equal(a.authority_granted,false);
21
+ assert.equal(a.owner_approved,false);
22
+ assert.equal(a.require_interactive_uac,true);
23
+ assert.match(a.review_phrase,/^APPROVE-[A-F0-9]{12}$/);
24
+ assert.match(a.request_sha256,/^[a-f0-9]{64}$/);
25
+ const r=verifyR188OwnerUacRequest({request:a,expected:fixture,now:new Date(issued.getTime()+1000)});
26
+ assert.equal(r.status,'VERIFIED_FOR_REVIEW_ONLY');
27
+ assert.equal(r.authority_granted,false);
28
+ assert.equal(r.request_sha256,a.request_sha256);
29
+ });
30
+ test('R188 disallows broad scopes and unsafe timestamps before preparing a review',()=>{
31
+ for(const change of [
32
+ {rootId:'all'}, {maxSeconds:3601}, {maxSeconds:0},
33
+ {machineEpoch:'a'}, {codingPolicySha256:h('g')},
34
+ {projectRoot:'D:\\'},{projectRoot:'relative'},
35
+ {expiresInMs:300001},{expiresInMs:-1}
36
+ ])assert.throws(()=>createR188OwnerUacRequest({...fixture,...change}),/R188/);
37
+ });
38
+ test('R188 rejects changed release, policy, epoch, path, signature-like receipt or expired request',()=>{
39
+ const request=createR188OwnerUacRequest(fixture);
40
+ for(const change of [
41
+ {releaseManifestSha256:h('f')},{codingPolicySha256:h('d')},
42
+ {autonomousPolicySha256:h('0')},{machineEpoch:h('1')},
43
+ {projectRoot:'D:\\Other'}
44
+ ])assert.throws(()=>verifyR188OwnerUacRequest({request,expected:{...fixture,...change},now:issued}),/R188/);
45
+ assert.throws(()=>verifyR188OwnerUacRequest({request:{...request,owner_approved:true},expected:fixture,now:issued}),/R188/);
46
+ assert.throws(()=>verifyR188OwnerUacRequest({request:{...request,challenge:'A'.repeat(43)},expected:fixture,now:issued}),/R188/);
47
+ assert.throws(()=>verifyR188OwnerUacRequest({request,expected:fixture,now:new Date(issued.getTime()+120000)}),/R188/);
48
+ });
@@ -0,0 +1,42 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ import {spawnSync} from 'node:child_process';
5
+ import {fileURLToPath} from 'node:url';
6
+ import path from 'node:path';
7
+ import {inspectTrustedInstallation,privilegedEpochInstallFiles} from '../src/privileged-install-trust-r89.mjs';
8
+ const root=fileURLToPath(new URL('..',import.meta.url));
9
+ test('R188 owner review is explicitly manual, protected, with UAC secure desktop and expiry review',async()=>{
10
+ const script=await readFile(path.join(root,'scripts','r188-owner-uac-review.ps1'),'utf8');
11
+ assert.match(script,/#requires -RunAsAdministrator/);
12
+ assert.match(script,/EnableLUA/);
13
+ assert.match(script,/PromptOnSecureDesktop/);
14
+ assert.match(script,/ConsentPromptBehaviorAdmin/);
15
+ assert.match(script,/Read-Host/);
16
+ assert.match(script,/REVIEWED_NO_GRANT/);
17
+ assert.match(script,/authority_granted=\$false/);
18
+ assert.match(script,/grant_issued=\$false/);
19
+ assert.match(script,/FileMode\]::CreateNew/);
20
+ assert.doesNotMatch(script,/Start-Process\s+.*-Verb\s+RunAs/i);
21
+ assert.doesNotMatch(script,/Arm-Autonomous|transaction_revoke|autonomous-grant\.json/);
22
+ });
23
+ test('R188 UAC preflight fails closed at the applicable trust or request boundary',async()=>{
24
+ let trusted=false;
25
+ try{
26
+ trusted=(await inspectTrustedInstallation(privilegedEpochInstallFiles(root,process.execPath))).trusted===true;
27
+ }catch{}
28
+ const script=path.join(root,'scripts','r188-uac-review-preview.mjs');
29
+ const r=spawnSync(process.execPath,[script,'D:\\bad-request.json'],{
30
+ encoding:'utf8',cwd:root,windowsHide:true,timeout:12000,maxBuffer:512*1024});
31
+ assert.equal(r.status,2);
32
+ if(trusted)assert.match(r.stderr,/ENOENT.*bad-request\.json/i);
33
+ else assert.match(r.stderr,/R188_UAC_REVIEW_BLOCKED|R89_PROTECTED_INSTALLATION_REQUIRED|R89 privileged installation not protected: UNTRUSTED_WRITE_ACE/);
34
+ assert.doesNotMatch(r.stdout,/authority_granted":true/);
35
+ });
36
+ test('R188 broker cannot pretend owner-reviewed data is a current epoch or signed grant',async()=>{
37
+ const script=await readFile(path.join(root,'scripts','r188-uac-review-preview.mjs'),'utf8');
38
+ assert.match(script,/live_epoch_verified:false/);
39
+ assert.match(script,/live_policies_verified:false/);
40
+ assert.match(script,/authority_granted:false/);
41
+ assert.match(script,/R89_PROTECTED_INSTALLATION_REQUIRED/);
42
+ });
@@ -8,17 +8,17 @@ test('R190 candidate identity separates published source 0.15.69 from active run
8
8
  json('package.json'),json('bridge/package.json'),json('RELEASE.json'),json('PROVENANCE.json'),
9
9
  json('TEST-MATRIX.json'),json('SBOM.cdx.json'),readFile(new URL('../src/version.mjs',import.meta.url),'utf8')]);
10
10
  for(const value of [pkg.version,bridge.version,release.version,provenance.version,matrix.version,
11
- sbom.metadata.component.version])assert.equal(value,'0.15.71');
12
- assert.match(versionSource,/DEADBYTE_VERSION = '0\.15\.71'/);
13
- assert.equal(release.train,'R191');assert.equal(matrix.train,'R191');
14
- assert.equal(release.source_predecessor.version,'0.15.70');
15
- assert.equal(release.source_predecessor.tarball_sha256,'1a5f5f30bf4781ed951d6d201b8a972d088b2091555d7f4cc2e2bb899ed5707e');
16
- assert.equal(release.source_predecessor.manifest_sha256,'df15db35c7ddddd769650f5c86557159d10d99e9eef4dd232cae67faeb8ad6e3');
17
- assert.equal(release.runtime_predecessor.version,'0.15.68');
18
- assert.equal(release.runtime_predecessor.release_id,'v0.15.68-ff29dbb2fbb89862');
19
- assert.equal(provenance.source_predecessor_version,'0.15.70');
11
+ sbom.metadata.component.version])assert.equal(value,'0.15.74');
12
+ assert.match(versionSource,/DEADBYTE_VERSION = '0\.15\.74'/);
13
+ assert.equal(release.train,'R194');assert.equal(matrix.train,'R194');
14
+ assert.equal(release.source_predecessor.version,'0.15.73');
15
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
16
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
17
+ assert.equal(release.runtime_predecessor.version,'0.15.72');
18
+ assert.equal(release.runtime_predecessor.release_id,'v0.15.72-0a5d9436e06e2d9e');
19
+ assert.equal(provenance.source_predecessor_version,'0.15.73');
20
20
  assert.equal(provenance.source_predecessor_tarball_sha256,release.source_predecessor.tarball_sha256);
21
- assert.match(sbom.serialNumber,/r191:0\.15\.71$/);
21
+ assert.match(sbom.serialNumber,/r194:0\.15\.74$/);
22
22
  });
23
23
 
24
24
  test('R190 release metadata records verified recovery without claiming publication or activation',async()=>{
@@ -6,23 +6,23 @@ import path from 'node:path';
6
6
  import {DEADBYTE_VERSION} from '../src/version.mjs';
7
7
  const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
8
8
  const json=async f=>JSON.parse(await readFile(path.join(root,f),'utf8'));
9
- const predecessor='v0.15.68-ff29dbb2fbb89862';
10
- const publishedManifest='df15db35c7ddddd769650f5c86557159d10d99e9eef4dd232cae67faeb8ad6e3';
11
- const publishedTarball='1a5f5f30bf4781ed951d6d201b8a972d088b2091555d7f4cc2e2bb899ed5707e';
9
+ const predecessor='v0.15.72-0a5d9436e06e2d9e';
10
+ const publishedManifest='0a5d9436e06e2d9e7cf9179417465955d8ca5ba88655b13dd019190243c1cc90';
11
+ const publishedTarball='15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d';
12
12
  test('R191 exact version identity includes bundled bridge, lock snapshot, SBOM, provenance and matrix',async()=>{
13
13
  const [pkg,bridge,lock,release,provenance,matrix,bom]=await Promise.all(['package.json','bridge/package.json','docs/R184-package-lock.json','RELEASE.json','PROVENANCE.json','TEST-MATRIX.json','SBOM.cdx.json'].map(json));
14
- for(const ver of [pkg.version,bridge.version,lock.version,lock.packages[''].version,release.version,provenance.version,matrix.version,bom.metadata.component.version,DEADBYTE_VERSION])assert.equal(ver,'0.15.71');
15
- for(const train of [release.train,matrix.train])assert.equal(train,'R191');
16
- assert.equal(bom.serialNumber,'urn:cdx:deadbyte-mcp:r191:0.15.71');
14
+ for(const ver of [pkg.version,bridge.version,lock.version,lock.packages[''].version,release.version,provenance.version,matrix.version,bom.metadata.component.version,DEADBYTE_VERSION])assert.equal(ver,'0.15.74');
15
+ for(const train of [release.train,matrix.train])assert.equal(train,'R194');
16
+ assert.equal(bom.serialNumber,'urn:cdx:deadbyte-mcp:r194:0.15.74');
17
17
  assert.equal(release.parent.release_id,predecessor);
18
18
  assert.equal(provenance.parent_release_id,predecessor);
19
- assert.equal(release.source_predecessor.version,'0.15.70');
20
- assert.equal(release.source_predecessor.manifest_sha256,publishedManifest);
21
- assert.equal(release.source_predecessor.tarball_sha256,publishedTarball);
22
- assert.equal(provenance.source_predecessor_version,'0.15.70');
19
+ assert.equal(release.source_predecessor.version,'0.15.73');
20
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
21
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
22
+ assert.equal(provenance.source_predecessor_version,'0.15.73');
23
23
  assert.equal(provenance.parent_tarball_sha256,publishedTarball);
24
- assert.equal(provenance.source_predecessor_tarball_sha256,publishedTarball);
25
- assert.equal(provenance.source_predecessor_manifest_file_sha256,publishedManifest);
24
+ assert.equal(provenance.source_predecessor_tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
25
+ assert.equal(provenance.source_predecessor_manifest_file_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
26
26
  assert.equal(release.r191_activation_repair.npm_publish,'NOT_RUN');
27
27
  assert.equal(release.r191_activation_repair.production_activation,'NOT_RUN');
28
28
  assert.equal(release.r190_foreground_recovery.status,'PREPUBLISH_VERIFIED');
@@ -0,0 +1,50 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {formatRuntimeDiagnosticLine,createLiveTimelineTracker,
4
+ pruneLiveLogReaders} from '../src/remote-live-log.mjs';
5
+
6
+ const compact=(reason)=>'[TOOL] 2026-10-28T14:00:00.000Z #12 ✗ coding_command_run 10ms — '+reason;
7
+
8
+ test('R192 runtime verbose diagnostics never disclose secret-bearing reasons',()=>{
9
+ const raw=compact('password=canaryNotForConsole123');
10
+ const out=formatRuntimeDiagnosticLine('bridge.stdout.log',raw,{verbose:true,displayMode:'ascii'});
11
+ assert.equal(typeof out,'string');
12
+ assert.match(out,/coding_command_run/);
13
+ assert.match(out,/REDACTED/);
14
+ assert.doesNotMatch(out,/canaryNotForConsole123/);
15
+ assert.equal(formatRuntimeDiagnosticLine('bridge.stdout.log',raw,{verbose:false}),null);
16
+ });
17
+
18
+ test('R192 runtime diagnostic detail is short, single-line and status-preserving',()=>{
19
+ const out=formatRuntimeDiagnosticLine('bridge.stdout.log',compact('slow write rejected '+('x'.repeat(800))),{verbose:true,displayMode:'ascii'});
20
+ assert.match(out,/\[BRIDGE.STDOUT.DEBUG\].*coding_command_run 10ms/);
21
+ assert.ok(out.length<350,'a single runtime diagnostic cannot flood the foreground');
22
+ assert.equal(out.split(/\r?\n/).length,1);
23
+ });
24
+
25
+ test('R192 audit result redacts secrets without hiding outcome classification',()=>{
26
+ const tracker=createLiveTimelineTracker({clock:()=>1000,displayMode:'ascii'});
27
+ tracker.observe({event_type:'tool.request',request_id:'123456789012',tool:'host_exec',args:{root_id:'core',mode:'native'}});
28
+ const out=tracker.observe({event_type:'tool.result',request_id:'123456789012',tool:'host_exec',
29
+ outcome:{status:'denied',is_error:true,duration_ms:24,reason:'authorization: Bearer supersensitive123456'}});
30
+ assert.match(out,/ERR/);
31
+ assert.doesNotMatch(out,/supersensitive123456/);
32
+ assert.match(out,/REDACTED/);
33
+ });
34
+
35
+ test('R192 rotation prunes stale cursors and partial line fragments without touching current streams',()=>{
36
+ const live=new Map([['current.log',{offset:12}],['gone.log',{offset:77}]]);
37
+ const fragments=new Map([['current.log','half'],['gone.log','secret']]);
38
+ const result=pruneLiveLogReaders(live,fragments,['current.log','other.log']);
39
+ assert.deepEqual(result,{cursors_removed:1,fragments_removed:1});
40
+ assert.deepEqual([...live.keys()],['current.log']);
41
+ assert.deepEqual([...fragments], [['current.log','half']]);
42
+ });
43
+
44
+ test('R192 reject malformed discovery before mutating any reader state',()=>{
45
+ const live=new Map([['current.log',{offset:12}]]);
46
+ const fragments=new Map([['current.log','half']]);
47
+ assert.throws(()=>pruneLiveLogReaders(live,fragments,[123]),/invalid/i);
48
+ assert.equal(live.has('current.log'),true);
49
+ assert.equal(fragments.get('current.log'),'half');
50
+ });
@@ -0,0 +1,40 @@
1
+ import test from 'node:test';import assert from 'node:assert/strict';
2
+ import {readFile} from 'node:fs/promises';import {createHash} from 'node:crypto';import path from 'node:path';import {fileURLToPath} from 'node:url';
3
+ import {DEADBYTE_VERSION} from '../src/version.mjs';
4
+ const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
5
+ const read=async name=>JSON.parse(await readFile(path.join(root,name),'utf8'));
6
+ const prevHash='0a5d9436e06e2d9e7cf9179417465955d8ca5ba88655b13dd019190243c1cc90';
7
+ const prevTar='15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d';
8
+ test('R193 current identity retains exact published R192 predecessor evidence',async()=>{
9
+ const [pkg,bridge,lock,release,prov,matrix,bom]=await Promise.all([
10
+ read('package.json'),read('bridge/package.json'),read('docs/R184-package-lock.json'),
11
+ read('RELEASE.json'),read('PROVENANCE.json'),read('TEST-MATRIX.json'),read('SBOM.cdx.json')]);
12
+ for(const actual of [pkg.version,bridge.version,lock.version,lock.packages[''].version,
13
+ release.version,prov.version,matrix.version,bom.metadata.component.version,DEADBYTE_VERSION])
14
+ assert.equal(actual,'0.15.74');
15
+ assert.equal(release.train,'R194');assert.equal(matrix.train,'R194');
16
+ assert.equal(bom.serialNumber,'urn:cdx:deadbyte-mcp:r194:0.15.74');
17
+ assert.equal(release.parent.release_id,'v0.15.72-0a5d9436e06e2d9e');
18
+ assert.equal(release.parent.manifest_sha256,prevHash);
19
+ assert.equal(release.source_predecessor.tarball_sha256,'13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534');
20
+ assert.equal(release.source_predecessor.manifest_sha256,'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd');
21
+ assert.equal(prov.parent_tarball_sha256,prevTar);
22
+ assert.equal(prov.parent_manifest_sha256,prevHash);
23
+ assert.equal(release.r192.production_activation,'NOT_RUN');
24
+ assert.equal(release.r192.public_tool_schema_changed,false);
25
+ assert.equal(release.r192.authority_grants_changed,false);
26
+ });
27
+ test('R192 foreground reader enforces caller-safe telemetry rather than changing authority',async()=>{
28
+ const [cli,log]=await Promise.all([
29
+ readFile(path.join(root,'src','deadbyte-cli.mjs'),'utf8'),
30
+ readFile(path.join(root,'src','remote-live-log.mjs'),'utf8')]);
31
+ assert.match(cli,/pruneLiveLogReaders\(activeOffsets,partialLines,liveFiles\)/);
32
+ assert.match(log,/export function pruneLiveLogReaders/);
33
+ assert.match(log,/sanitizeAuditArgs\(compact\[6\]\)/);
34
+ const [policy,release]=await Promise.all([
35
+ read('controller/deadbyte-process-policy.json'),read('RELEASE.json')]);
36
+ const approved=release.r194.development_policy_root;
37
+ assert.equal(typeof approved,'string');
38
+ assert.ok(path.isAbsolute(approved));
39
+ assert.equal(path.resolve(policy.roots.core.path),path.resolve(approved));
40
+ });
@@ -0,0 +1,26 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ import {fileURLToPath} from 'node:url';
5
+ import path from 'node:path';
6
+ const root=fileURLToPath(new URL('..',import.meta.url));
7
+ test('R193 Limited migration uses supported lifecycle, Limited tasks and never silently rearms',async()=>{
8
+ const source=await readFile(path.join(root,'scripts','r193-migrate-runtime-limited.ps1'),'utf8');
9
+ assert.match(source,/#requires -RunAsAdministrator/);
10
+ assert.match(source,/Invoke-Controller supervisorstop/);
11
+ assert.match(source,/Invoke-Controller stop/);
12
+ assert.match(source,/DEADBYTE-MCP-Runtime-Logon/);
13
+ assert.match(source,/RunLevel Limited/);
14
+ assert.match(source,/desktop_reapproval_required=\$true/);
15
+ assert.doesNotMatch(source,/armdesktop|armprocess|armcoding|armhost|armautonomous/i);
16
+ assert.doesNotMatch(source,/Stop-Process|taskkill|TerminateProcess/i);
17
+ });
18
+ test('R193 owner request is generated only from fixed protected live state after migration',async()=>{
19
+ const source=await readFile(path.join(root,'scripts','r193-owner-request-live.mjs'),'utf8');
20
+ assert.match(source,/process\.argv\.length!==2/);
21
+ assert.match(source,/createR193LiveMachineEpoch/);
22
+ assert.match(source,/verifyManifestTreeExact/);
23
+ assert.match(source,/observation\.state!=='ONLINE'/);
24
+ assert.match(source,/authority_granted:false/);
25
+ assert.doesNotMatch(source,/createPrivateKey|issueR186AutonomousGrant|createAuthorityEpochStore|armautonomous/i);
26
+ });
@@ -0,0 +1,61 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {createHash} from 'node:crypto';
4
+ import {createR188OwnerUacRequest} from '../src/r188-owner-uac.mjs';
5
+ import {buildR193LiveOwnerBoundary,createR193LiveMachineEpoch} from '../src/r193-live-owner-subject.mjs';
6
+
7
+ const sha=b=>createHash('sha256').update(b).digest('hex');
8
+ const filetime=iso=>{
9
+ const m=/^(\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d)\.(\d{1,7})Z$/.exec(iso);
10
+ return (BigInt(Date.parse(m[1]+'.000Z')+11644473600000)*10000n+BigInt(m[2].padEnd(7,'0'))).toString(16).padStart(16,'0');
11
+ };
12
+ function fixture(){
13
+ const manifest=Buffer.from('manifest'),coding=Buffer.from('coding'),autonomous=Buffer.from('autonomous');
14
+ const pointer={release_id:'v0.15.72-test',version:'0.15.72',manifest_sha256:sha(manifest),
15
+ generation_manifest_sha256:'d'.repeat(64),release_root:'C:\\Program Files\\DEADBYTE-Test'};
16
+ const authority={process:{configured:true,armed:true,reason:'standing-grant',epoch_seq:1,epoch_sha256:'1'.repeat(64)},
17
+ coding:{configured:true,armed:true,reason:'standing-grant',epoch_seq:2,epoch_sha256:'2'.repeat(64)},
18
+ autonomous:{configured:true,armed:false,reason:'disarmed'},
19
+ desktop:{configured:true,armed:true,reason:'standing-grant',epoch_seq:3,epoch_sha256:'3'.repeat(64)},
20
+ host:{configured:true,armed:true,reason:'standing-grant',epoch_seq:4,epoch_sha256:'4'.repeat(64)}};
21
+ const times={bridge:'2026-10-29T08:00:00.1234567Z',core:'2026-10-29T08:00:01.0000000Z',
22
+ cloud:'2026-10-29T08:00:02.7654321Z',supervisor:'2026-10-29T08:00:03.1000000Z'};
23
+ const observation={schema:'deadbyte.controller-observation.v1',core_root:pointer.release_root,
24
+ bridge:{alive:true,pid:101,creation_time_utc:times.bridge},core:{alive:true,pid:102,creation_time_utc:times.core},
25
+ cloud:{alive:true,pid:103,creation_time_utc:times.cloud},supervisor:{running:true},authority};
26
+ const supervisor={pid:104,creation_time_utc:times.supervisor};
27
+ const reports=Object.fromEntries(['bridge','core','cloud','supervisor'].map((component,index)=>[component,{
28
+ schema:'deadbyte.r193-native-process-token.v1',pid:101+index,creation_filetime_hex:filetime(times[component]),
29
+ alive:true,identity_verified:true,elevated:false,admin_enabled:false,integrity_rid:8192,token_type:'primary'}]));
30
+ const machineEpoch=createR193LiveMachineEpoch({activePointer:pointer,controllerObservation:observation});
31
+ const now=new Date('2026-10-29T08:01:00.000Z');
32
+ const request=createR188OwnerUacRequest({machineEpoch,releaseManifestSha256:sha(manifest),
33
+ codingPolicySha256:sha(coding),autonomousPolicySha256:sha(autonomous),rootId:'core',
34
+ projectRoot:'D:\\Projects\\deadbyte-mcp',maxSeconds:600,now,expiresInMs:120000});
35
+ return {manifest,coding,autonomous,pointer,observation,supervisor,reports,request,now};
36
+ }
37
+ const build=(f,changes={})=>buildR193LiveOwnerBoundary({request:f.request,activePointer:f.pointer,
38
+ installedManifestBytes:f.manifest,codingPolicyBytes:f.coding,autonomousPolicyBytes:f.autonomous,
39
+ controllerObservation:f.observation,supervisorLedger:f.supervisor,processReports:f.reports,
40
+ brokerR89Trusted:true,keyAclTrusted:true,uac:{enable_uac:true,secure_desktop:true,prompt_mode:'explicit_secure_desktop'},
41
+ ownerGesture:'approved',now:new Date(f.now.getTime()+1000),...changes});
42
+
43
+ test('R193 derives exact owner boundary from live release, policies, epoch and kernel process identities',()=>{
44
+ const f=fixture(),out=build(f);
45
+ assert.equal(out.expected.machineEpoch,f.request.subject.machine_epoch);
46
+ assert.equal(out.boundary.agent_processes.length,4);
47
+ assert.equal(out.boundary.agent_processes.every(x=>x.identity_verified&&!x.elevated),true);
48
+ });
49
+
50
+ test('R193 live subject rejects release, policy, authority and process identity drift',()=>{
51
+ const f=fixture();
52
+ for(const changes of [
53
+ {installedManifestBytes:Buffer.from('changed')},
54
+ {codingPolicyBytes:Buffer.from('changed')},
55
+ {autonomousPolicyBytes:Buffer.from('changed')},
56
+ {activePointer:{...f.pointer,generation_manifest_sha256:'e'.repeat(64)}},
57
+ {processReports:{...f.reports,core:{...f.reports.core,pid:999}}},
58
+ {processReports:{...f.reports,cloud:{...f.reports.cloud,creation_filetime_hex:'0'.repeat(16)}}},
59
+ {controllerObservation:{...f.observation,authority:{...f.observation.authority,host:{...f.observation.authority.host,epoch_seq:5}}}}
60
+ ])assert.throws(()=>build(f,changes),/R193|R188/);
61
+ });
@@ -0,0 +1,36 @@
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
+
7
+ const root=fileURLToPath(new URL('..',import.meta.url));
8
+ const binary=path.join(root,'bin','deadbyte-owner-token-r193.exe');
9
+
10
+ test('R193 native observer reports target process token and kernel creation identity',()=>{
11
+ const result=spawnSync(binary,['--inspect-pid',String(process.pid)],{
12
+ cwd:root,encoding:'utf8',windowsHide:true,timeout:10000,maxBuffer:256*1024});
13
+ assert.equal(result.status,0,result.stderr);
14
+ const report=JSON.parse(result.stdout);
15
+ assert.equal(report.schema,'deadbyte.r193-native-process-token.v1');
16
+ assert.equal(report.pid,process.pid);
17
+ assert.equal(report.alive,true);
18
+ assert.equal(report.identity_verified,true);
19
+ assert.match(report.creation_filetime_hex,/^[0-9a-f]{16}$/);
20
+ assert.equal(typeof report.elevated,'boolean');
21
+ assert.equal(typeof report.admin_enabled,'boolean');
22
+ assert.ok(Number.isSafeInteger(report.integrity_rid));
23
+ assert.equal(report.token_type,'primary');
24
+ assert.equal(report.owner_approved,false);
25
+ assert.equal(report.authority_granted,false);
26
+ });
27
+
28
+ test('R193 native observer rejects missing, malformed and nonexistent target PIDs',()=>{
29
+ for(const args of [['--inspect-pid'],['--inspect-pid','0'],['--inspect-pid','x'],
30
+ ['--inspect-pid','2147483647']]){
31
+ const result=spawnSync(binary,args,{cwd:root,encoding:'utf8',windowsHide:true,
32
+ timeout:10000,maxBuffer:256*1024});
33
+ assert.notEqual(result.status,0);
34
+ assert.doesNotMatch(result.stdout,/"identity_verified":true/);
35
+ }
36
+ });
@@ -0,0 +1,43 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {spawnSync} from 'node:child_process';
4
+ import {existsSync,readFileSync} from 'node:fs';
5
+ import {createHash} from 'node:crypto';
6
+ import path from 'node:path';
7
+ import {fileURLToPath} from 'node:url';
8
+
9
+ const root=fileURLToPath(new URL('..',import.meta.url));
10
+ const file=path.join(root,'bin','deadbyte-owner-token-r193.exe');
11
+ const binarySha='d554d732872f3d671fd2fb63c11fc0dac1f8cae377259c6d64dd0c5b3762f2b8';
12
+ const sha=x=>createHash('sha256').update(x).digest('hex');
13
+ const onlyWindows={skip:process.platform!=='win32'?'Windows token ABI required':false};
14
+
15
+ test('R193 native token inspection reports observed privilege, but never owner consent',onlyWindows,()=>{
16
+ assert.ok(existsSync(file),'compile R193 native Windows token gate before testing');
17
+ assert.equal(sha(readFileSync(file)),binarySha);
18
+ const result=spawnSync(file,['--report'],{encoding:'utf8',shell:false,timeout:10000});
19
+ assert.equal(result.status,0,result.stderr);
20
+ const v=JSON.parse(result.stdout);
21
+ assert.equal(v.schema,'deadbyte.r193-native-token.v1');
22
+ assert.equal(v.parent_independence_verified,false);
23
+ assert.equal(v.owner_approved,false);
24
+ assert.equal(v.authority_granted,false);
25
+ assert.equal(v.token_type,1);
26
+ const elevated=v.elevated||v.admin_enabled||v.integrity_rid>=12288;
27
+ assert.equal(v.status,elevated?'BLOCKED':'STANDARD_TOKEN_OBSERVED');
28
+ });
29
+
30
+ test('R193 native --require-standard denies elevated processes and honors limited tokens',onlyWindows,()=>{
31
+ const raw=spawnSync(file,['--require-standard'],{encoding:'utf8',shell:false,timeout:10000});
32
+ const v=JSON.parse(raw.stdout);
33
+ assert.equal(raw.status,v.status==='STANDARD_TOKEN_OBSERVED'?0:3,raw.stderr);
34
+ assert.equal(v.owner_approved,false);
35
+ assert.equal(v.authority_granted,false);
36
+ });
37
+
38
+ test('R193 native gate does not expose any grant subcommand',onlyWindows,()=>{
39
+ const raw=spawnSync(file,['--grant'],{encoding:'utf8',shell:false,timeout:10000});
40
+ assert.equal(raw.status,64);
41
+ assert.match(raw.stderr,/usage:/i);
42
+ assert.equal(raw.stdout,'');
43
+ });
@@ -0,0 +1,38 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {readFile} from 'node:fs/promises';
4
+ import {spawnSync} from 'node:child_process';
5
+ import {fileURLToPath} from 'node:url';
6
+ import path from 'node:path';
7
+ import {inspectTrustedInstallation,privilegedEpochInstallFiles} from '../src/privileged-install-trust-r89.mjs';
8
+ const root=fileURLToPath(new URL('..',import.meta.url));
9
+ test('R193 one-time enrollment has fixed owner path, no key export and no grant operation',async()=>{
10
+ const keygen=await readFile(path.join(root,'scripts','r193-owner-keygen.mjs'),'utf8');
11
+ const installer=await readFile(path.join(root,'scripts','r193-owner-uac-enroll-and-approve.ps1'),'utf8');
12
+ assert.match(keygen,/const OWNER='C:\\\\Program Files\\\\DEADBYTE-OwnerAuthority'/);
13
+ assert.match(keygen,/process\.argv\.length!==2/);
14
+ assert.match(keygen,/private_key_exported:false/);
15
+ assert.doesNotMatch(keygen,/issueR186AutonomousGrant|createAuthorityEpochStore|Arm-Autonomous|armautonomous/i);
16
+ assert.match(installer,/#requires -RunAsAdministrator/);
17
+ assert.match(installer,/SetAccessRuleProtection\(\$true,\$false\)/);
18
+ assert.doesNotMatch(installer,/BuiltinUsers|S-1-5-32-545|Users.*Read/i);
19
+ assert.match(installer,/FileMode\]::CreateNew/);
20
+ assert.match(installer,/Read-Host/);
21
+ assert.doesNotMatch(installer,/Start-Process.*-Verb\s+RunAs/i);
22
+ });
23
+ test('R193 keygen refuses mutable development bytes before creating owner material',async t=>{
24
+ let trusted=false;
25
+ try{
26
+ trusted=(await inspectTrustedInstallation(privilegedEpochInstallFiles(root,process.execPath))).trusted===true;
27
+ }catch{}
28
+ if(trusted){
29
+ t.skip('protected installation: executing keygen would cross the owner-enrollment boundary');
30
+ return;
31
+ }
32
+ const cli=path.join(root,'scripts','r193-owner-keygen.mjs');
33
+ const result=spawnSync(process.execPath,[cli],{cwd:root,encoding:'utf8',windowsHide:true,
34
+ timeout:20000,maxBuffer:256*1024});
35
+ assert.equal(result.status,2);
36
+ assert.match(result.stderr,/R89 privileged installation not protected|R193/i);
37
+ assert.equal(result.stdout,'');
38
+ });
@@ -0,0 +1,23 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {evaluateR193OwnerSecretAcl} from '../src/r193-owner-secret-acl.mjs';
4
+ const admin='S-1-5-32-544',system='S-1-5-18',users='S-1-5-32-545';
5
+ const files=['C:\\Program Files\\DEADBYTE-OwnerAuthority','C:\\Program Files\\DEADBYTE-OwnerAuthority\\owner-private.der'];
6
+ const records=()=>[
7
+ {path:files[0],owner:admin,reparse:false,protected:true,directory:true,
8
+ aces:[{sid:admin,type:'Allow',mask:0x1f01ff,inherited:false},{sid:system,type:'Allow',mask:0x1f01ff,inherited:false}]},
9
+ {path:files[1],owner:admin,reparse:false,protected:true,directory:false,
10
+ aces:[{sid:admin,type:'Allow',mask:0x1f01ff,inherited:false},{sid:system,type:'Allow',mask:0x1f01ff,inherited:false}]}
11
+ ];
12
+ test('R193 owner secret ACL accepts only protected Administrator and SYSTEM access',()=>{
13
+ assert.deepEqual(evaluateR193OwnerSecretAcl(records(),files),
14
+ {trusted:true,reason:'OWNER_SECRET_ADMIN_SYSTEM_ONLY'});
15
+ });
16
+ test('R193 owner secret ACL rejects Users read, inheritance, reparse and wrong owner',()=>{
17
+ const cases=[
18
+ x=>x[1].aces.push({sid:users,type:'Allow',mask:0x120089,inherited:false}),
19
+ x=>x[1].aces[0].inherited=true,x=>x[0].reparse=true,x=>x[0].owner=users
20
+ ];
21
+ for(const mutate of cases){const value=records();mutate(value);
22
+ assert.equal(evaluateR193OwnerSecretAcl(value,files).trusted,false);}
23
+ });