deadbyte-mcp 0.15.39 → 0.15.42
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.
- package/DEADBYTE-MCP.cmd +8 -4
- package/MANIFEST.SHA256 +99 -45
- package/PROVENANCE.json +90 -20
- package/README.txt +39 -18
- package/RELEASE.json +85 -20
- package/SBOM.cdx.json +2 -2
- package/TEST-MATRIX.json +134 -34
- package/bridge/package.json +1 -1
- package/controller/deadbyte-controller.ps1 +132 -12
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/R64-EVIDENCE.json +95 -0
- package/docs/R64-REFERENCE-GAP-MATRIX.json +98 -0
- package/docs/R64-SCOPE.json +41 -0
- package/docs/R65-AUTHORITY-CONTINUITY-DESIGN.json +27 -0
- package/docs/R65-REFERENCE-GAP-MATRIX.json +22 -0
- package/package.json +7 -4
- package/scripts/deploy-r48.mjs +123 -7
- package/scripts/gate-windows-r63-prepublish.ps1 +45 -0
- package/scripts/gate-windows-r64-prepublish.ps1 +68 -0
- package/scripts/gate-windows-r65-prepublish.ps1 +65 -0
- package/scripts/npm-publication-r65.mjs +139 -0
- package/scripts/npm-release-r48.mjs +62 -37
- package/scripts/r64-predecessor-reproducer.mjs +32 -0
- package/scripts/r64-read-benchmark.mjs +84 -0
- package/scripts/r65-canonical-full.mjs +45 -0
- package/scripts/r65-focused.mjs +37 -0
- package/scripts/verify-r65-parent-source.mjs +75 -0
- package/src/activation-continuity-engine-r65.mjs +225 -0
- package/src/activation-lock-r65.mjs +155 -0
- package/src/activation-preflight-r65.mjs +197 -0
- package/src/authority-continuity-r65.mjs +541 -0
- package/src/authority-epoch-cli-r65.mjs +10 -0
- package/src/autonomous-policy.mjs +7 -3
- package/src/coding-plane.mjs +12 -3
- package/src/compact-gateway-mcp-tools.mjs +1 -1
- package/src/deadbyte-cli.mjs +16 -2
- package/src/desktop-policy-r40.mjs +6 -3
- package/src/doctor-transactions-r58.mjs +1 -1
- package/src/host-plane.mjs +9 -3
- package/src/machine-fs-mcp-tools.mjs +1 -1
- package/src/machine-fs.mjs +7 -4
- package/src/process-policy.mjs +7 -4
- package/src/remote-authority.mjs +20 -1
- package/src/runtime-update.mjs +15 -5
- package/src/version.mjs +1 -1
- package/test/audit-context.test.mjs +15 -4
- package/test/autonomous-local-supervisor.test.mjs +7 -6
- package/test/autonomous-supervisor-integration.test.mjs +8 -7
- package/test/capability-resolver.test.mjs +11 -5
- package/test/codex-autonomous-r44.test.mjs +7 -6
- package/test/coding-observation.test.mjs +4 -3
- package/test/commander-real-parity-r47.test.mjs +5 -4
- package/test/commander-torture-r47.test.mjs +5 -4
- package/test/desktop-policy-r40.test.mjs +6 -4
- package/test/desktop-runtime-r40.test.mjs +8 -3
- package/test/host-inline-r45.test.mjs +4 -3
- package/test/machine-fs-runtime.test.mjs +4 -3
- package/test/process-longrun-r36.test.mjs +3 -2
- package/test/process-policy.test.mjs +10 -6
- package/test/process-runtime.test.mjs +9 -6
- package/test/r52-host-revocation.test.mjs +1 -0
- package/test/r59-tool-surface-compat.test.mjs +14 -4
- package/test/r62-release-contract.test.mjs +2 -1
- package/test/r63-one-shot-coherence.test.mjs +38 -0
- package/test/r63-release-contract.test.mjs +59 -0
- package/test/r64-machine-fs-large-read.test.mjs +136 -0
- package/test/r64-release-contract.test.mjs +52 -0
- package/test/r65-activation-lock-recovery.test.mjs +72 -0
- package/test/r65-activation-lock.test.mjs +59 -0
- package/test/r65-activation-orchestration.test.mjs +179 -0
- package/test/r65-activation-preflight.test.mjs +35 -0
- package/test/r65-authority-continuity-decision.test.mjs +58 -0
- package/test/r65-authority-durable-policy-binding.test.mjs +34 -0
- package/test/r65-authority-epoch-cli.test.mjs +125 -0
- package/test/r65-authority-epoch-races.test.mjs +87 -0
- package/test/r65-authority-epoch-recovery.test.mjs +82 -0
- package/test/r65-authority-epoch-store.test.mjs +94 -0
- package/test/r65-authority-fixture.mjs +41 -0
- package/test/r65-authority-grant-capture.test.mjs +37 -0
- package/test/r65-authority-observation-epoch.test.mjs +25 -0
- package/test/r65-authority-policy-envelope.test.mjs +46 -0
- package/test/r65-authority-restored-safe.test.mjs +75 -0
- package/test/r65-authority-runtime-epoch.test.mjs +115 -0
- package/test/r65-authority-runtime-policy-binding.test.mjs +29 -0
- package/test/r65-authority-test-trust.mjs +20 -0
- package/test/r65-cli-invocation.test.mjs +38 -0
- package/test/r65-controller-authority-epoch-live.test.mjs +100 -0
- package/test/r65-controller-authority-epoch.test.mjs +37 -0
- package/test/r65-deploy-preflight.test.mjs +55 -0
- package/test/r65-epoch-native-activation-integration.test.mjs +141 -0
- package/test/r65-epoch-native-continuity-engine.test.mjs +112 -0
- package/test/r65-epoch-native-cross-plane.test.mjs +95 -0
- package/test/r65-legacy-authority-migration.test.mjs +63 -0
- package/test/r65-legacy-auto-restore-rejection.test.mjs +17 -0
- package/test/r65-npm-publication.test.mjs +114 -0
- package/test/r65-parent-source-verifier.test.mjs +63 -0
- package/test/r65-release-contract.test.mjs +74 -0
- package/test/r65-transaction-precondition.test.mjs +36 -0
- package/test/remote-session-cli.test.mjs +13 -11
- package/test/standing-grants.test.mjs +20 -4
|
@@ -10,6 +10,7 @@ import { createMachineFsRuntime, verifyMachineFsReceiptFile } from '../src/machi
|
|
|
10
10
|
import { PROCESS_GRANT_SCHEMA, PROCESS_POLICY_SCHEMA, loadProcessPolicy } from '../src/process-policy.mjs';
|
|
11
11
|
import { createProcessRuntime } from '../src/process-runtime.mjs';
|
|
12
12
|
import { createCommanderWireAdapter } from '../src/commander-wire-adapter-r47.mjs';
|
|
13
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
13
14
|
|
|
14
15
|
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
15
16
|
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
|
@@ -17,13 +18,13 @@ const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
|
|
17
18
|
async function fsFixture(){
|
|
18
19
|
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-commander-real-fs-'));
|
|
19
20
|
const project=path.join(root,'project'); await mkdir(project);
|
|
20
|
-
const policyPath=path.join(root,'policy.json'), grantPath=path.join(root,'grant.json');
|
|
21
|
+
const policyPath=path.join(root,'policy.json'), grantPath=path.join(root,'runtime','grant.json');
|
|
21
22
|
const policy=await (async()=>{await writeFile(policyPath,JSON.stringify({
|
|
22
23
|
schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:grantPath,evidence_dir:path.join(root,'evidence'),
|
|
23
24
|
roots:{project:{path:project,read:true,write:true,exec:false,deny_paths:['blocked']}},
|
|
24
25
|
commands:{},max_read_bytes:65536,max_write_bytes:65536
|
|
25
26
|
})); return loadCodingPolicy(policyPath)})();
|
|
26
|
-
await
|
|
27
|
+
await writeBoundStandingGrant('coding', grantPath, {schema:'deadbyte.coding-grant.v2',policy_sha256:policy.policy_sha256,instance_nonce:'b'.repeat(64),root_ids:['project'],granted_at_utc:new Date().toISOString()});
|
|
27
28
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(root,'private.pem'),publicKeyPath:path.join(root,'public.pem')});
|
|
28
29
|
return {root,project,policy,keys,runtime:createMachineFsRuntime({policy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath})};
|
|
29
30
|
}
|
|
@@ -34,7 +35,7 @@ async function processFixture(){
|
|
|
34
35
|
const host=path.resolve('bin/deadbyte-process-host.exe'), exe='C:\\Windows\\System32\\cmd.exe';
|
|
35
36
|
const powershell='C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
|
|
36
37
|
const h=sha(await readFile(host)), e=sha(await readFile(exe)),ps=sha(await readFile(powershell));
|
|
37
|
-
const grantFile=path.join(root,'grant.json'), stateDir=path.join(root,'state'), policyPath=path.join(root,'policy.json');
|
|
38
|
+
const grantFile=path.join(root,'runtime','grant.json'), stateDir=path.join(root,'state'), policyPath=path.join(root,'policy.json');
|
|
38
39
|
await writeFile(policyPath,JSON.stringify({schema:PROCESS_POLICY_SCHEMA,enabled:true,grant_file:grantFile,state_dir:stateDir,
|
|
39
40
|
native_host:{path:host,sha256:h},roots:{core:{path:project,deny_paths:[]}},profiles:{
|
|
40
41
|
echo:{executable:exe,executable_sha256:e,root_ids:['core'],prefix_args:['/d','/c'],max_args:4,max_arg_bytes:256,max_sessions:2,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}},
|
|
@@ -42,7 +43,7 @@ async function processFixture(){
|
|
|
42
43
|
powershell_repl:{executable:powershell,executable_sha256:ps,root_ids:['core'],transport:'pipe',prefix_args:['-NoLogo','-NoProfile','-NonInteractive','-Command','-'],allow_raw_input:true,max_args:0,max_arg_bytes:256,max_sessions:2,max_input_bytes:8192,max_retained_output_bytes:2*1024*1024,env_allow:['PATH','TEMP','TMP'],input_actions:{}}
|
|
43
44
|
}}));
|
|
44
45
|
const policy=await loadProcessPolicy(policyPath);
|
|
45
|
-
await
|
|
46
|
+
await writeBoundStandingGrant('process', grantFile, {schema:PROCESS_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,instance_nonce:'a'.repeat(64),profile_ids:['echo','hold','powershell_repl'],root_ids:['core'],granted_at_utc:new Date().toISOString()});
|
|
46
47
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(trust,'private.pem'),publicKeyPath:path.join(trust,'public.pem')});
|
|
47
48
|
return {root,policy,keys,runtime:createProcessRuntime({policy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath})};
|
|
48
49
|
}
|
|
@@ -9,6 +9,7 @@ import { createMachineFsRuntime } from '../src/machine-fs.mjs';
|
|
|
9
9
|
import { PROCESS_GRANT_SCHEMA, PROCESS_POLICY_SCHEMA, loadProcessPolicy } from '../src/process-policy.mjs';
|
|
10
10
|
import { createProcessRuntime } from '../src/process-runtime.mjs';
|
|
11
11
|
import { createHash } from 'node:crypto';
|
|
12
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
12
13
|
|
|
13
14
|
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
14
15
|
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
|
@@ -16,10 +17,10 @@ const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
|
|
16
17
|
async function fsFixture(){
|
|
17
18
|
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-torture-fs-')), project=path.join(root,'project');
|
|
18
19
|
await mkdir(project);
|
|
19
|
-
const policyPath=path.join(root,'policy.json'), grantPath=path.join(root,'grant.json');
|
|
20
|
+
const policyPath=path.join(root,'policy.json'), grantPath=path.join(root,'runtime','grant.json');
|
|
20
21
|
await writeFile(policyPath,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:grantPath,evidence_dir:path.join(root,'evidence'),roots:{project:{path:project,read:true,write:true,exec:false,deny_paths:['blocked']}},commands:{},max_read_bytes:65536,max_write_bytes:65536}));
|
|
21
22
|
const policy=await loadCodingPolicy(policyPath);
|
|
22
|
-
await
|
|
23
|
+
await writeBoundStandingGrant('coding', grantPath, {schema:'deadbyte.coding-grant.v2',policy_sha256:policy.policy_sha256,instance_nonce:'c'.repeat(64),root_ids:['project'],granted_at_utc:new Date().toISOString()});
|
|
23
24
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(root,'private.pem'),publicKeyPath:path.join(root,'public.pem')});
|
|
24
25
|
return {root,project,runtime:createMachineFsRuntime({policy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath})};
|
|
25
26
|
}
|
|
@@ -28,13 +29,13 @@ async function processFixture(){
|
|
|
28
29
|
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-torture-proc-')), project=path.join(root,'project'),trust=path.join(root,'trust');
|
|
29
30
|
await mkdir(project); await mkdir(trust);
|
|
30
31
|
const host=path.resolve('bin/deadbyte-process-host.exe'), exe='C:\\Windows\\System32\\cmd.exe';
|
|
31
|
-
const grantFile=path.join(root,'grant.json'), stateDir=path.join(root,'state'), policyPath=path.join(root,'policy.json');
|
|
32
|
+
const grantFile=path.join(root,'runtime','grant.json'), stateDir=path.join(root,'state'), policyPath=path.join(root,'policy.json');
|
|
32
33
|
await writeFile(policyPath,JSON.stringify({schema:PROCESS_POLICY_SCHEMA,enabled:true,grant_file:grantFile,state_dir:stateDir,native_host:{path:host,sha256:sha(await readFile(host))},roots:{core:{path:project,deny_paths:[]}},profiles:{
|
|
33
34
|
echo:{executable:exe,executable_sha256:sha(await readFile(exe)),root_ids:['core'],prefix_args:['/d','/c'],max_args:4,max_arg_bytes:256,max_sessions:8,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}},
|
|
34
35
|
hold:{executable:exe,executable_sha256:sha(await readFile(exe)),root_ids:['core'],transport:'pipe',prefix_args:['/d','/q'],max_args:0,max_arg_bytes:256,max_sessions:8,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}}
|
|
35
36
|
}}));
|
|
36
37
|
const policy=await loadProcessPolicy(policyPath);
|
|
37
|
-
await
|
|
38
|
+
await writeBoundStandingGrant('process', grantFile, {schema:PROCESS_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,instance_nonce:'d'.repeat(64),profile_ids:['echo','hold'],root_ids:['core'],granted_at_utc:new Date().toISOString()});
|
|
38
39
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(trust,'private.pem'),publicKeyPath:path.join(trust,'public.pem')});
|
|
39
40
|
return {root,runtime:createProcessRuntime({policy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath})};
|
|
40
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtemp,writeFile } from 'node:fs/promises';
|
|
3
|
+
import { mkdtemp,mkdir,writeFile } from 'node:fs/promises';
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { createHash } from 'node:crypto';
|
|
@@ -8,12 +8,14 @@ import {
|
|
|
8
8
|
DESKTOP_POLICY_SCHEMA,DESKTOP_GRANT_SCHEMA,DESKTOP_ACTION_KINDS,
|
|
9
9
|
loadDesktopPolicy,desktopSessionStatus,assertDesktopArmed
|
|
10
10
|
} from '../src/desktop-policy-r40.mjs';
|
|
11
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
11
12
|
|
|
12
13
|
const H=value=>createHash('sha256').update(String(value)).digest('hex');
|
|
13
14
|
|
|
14
15
|
async function fixture(){
|
|
15
16
|
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r40-desktop-policy-'));
|
|
16
|
-
|
|
17
|
+
await mkdir(path.join(root,'runtime'));
|
|
18
|
+
const grant=path.join(root,'runtime','desktop-grant.json');
|
|
17
19
|
const evidence=path.join(root,'evidence');
|
|
18
20
|
const observer=path.join(root,'observer.exe');
|
|
19
21
|
const input=path.join(root,'input.exe');
|
|
@@ -57,10 +59,10 @@ test('desktop plane is fail-closed when no grant exists',async()=>{
|
|
|
57
59
|
|
|
58
60
|
test('desktop standing grant is policy-hash-bound and action-scoped',async()=>{
|
|
59
61
|
const {policy,grant}=await fixture();
|
|
60
|
-
await
|
|
62
|
+
await writeBoundStandingGrant('desktop', grant, {
|
|
61
63
|
schema:DESKTOP_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,instance_nonce:H('nonce'),
|
|
62
64
|
action_kinds:['pointer_move','click_primary']
|
|
63
|
-
})
|
|
65
|
+
});
|
|
64
66
|
const status=await desktopSessionStatus(policy);
|
|
65
67
|
assert.equal(status.armed,true);
|
|
66
68
|
assert.equal(status.reason,'standing-grant');
|
|
@@ -7,6 +7,7 @@ import path from 'node:path';
|
|
|
7
7
|
import { createDesktopFrame } from '../src/desktop-contract.mjs';
|
|
8
8
|
import { DESKTOP_POLICY_SCHEMA,DESKTOP_GRANT_SCHEMA } from '../src/desktop-policy-r40.mjs';
|
|
9
9
|
import { createDesktopRuntime,verifyDesktopReceiptObject } from '../src/desktop-runtime-r40.mjs';
|
|
10
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
10
11
|
|
|
11
12
|
const H=value=>createHash('sha256').update(String(value)).digest('hex');
|
|
12
13
|
const EPOCH=H('epoch');
|
|
@@ -21,7 +22,7 @@ function F(at,image=H('same'),window=WIN){
|
|
|
21
22
|
}
|
|
22
23
|
async function fixture({grantActions=['click_primary','text_input'],captureFrames=null,times=null,inputProvider=null,grounderProvider=null,clockMs=null,sleeper=null}={}){
|
|
23
24
|
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r40-desktop-runtime-'));
|
|
24
|
-
const grant=path.join(root,'grant.json'),evidence=path.join(root,'evidence');
|
|
25
|
+
const grant=path.join(root,'runtime','grant.json'),evidence=path.join(root,'evidence');
|
|
25
26
|
const policy={
|
|
26
27
|
schema:DESKTOP_POLICY_SCHEMA,enabled:true,policy_path:path.join(root,'policy.json'),
|
|
27
28
|
policy_sha256:H('policy'),grant_file:grant,evidence_dir:evidence,
|
|
@@ -31,9 +32,13 @@ async function fixture({grantActions=['click_primary','text_input'],captureFrame
|
|
|
31
32
|
allowed_actions:['pointer_move','click_primary','click_secondary','double_click_primary','scroll','key_chord','text_input'],
|
|
32
33
|
limits:{max_frame_age_ms:2000,max_frame_bytes:8*1024*1024,capture_timeout_ms:5000,input_timeout_ms:2000,post_observe_timeout_ms:5000,max_preview_bytes:512*1024,max_text_bytes:4096}
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
const {policy_path:policyPath,policy_sha256:_unusedSha,...rawPolicy}=policy;
|
|
36
|
+
const policyBytes=Buffer.from(JSON.stringify(rawPolicy));
|
|
37
|
+
await writeFile(policyPath,policyBytes);
|
|
38
|
+
policy.policy_sha256=createHash('sha256').update(policyBytes).digest('hex');
|
|
39
|
+
await writeBoundStandingGrant('desktop', grant, {
|
|
35
40
|
schema:DESKTOP_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,instance_nonce:H('grant-nonce'),action_kinds:grantActions
|
|
36
|
-
})
|
|
41
|
+
});
|
|
37
42
|
const expected=F('2026-09-19T02:00:00.000Z');
|
|
38
43
|
const frames=captureFrames??[
|
|
39
44
|
{frame:F('2026-09-19T02:00:00.700Z'),backend:'fake',byte_length:4},
|
|
@@ -7,13 +7,14 @@ import path from 'node:path';
|
|
|
7
7
|
import {
|
|
8
8
|
HOST_GRANT_SCHEMA, HOST_POLICY_SCHEMA_V2, hostExecInline, hostExecNative, loadHostPolicy
|
|
9
9
|
} from '../src/host-plane.mjs';
|
|
10
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
10
11
|
|
|
11
12
|
const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
12
13
|
|
|
13
14
|
async function fixture(){
|
|
14
15
|
const dir=await mkdtemp(path.join(os.tmpdir(),'deadbyte-host-inline-r45-'));
|
|
15
16
|
const root=path.join(dir,'root');await mkdir(root);
|
|
16
|
-
const arm=path.join(dir,'arm.json'), policyPath=path.join(dir,'policy.json');
|
|
17
|
+
const arm=path.join(dir,'runtime','arm.json'), policyPath=path.join(dir,'policy.json');
|
|
17
18
|
const exeSha=sha(await readFile(process.execPath));
|
|
18
19
|
const raw={
|
|
19
20
|
schema:HOST_POLICY_SCHEMA_V2,enabled:true,arm_file:arm,
|
|
@@ -27,8 +28,8 @@ async function fixture(){
|
|
|
27
28
|
};
|
|
28
29
|
await writeFile(policyPath,JSON.stringify(raw,null,2));
|
|
29
30
|
const policy=await loadHostPolicy(policyPath);
|
|
30
|
-
await
|
|
31
|
-
instance_nonce:randomBytes(32).toString('hex'),armed_at_utc:new Date().toISOString()},
|
|
31
|
+
await writeBoundStandingGrant('host', arm, {schema:HOST_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,
|
|
32
|
+
instance_nonce:randomBytes(32).toString('hex'),armed_at_utc:new Date().toISOString()},{space:2});
|
|
32
33
|
return {dir,root,arm,policy,exeSha};
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -7,6 +7,7 @@ import path from 'node:path';
|
|
|
7
7
|
import { generateTrustKeypair } from '../src/trust.mjs';
|
|
8
8
|
import { loadCodingPolicy } from '../src/coding-plane.mjs';
|
|
9
9
|
import { createMachineFsRuntime, verifyMachineFsReceiptFile } from '../src/machine-fs.mjs';
|
|
10
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
10
11
|
|
|
11
12
|
const sha = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
12
13
|
|
|
@@ -15,17 +16,17 @@ async function fixture({ readWorkerPath = undefined, listEntryLstat = undefined
|
|
|
15
16
|
const project = path.join(root, 'project');
|
|
16
17
|
await mkdir(project);
|
|
17
18
|
const policyPath = path.join(root, 'coding-policy.json');
|
|
18
|
-
const grantPath = path.join(root, 'coding-grant.json');
|
|
19
|
+
const grantPath = path.join(root, 'runtime', 'coding-grant.json');
|
|
19
20
|
await writeFile(policyPath, JSON.stringify({
|
|
20
21
|
schema: 'deadbyte.coding-policy.v1', enabled: true,
|
|
21
22
|
lease_file: grantPath, evidence_dir: path.join(root, 'evidence'),
|
|
22
23
|
roots: { project: { path: project, read: true, write: true, exec: false, deny_paths: ['blocked'] } },
|
|
23
24
|
commands: {}, max_read_bytes: 65536, max_write_bytes: 65536
|
|
24
25
|
})); const policy = await loadCodingPolicy(policyPath);
|
|
25
|
-
await
|
|
26
|
+
await writeBoundStandingGrant('coding', grantPath, {
|
|
26
27
|
schema: 'deadbyte.coding-grant.v2', policy_sha256: policy.policy_sha256,
|
|
27
28
|
instance_nonce: 'b'.repeat(64), root_ids: ['project'], granted_at_utc: new Date().toISOString()
|
|
28
|
-
})
|
|
29
|
+
});
|
|
29
30
|
const keys = await generateTrustKeypair({
|
|
30
31
|
privateKeyPath: path.join(root, 'private.pem'), publicKeyPath: path.join(root, 'public.pem')
|
|
31
32
|
});
|
|
@@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
8
8
|
import { PROCESS_GRANT_SCHEMA, PROCESS_POLICY_SCHEMA, loadProcessPolicy } from '../src/process-policy.mjs';
|
|
9
9
|
import { createProcessRuntime } from '../src/process-runtime.mjs';
|
|
10
10
|
import { generateTrustKeypair } from '../src/trust.mjs';
|
|
11
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
11
12
|
|
|
12
13
|
const repo=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
13
14
|
const host=path.join(repo,'bin','deadbyte-process-host.exe');
|
|
@@ -20,11 +21,11 @@ async function fixture(){
|
|
|
20
21
|
await mkdir(project); await mkdir(trust);
|
|
21
22
|
const script=path.join(project,'longrun.mjs');
|
|
22
23
|
await writeFile(script,`process.stdout.write('chunk-1\\n');\nsetTimeout(()=>process.stdout.write('chunk-2\\n'),180);\nsetTimeout(()=>process.stdout.write('chunk-3\\n'),360);\nsetTimeout(()=>process.exit(0),540);\n`);
|
|
23
|
-
const grantFile=path.join(root,'process-grant.json'); const stateDir=path.join(root,'state'); const policyPath=path.join(root,'process-policy.json');
|
|
24
|
+
const grantFile=path.join(root,'runtime','process-grant.json'); const stateDir=path.join(root,'state'); const policyPath=path.join(root,'process-policy.json');
|
|
24
25
|
const raw={schema:PROCESS_POLICY_SCHEMA,enabled:true,grant_file:grantFile,state_dir:stateDir,native_host:{path:host,sha256:sha(await readFile(host))},roots:{core:{path:project,deny_paths:[]}},profiles:{longrun:{executable:process.execPath,executable_sha256:sha(await readFile(process.execPath)),root_ids:['core'],transport:'pipe',prefix_args:[script],max_args:0,max_arg_bytes:256,max_sessions:1,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}}}};
|
|
25
26
|
await writeFile(policyPath,JSON.stringify(raw));
|
|
26
27
|
const policy=await loadProcessPolicy(policyPath);
|
|
27
|
-
await
|
|
28
|
+
await writeBoundStandingGrant('process', grantFile, {schema:PROCESS_GRANT_SCHEMA,policy_sha256:policy.policy_sha256,instance_nonce:'6'.repeat(64),profile_ids:['longrun'],root_ids:['core'],granted_at_utc:new Date().toISOString()});
|
|
28
29
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(trust,'private.pem'),publicKeyPath:path.join(trust,'public.pem')});
|
|
29
30
|
const make=()=>createProcessRuntime({policy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
|
|
30
31
|
return {root,project,stateDir,policy,keys,make,runtime:make()};
|
|
@@ -12,17 +12,19 @@ import {
|
|
|
12
12
|
processSessionStatus,
|
|
13
13
|
recheckProcessAuthority
|
|
14
14
|
} from '../src/process-policy.mjs';
|
|
15
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
15
16
|
|
|
16
17
|
const sha = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
17
18
|
|
|
18
19
|
async function fixture() {
|
|
19
20
|
const root = await mkdtemp(path.join(os.tmpdir(), 'deadbyte-process-policy-'));
|
|
21
|
+
await mkdir(path.join(root,'runtime'));
|
|
20
22
|
const project = path.join(root, 'project');
|
|
21
23
|
await mkdir(project);
|
|
22
24
|
const executable = process.execPath;
|
|
23
25
|
const executableSha = sha(await readFile(executable));
|
|
24
26
|
const policyPath = path.join(root, 'process-policy.json');
|
|
25
|
-
const grantFile = path.join(root, 'process-grant.json');
|
|
27
|
+
const grantFile = path.join(root, 'runtime', 'process-grant.json');
|
|
26
28
|
const stateDir = path.join(root, 'process-state'); const raw = {
|
|
27
29
|
schema: PROCESS_POLICY_SCHEMA, enabled: true, grant_file: grantFile, state_dir: stateDir,
|
|
28
30
|
native_host: { path: executable, sha256: executableSha },
|
|
@@ -52,14 +54,14 @@ test('process policy loads pinned native host, profile and root while grant is a
|
|
|
52
54
|
});test('process standing grant binds exact policy, profile and root', async () => {
|
|
53
55
|
const f = await fixture();
|
|
54
56
|
const policy = await loadProcessPolicy(f.policyPath);
|
|
55
|
-
await
|
|
57
|
+
await writeBoundStandingGrant('process', f.grantFile, {
|
|
56
58
|
schema: PROCESS_GRANT_SCHEMA,
|
|
57
59
|
policy_sha256: policy.policy_sha256,
|
|
58
60
|
instance_nonce: 'a'.repeat(64),
|
|
59
61
|
profile_ids: ['node'],
|
|
60
62
|
root_ids: ['core'],
|
|
61
63
|
granted_at_utc: '2026-09-14T00:00:00Z'
|
|
62
|
-
})
|
|
64
|
+
});
|
|
63
65
|
const status = await processSessionStatus(policy);
|
|
64
66
|
assert.equal(status.armed, true);
|
|
65
67
|
assert.equal(status.reason, 'standing-grant');
|
|
@@ -81,13 +83,15 @@ test('process authority recheck rejects grant generation or scope drift before s
|
|
|
81
83
|
root_ids: ['core'],
|
|
82
84
|
granted_at_utc: '2026-09-14T00:00:00Z'
|
|
83
85
|
};
|
|
84
|
-
await
|
|
86
|
+
await writeBoundStandingGrant('process', f.grantFile, grant);
|
|
85
87
|
const initial = await assertProcessArmed(policy, 'node', 'core');
|
|
86
88
|
await writeFile(f.grantFile, JSON.stringify({ ...grant, instance_nonce: 'b'.repeat(64) }));
|
|
87
89
|
await assert.rejects(() => recheckProcessAuthority(policy, initial, 'node', 'core'), /process authority changed during operation/);
|
|
88
90
|
await writeFile(f.grantFile, JSON.stringify({ ...grant, profile_ids: ['node', 'node'] }));
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
await assert.rejects(
|
|
92
|
+
() => recheckProcessAuthority(policy, initial, 'node', 'core'),
|
|
93
|
+
/process authority changed during operation|epoch-grant-mismatch/
|
|
94
|
+
);
|
|
91
95
|
});
|
|
92
96
|
|
|
93
97
|
test('process grant with wrong policy digest is disarmed', async () => {
|
|
@@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
8
8
|
import { PROCESS_GRANT_SCHEMA, PROCESS_POLICY_SCHEMA, loadProcessPolicy } from '../src/process-policy.mjs';
|
|
9
9
|
import { createProcessRuntime } from '../src/process-runtime.mjs';
|
|
10
10
|
import { generateTrustKeypair } from '../src/trust.mjs';
|
|
11
|
+
import { writeBoundStandingGrant } from './r65-authority-fixture.mjs';
|
|
11
12
|
|
|
12
13
|
const repo = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
13
14
|
const host = path.join(repo, 'bin', 'deadbyte-process-host.exe');
|
|
@@ -21,7 +22,7 @@ async function fixture() {
|
|
|
21
22
|
const project = path.join(root, 'project');
|
|
22
23
|
const trust = path.join(root, 'trust');
|
|
23
24
|
await mkdir(project); await mkdir(trust);
|
|
24
|
-
const grantFile = path.join(root, 'process-grant.json');
|
|
25
|
+
const grantFile = path.join(root, 'runtime', 'process-grant.json');
|
|
25
26
|
const stateDir = path.join(root, 'process-state');
|
|
26
27
|
const policyPath = path.join(root, 'process-policy.json');
|
|
27
28
|
const hostSha = sha(await readFile(host));
|
|
@@ -66,11 +67,11 @@ async function fixture() {
|
|
|
66
67
|
};
|
|
67
68
|
await writeFile(policyPath, JSON.stringify(raw));
|
|
68
69
|
const policy = await loadProcessPolicy(policyPath);
|
|
69
|
-
await
|
|
70
|
+
await writeBoundStandingGrant('process', grantFile, {
|
|
70
71
|
schema: PROCESS_GRANT_SCHEMA, policy_sha256: policy.policy_sha256,
|
|
71
72
|
instance_nonce: 'a'.repeat(64), profile_ids: ['echo', 'hold', 'conptyhold', 'powershell', 'powershell_repl'], root_ids: ['core'],
|
|
72
73
|
granted_at_utc: '2026-09-14T00:00:00Z'
|
|
73
|
-
})
|
|
74
|
+
});
|
|
74
75
|
const keys = await generateTrustKeypair({
|
|
75
76
|
privateKeyPath: path.join(trust, 'private.pem'), publicKeyPath: path.join(trust, 'public.pem')
|
|
76
77
|
});
|
|
@@ -99,9 +100,11 @@ test('R31 runtime starts one approved profile and exposes ordered bounded output
|
|
|
99
100
|
assert.equal(started.profile_id, 'echo');
|
|
100
101
|
assert.equal(started.stream_id, started.session_id);
|
|
101
102
|
assert.equal(started.stream_generation, 1);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// The child may emit its first chunk while start() persists the started
|
|
104
|
+
// event. Assert stream/coverage coherence, not an impossible empty-stream
|
|
105
|
+
// timing promise that fails only under parallel suite load.
|
|
106
|
+
assert.equal(started.stream_next_seq, started.stream_coverage.logical_item_count + 1);
|
|
107
|
+
assert.ok(started.stream_coverage.retained_item_count <= started.stream_coverage.logical_item_count);
|
|
105
108
|
assert.equal(started.stream_coverage.complete, true);
|
|
106
109
|
const observed = await waitFor(f.runtime, started.session_id, text => text.includes('DBR31RUNTIME:42'));
|
|
107
110
|
assert.match(observed.text, /DBR31RUNTIME:42/);
|
|
@@ -13,6 +13,7 @@ async function runRevoke(t,prelude){
|
|
|
13
13
|
// filesystem that refuses deletion while Test-Path still sees the grant.
|
|
14
14
|
const script=`$ErrorActionPreference='Stop'
|
|
15
15
|
function Get-HostPolicyMetadata($Cfg) { return @{ArmFile='fixture-host-grant'} }
|
|
16
|
+
function Invoke-AuthorityEpochCommand($Cfg,[string]$Plane,[string]$Action,[string]$GrantFile) { return @{} }
|
|
16
17
|
${prelude}
|
|
17
18
|
${source.slice(begin,end)}
|
|
18
19
|
try { Disarm-Host @{}; exit 0 } catch { Write-Output $_.Exception.Message; exit 7 }
|
|
@@ -71,7 +71,7 @@ async function captureCurrentSurface(){
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
test('R59 compact
|
|
74
|
+
test('R59 compact baseline changes only at the explicitly authorized R64 read-offset bound',async()=>{
|
|
75
75
|
const raw=JSON.parse(await readFile(fixturePath,'utf8'));
|
|
76
76
|
assert.equal(raw.schema,'deadbyte.tool-surface-baseline.v1');
|
|
77
77
|
assert.equal(raw.release_id,'v0.15.35-1b5715b276facbc0');
|
|
@@ -82,9 +82,19 @@ test('R59 compact client-visible tool names and schemas match sealed 0.15.35 bas
|
|
|
82
82
|
const diff=diffToolSurface(baseline,current);
|
|
83
83
|
assert.deepEqual(diff.added,[]);
|
|
84
84
|
assert.deepEqual(diff.removed,[]);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const packageVersion=JSON.parse(await readFile(path.join(repoRoot,'package.json'),'utf8')).version;
|
|
86
|
+
if(packageVersion==='0.15.41'||packageVersion==='0.15.42'){
|
|
87
|
+
assert.deepEqual(diff.schema_changed,['machine_fs']);
|
|
88
|
+
assert.equal(diff.unchanged.length,42);
|
|
89
|
+
const prior=baseline.tools.find(tool=>tool.name==='machine_fs');
|
|
90
|
+
const present=current.tools.find(tool=>tool.name==='machine_fs');
|
|
91
|
+
assert.equal(present.output_sha256,prior.output_sha256,'output contract must remain unchanged');
|
|
92
|
+
assert.notEqual(present.input_sha256,prior.input_sha256,'R64 must expose the widened read offset');
|
|
93
|
+
}else{
|
|
94
|
+
assert.deepEqual(diff.schema_changed,[]);
|
|
95
|
+
assert.equal(diff.unchanged.length,43);
|
|
96
|
+
assert.equal(current.surface_sha256,baseline.surface_sha256);
|
|
97
|
+
}
|
|
88
98
|
console.log(JSON.stringify({baseline_release:raw.release_id,surface_sha256:current.surface_sha256,
|
|
89
99
|
unchanged:diff.unchanged.length,added:diff.added,removed:diff.removed,schema_changed:diff.schema_changed}));
|
|
90
100
|
});
|
|
@@ -4,6 +4,7 @@ import {readFile} from 'node:fs/promises';
|
|
|
4
4
|
|
|
5
5
|
const read=rel=>readFile(new URL('../'+rel,import.meta.url),'utf8');
|
|
6
6
|
const json=rel=>read(rel).then(raw=>JSON.parse(raw.replace(/^\uFEFF/,'')));
|
|
7
|
+
const currentPackage=await json('package.json');
|
|
7
8
|
const PARENT={
|
|
8
9
|
version:'0.15.38',
|
|
9
10
|
release_id:'v0.15.38-917901b3fcb2a77f',
|
|
@@ -11,7 +12,7 @@ const PARENT={
|
|
|
11
12
|
generation_manifest_sha256:'9d320a8af1ba8e9e6a23552f35263da2670c00af1355464820552d849d9033c6'
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
test('R62 identity binds exact sealed 0.15.38 parent and transaction reconciliation scope',async()=>{
|
|
15
|
+
test('R62 identity binds exact sealed 0.15.38 parent and transaction reconciliation scope',{skip:currentPackage.version!=='0.15.39'},async()=>{
|
|
15
16
|
const [pkg,lock,bridge,release,provenance,matrix,sbom,version,gate]=await Promise.all([
|
|
16
17
|
json('package.json'),json('package-lock.json'),json('bridge/package.json'),json('RELEASE.json'),
|
|
17
18
|
json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs'),
|
|
@@ -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 path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
|
|
8
|
+
const authority=await import('../src/remote-authority.mjs');
|
|
9
|
+
|
|
10
|
+
test('R63 one-shot upgrade restore plan reproduces the exact pre-upgrade authority vector',()=>{
|
|
11
|
+
assert.equal(typeof authority.authorityRestorePlan,'function','authorityRestorePlan must exist');
|
|
12
|
+
const snapshot={
|
|
13
|
+
authority:{
|
|
14
|
+
process:{configured:true,armed:true,reason:'standing-grant'},
|
|
15
|
+
coding:{configured:true,armed:true,reason:'standing-grant'},
|
|
16
|
+
autonomous:{configured:true,armed:true,reason:'standing-grant'},
|
|
17
|
+
desktop:{configured:true,armed:false,reason:'disarmed'},
|
|
18
|
+
host:{configured:true,armed:true,reason:'standing-grant'}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
assert.deepEqual(authority.authorityRestorePlan(snapshot),[
|
|
22
|
+
'disarmdesktop',
|
|
23
|
+
'armprocess','armcoding','armautonomous','armhost'
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('R63 explicit remote command synchronizes runtime before dispatch instead of warn-only skew reporting',async()=>{
|
|
28
|
+
const source=await readFile(path.join(root,'src','deadbyte-cli.mjs'),'utf8');
|
|
29
|
+
const start=source.indexOf('async function runRemote(args){');
|
|
30
|
+
const end=source.indexOf('\nasync function runSupervisor(',start);
|
|
31
|
+
assert.ok(start>=0&&end>start,'runRemote source boundary missing');
|
|
32
|
+
const body=source.slice(start,end);
|
|
33
|
+
const sync=body.indexOf("await synchronizeOneShotRuntime(ctx,{displayMode:'ascii'});");
|
|
34
|
+
const dispatch=body.indexOf('invokeController(ctx,command,{allowFailure:true})');
|
|
35
|
+
assert.ok(sync>=0,'one-shot remote command must synchronize the active runtime');
|
|
36
|
+
assert.ok(dispatch>sync,'runtime synchronization must complete before controller dispatch');
|
|
37
|
+
assert.doesNotMatch(body,/reportVersionCoherence/,'warn-only skew path must not remain in one-shot dispatch');
|
|
38
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {readFile} from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
const read=rel=>readFile(new URL('../'+rel,import.meta.url),'utf8');
|
|
6
|
+
const json=rel=>read(rel).then(raw=>JSON.parse(raw.replace(/^\uFEFF/,'')));
|
|
7
|
+
const currentPackage=await json('package.json');
|
|
8
|
+
const PARENT={
|
|
9
|
+
version:'0.15.39',
|
|
10
|
+
release_id:'v0.15.39-3cda3b1c65b7b7c5',
|
|
11
|
+
manifest_sha256:'3cda3b1c65b7b7c561c5a8617156ab87d69cf162f447f3e99a4cb4a76471b3de',
|
|
12
|
+
generation_manifest_sha256:'f47cb96083679e764725df1bde6eda53169a39f55772c173ab22f89a1dfaa7ab'
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
test('R63 identity binds exact active 0.15.39 parent and one-shot runtime coherence repair',{skip:currentPackage.version!=='0.15.40'},async()=>{
|
|
16
|
+
const pkg=await json('package.json');
|
|
17
|
+
assert.equal(pkg.version,'0.15.40');
|
|
18
|
+
assert.match(pkg.scripts['r63:focused:test'],/r63-one-shot-coherence\.test\.mjs/);
|
|
19
|
+
assert.equal(pkg.scripts['gate:windows'],'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r63-prepublish.ps1');
|
|
20
|
+
|
|
21
|
+
const [lock,bridge,release,provenance,matrix,sbom,version,gate]=await Promise.all([
|
|
22
|
+
json('package-lock.json'),json('bridge/package.json'),json('RELEASE.json'),json('PROVENANCE.json'),
|
|
23
|
+
json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs'),read('scripts/gate-windows-r63-prepublish.ps1')
|
|
24
|
+
]);
|
|
25
|
+
assert.equal(lock.version,pkg.version);
|
|
26
|
+
assert.equal(lock.packages[''].version,pkg.version);
|
|
27
|
+
assert.equal(bridge.version,pkg.version);
|
|
28
|
+
assert.match(version,/DEADBYTE_VERSION = '0\.15\.40'/);
|
|
29
|
+
assert.equal(release.version,pkg.version);
|
|
30
|
+
assert.equal(release.train,'R63');
|
|
31
|
+
assert.equal(release.parent.version,PARENT.version);
|
|
32
|
+
assert.equal(release.parent.release_id,PARENT.release_id);
|
|
33
|
+
assert.equal(release.parent.manifest_sha256,PARENT.manifest_sha256);
|
|
34
|
+
assert.equal(release.parent.generation_manifest_sha256,PARENT.generation_manifest_sha256);
|
|
35
|
+
assert.deepEqual(release.runtime_predecessor,{
|
|
36
|
+
release_id:PARENT.release_id,
|
|
37
|
+
manifest_sha256:PARENT.manifest_sha256,
|
|
38
|
+
generation_manifest_sha256:PARENT.generation_manifest_sha256
|
|
39
|
+
});
|
|
40
|
+
assert.equal(provenance.version,pkg.version);
|
|
41
|
+
assert.equal(provenance.parent_release_id,PARENT.release_id);
|
|
42
|
+
assert.equal(provenance.parent_manifest_sha256,PARENT.manifest_sha256);
|
|
43
|
+
assert.equal(provenance.parent_generation_manifest_sha256,PARENT.generation_manifest_sha256);
|
|
44
|
+
assert.equal(matrix.version,pkg.version);
|
|
45
|
+
assert.equal(matrix.train,'R63');
|
|
46
|
+
assert.equal(sbom.metadata.component.version,pkg.version);
|
|
47
|
+
assert.equal(sbom.serialNumber,'urn:cdx:deadbyte-mcp:r63:0.15.40');
|
|
48
|
+
assert.equal(release.r63_one_shot_runtime_coherence.public_surface_tool_count,43);
|
|
49
|
+
assert.equal(release.r63_one_shot_runtime_coherence.new_authority_scopes,0);
|
|
50
|
+
assert.equal(release.r63_one_shot_runtime_coherence.one_shot_auto_coherence,true);
|
|
51
|
+
assert.equal(release.r63_one_shot_runtime_coherence.pre_upgrade_authority_snapshot,true);
|
|
52
|
+
assert.equal(release.r63_one_shot_runtime_coherence.exact_authority_restore_verified,true);
|
|
53
|
+
assert.equal(release.r63_one_shot_runtime_coherence.warn_only_skew_path_removed,true);
|
|
54
|
+
assert.equal(release.r63_one_shot_runtime_coherence.stable_final_claim,false);
|
|
55
|
+
assert.match(gate,/v0\.15\.39-3cda3b1c65b7b7c5/);
|
|
56
|
+
assert.match(gate,/3cda3b1c65b7b7c561c5a8617156ab87d69cf162f447f3e99a4cb4a76471b3de/);
|
|
57
|
+
assert.match(gate,/f47cb96083679e764725df1bde6eda53169a39f55772c173ab22f89a1dfaa7ab/);
|
|
58
|
+
assert.match(gate,/r63:focused:test/);
|
|
59
|
+
});
|