deadbyte-mcp 0.10.0 → 0.11.1
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/MANIFEST.SHA256 +81 -59
- package/README.txt +13 -14
- package/bin/WORKER-REGISTRY.txt +3 -3
- package/bin/appcontainer-stage.exe +0 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.exe +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.exe +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.exe +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.exe +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.exe +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.exe +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.exe +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.exe +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.exe +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.exe +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.exe +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.exe +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +3 -3
- package/controller/deadbyte-controller.ps1 +1 -1
- package/controller/deadbyte-process-policy.json +1 -1
- package/docs/ARCHITECTURE.md +1 -1
- package/package.json +1 -1
- package/scripts/build-containment.ps1 +15 -15
- package/scripts/deferred-slot-operation-r37-0110.mjs +124 -0
- package/scripts/deferred-slot-operation.mjs +1 -1
- package/scripts/final-closure-r36.mjs +113 -0
- package/scripts/final-closure-r37-0110.mjs +113 -0
- package/scripts/final-closure-verify-r36.mjs +208 -0
- package/scripts/final-closure-verify-r37-0110.mjs +208 -0
- package/scripts/final-closure-verify.mjs +48 -48
- package/scripts/final-closure.mjs +13 -13
- package/scripts/gate-windows-r36.ps1 +42 -0
- package/scripts/gate-windows-r37-0110.ps1 +42 -0
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/release-parity-r36.mjs +200 -0
- package/scripts/release-parity-r37-0110.mjs +200 -0
- package/scripts/release-parity-tests.ps1 +2 -2
- package/scripts/release-parity.mjs +37 -37
- package/scripts/windows-gate-evidence-r36.mjs +52 -0
- package/scripts/windows-gate-evidence-r37-0110.mjs +52 -0
- package/scripts/windows-gate-evidence.mjs +5 -5
- package/src/agent-memory-plane.mjs +98 -0
- package/src/autonomous-output-contracts.mjs +5 -2
- package/src/autonomous-runtime.mjs +155 -31
- package/src/autonomous-timeout-recovery.mjs +27 -0
- package/src/deadbyte-cli.mjs +90 -94
- package/src/effect-ledger.mjs +47 -0
- package/src/observation-lease.mjs +32 -0
- package/src/remote-live-log.mjs +81 -0
- package/src/remote-mcp-autonomous-smoke-client.mjs +15 -9
- package/src/remote-result-journal.mjs +23 -4
- package/src/version.mjs +1 -1
- package/src/worker-scheduler.mjs +53 -0
- package/test/autonomous-output-contract.test.mjs +1 -1
- package/test/cli-entrypoint.test.mjs +9 -0
- package/test/containment.test.mjs +18 -0
- package/test/core.test.mjs +1 -1
- package/test/production-docs.test.mjs +5 -5
- package/test/r33-closeout-regression.test.mjs +4 -4
- package/test/r33-finalization.test.mjs +6 -6
- package/test/r36-finalization.test.mjs +5 -5
- package/test/r36-release-identity.test.mjs +12 -19
- package/test/r37-0110-history.test.mjs +20 -0
- package/test/r37-agent-fabric.test.mjs +92 -0
- package/test/r37-autonomous-timeout-recovery.test.mjs +60 -0
- package/test/r37-finalization.test.mjs +74 -0
- package/test/r37-remote-tool-call-timeline.test.mjs +94 -0
- package/test/release-version.test.mjs +35 -36
- package/test/remote-live-log-r37.test.mjs +50 -0
- package/test/remote-session-cli.test.mjs +86 -68
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { canonicalJson } from './canonical-json.mjs';
|
|
3
|
+
|
|
4
|
+
export const WORKER_SCHEDULER_SCHEMA='deadbyte.worker-scheduler.v1';
|
|
5
|
+
const sha=value=>createHash('sha256').update(Buffer.from(canonicalJson(value),'utf8')).digest('hex');
|
|
6
|
+
|
|
7
|
+
export function createWorkerScheduler({maxConcurrent=1,totalCpuUnits=1,totalMemoryMb=1024,leaseMs=60000,clock=()=>Date.now()}={}){
|
|
8
|
+
if(!Number.isInteger(maxConcurrent)||maxConcurrent<1) throw new Error('maxConcurrent invalid');
|
|
9
|
+
if(!Number.isInteger(totalCpuUnits)||totalCpuUnits<1) throw new Error('totalCpuUnits invalid');
|
|
10
|
+
if(!Number.isInteger(totalMemoryMb)||totalMemoryMb<1) throw new Error('totalMemoryMb invalid');
|
|
11
|
+
if(!Number.isInteger(leaseMs)||leaseMs<100) throw new Error('leaseMs invalid');
|
|
12
|
+
const active=new Map(),attempts=new Map(),history=[];
|
|
13
|
+
function reclaim(){
|
|
14
|
+
const now=clock();
|
|
15
|
+
for(const [id,lease] of active) if(lease.expires_at_ms<=now){
|
|
16
|
+
active.delete(id);history.push({...lease,status:'expired',released_at_ms:now});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function usage(){
|
|
20
|
+
return [...active.values()].reduce((x,l)=>({cpu:x.cpu+l.cpu_units,memory:x.memory+l.memory_mb}),{cpu:0,memory:0});
|
|
21
|
+
}
|
|
22
|
+
function snapshot(){
|
|
23
|
+
reclaim();
|
|
24
|
+
const used=usage();
|
|
25
|
+
return Object.freeze({schema:WORKER_SCHEDULER_SCHEMA,max_concurrent:maxConcurrent,total_cpu_units:totalCpuUnits,total_memory_mb:totalMemoryMb,
|
|
26
|
+
active:[...active.values()].sort((a,b)=>a.lease_id.localeCompare(b.lease_id,'en')),
|
|
27
|
+
history:[...history],used_cpu_units:used.cpu,used_memory_mb:used.memory});
|
|
28
|
+
}
|
|
29
|
+
function acquire({taskId,workerClass,cpuUnits=1,memoryMb=128}){
|
|
30
|
+
reclaim();
|
|
31
|
+
if(typeof taskId!=='string'||!taskId) throw new Error('taskId invalid');
|
|
32
|
+
if(typeof workerClass!=='string'||!workerClass) throw new Error('workerClass invalid');
|
|
33
|
+
if(!Number.isInteger(cpuUnits)||cpuUnits<1||!Number.isInteger(memoryMb)||memoryMb<1) throw new Error('worker resources invalid');
|
|
34
|
+
const used=usage();
|
|
35
|
+
if(active.size>=maxConcurrent||used.cpu+cpuUnits>totalCpuUnits||used.memory+memoryMb>totalMemoryMb) throw new Error('worker scheduler capacity exceeded');
|
|
36
|
+
const attempt=(attempts.get(taskId)??0)+1;attempts.set(taskId,attempt);
|
|
37
|
+
const issued=clock(),expires=issued+leaseMs;
|
|
38
|
+
const body={schema:'deadbyte.worker-lease.v1',task_id:taskId,worker_class:workerClass,attempt,cpu_units:cpuUnits,memory_mb:memoryMb,issued_at_ms:issued,expires_at_ms:expires};
|
|
39
|
+
const lease=Object.freeze({...body,lease_id:sha(body)});
|
|
40
|
+
active.set(lease.lease_id,lease);
|
|
41
|
+
return lease;
|
|
42
|
+
}
|
|
43
|
+
function heartbeat(leaseId){
|
|
44
|
+
reclaim();const current=active.get(leaseId);if(!current) throw new Error('worker lease unavailable');
|
|
45
|
+
const next=Object.freeze({...current,expires_at_ms:clock()+leaseMs});active.set(leaseId,next);return next;
|
|
46
|
+
}
|
|
47
|
+
function release(leaseId,{status='completed'}={}){
|
|
48
|
+
reclaim();const lease=active.get(leaseId);if(!lease) throw new Error('worker lease unavailable');
|
|
49
|
+
active.delete(leaseId);const item={...lease,status,released_at_ms:clock()};history.push(item);
|
|
50
|
+
return Object.freeze({status:'released',lease:item});
|
|
51
|
+
}
|
|
52
|
+
return Object.freeze({acquire,heartbeat,release,snapshot});
|
|
53
|
+
}
|
|
@@ -48,7 +48,7 @@ test('R34 run/status output contracts accept only the sanitized public loop proj
|
|
|
48
48
|
assert.equal(run.structuredContent.loop.phase,'ACTING');
|
|
49
49
|
const status = autonomousStructuredResult(autonomousGoalStatusOutputSchema,{
|
|
50
50
|
status:'ok',goal_id:'1'.repeat(64),goal_sha256:'2'.repeat(64),title:'x',root_id:'project',journal_verified:true,
|
|
51
|
-
|
|
51
|
+
run_busy:false,run_owner_pid:null,run_lock_created_at_utc:null,...baseDerived(),loop:publicLoop
|
|
52
52
|
});
|
|
53
53
|
assert.equal(status.structuredContent.loop.pending_action.kind,'patch');
|
|
54
54
|
const approved = autonomousStructuredResult(autonomousGoalApproveOutputSchema,{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
|
|
@@ -16,6 +17,14 @@ test('package exposes npx-first deadbyte-mcp bin and is registry-publishable',as
|
|
|
16
17
|
assert.equal(pkg.publishConfig?.access,'public');
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
test('npx CLI reports the canonical package version through --version, -v and version',()=>{
|
|
21
|
+
for(const arg of ['--version','-v','version']){
|
|
22
|
+
const result=spawnSync(process.execPath,[cliPath,arg],{cwd:root,encoding:'utf8',windowsHide:true});
|
|
23
|
+
assert.equal(result.status,0,result.stderr);
|
|
24
|
+
assert.equal(result.stdout.trim(),'0.11.1');
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
19
28
|
test('npx CLI remote path invokes stable PS1 directly and never routes through CMD',async()=>{
|
|
20
29
|
const source=await readFile(cliPath,'utf8');
|
|
21
30
|
assert.match(source,/^#!\/usr\/bin\/env node/m);
|
|
@@ -230,6 +230,24 @@ test('native build script targets Windows 10 and preserves MSVC diagnostics', as
|
|
|
230
230
|
assert.doesNotMatch(source, /\$VsWhere = Join-Path \$\{env:ProgramFiles\(x86\)\}/);
|
|
231
231
|
});
|
|
232
232
|
|
|
233
|
+
test('native build is reproducible at both MSVC object and linker boundaries', async () => {
|
|
234
|
+
const buildScript = fileURLToPath(new URL('../scripts/build-containment.ps1', import.meta.url));
|
|
235
|
+
const source = await readFile(buildScript, 'utf8');
|
|
236
|
+
const lines = source.split(/\r?\n/);
|
|
237
|
+
const commonLine = lines.find(line => line.startsWith('$Common ='));
|
|
238
|
+
const bootstrapLine = lines.find(line => line.startsWith('$BootstrapCommon ='));
|
|
239
|
+
assert.ok(commonLine?.includes('/Brepro'), 'common compiler flags must include /Brepro');
|
|
240
|
+
assert.ok(bootstrapLine?.includes('/Brepro'), 'bootstrap compiler flags must include /Brepro');
|
|
241
|
+
for (const name of [
|
|
242
|
+
'Launcher','Probe','BootstrapKernel','BootstrapAdvapi','StageLauncher','BootstrapExit',
|
|
243
|
+
'ChildControlStage','ChildControlProbe','ContainedLauncher','ContainedWorker',
|
|
244
|
+
'ContainedReverseWorker','TunnelHost','ProcessHost'
|
|
245
|
+
]) {
|
|
246
|
+
const line = lines.find(candidate => candidate.startsWith(`$${name}Command =`));
|
|
247
|
+
assert.ok(line?.includes('/link /Brepro /INCREMENTAL:NO'), `${name} linker flags must be reproducible and non-incremental`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
233
251
|
|
|
234
252
|
|
|
235
253
|
test('native build command composition is Windows PowerShell 5.1 parser-safe', async () => {
|
package/test/core.test.mjs
CHANGED
|
@@ -105,7 +105,7 @@ test('proof execution creates deterministic output and signed verifiable receipt
|
|
|
105
105
|
assert.equal(result.receipt.request.schema, 'deadbyte.request.v1');
|
|
106
106
|
assert.match(result.receipt.request.nonce, /^[0-9a-f]{64}$/);
|
|
107
107
|
assert.match(result.receipt.request.sha256, /^[0-9a-f]{64}$/);
|
|
108
|
-
assert.equal(result.receipt.runtime.package_version, '0.
|
|
108
|
+
assert.equal(result.receipt.runtime.package_version, '0.11.1');
|
|
109
109
|
assert.match(result.receipt.runtime.mcp_ingress_adapter, /^(?:none|tunnel-stdio-probe-compat-v1)$/);
|
|
110
110
|
assert.match(result.receipt.runtime.mcp_ingress_adapter_sha256, /^[0-9a-f]{64}$/);
|
|
111
111
|
assert.match(result.receipt.runtime.mcp_ingress_mode_source_sha256, /^[0-9a-f]{64}$/);
|
|
@@ -9,9 +9,9 @@ const readme=()=>readFile(path.join(root,'README.txt'),'utf8');
|
|
|
9
9
|
|
|
10
10
|
test('production README documents one-command stdio configs for major MCP clients',async()=>{
|
|
11
11
|
const text=await readme();
|
|
12
|
-
assert.match(text,/npx -y deadbyte-mcp@0\.
|
|
12
|
+
assert.match(text,/npx -y deadbyte-mcp@0\.11\.1 mcp/);
|
|
13
13
|
assert.match(text,/CLAUDE DESKTOP/);
|
|
14
|
-
assert.match(text,/"mcpServers"[\s\S]*?"command"\s*:\s*"npx"[\s\S]*?"-y"[\s\S]*?"deadbyte-mcp@0\.
|
|
14
|
+
assert.match(text,/"mcpServers"[\s\S]*?"command"\s*:\s*"npx"[\s\S]*?"-y"[\s\S]*?"deadbyte-mcp@0\.11\.1"[\s\S]*?"mcp"/);
|
|
15
15
|
assert.match(text,/CURSOR/);
|
|
16
16
|
assert.match(text,/\.cursor\/mcp\.json/);
|
|
17
17
|
assert.match(text,/VS CODE/);
|
|
@@ -20,7 +20,7 @@ test('production README documents one-command stdio configs for major MCP client
|
|
|
20
20
|
assert.match(text,/CODEX/);
|
|
21
21
|
assert.match(text,/\[mcp_servers\.deadbyte\]/);
|
|
22
22
|
assert.match(text,/command\s*=\s*"npx"/);
|
|
23
|
-
assert.match(text,/args\s*=\s*\["-y",\s*"deadbyte-mcp@0\.
|
|
23
|
+
assert.match(text,/args\s*=\s*\["-y",\s*"deadbyte-mcp@0\.11\.1",\s*"mcp"\]/);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
test('production README records tracer bullet, semantic scope, remote UX, safety and document extension',async()=>{
|
|
@@ -29,8 +29,8 @@ test('production README records tracer bullet, semantic scope, remote UX, safety
|
|
|
29
29
|
for(const token of ['coding_files_read','coding_symbol_outline','coding_symbol_definition','coding_symbol_references','coding_symbol_replace']) assert.match(text,new RegExp(token));
|
|
30
30
|
assert.match(text,/JavaScript\/TypeScript|JS\/TS/);
|
|
31
31
|
assert.match(text,/does not claim|not claim|limited to/i);
|
|
32
|
-
assert.
|
|
33
|
-
assert.match(text,/
|
|
32
|
+
assert.doesNotMatch(text,/remote --verbose/);
|
|
33
|
+
assert.match(text,/unified live timeline/i);
|
|
34
34
|
assert.match(text,/workspace allowlist|coding-policy root/i);
|
|
35
35
|
assert.match(text,/destructive|standing grant|authority plane/i);
|
|
36
36
|
assert.match(text,/document adapter/i);
|
|
@@ -86,7 +86,7 @@ test('audit restart reconciles an orphan request with an explicit interrupted re
|
|
|
86
86
|
}finally{await rm(stateRoot,{recursive:true,force:true});}
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
test('Windows
|
|
89
|
+
test('Windows R37 gate emits manifest-bound machine-readable evidence outside the candidate tree', async()=>{
|
|
90
90
|
const stateRoot=await temp('deadbyte-r33-windows-evidence-');
|
|
91
91
|
try{
|
|
92
92
|
const gate=await readFile(path.join(root,'scripts','gate-windows.ps1'),'utf8');
|
|
@@ -99,12 +99,12 @@ test('Windows R36 gate emits manifest-bound machine-readable evidence outside th
|
|
|
99
99
|
assert.equal(summary.status,'written');
|
|
100
100
|
const evidence=JSON.parse(await readFile(summary.path,'utf8'));
|
|
101
101
|
const manifestSha=sha256(await readFile(path.join(root,'MANIFEST.SHA256')));
|
|
102
|
-
assert.equal(evidence.schema,'deadbyte.
|
|
102
|
+
assert.equal(evidence.schema,'deadbyte.r37-windows-gate.v1');
|
|
103
103
|
assert.equal(evidence.status,'passed');
|
|
104
104
|
assert.equal(evidence.exit_code,0);
|
|
105
|
-
assert.equal(evidence.version,'0.
|
|
105
|
+
assert.equal(evidence.version,'0.11.1');
|
|
106
106
|
assert.equal(evidence.manifest_sha256,manifestSha);
|
|
107
|
-
assert.equal(evidence.marker,'DEADBYTE V0.
|
|
107
|
+
assert.equal(evidence.marker,'DEADBYTE V0.11.1 / R37 WINDOWS BATCH GATE: PASS');
|
|
108
108
|
assert.ok(summary.path.startsWith(path.join(stateRoot,'evidence','release')));
|
|
109
109
|
}finally{await rm(stateRoot,{recursive:true,force:true});}
|
|
110
110
|
});
|
|
@@ -26,17 +26,17 @@ test('release parity and final verifier are package entry points', async () => {
|
|
|
26
26
|
assert.equal(typeof verifyFinalClosureObject, 'function');
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
test('
|
|
29
|
+
test('R37 final closure verifier is implementation-independent from production helpers', async () => {
|
|
30
30
|
const verifier = await text('scripts/final-closure-verify.mjs');
|
|
31
31
|
const writer = await text('scripts/final-closure.mjs');
|
|
32
32
|
assert.doesNotMatch(verifier, /from ['"]\.\.\/src\//);
|
|
33
33
|
assert.match(verifier, /DEADBYTE-R27-SLOT-UPDATE-V1/);
|
|
34
34
|
assert.match(verifier, /DEADBYTE-MACHINE-PING-V1/);
|
|
35
|
-
assert.match(verifier, /DEADBYTE-
|
|
36
|
-
assert.match(writer, /pointer\.version==='0\.
|
|
37
|
-
assert.match(verifier, /envelope\.body\.version==='0\.
|
|
38
|
-
assert.match(verifier, /release_label==='
|
|
39
|
-
assert.match(verifier, /
|
|
35
|
+
assert.match(verifier, /DEADBYTE-R37-FINAL-CLOSURE-V1/);
|
|
36
|
+
assert.match(writer, /pointer\.version==='0\.11\.1'/);
|
|
37
|
+
assert.match(verifier, /envelope\.body\.version==='0\.11\.1'/);
|
|
38
|
+
assert.match(verifier, /release_label==='R37 FINAL MACHINE BASELINE'/);
|
|
39
|
+
assert.match(verifier, /08c2a0008b1f84c90f7ce7faa1e3decbd03f33612bc0fdc7d1ba591b548798e8/);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
test('final closure verifier canonicalizes traversal order before exact-tree comparison', async () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import { validateParityEvidence, R35_PREDECESSOR_RELEASE_ID, R35_PREDECESSOR_MANIFEST } from '../scripts/release-parity.mjs';
|
|
5
|
-
import { verifyFinalClosureObject } from '../scripts/final-closure-verify.mjs';
|
|
4
|
+
import { validateParityEvidence, R35_PREDECESSOR_RELEASE_ID, R35_PREDECESSOR_MANIFEST } from '../scripts/release-parity-r36.mjs';
|
|
5
|
+
import { verifyFinalClosureObject } from '../scripts/final-closure-verify-r36.mjs';
|
|
6
6
|
|
|
7
7
|
const root=new URL('../',import.meta.url);
|
|
8
8
|
const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
@@ -45,7 +45,7 @@ test('R36 compact disarmed probe carries signed machine status/ping evidence int
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
test('R36 parity captures exact successor bridge before rollback and reuses it for restore',async()=>{
|
|
48
|
-
const parity=await text('scripts/release-parity.mjs');
|
|
48
|
+
const parity=await text('scripts/release-parity-r36.mjs');
|
|
49
49
|
assert.match(parity,/loadPowerShellDataFile/);
|
|
50
50
|
assert.match(parity,/successorBridge/);
|
|
51
51
|
assert.match(parity,/Bridge\?\.WorkingDirectory/);
|
|
@@ -72,7 +72,7 @@ test('R36 compact parity treats stale machine-fs precondition denial as expected
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
test('R36 final closure writer binds compact public evidence and R36 release evidence domains',async()=>{
|
|
75
|
-
const writer=await text('scripts/final-closure.mjs');
|
|
75
|
+
const writer=await text('scripts/final-closure-r36.mjs');
|
|
76
76
|
assert.match(writer,/DEADBYTE-R36-FINAL-CLOSURE-V1/);
|
|
77
77
|
assert.match(writer,/deadbyte\.r36-final-closure\.v1/);
|
|
78
78
|
assert.match(writer,/pointer\.version==='0\.10\.0'/);
|
|
@@ -86,7 +86,7 @@ test('R36 final closure writer binds compact public evidence and R36 release evi
|
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
test('R36 independent closure verifier binds full, compact, predecessor, restore, Windows gate and immutable slot',async()=>{
|
|
89
|
-
const verifier=await text('scripts/final-closure-verify.mjs');
|
|
89
|
+
const verifier=await text('scripts/final-closure-verify-r36.mjs');
|
|
90
90
|
assert.equal(typeof verifyFinalClosureObject,'function');
|
|
91
91
|
assert.doesNotMatch(verifier,/from ['"]\.\.\/src\//);
|
|
92
92
|
assert.match(verifier,/DEADBYTE-R36-FINAL-CLOSURE-V1/);
|
|
@@ -6,35 +6,28 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const R35_RELEASE_ID='v0.9.0-b95e1ec1d9a7e26a';
|
|
8
8
|
const R35_MANIFEST='b95e1ec1d9a7e26a96ef492306c1be4df18c883ff03ab3b6015f677d7429ec8d';
|
|
9
|
+
const R36_RELEASE_ID='v0.10.0-8d1e5f09745e7647';
|
|
10
|
+
const R36_MANIFEST='8d1e5f09745e764796b60e0a8a0168be7334ed4bf834fad5974a80eba295b4e8';
|
|
9
11
|
|
|
10
|
-
test('R36
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
text('
|
|
14
|
-
text('
|
|
15
|
-
text('scripts/deferred-slot-operation.mjs'),text('scripts/release-parity.mjs'),text('scripts/final-closure.mjs'),
|
|
16
|
-
text('scripts/final-closure-verify.mjs'),text('scripts/windows-gate-evidence.mjs')
|
|
12
|
+
test('sealed R36 historical proof scripts preserve 0.10.0 / R36 and exact R35 predecessor',async()=>{
|
|
13
|
+
const [gate,parity,closure,closureVerify,windowsGate,r37_0110Parity]=await Promise.all([
|
|
14
|
+
text('scripts/gate-windows-r36.ps1'),text('scripts/release-parity-r36.mjs'),
|
|
15
|
+
text('scripts/final-closure-r36.mjs'),text('scripts/final-closure-verify-r36.mjs'),
|
|
16
|
+
text('scripts/windows-gate-evidence-r36.mjs'),text('scripts/release-parity-r37-0110.mjs')
|
|
17
17
|
]);
|
|
18
|
-
assert.equal(pkg.version,'0.10.0');
|
|
19
|
-
assert.match(version,/DEADBYTE_VERSION = '0\.10\.0'/);
|
|
20
|
-
assert.match(controller,/CONTROLLER V0\.10\.0 \/ R36/);
|
|
21
18
|
assert.match(gate,/DEADBYTE V0\.10\.0 \/ R36 WINDOWS BATCH GATE: PASS/);
|
|
22
|
-
assert.match(readme,/^DEADBYTE MCP V0\.10\.0 \/ R36 PRODUCTION BASELINE$/m);
|
|
23
|
-
assert.match(architecture,/^# DEADBYTE MCP V0\.10\.0 \/ R36 ARCHITECTURE$/m);
|
|
24
|
-
assert.match(controllerReadme,/^DEADBYTE MCP V0\.10\.0 \/ R36 CONTROLLER$/m);
|
|
25
|
-
assert.match(deferred,/--expected-version','0\.10\.0'/);
|
|
26
19
|
assert.match(parity,/deadbyte\.r36-parity\.v1/);
|
|
27
20
|
assert.match(parity,new RegExp(R35_RELEASE_ID.replaceAll('.','\\.')));
|
|
28
21
|
assert.match(parity,new RegExp(R35_MANIFEST));
|
|
29
22
|
assert.match(closure,/DEADBYTE-R36-FINAL-CLOSURE-V1/);
|
|
30
23
|
assert.match(closure,/version:'0\.10\.0'/);
|
|
31
|
-
assert.match(closure,/release_label:'R36 FINAL MACHINE BASELINE'/);
|
|
32
24
|
assert.match(closureVerify,/DEADBYTE-R36-FINAL-CLOSURE-V1/);
|
|
33
|
-
assert.match(
|
|
34
|
-
assert.match(
|
|
25
|
+
assert.match(windowsGate,/deadbyte\.r36-windows-gate\.v1/);
|
|
26
|
+
assert.match(r37_0110Parity,new RegExp(R36_RELEASE_ID.replaceAll('.','\\.')));
|
|
27
|
+
assert.match(r37_0110Parity,new RegExp(R36_MANIFEST));
|
|
35
28
|
});
|
|
36
29
|
|
|
37
|
-
test('
|
|
30
|
+
test('current R37 controller still binds production remote to compact profile and restores parent environment',async()=>{
|
|
38
31
|
const controller=await text('controller/deadbyte-controller.ps1');
|
|
39
32
|
assert.match(controller,/Test-Path Env:DEADBYTE_CAPABILITY_PROFILE/);
|
|
40
33
|
assert.match(controller,/\$previousCapabilityProfileEnv = \$env:DEADBYTE_CAPABILITY_PROFILE/);
|
|
@@ -43,7 +36,7 @@ test('R36 controller binds production remote to compact profile and restores par
|
|
|
43
36
|
assert.match(controller,/\$env:DEADBYTE_CAPABILITY_PROFILE = \$previousCapabilityProfileEnv/);
|
|
44
37
|
});
|
|
45
38
|
|
|
46
|
-
test('R36
|
|
39
|
+
test('R36 surface contract remains exact full 76 plus compact gateway closure for R37',async()=>{
|
|
47
40
|
const parity=await text('src/remote-mcp-r36-parity-client.mjs');
|
|
48
41
|
assert.match(parity,/R36_EXPECTED_TOOLS/);
|
|
49
42
|
assert.match(parity,/R36_EXPECTED_TOOLS\.length !== 76|tool_count !== 76|length === 76/);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
const root=new URL('../',import.meta.url);
|
|
5
|
+
const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
6
|
+
|
|
7
|
+
test('sealed public 0.11.0 release scripts remain preserved as historical R37 authority',async()=>{
|
|
8
|
+
const [gate,evidence,parity,closure,verify,deferred]=await Promise.all([
|
|
9
|
+
text('scripts/gate-windows-r37-0110.ps1'),text('scripts/windows-gate-evidence-r37-0110.mjs'),
|
|
10
|
+
text('scripts/release-parity-r37-0110.mjs'),text('scripts/final-closure-r37-0110.mjs'),
|
|
11
|
+
text('scripts/final-closure-verify-r37-0110.mjs'),text('scripts/deferred-slot-operation-r37-0110.mjs')
|
|
12
|
+
]);
|
|
13
|
+
assert.match(gate,/V0\.11\.0 \/ R37/);
|
|
14
|
+
assert.match(evidence,/version:'0\.11\.0'/);
|
|
15
|
+
assert.match(parity,/v0\.10\.0-8d1e5f09745e7647/);
|
|
16
|
+
assert.match(parity,/candidate\?\.version==='0\.11\.0'/);
|
|
17
|
+
assert.match(closure,/version:'0\.11\.0'/);
|
|
18
|
+
assert.match(verify,/value\?\.version==='0\.11\.0'/);
|
|
19
|
+
assert.match(deferred,/--expected-version','0\.11\.0'/);
|
|
20
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
import { effectIdentity, loopGuardDisposition, bindEffectCompletion } from '../src/effect-ledger.mjs';
|
|
7
|
+
import { deriveAgentMemory, queryAgentMemory } from '../src/agent-memory-plane.mjs';
|
|
8
|
+
import { createWorkerScheduler } from '../src/worker-scheduler.mjs';
|
|
9
|
+
import { issueObservationLease, verifyObservationLease } from '../src/observation-lease.mjs';
|
|
10
|
+
|
|
11
|
+
const repo=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
12
|
+
|
|
13
|
+
test('R37 effect ledger detects semantically identical repeated effects across planner wording',()=>{
|
|
14
|
+
const base={goalId:'a'.repeat(64),planId:'b'.repeat(64),stepId:'fix',mutationEpoch:4,
|
|
15
|
+
action:{kind:'patch',operations:[{kind:'replace',path:'src/a.mjs',old_string:'x',new_string:'y'}]},
|
|
16
|
+
observationHeadSha256:'c'.repeat(64)};
|
|
17
|
+
const first=effectIdentity(base);
|
|
18
|
+
const second=effectIdentity({...base,plannerSummary:'different prose'});
|
|
19
|
+
assert.equal(first.fingerprint,second.fingerprint);
|
|
20
|
+
const events=[
|
|
21
|
+
{type:'effect_started',payload:{fingerprint:first.fingerprint,effect_id:first.effect_id}},
|
|
22
|
+
{type:'effect_completed',payload:{fingerprint:first.fingerprint,effect_id:first.effect_id}},
|
|
23
|
+
{type:'effect_started',payload:{fingerprint:first.fingerprint,effect_id:'d'.repeat(64)}},
|
|
24
|
+
{type:'effect_failed',payload:{fingerprint:first.fingerprint,effect_id:'d'.repeat(64)}}
|
|
25
|
+
];
|
|
26
|
+
const guard=loopGuardDisposition(events,second,{maxRepeats:2,window:16});
|
|
27
|
+
assert.equal(guard.allowed,false);
|
|
28
|
+
assert.equal(guard.reason,'effect_repeat_limit');
|
|
29
|
+
assert.equal(guard.repeated_count,2);
|
|
30
|
+
const completion=bindEffectCompletion(first,{status:'passed',receipt_sha256:'e'.repeat(64)});
|
|
31
|
+
assert.equal(completion.effect_id,first.effect_id);
|
|
32
|
+
assert.match(completion.result_sha256,/^[0-9a-f]{64}$/);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('R37 memory plane derives deterministic core archival and graph views from journal',()=>{
|
|
36
|
+
const events=[
|
|
37
|
+
{seq:1,type:'goal_created',event_sha256:'1'.repeat(64),payload:{acceptance:'all gates pass'}},
|
|
38
|
+
{seq:2,type:'profile_completed',event_sha256:'2'.repeat(64),payload:{profile_id:'quick-test',passed:true,receipt_sha256:'a'.repeat(64)}},
|
|
39
|
+
{seq:3,type:'native_diff_committed',event_sha256:'3'.repeat(64),payload:{paths:['src/a.mjs'],diff_receipt_sha256:'b'.repeat(64),mutation_epoch:1}},
|
|
40
|
+
{seq:4,type:'planner_rejected',event_sha256:'4'.repeat(64),payload:{reason:'stale approach'}},
|
|
41
|
+
{seq:5,type:'waiting_entered',event_sha256:'5'.repeat(64),payload:{reason:'needs evidence'}}
|
|
42
|
+
];
|
|
43
|
+
const one=deriveAgentMemory(events);
|
|
44
|
+
const two=deriveAgentMemory(structuredClone(events));
|
|
45
|
+
assert.equal(one.memory_sha256,two.memory_sha256);
|
|
46
|
+
assert.deepEqual(one.core.acceptance_constraints,['all gates pass']);
|
|
47
|
+
assert.ok(one.archival.some(x=>x.type==='planner_rejected'));
|
|
48
|
+
assert.ok(one.graph.nodes.some(x=>x.id==='file:src/a.mjs'));
|
|
49
|
+
const local=queryAgentMemory(one,{query:'src a mjs',mode:'local',limit:8});
|
|
50
|
+
assert.ok(local.results.some(x=>JSON.stringify(x).includes('src/a.mjs')));
|
|
51
|
+
const global=queryAgentMemory(one,{query:'gates profiles blockers',mode:'global',limit:8});
|
|
52
|
+
assert.ok(global.results.length>0);
|
|
53
|
+
const drift=queryAgentMemory(one,{query:'src/a.mjs',mode:'drift',limit:8});
|
|
54
|
+
assert.ok(drift.results.length>0);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('R37 worker scheduler enforces resources, leases and expiry recovery',()=>{
|
|
58
|
+
let now=1000;
|
|
59
|
+
const scheduler=createWorkerScheduler({maxConcurrent:2,totalCpuUnits:2,totalMemoryMb:1024,leaseMs:5000,clock:()=>now});
|
|
60
|
+
const a=scheduler.acquire({taskId:'test-a',workerClass:'test',cpuUnits:1,memoryMb:512});
|
|
61
|
+
const b=scheduler.acquire({taskId:'test-b',workerClass:'test',cpuUnits:1,memoryMb:512});
|
|
62
|
+
assert.equal(scheduler.snapshot().active.length,2);
|
|
63
|
+
assert.throws(()=>scheduler.acquire({taskId:'test-c',workerClass:'test',cpuUnits:1,memoryMb:128}),/capacity/i);
|
|
64
|
+
now=7000;
|
|
65
|
+
const c=scheduler.acquire({taskId:'test-c',workerClass:'test',cpuUnits:2,memoryMb:1024});
|
|
66
|
+
assert.equal(scheduler.snapshot().active.length,1);
|
|
67
|
+
assert.equal(c.task_id,'test-c');
|
|
68
|
+
assert.equal(scheduler.release(c.lease_id,{status:'passed'}).status,'released');
|
|
69
|
+
assert.equal(scheduler.snapshot().active.length,0);
|
|
70
|
+
assert.notEqual(a.lease_id,b.lease_id);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('R37 observation leases bind effects to fresh observed state and mutation epoch',()=>{
|
|
74
|
+
const lease=issueObservationLease({goalId:'a'.repeat(64),mutationEpoch:3,
|
|
75
|
+
observations:[{event_sha256:'b'.repeat(64),receipt_sha256:'c'.repeat(64),result_head_sha256:'d'.repeat(64)}],
|
|
76
|
+
ttlMs:1000,nowMs:5000});
|
|
77
|
+
assert.equal(verifyObservationLease(lease,{goalId:'a'.repeat(64),currentMutationEpoch:3,nowMs:5500}).ok,true);
|
|
78
|
+
assert.throws(()=>verifyObservationLease(lease,{goalId:'a'.repeat(64),currentMutationEpoch:4,nowMs:5500}),/stale mutation epoch/i);
|
|
79
|
+
assert.throws(()=>verifyObservationLease(lease,{goalId:'a'.repeat(64),currentMutationEpoch:3,nowMs:7000}),/expired/i);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('R37 autonomous runtime integrates memory, effect guard, worker scheduler and observation lease',async()=>{
|
|
83
|
+
const source=await readFile(path.join(repo,'src','autonomous-runtime.mjs'),'utf8');
|
|
84
|
+
assert.match(source,/deriveAgentMemory/);
|
|
85
|
+
assert.match(source,/effectIdentity/);
|
|
86
|
+
assert.match(source,/loopGuardDisposition/);
|
|
87
|
+
assert.match(source,/createWorkerScheduler/);
|
|
88
|
+
assert.match(source,/issueObservationLease/);
|
|
89
|
+
assert.match(source,/project_memory:memory/);
|
|
90
|
+
assert.match(source,/effect_guard_blocked/);
|
|
91
|
+
assert.match(source,/worker_lease_acquired/);
|
|
92
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { classifyAutonomousTimeoutRecovery } from '../src/autonomous-timeout-recovery.mjs';
|
|
4
|
+
|
|
5
|
+
const before='a'.repeat(64);
|
|
6
|
+
const after='b'.repeat(64);
|
|
7
|
+
const base={status:'ok',state:'running',reason:null,journal_head_sha256:after,pending_request:null,pending_decision:null,run_busy:false,run_owner_pid:null,run_lock_created_at_utc:null};
|
|
8
|
+
|
|
9
|
+
test('R37 timeout recovery accepts signed durable terminal success',()=>{
|
|
10
|
+
assert.deepEqual(classifyAutonomousTimeoutRecovery({...base,state:'succeeded'},{beforeJournalHead:before}),
|
|
11
|
+
{kind:'completed',state:'succeeded',journal_head_sha256:after});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('R37 timeout recovery surfaces paused or cancelled as terminal failure',()=>{
|
|
15
|
+
assert.equal(classifyAutonomousTimeoutRecovery({...base,state:'paused',reason:'benchmark_regression'},{beforeJournalHead:before}).kind,'terminal_failure');
|
|
16
|
+
assert.equal(classifyAutonomousTimeoutRecovery({...base,state:'cancelled'},{beforeJournalHead:before}).kind,'terminal_failure');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('R37 timeout recovery waits while planner or decision is still in flight',()=>{
|
|
20
|
+
assert.equal(classifyAutonomousTimeoutRecovery({...base,pending_request:{request_id:'x'}},{beforeJournalHead:before}).kind,'wait');
|
|
21
|
+
assert.equal(classifyAutonomousTimeoutRecovery({...base,pending_decision:{event_sha256:'c'.repeat(64)}},{beforeJournalHead:before}).kind,'wait');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('R37 timeout recovery resumes only after durable head advance and cleared pending state',()=>{
|
|
25
|
+
assert.deepEqual(classifyAutonomousTimeoutRecovery(base,{beforeJournalHead:before}),{
|
|
26
|
+
kind:'resumable',state:'running',reason:'durable_cycle_completed',journal_head_sha256:after
|
|
27
|
+
});
|
|
28
|
+
assert.equal(classifyAutonomousTimeoutRecovery({...base,journal_head_sha256:before},{beforeJournalHead:before}).kind,'wait');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
test('R37 public autonomous smoke binds timeout recovery to pre-run journal head and resumes yielded work',async()=>{
|
|
33
|
+
const {readFile}=await import('node:fs/promises');
|
|
34
|
+
const src=await readFile(new URL('../src/remote-mcp-autonomous-smoke-client.mjs',import.meta.url),'utf8');
|
|
35
|
+
assert.match(src,/classifyAutonomousTimeoutRecovery/);
|
|
36
|
+
assert.match(src,/const beforeRun=structured\(await client\.callTool/);
|
|
37
|
+
assert.match(src,/recoverTimedOutGoal\(client, goalId, beforeRun\.journal_head_sha256\)/);
|
|
38
|
+
assert.match(src,/recovered\.kind === 'completed'/);
|
|
39
|
+
assert.match(src,/status:'yielded'/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
test('R37 timeout recovery waits until server-side run lock is released even after durable progress',()=>{
|
|
44
|
+
const busy={...base,run_busy:true,run_owner_pid:2904,run_lock_created_at_utc:'2026-09-18T14:22:02.000Z'};
|
|
45
|
+
const result=classifyAutonomousTimeoutRecovery(busy,{beforeJournalHead:before});
|
|
46
|
+
assert.equal(result.kind,'wait');
|
|
47
|
+
assert.equal(result.reason,'server_run_in_flight');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('R37 autonomous goal status exposes run-lock state for timeout-safe clients',async()=>{
|
|
51
|
+
const {readFile}=await import('node:fs/promises');
|
|
52
|
+
const [runtime,contracts]=await Promise.all([
|
|
53
|
+
readFile(new URL('../src/autonomous-runtime.mjs',import.meta.url),'utf8'),
|
|
54
|
+
readFile(new URL('../src/autonomous-output-contracts.mjs',import.meta.url),'utf8')
|
|
55
|
+
]);
|
|
56
|
+
assert.match(runtime,/runLockStatus/);
|
|
57
|
+
assert.match(runtime,/run_busy/);
|
|
58
|
+
assert.match(contracts,/run_busy:z\.boolean/);
|
|
59
|
+
assert.match(contracts,/run_owner_pid:z\.number\(\)\.int\(\)\.min\(1\)\.nullable/);
|
|
60
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { validateParityEvidence, R37_PREDECESSOR_RELEASE_ID, R37_PREDECESSOR_MANIFEST } from '../scripts/release-parity.mjs';
|
|
5
|
+
import { verifyFinalClosureObject } from '../scripts/final-closure-verify.mjs';
|
|
6
|
+
|
|
7
|
+
const root=new URL('../',import.meta.url);
|
|
8
|
+
const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
9
|
+
|
|
10
|
+
function parityFixture(){
|
|
11
|
+
const manifest='a'.repeat(64);
|
|
12
|
+
return {
|
|
13
|
+
schema:'deadbyte.r37-parity.v1',status:'passed',execution_provider:'deadbyte_mcp',rdc_operation_count:0,
|
|
14
|
+
candidate:{release_id:`v0.11.1-${manifest.slice(0,16)}`,version:'0.11.1',manifest_sha256:manifest},
|
|
15
|
+
immutable_slot:{protected:true,release_root:'C:/immutable/r37',development_root:'D:/Projects/deadbyte-mcp-r36-dev'},
|
|
16
|
+
local_full:{status:'passed',tool_count:76,strict_output_schemas:true},
|
|
17
|
+
public_compact:{status:'passed',tool_count:41,capability_closure:true,gateway_count:5},
|
|
18
|
+
autonomous:{status:'passed',signed_release_verified:true,observed_failure_before_replan:true},
|
|
19
|
+
before_rollback_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false},
|
|
20
|
+
rollback:{state:'completed'},stage_restore:{status:'restored',manifest_sha256:manifest},restore:{state:'completed'},
|
|
21
|
+
predecessor:{release_id:R37_PREDECESSOR_RELEASE_ID,version:'0.11.0',manifest_sha256:R37_PREDECESSOR_MANIFEST},
|
|
22
|
+
predecessor_disarmed:{status:'passed',tool_count:41,capability_closure:true},
|
|
23
|
+
successor:{release_id:`v0.11.1-${manifest.slice(0,16)}`,version:'0.11.1',manifest_sha256:manifest},
|
|
24
|
+
successor_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false},
|
|
25
|
+
requirements:Object.fromEntries(['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface'].map(key=>[key,true]))
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
test('R37 parity validator requires full-76, compact closure, exact public 0.11.0 predecessor and immutable-slot separation',()=>{
|
|
30
|
+
const good=parityFixture();
|
|
31
|
+
assert.equal(validateParityEvidence(good),true);
|
|
32
|
+
assert.throws(()=>validateParityEvidence({...good,local_full:{...good.local_full,tool_count:75}}),/full 76/i);
|
|
33
|
+
assert.throws(()=>validateParityEvidence({...good,public_compact:{...good.public_compact,capability_closure:false}}),/compact closure/i);
|
|
34
|
+
assert.throws(()=>validateParityEvidence({...good,predecessor:{...good.predecessor,manifest_sha256:'b'.repeat(64)}}),/predecessor/i);
|
|
35
|
+
assert.throws(()=>validateParityEvidence({...good,immutable_slot:{...good.immutable_slot,development_root:good.immutable_slot.release_root}}),/immutable-slot/i);
|
|
36
|
+
assert.throws(()=>validateParityEvidence({...good,stage_restore:{status:'missing',manifest_sha256:good.candidate.manifest_sha256}}),/stage restore/i);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('R37 parity captures R37 bridge, exact public 0.11.0 predecessor, stage reseed and successor restore',async()=>{
|
|
40
|
+
const parity=await text('scripts/release-parity.mjs');
|
|
41
|
+
assert.match(parity,/R37_PREDECESSOR_RELEASE_ID='v0\.11\.0-08c2a0008b1f84c9'/);
|
|
42
|
+
assert.match(parity,/08c2a0008b1f84c90f7ce7faa1e3decbd03f33612bc0fdc7d1ba591b548798e8/);
|
|
43
|
+
assert.match(parity,/const stageRestore=await restoreFrozenStage/);
|
|
44
|
+
assert.match(parity,/publicR37Disarmed/);
|
|
45
|
+
assert.match(parity,/scheduleDeferred\('activate',candidateManifest,\{bridgeRoot:successorBridge\.root,bridgeScriptSha256:successorBridge\.sha256\}\)/);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('R37 current final closure writer and independent verifier bind R37 domains and public 0.11.0 predecessor',async()=>{
|
|
49
|
+
const [writer,verifier]=await Promise.all([text('scripts/final-closure.mjs'),text('scripts/final-closure-verify.mjs')]);
|
|
50
|
+
assert.equal(typeof verifyFinalClosureObject,'function');
|
|
51
|
+
assert.match(writer,/DEADBYTE-R37-FINAL-CLOSURE-V1/);
|
|
52
|
+
assert.match(writer,/deadbyte\.r37-final-closure\.v1/);
|
|
53
|
+
assert.match(writer,/pointer\.version==='0\.11\.1'/);
|
|
54
|
+
assert.match(writer,/R37 FINAL MACHINE BASELINE/);
|
|
55
|
+
assert.match(writer,/deadbyte\.r37-parity\.v1/);
|
|
56
|
+
assert.match(writer,/deadbyte\.r37-windows-gate\.v1/);
|
|
57
|
+
assert.match(writer,/R37_PREDECESSOR_RELEASE_ID/);
|
|
58
|
+
assert.doesNotMatch(verifier,/from ['"]\.\.\/src\//);
|
|
59
|
+
assert.match(verifier,/DEADBYTE-R37-FINAL-CLOSURE-V1/);
|
|
60
|
+
assert.match(verifier,/deadbyte\.r37-final-closure\.v1/);
|
|
61
|
+
assert.match(verifier,/envelope\.body\.version==='0\.11\.1'/);
|
|
62
|
+
assert.match(verifier,/R37 FINAL MACHINE BASELINE/);
|
|
63
|
+
assert.match(verifier,/deadbyte\.r37-parity\.v1/);
|
|
64
|
+
assert.match(verifier,/deadbyte\.r37-windows-gate\.v1/);
|
|
65
|
+
assert.match(verifier,/08c2a0008b1f84c90f7ce7faa1e3decbd03f33612bc0fdc7d1ba591b548798e8/);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('R37 bounded public parity suite covers current release identity and agent fabric',async()=>{
|
|
69
|
+
const script=await text('scripts/release-parity-tests.ps1');
|
|
70
|
+
assert.match(script,/r37-finalization\.test\.mjs/);
|
|
71
|
+
assert.match(script,/release-version\.test\.mjs/);
|
|
72
|
+
assert.match(script,/r37-agent-fabric\.test\.mjs/);
|
|
73
|
+
assert.match(script,/remote-live-log-r37\.test\.mjs/);
|
|
74
|
+
});
|