deadbyte-mcp 0.12.0 → 0.14.0
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/.gitattributes +7 -0
- package/AGENTS.md +25 -0
- package/CONTEXT.md +3 -3
- package/MANIFEST.SHA256 +89 -45
- package/R41-PARENT.json +15 -0
- package/R42-PARENT.json +19 -0
- package/README.txt +2 -2
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +1 -1
- package/controller/deadbyte-controller.ps1 +1 -1
- package/controller/deadbyte-desktop-policy.json +5 -5
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/superpowers/specs/2026-09-20-r41-deterministic-memory-design.md +132 -0
- package/harness/r42-agent-evals.json +48 -0
- package/harness/task-contract.schema.json +33 -0
- package/package.json +11 -7
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/scripts/agent-eval-r42.mjs +46 -0
- package/scripts/build-containment.ps1 +24 -14
- package/scripts/build-desktop-r40.ps1 +15 -9
- package/scripts/deferred-slot-operation-r41.mjs +127 -0
- package/scripts/deferred-slot-operation-r42.mjs +126 -0
- package/scripts/final-closure-r41.mjs +116 -0
- package/scripts/final-closure-r42.mjs +116 -0
- package/scripts/final-closure-verify-r41.mjs +215 -0
- package/scripts/final-closure-verify-r42.mjs +223 -0
- package/scripts/gate-windows-r41.ps1 +48 -0
- package/scripts/gate-windows-r42.ps1 +54 -0
- package/scripts/init-desktop-policy-r40.ps1 +10 -4
- package/scripts/release-parity-r41.mjs +221 -0
- package/scripts/release-parity-r42.mjs +235 -0
- package/scripts/release-parity-tests-r41.ps1 +9 -0
- package/scripts/release-parity-tests-r42.ps1 +6 -0
- package/scripts/verify-memory-r41.mjs +88 -0
- package/scripts/verify-r41-parent.mjs +61 -0
- package/scripts/verify-r42-parent.mjs +101 -0
- package/scripts/windows-gate-evidence-r41.mjs +53 -0
- package/scripts/windows-gate-evidence-r42.mjs +64 -0
- package/src/agent-eval-r42.mjs +73 -0
- package/src/agent-eval-runner-r42.mjs +138 -0
- package/src/agent-governance-r42.mjs +142 -0
- package/src/autonomous-context-engine.mjs +4 -1
- package/src/autonomous-loop-state.mjs +10 -0
- package/src/autonomous-mcp-tools.mjs +21 -6
- package/src/autonomous-output-contracts.mjs +18 -2
- package/src/autonomous-planner-contracts.mjs +3 -0
- package/src/autonomous-planner.mjs +48 -6
- package/src/autonomous-policy.mjs +10 -2
- package/src/autonomous-runtime.mjs +144 -25
- package/src/autonomous-supervisor.mjs +1 -1
- package/src/evidence-publisher-r42.mjs +76 -0
- package/src/mcp-server.mjs +15 -2
- package/src/memory-r41.mjs +692 -0
- package/src/provider-circuit.mjs +4 -4
- package/src/version.mjs +1 -1
- package/test/agent-eval-r42.test.mjs +39 -0
- package/test/agent-eval-runner-r42.test.mjs +61 -0
- package/test/agent-governance-r42.test.mjs +77 -0
- package/test/autonomous-r34-e2e.test.mjs +2 -1
- package/test/cli-entrypoint.test.mjs +1 -1
- package/test/controller-desktop-r40.test.mjs +2 -1
- package/test/core.test.mjs +1 -1
- package/test/evidence-publisher-r42.test.mjs +53 -0
- package/test/helpers/autonomous-r34-fixture.mjs +3 -3
- package/test/human-clarification-r42.test.mjs +53 -0
- package/test/memory-autonomous-integration-r41.test.mjs +31 -0
- package/test/memory-history-r41.test.mjs +126 -0
- package/test/memory-projections-r41.test.mjs +92 -0
- package/test/memory-retrieval-r41.test.mjs +124 -0
- package/test/memory-snapshot-r41.test.mjs +106 -0
- package/test/provider-responses-r42.test.mjs +90 -0
- package/test/r33-closeout-regression.test.mjs +27 -12
- package/test/r33-finalization.test.mjs +4 -4
- package/test/r41-finalization.test.mjs +38 -0
- package/test/r42-finalization.test.mjs +38 -0
- package/test/release-version.test.mjs +14 -13
- package/test/task-contract-r42.test.mjs +41 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createHash, generateKeyPairSync, sign as cryptoSign } from 'node:crypto';
|
|
4
|
+
import { canonicalJson } from '../src/canonical-json.mjs';
|
|
5
|
+
import {
|
|
6
|
+
deriveEpisodicMemory,verifyEpisode,
|
|
7
|
+
deriveDecisionMemory,verifyDecisionMemory,
|
|
8
|
+
deriveIncidentMemory,verifyIncidentMemory
|
|
9
|
+
} from '../src/memory-r41.mjs';
|
|
10
|
+
|
|
11
|
+
const DOMAIN=Buffer.from('DEADBYTE-AUTONOMOUS-EVENT-V1\0');
|
|
12
|
+
const ZERO='0'.repeat(64);
|
|
13
|
+
const sha=value=>createHash('sha256').update(Buffer.from(typeof value==='string'?value:canonicalJson(value),'utf8')).digest('hex');
|
|
14
|
+
const {privateKey,publicKey}=generateKeyPairSync('ed25519');
|
|
15
|
+
const keyId=sha(Buffer.from(publicKey.export({type:'spki',format:'der'})));
|
|
16
|
+
const goalId=sha('projection-goal');
|
|
17
|
+
const goal={schema:'deadbyte.autonomous-goal.v1',goal_id:goalId,goal_sha256:sha('projection-body'),root_id:'core',
|
|
18
|
+
title:'repair linker',goal:'repair LNK2019',acceptance:'build and tests pass'};
|
|
19
|
+
|
|
20
|
+
function appendJournal(out,type,payload){
|
|
21
|
+
const index=out.length;
|
|
22
|
+
const body={schema:'deadbyte.autonomous-event.v1',seq:index+1,goal_id:goalId,
|
|
23
|
+
created_at_utc:`2026-09-20T02:00:${String(index).padStart(2,'0')}.000Z`,prev_sha256:out.at(-1)?.event_sha256??ZERO,type,payload};
|
|
24
|
+
const event_sha256=sha(body);const signed={...body,event_sha256};
|
|
25
|
+
const signature_base64=cryptoSign(null,Buffer.concat([DOMAIN,Buffer.from(canonicalJson(signed),'utf8')]),privateKey).toString('base64');
|
|
26
|
+
out.push({...signed,attestation:{algorithm:'ed25519',key_id:keyId,signature_base64}});
|
|
27
|
+
}
|
|
28
|
+
function journal(items){
|
|
29
|
+
const out=[];
|
|
30
|
+
for(const [type,payload] of items)appendJournal(out,type,payload);
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const base=journal([
|
|
35
|
+
['goal_created',{submission_id:'incident-1',acceptance:'build and tests pass'}],
|
|
36
|
+
['planner_decision',{planner_round:1,decision:{action:'inspect',summary:'inspect linker output'}}],
|
|
37
|
+
['profile_completed',{profile_id:'build',passed:false,tool:'msbuild',operation:'build',platform:'win32',architecture:'x64',
|
|
38
|
+
exit_code:1,diagnostic_codes:['LNK2019'],stderr_sha256:sha('stderr'),target:'release',symbols:['FooBar'],receipt_sha256:sha('build-fail')}],
|
|
39
|
+
['planner_decision',{planner_round:2,decision:{action:'patch',summary:'add missing FooBar definition'}}],
|
|
40
|
+
['native_diff_committed',{paths:['src/foo.cpp'],diff_receipt_sha256:sha('diff'),artifact_sha256:sha('foo-obj')}],
|
|
41
|
+
['profile_completed',{profile_id:'build',passed:true,receipt_sha256:sha('build-pass')}],
|
|
42
|
+
['release_completed',{receipt_sha256:sha('release')}]
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
test('R41 episodic memory contains only canonical journal references and rejects nonexistent events',()=>{
|
|
46
|
+
const episode=deriveEpisodicMemory(goal,base,{publicKey,keyId});
|
|
47
|
+
assert.equal(episode.schema,'deadbyte.episode.v1');
|
|
48
|
+
assert.equal(episode.outcome,'succeeded');
|
|
49
|
+
assert.deepEqual(episode.event_range,{first_seq:1,last_seq:7,journal_head_sha256:base.at(-1).event_sha256});
|
|
50
|
+
assert.ok(episode.observations.every(item=>item.event_ref?.event_sha256));
|
|
51
|
+
assert.ok(episode.decisions.every(item=>item.event_ref?.event_sha256));
|
|
52
|
+
assert.ok(episode.receipt_refs.includes(sha('release')));
|
|
53
|
+
assert.equal(verifyEpisode(episode,{goal,events:base,publicKey,keyId}).ok,true);
|
|
54
|
+
const forged=structuredClone(episode);forged.actions[0].event_ref.event_sha256=sha('nonexistent');
|
|
55
|
+
assert.equal(verifyEpisode(forged,{goal,events:base,publicKey,keyId}).ok,false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('R41 decision memory preserves supersession edges and rejects cycles',()=>{
|
|
59
|
+
const events=journal([
|
|
60
|
+
['goal_created',{submission_id:'decisions'}],
|
|
61
|
+
['planner_decision',{planner_round:1,decision:{action:'inspect',summary:'inspect first'}}]
|
|
62
|
+
]);
|
|
63
|
+
const firstId=sha({schema:'deadbyte.decision-id.v1',goal_id:goalId,event_sha256:events[1].event_sha256});
|
|
64
|
+
appendJournal(events,'planner_decision',{planner_round:2,decision:{action:'patch',summary:'patch after evidence',supersedes:firstId}});
|
|
65
|
+
const memory=deriveDecisionMemory(goal,events,{publicKey,keyId});
|
|
66
|
+
assert.equal(memory.decisions.length,2);
|
|
67
|
+
assert.equal(memory.decisions[0].status,'superseded');
|
|
68
|
+
assert.equal(memory.decisions[1].status,'active');
|
|
69
|
+
assert.equal(memory.decisions[1].supersedes,memory.decisions[0].decision_id);
|
|
70
|
+
assert.equal(memory.decisions[0].superseded_by,memory.decisions[1].decision_id);
|
|
71
|
+
assert.equal(verifyDecisionMemory(memory,{goal,events,publicKey,keyId}).ok,true);
|
|
72
|
+
|
|
73
|
+
const cyclic=structuredClone(memory);
|
|
74
|
+
cyclic.decisions[0].supersedes=cyclic.decisions[1].decision_id;
|
|
75
|
+
cyclic.decisions[1].superseded_by=cyclic.decisions[0].decision_id;
|
|
76
|
+
assert.equal(verifyDecisionMemory(cyclic,{goal,events,publicKey,keyId}).ok,false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('R41 incidents use deterministic structured fingerprints and reject spoofing',()=>{
|
|
80
|
+
const memory=deriveIncidentMemory(goal,base,{publicKey,keyId});
|
|
81
|
+
assert.equal(memory.schema,'deadbyte.incident-memory.v1');
|
|
82
|
+
assert.equal(memory.incidents.length,1);
|
|
83
|
+
const incident=memory.incidents[0];
|
|
84
|
+
assert.equal(incident.fingerprint.tool,'msbuild');
|
|
85
|
+
assert.deepEqual(incident.fingerprint.diagnostic_codes,['LNK2019']);
|
|
86
|
+
assert.deepEqual(incident.fingerprint.symbols,['FooBar']);
|
|
87
|
+
assert.equal(incident.status,'resolved');
|
|
88
|
+
assert.ok(incident.successful_fix.some(ref=>ref.event_sha256===base[4].event_sha256));
|
|
89
|
+
assert.equal(verifyIncidentMemory(memory,{goal,events:base,publicKey,keyId}).ok,true);
|
|
90
|
+
const forged=structuredClone(memory);forged.incidents[0].fingerprint.exit_code=0;
|
|
91
|
+
assert.equal(verifyIncidentMemory(forged,{goal,events:base,publicKey,keyId}).ok,false);
|
|
92
|
+
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createHash, generateKeyPairSync, sign as cryptoSign } from 'node:crypto';
|
|
4
|
+
import { mkdtemp,readFile,rm } from 'node:fs/promises';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { canonicalJson } from '../src/canonical-json.mjs';
|
|
8
|
+
import {
|
|
9
|
+
buildMemoryCorpus,buildRetrievalIndex,verifyRetrievalIndex,queryMemoryIndex,
|
|
10
|
+
buildWorkingMemory,verifyWorkingMemory,createSemanticMemoryAdapter,createR41MemoryProvider
|
|
11
|
+
} from '../src/memory-r41.mjs';
|
|
12
|
+
|
|
13
|
+
const DOMAIN=Buffer.from('DEADBYTE-AUTONOMOUS-EVENT-V1\0');
|
|
14
|
+
const ZERO='0'.repeat(64);
|
|
15
|
+
const sha=value=>createHash('sha256').update(Buffer.from(typeof value==='string'?value:canonicalJson(value),'utf8')).digest('hex');
|
|
16
|
+
const {privateKey,publicKey}=generateKeyPairSync('ed25519');
|
|
17
|
+
const keyId=sha(Buffer.from(publicKey.export({type:'spki',format:'der'})));
|
|
18
|
+
const goalId=sha('retrieval-goal');
|
|
19
|
+
const manifest=sha('r41-release');
|
|
20
|
+
const goal={schema:'deadbyte.autonomous-goal.v1',goal_id:goalId,goal_sha256:sha('retrieval-body'),root_id:'core',
|
|
21
|
+
title:'repair parser',goal:'repair ParserSymbol timeout',acceptance:'build and tests pass'};
|
|
22
|
+
|
|
23
|
+
function journal(items){
|
|
24
|
+
const out=[];
|
|
25
|
+
for(const [index,[type,payload]] of items.entries()){
|
|
26
|
+
const body={schema:'deadbyte.autonomous-event.v1',seq:index+1,goal_id:goalId,
|
|
27
|
+
created_at_utc:`2026-09-20T04:00:${String(index).padStart(2,'0')}.000Z`,prev_sha256:out.at(-1)?.event_sha256??ZERO,type,payload};
|
|
28
|
+
const event_sha256=sha(body);const signed={...body,event_sha256};
|
|
29
|
+
const signature_base64=cryptoSign(null,Buffer.concat([DOMAIN,Buffer.from(canonicalJson(signed),'utf8')]),privateKey).toString('base64');
|
|
30
|
+
out.push({...signed,attestation:{algorithm:'ed25519',key_id:keyId,signature_base64}});
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const events=journal([
|
|
36
|
+
['goal_created',{submission_id:'retrieval',acceptance:'build and tests pass'}],
|
|
37
|
+
['planner_decision',{planner_round:1,decision:{action:'inspect',summary:'inspect ParserSymbol timeout'}}],
|
|
38
|
+
['profile_completed',{profile_id:'test',passed:false,tool:'node',operation:'test',platform:'win32',architecture:'x64',
|
|
39
|
+
timeout_state:'expired',diagnostic_codes:['ERR_TEST_TIMEOUT'],stderr_sha256:sha('stderr'),symbols:['ParserSymbol'],receipt_sha256:sha('failed')}],
|
|
40
|
+
['native_diff_committed',{paths:['src/parser.mjs'],diff_receipt_sha256:sha('diff'),artifact_sha256:sha('artifact')}],
|
|
41
|
+
['profile_completed',{profile_id:'test',passed:true,receipt_sha256:sha('passed')}],
|
|
42
|
+
['release_completed',{receipt_sha256:sha('release')}]
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
function fixture(){
|
|
46
|
+
const corpus=buildMemoryCorpus({goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
47
|
+
const index=buildRetrievalIndex(corpus,{sourceReleaseManifest:manifest});
|
|
48
|
+
return {corpus,index};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test('R41 retrieval indexes rebuild byte-identically and support exact token symbol artifact and incident lookup',()=>{
|
|
52
|
+
const {corpus,index}=fixture();
|
|
53
|
+
const rebuilt=buildRetrievalIndex(corpus,{sourceReleaseManifest:manifest});
|
|
54
|
+
assert.equal(canonicalJson(index),canonicalJson(rebuilt));
|
|
55
|
+
assert.equal(verifyRetrievalIndex(index,{corpus,sourceReleaseManifest:manifest}).ok,true);
|
|
56
|
+
assert.ok(queryMemoryIndex(index,{query:'ParserSymbol timeout',limit:8}).candidate_ids.length>=1);
|
|
57
|
+
assert.ok(queryMemoryIndex(index,{symbol:'ParserSymbol',limit:8}).candidate_ids.length>=1);
|
|
58
|
+
assert.ok(queryMemoryIndex(index,{artifact_sha256:sha('artifact'),limit:8}).candidate_ids.length>=1);
|
|
59
|
+
assert.ok(queryMemoryIndex(index,{incident_fingerprint:corpus.incidents.incidents[0].fingerprint_sha256,limit:8}).candidate_ids.includes(corpus.incidents.incidents[0].incident_id));
|
|
60
|
+
assert.deepEqual(queryMemoryIndex(index,{id:corpus.episode.episode_id,limit:1}).candidate_ids,[corpus.episode.episode_id]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('R41 poisoned or cross-release indexes fail closed',()=>{
|
|
64
|
+
const {corpus,index}=fixture();
|
|
65
|
+
const poisoned=structuredClone(index);
|
|
66
|
+
poisoned.token_index.timeout=[sha('forged-document')];
|
|
67
|
+
assert.equal(verifyRetrievalIndex(poisoned,{corpus,sourceReleaseManifest:manifest}).ok,false);
|
|
68
|
+
assert.equal(verifyRetrievalIndex(index,{corpus,sourceReleaseManifest:sha('other-release')}).ok,false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('R41 working memory is bounded provenance-bearing disposable state and rejects staleness',()=>{
|
|
72
|
+
const {corpus,index}=fixture();
|
|
73
|
+
const args={goal,events,corpus,index,publicKey,keyId,sourceReleaseManifest:manifest,byteBudget:16384,
|
|
74
|
+
currentPlan:{step:'verify'},currentFiles:[{path:'src/parser.mjs',sha256:sha('parser'),source_event_sha256:events[3].event_sha256}],
|
|
75
|
+
currentSymbols:['ParserSymbol'],currentAuthority:{coding:{armed:true,reason:'standing-grant',instance_nonce:sha('secret')}}};
|
|
76
|
+
const working=buildWorkingMemory(args);
|
|
77
|
+
assert.ok(Buffer.byteLength(canonicalJson(working),'utf8')<=16384);
|
|
78
|
+
assert.equal(working.source_release_manifest,manifest);
|
|
79
|
+
assert.equal(working.journal_head_sha256,events.at(-1).event_sha256);
|
|
80
|
+
assert.equal(working.current_authority.authorizes_execution,false);
|
|
81
|
+
assert.equal(JSON.stringify(working).includes('instance_nonce'),false);
|
|
82
|
+
assert.ok(working.relevant_incidents[0].source_event_ids.length>=1);
|
|
83
|
+
assert.equal(verifyWorkingMemory(working,args).ok,true);
|
|
84
|
+
const staleArgs={...args,events:events.slice(0,-1)};
|
|
85
|
+
assert.equal(verifyWorkingMemory(working,staleArgs).ok,false);
|
|
86
|
+
assert.equal(verifyWorkingMemory(working,{...args,sourceReleaseManifest:sha('wrong-release')}).ok,false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('R41 semantic retrieval is disabled by default and verifies candidate IDs against canonical memory',async()=>{
|
|
90
|
+
const {corpus,index}=fixture();
|
|
91
|
+
const disabled=createSemanticMemoryAdapter();
|
|
92
|
+
await assert.rejects(disabled.query({query:'parser',corpus,index,sourceReleaseManifest:manifest}),/disabled/);
|
|
93
|
+
|
|
94
|
+
const validId=corpus.incidents.incidents[0].incident_id;
|
|
95
|
+
const enabled=createSemanticMemoryAdapter({enabled:true,retrieveCandidates:async()=>[validId]});
|
|
96
|
+
const resolved=await enabled.query({query:'parser timeout',corpus,index,sourceReleaseManifest:manifest});
|
|
97
|
+
assert.deepEqual(resolved.candidate_ids,[validId]);
|
|
98
|
+
assert.equal(resolved.records[0].incident_id,validId);
|
|
99
|
+
|
|
100
|
+
const poisoned=createSemanticMemoryAdapter({enabled:true,retrieveCandidates:async()=>[sha('not-canonical')]});
|
|
101
|
+
await assert.rejects(poisoned.query({query:'parser',corpus,index,sourceReleaseManifest:manifest}),/canonical candidate/);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('R41 content-addressed projections survive deletion and rebuild byte-identically',async()=>{
|
|
105
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r41-provider-'));
|
|
106
|
+
try{
|
|
107
|
+
const provider=createR41MemoryProvider({memoryRoot:root,sourceReleaseManifest:manifest,writerVersion:'0.13.0',
|
|
108
|
+
privateKey,publicKey,keyId,byteBudget:16384});
|
|
109
|
+
const input={goal,events,currentPlan:null,currentFiles:[],currentSymbols:['ParserSymbol'],currentAuthority:{}};
|
|
110
|
+
const first=await provider.refresh(input);
|
|
111
|
+
assert.equal(first.replay_mode,'full-replay');
|
|
112
|
+
const snapshotBytes=await readFile(first.snapshot_path);
|
|
113
|
+
const indexBytes=await readFile(first.index_path);
|
|
114
|
+
await rm(first.index_path);
|
|
115
|
+
const rebuilt=await provider.refresh(input);
|
|
116
|
+
assert.equal(rebuilt.replay_mode,'snapshot-suffix');
|
|
117
|
+
assert.equal(rebuilt.snapshot_sha256,first.snapshot_sha256);
|
|
118
|
+
assert.equal(rebuilt.index_sha256,first.index_sha256);
|
|
119
|
+
assert.deepEqual(await readFile(rebuilt.snapshot_path),snapshotBytes);
|
|
120
|
+
assert.deepEqual(await readFile(rebuilt.index_path),indexBytes);
|
|
121
|
+
assert.equal(provider.semantic_enabled,false);
|
|
122
|
+
assert.equal(Object.hasOwn(provider,'arm'),false);
|
|
123
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
124
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createHash, generateKeyPairSync, sign as cryptoSign } from 'node:crypto';
|
|
4
|
+
import { mkdtemp, readFile, writeFile } from 'node:fs/promises';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { canonicalJson } from '../src/canonical-json.mjs';
|
|
8
|
+
import {
|
|
9
|
+
deriveMemoryState,
|
|
10
|
+
createMemorySnapshot,
|
|
11
|
+
verifyMemorySnapshot,
|
|
12
|
+
replayFromMemorySnapshot,
|
|
13
|
+
loadMemoryState,
|
|
14
|
+
writeMemorySnapshot
|
|
15
|
+
} from '../src/memory-r41.mjs';
|
|
16
|
+
|
|
17
|
+
const EVENT_DOMAIN=Buffer.from('DEADBYTE-AUTONOMOUS-EVENT-V1\0');
|
|
18
|
+
const ZERO='0'.repeat(64);
|
|
19
|
+
const sha=value=>createHash('sha256').update(Buffer.from(canonicalJson(value),'utf8')).digest('hex');
|
|
20
|
+
const {privateKey,publicKey}=generateKeyPairSync('ed25519');
|
|
21
|
+
const keyId=sha(Buffer.from(publicKey.export({type:'spki',format:'der'})));
|
|
22
|
+
const goalId=sha('goal');
|
|
23
|
+
const manifest=sha('r41-manifest');
|
|
24
|
+
const goal={schema:'deadbyte.autonomous-goal.v1',goal_id:goalId,goal_sha256:sha('goal-body'),title:'repair',goal:'repair source',acceptance:'tests pass'};
|
|
25
|
+
|
|
26
|
+
function journal(types){
|
|
27
|
+
const events=[];
|
|
28
|
+
for(const [index,[type,payload]] of types.entries()){
|
|
29
|
+
const body={schema:'deadbyte.autonomous-event.v1',seq:index+1,goal_id:goalId,
|
|
30
|
+
created_at_utc:`2026-09-20T00:00:${String(index).padStart(2,'0')}.000Z`,
|
|
31
|
+
prev_sha256:events.at(-1)?.event_sha256??ZERO,type,payload};
|
|
32
|
+
const event_sha256=sha(body);
|
|
33
|
+
const signed={...body,event_sha256};
|
|
34
|
+
const signature_base64=cryptoSign(null,Buffer.concat([EVENT_DOMAIN,Buffer.from(canonicalJson(signed),'utf8')]),privateKey).toString('base64');
|
|
35
|
+
events.push({...signed,attestation:{algorithm:'ed25519',key_id:keyId,signature_base64}});
|
|
36
|
+
}
|
|
37
|
+
return events;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const events=journal([
|
|
41
|
+
['goal_created',{submission_id:'r41',acceptance:'tests pass'}],
|
|
42
|
+
['planner_decision',{planner_round:1,decision:{action:'inspect',summary:'inspect source'}}],
|
|
43
|
+
['inspect_completed',{contexts:[{path:'src/a.mjs',sha256:sha('a'),bytes:1}]}],
|
|
44
|
+
['profile_completed',{profile_id:'test',passed:false,receipt_sha256:sha('failed')}],
|
|
45
|
+
['planner_decision',{planner_round:2,decision:{action:'patch',summary:'apply exact fix'}}],
|
|
46
|
+
['native_diff_committed',{paths:['src/a.mjs'],mutation_epoch:1,diff_receipt_sha256:sha('diff')}],
|
|
47
|
+
['profile_completed',{profile_id:'test',passed:true,receipt_sha256:sha('passed')}],
|
|
48
|
+
['release_completed',{receipt_sha256:sha('release')}]
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
function makeSnapshot(prefix=events.slice(0,5)){
|
|
52
|
+
return createMemorySnapshot({goal,events:prefix,snapshotSequence:1,sourceReleaseManifest:manifest,
|
|
53
|
+
writerVersion:'0.13.0',createdAtUtc:'2026-09-20T01:00:00.000Z',privateKey,keyId,publicKey});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
test('R41 snapshot plus verified suffix is byte-equivalent to full replay',()=>{
|
|
57
|
+
const snapshot=makeSnapshot();
|
|
58
|
+
assert.equal(snapshot.schema,'deadbyte.memory-snapshot.v1');
|
|
59
|
+
assert.equal(snapshot.schema_version,1);
|
|
60
|
+
assert.equal(snapshot.last_event_seq,5);
|
|
61
|
+
assert.equal(snapshot.journal_prefix_hash,events[4].event_sha256);
|
|
62
|
+
assert.equal(snapshot.source_release_manifest,manifest);
|
|
63
|
+
assert.equal(verifyMemorySnapshot(snapshot,{goal,events,publicKey,keyId,sourceReleaseManifest:manifest}).ok,true);
|
|
64
|
+
const resumed=replayFromMemorySnapshot(snapshot,{goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
65
|
+
assert.equal(canonicalJson(resumed),canonicalJson(deriveMemoryState(goal,events,{publicKey,keyId})));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('R41 snapshot tampering fails closed for schema sequence prefix state hash and signature',()=>{
|
|
69
|
+
const base=makeSnapshot();
|
|
70
|
+
const mutations=[
|
|
71
|
+
value=>{value.schema='deadbyte.memory-snapshot.v0';},
|
|
72
|
+
value=>{value.snapshot_sequence=0;},
|
|
73
|
+
value=>{value.last_event_seq=6;},
|
|
74
|
+
value=>{value.journal_prefix_hash=sha('wrong-prefix');},
|
|
75
|
+
value=>{value.state.last_event_seq=4;},
|
|
76
|
+
value=>{value.state_hash=sha('wrong-state');},
|
|
77
|
+
value=>{value.attestation.signature_base64=Buffer.alloc(64).toString('base64');}
|
|
78
|
+
];
|
|
79
|
+
for(const mutate of mutations){
|
|
80
|
+
const candidate=structuredClone(base);mutate(candidate);
|
|
81
|
+
const proof=verifyMemorySnapshot(candidate,{goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
82
|
+
assert.equal(proof.ok,false,JSON.stringify(candidate));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('R41 missing or corrupt snapshot falls back explicitly to full verified replay',async()=>{
|
|
87
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r41-snapshot-'));
|
|
88
|
+
const file=path.join(root,'memory.snapshot.json');
|
|
89
|
+
const missing=await loadMemoryState({snapshotPath:file,goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
90
|
+
assert.equal(missing.mode,'full-replay');
|
|
91
|
+
assert.equal(missing.snapshot_reason,'missing');
|
|
92
|
+
assert.equal(canonicalJson(missing.state),canonicalJson(deriveMemoryState(goal,events,{publicKey,keyId})));
|
|
93
|
+
|
|
94
|
+
await writeFile(file,'{"broken":true}\n');
|
|
95
|
+
const corrupt=await loadMemoryState({snapshotPath:file,goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
96
|
+
assert.equal(corrupt.mode,'full-replay');
|
|
97
|
+
assert.match(corrupt.snapshot_reason,/snapshot/i);
|
|
98
|
+
|
|
99
|
+
const snapshot=makeSnapshot();
|
|
100
|
+
await writeMemorySnapshot(file,snapshot);
|
|
101
|
+
const disk=JSON.parse(await readFile(file,'utf8'));
|
|
102
|
+
assert.equal(disk.snapshot_sha256,snapshot.snapshot_sha256);
|
|
103
|
+
const resumed=await loadMemoryState({snapshotPath:file,goal,events,publicKey,keyId,sourceReleaseManifest:manifest});
|
|
104
|
+
assert.equal(resumed.mode,'snapshot-suffix');
|
|
105
|
+
assert.equal(canonicalJson(resumed.state),canonicalJson(deriveMemoryState(goal,events,{publicKey,keyId})));
|
|
106
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { loadAutonomousPolicy } from '../src/autonomous-policy.mjs';
|
|
7
|
+
import { requestProviderDecision } from '../src/autonomous-planner.mjs';
|
|
8
|
+
import { providerCircuitId } from '../src/provider-circuit.mjs';
|
|
9
|
+
|
|
10
|
+
const H = value => String(value).repeat(64).slice(0,64);
|
|
11
|
+
|
|
12
|
+
async function policyFixture(planner) {
|
|
13
|
+
const root = await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-provider-'));
|
|
14
|
+
const project = path.join(root,'project');
|
|
15
|
+
await mkdir(project);
|
|
16
|
+
const codingPolicy = {
|
|
17
|
+
policy_sha256:H('c'), roots:{project:{path:project}}, commands:{}
|
|
18
|
+
};
|
|
19
|
+
const policyPath = path.join(root,'autonomous-policy.json');
|
|
20
|
+
await writeFile(policyPath,JSON.stringify({
|
|
21
|
+
schema:'deadbyte.autonomous-policy.v1', enabled:true,
|
|
22
|
+
lease_file:path.join(root,'grant.json'), evidence_dir:path.join(root,'evidence'),
|
|
23
|
+
coding_policy_sha256:codingPolicy.policy_sha256, root_ids:['project'], planner,
|
|
24
|
+
profiles:{}, limits:{max_wall_ms:null}
|
|
25
|
+
}));
|
|
26
|
+
const policy = await loadAutonomousPolicy(policyPath,codingPolicy);
|
|
27
|
+
return {root,policy,cleanup:()=>rm(root,{recursive:true,force:true})};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test('R42 policy accepts bounded OpenAI Responses planner configuration',async()=>{
|
|
31
|
+
const f=await policyFixture({
|
|
32
|
+
backend:'openai_responses', endpoint:'https://api.openai.com/v1/responses',
|
|
33
|
+
model:'gpt-5', api_key_env:'OPENAI_API_KEY', max_tokens:4096,
|
|
34
|
+
reasoning_effort:'medium', timeout_ms:45000, max_response_bytes:131072,
|
|
35
|
+
circuit:{failure_threshold:2,open_ms:1000,half_open_probe_limit:1}
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
assert.equal(f.policy.planner.backend,'openai_responses');
|
|
39
|
+
assert.equal(f.policy.planner.reasoning_effort,'medium');
|
|
40
|
+
assert.equal(f.policy.planner.store,false);
|
|
41
|
+
assert.match(providerCircuitId(f.policy.planner),/^openai_responses:[0-9a-f]{64}$/);
|
|
42
|
+
} finally { await f.cleanup(); }
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('R42 Responses adapter sends JSON mode and extracts bounded output with provenance',async()=>{
|
|
46
|
+
const old=process.env.DEADBYTE_R42_TEST_KEY;
|
|
47
|
+
process.env.DEADBYTE_R42_TEST_KEY='test-only-token';
|
|
48
|
+
const policy={planner:{
|
|
49
|
+
backend:'openai_responses', endpoint:'https://api.openai.com/v1/responses', model:'gpt-5',
|
|
50
|
+
api_key_env:'DEADBYTE_R42_TEST_KEY', max_tokens:2048, reasoning_effort:'high', store:false,
|
|
51
|
+
timeout_ms:30000, max_response_bytes:65536
|
|
52
|
+
}};
|
|
53
|
+
let captured;
|
|
54
|
+
const fetchImpl=async(url,options)=>{
|
|
55
|
+
captured={url,options,body:JSON.parse(options.body)};
|
|
56
|
+
return new Response(JSON.stringify({
|
|
57
|
+
id:'resp_test_123', status:'completed', model:'gpt-5-2026-01-01',
|
|
58
|
+
output:[{type:'message',role:'assistant',content:[{type:'output_text',text:'{"schema":"deadbyte.autonomous-decision.v2","kind":"pause","reason":"need fixture"}'}]}],
|
|
59
|
+
usage:{input_tokens:111,output_tokens:22,total_tokens:133}
|
|
60
|
+
}),{status:200,headers:{'content-type':'application/json'}});
|
|
61
|
+
};
|
|
62
|
+
try {
|
|
63
|
+
const result=await requestProviderDecision(policy,'bounded prompt',fetchImpl);
|
|
64
|
+
assert.equal(captured.url,policy.planner.endpoint);
|
|
65
|
+
assert.equal(captured.options.headers.authorization,'Bearer test-only-token');
|
|
66
|
+
assert.deepEqual(captured.body.text,{format:{type:'json_object'}});
|
|
67
|
+
assert.equal(captured.body.store,false);
|
|
68
|
+
assert.equal(captured.body.max_output_tokens,2048);
|
|
69
|
+
assert.deepEqual(captured.body.reasoning,{effort:'high'});
|
|
70
|
+
assert.equal(captured.body.input[0].role,'system');
|
|
71
|
+
assert.equal(captured.body.input[1].role,'user');
|
|
72
|
+
assert.equal(result.backend,'openai_responses');
|
|
73
|
+
assert.equal(result.response_id,'resp_test_123');
|
|
74
|
+
assert.deepEqual(result.usage,{input_tokens:111,output_tokens:22,total_tokens:133});
|
|
75
|
+
assert.match(result.raw_text,/deadbyte\.autonomous-decision\.v2/);
|
|
76
|
+
} finally {
|
|
77
|
+
if(old===undefined) delete process.env.DEADBYTE_R42_TEST_KEY; else process.env.DEADBYTE_R42_TEST_KEY=old;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('R42 Responses adapter fails closed on refusal and incomplete response',async()=>{
|
|
82
|
+
const policy={planner:{backend:'openai_responses',endpoint:'https://api.openai.com/v1/responses',model:'gpt-5',
|
|
83
|
+
api_key_env:null,max_tokens:2048,reasoning_effort:null,store:false,timeout_ms:30000,max_response_bytes:65536}};
|
|
84
|
+
const refusal=async()=>new Response(JSON.stringify({id:'resp_refuse',status:'completed',model:'gpt-5',
|
|
85
|
+
output:[{type:'message',content:[{type:'refusal',refusal:'cannot comply'}]}]}),{status:200});
|
|
86
|
+
await assert.rejects(requestProviderDecision(policy,'x',refusal),/refusal|output_text/i);
|
|
87
|
+
const incomplete=async()=>new Response(JSON.stringify({id:'resp_incomplete',status:'incomplete',model:'gpt-5',output:[],
|
|
88
|
+
incomplete_details:{reason:'max_output_tokens'}}),{status:200});
|
|
89
|
+
await assert.rejects(requestProviderDecision(policy,'x',incomplete),/not completed|incomplete/i);
|
|
90
|
+
});
|
|
@@ -86,25 +86,40 @@ 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 current
|
|
90
|
-
const stateRoot=await temp('deadbyte-
|
|
89
|
+
test('Windows current R42 gate emits manifest-bound model-eval evidence outside the candidate tree', async()=>{
|
|
90
|
+
const stateRoot=await temp('deadbyte-r42-windows-evidence-');
|
|
91
91
|
try{
|
|
92
|
-
const gate=await readFile(path.join(root,'scripts','gate-windows-
|
|
93
|
-
assert.match(gate,/windows-gate-evidence-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
const gate=await readFile(path.join(root,'scripts','gate-windows-r42.ps1'),'utf8');
|
|
93
|
+
assert.match(gate,/windows-gate-evidence-r42\.mjs/,'gate-windows-r42.ps1 must invoke the evidence writer');
|
|
94
|
+
assert.match(gate,/r42-model-backed-eval/,'R42 gate must require model-backed eval before evidence writer');
|
|
95
|
+
|
|
96
|
+
const suite=JSON.parse(await readFile(path.join(root,'harness','r42-agent-evals.json'),'utf8'));
|
|
97
|
+
const manifestSha=sha256(await readFile(path.join(root,'MANIFEST.SHA256')));
|
|
98
|
+
const { runAgentEvalSuiteR42 }=await import('../src/agent-eval-runner-r42.mjs');
|
|
99
|
+
const { writeWindowsGateEvidence }=await import('../scripts/windows-gate-evidence-r42.mjs');
|
|
100
|
+
const evaluation=await runAgentEvalSuiteR42({
|
|
101
|
+
suite,subjectManifestSha256:manifestSha,
|
|
102
|
+
evidenceRoot:path.join(stateRoot,'evidence','release','r42-agent-evals'),
|
|
103
|
+
clock:()=>new Date('2026-09-20T02:00:00.000Z'),
|
|
104
|
+
requestModel:async call=>call.role==='generator'
|
|
105
|
+
?{backend:'fixture',model:'fixture',response_id:`g-${call.case_id}`,raw_text:JSON.stringify({artifact:{plan:['inspect','verify','fail_closed']}})}
|
|
106
|
+
:{backend:'fixture',model:'fixture',response_id:`j-${call.case_id}`,raw_text:JSON.stringify({
|
|
107
|
+
schema:'deadbyte.agent-eval-judge-result.v1',verdict:'pass',advisory:true,findings:[],evidence_refs:['1'.repeat(64)]
|
|
108
|
+
})}
|
|
96
109
|
});
|
|
97
|
-
assert.equal(
|
|
98
|
-
|
|
110
|
+
assert.equal(evaluation.payload.status,'passed');
|
|
111
|
+
|
|
112
|
+
const summary=await writeWindowsGateEvidence({candidateRoot:root,stateRoot,clock:()=>new Date('2026-09-20T02:01:00.000Z')});
|
|
99
113
|
assert.equal(summary.status,'written');
|
|
100
114
|
const evidence=JSON.parse(await readFile(summary.path,'utf8'));
|
|
101
|
-
|
|
102
|
-
assert.equal(evidence.schema,'deadbyte.r40-windows-gate.v1');
|
|
115
|
+
assert.equal(evidence.schema,'deadbyte.r42-windows-gate.v1');
|
|
103
116
|
assert.equal(evidence.status,'passed');
|
|
104
117
|
assert.equal(evidence.exit_code,0);
|
|
105
|
-
assert.equal(evidence.version,'0.
|
|
118
|
+
assert.equal(evidence.version,'0.14.0');
|
|
106
119
|
assert.equal(evidence.manifest_sha256,manifestSha);
|
|
107
|
-
assert.equal(evidence.marker,'DEADBYTE V0.
|
|
120
|
+
assert.equal(evidence.marker,'DEADBYTE V0.14.0 / R42 WINDOWS BATCH GATE: PASS');
|
|
121
|
+
assert.equal(evidence.model_eval.evidence_sha256,evaluation.publication.evidence_sha256);
|
|
122
|
+
assert.equal(evidence.model_eval.case_count,suite.cases.length);
|
|
108
123
|
assert.ok(summary.path.startsWith(path.join(stateRoot,'evidence','release')));
|
|
109
124
|
}finally{await rm(stateRoot,{recursive:true,force:true});}
|
|
110
125
|
});
|
|
@@ -19,9 +19,9 @@ test('R34 public parity catalog is exact, unique, and includes production coding
|
|
|
19
19
|
|
|
20
20
|
test('release parity and final verifier are package entry points', async () => {
|
|
21
21
|
const pkg = JSON.parse(await text('package.json'));
|
|
22
|
-
assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity-
|
|
23
|
-
assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure-
|
|
24
|
-
assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify-
|
|
22
|
+
assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity-r42.mjs');
|
|
23
|
+
assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure-r42.mjs');
|
|
24
|
+
assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify-r42.mjs');
|
|
25
25
|
assert.equal(typeof validateParityEvidence, 'function');
|
|
26
26
|
assert.equal(typeof verifyFinalClosureObject, 'function');
|
|
27
27
|
});
|
|
@@ -72,4 +72,4 @@ test('R34 parity isolates scratch mutation and search from the core release tree
|
|
|
72
72
|
assert.match(parity, /machine_search_start[\s\S]*?root_id:scratchRoot/);
|
|
73
73
|
assert.match(parity, /machine_fs_delete[\s\S]*?root_id:scratchRoot/);
|
|
74
74
|
assert.doesNotMatch(parity, /machine_fs_(?:write|read|edit_exact|stat|delete)'[^\n]*root_id:'core'/);
|
|
75
|
-
});
|
|
75
|
+
});
|
|
@@ -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 { validateParityEvidence,R41_PREDECESSOR_RELEASE_ID,R41_PREDECESSOR_MANIFEST } from '../scripts/release-parity-r41.mjs';
|
|
5
|
+
import { verifyFinalClosureObject } from '../scripts/final-closure-verify-r41.mjs';
|
|
6
|
+
|
|
7
|
+
const root=new URL('../',import.meta.url);const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
8
|
+
function parity(){const manifest='a'.repeat(64);return {schema:'deadbyte.r41-parity.v1',status:'passed',execution_provider:'deadbyte_mcp',rdc_operation_count:0,
|
|
9
|
+
candidate:{release_id:`v0.13.0-${manifest.slice(0,16)}`,version:'0.13.0',manifest_sha256:manifest},
|
|
10
|
+
immutable_slot:{protected:true,release_root:'C:/immutable/r41',development_root:'D:/Projects/deadbyte-mcp-r41-memory-dev'},
|
|
11
|
+
local_full:{status:'passed',tool_count:80,strict_output_schemas:true},
|
|
12
|
+
public_compact:{status:'passed',tool_count:42,capability_closure:true,gateway_count:6,desktop_armed:false,desktop_observation_receipt_verified:true,desktop_grounding_receipt_verified:true},
|
|
13
|
+
autonomous:{status:'passed',signed_release_verified:true},desktop_guarded:{status:'passed',native_injected:true,replay_performed:false,predispatch_retry_count:0,observation_receipts_verified:1,action_receipts_verified:3},
|
|
14
|
+
deterministic_memory:{status:'passed',goal_count:1,snapshot_count:1,index_count:1},
|
|
15
|
+
before_rollback_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false,desktop_armed:false},rollback:{state:'completed'},restore:{state:'completed'},stage_restore:{status:'restored',manifest_sha256:manifest},
|
|
16
|
+
predecessor:{release_id:R41_PREDECESSOR_RELEASE_ID,version:'0.12.0',manifest_sha256:R41_PREDECESSOR_MANIFEST},predecessor_disarmed:{status:'passed',tool_count:42,capability_closure:true},
|
|
17
|
+
successor:{release_id:`v0.13.0-${manifest.slice(0,16)}`,version:'0.13.0',manifest_sha256:manifest},successor_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false,desktop_armed:false},
|
|
18
|
+
requirements:Object.fromEntries(['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface','desktop_readonly','desktop_guarded_input','deterministic_memory'].map(key=>[key,true]))};}
|
|
19
|
+
|
|
20
|
+
test('R41 parity requires exact R40 predecessor and immutable R41 slot',()=>{const value=parity();assert.equal(validateParityEvidence(value),true);
|
|
21
|
+
assert.throws(()=>validateParityEvidence({...value,predecessor:{...value.predecessor,manifest_sha256:'b'.repeat(64)}}),/predecessor/i);
|
|
22
|
+
assert.throws(()=>validateParityEvidence({...value,immutable_slot:{...value.immutable_slot,development_root:value.immutable_slot.release_root}}),/immutable-slot/i);});
|
|
23
|
+
|
|
24
|
+
test('R41 release machinery binds 0.13.0, R40 predecessor, memory gates and R41 domains',async()=>{const [gate,deferred,paritySource,writer,verifier,evidence,suite]=await Promise.all([
|
|
25
|
+
text('scripts/gate-windows-r41.ps1'),text('scripts/deferred-slot-operation-r41.mjs'),text('scripts/release-parity-r41.mjs'),text('scripts/final-closure-r41.mjs'),text('scripts/final-closure-verify-r41.mjs'),text('scripts/windows-gate-evidence-r41.mjs'),text('scripts/release-parity-tests-r41.ps1')]);
|
|
26
|
+
assert.equal(R41_PREDECESSOR_RELEASE_ID,'v0.12.0-70906ae0a7e4f062');assert.equal(R41_PREDECESSOR_MANIFEST,'70906ae0a7e4f0627efbb5087b40b85677c81ed6d64ed89c0ba2af846e390f39');
|
|
27
|
+
assert.match(gate,/r41-parent-verify/);assert.match(gate,/memory-history-r41\.test\.mjs/);assert.match(gate,/DEADBYTE V0\.13\.0 \/ R41 WINDOWS BATCH GATE: PASS/);
|
|
28
|
+
assert.match(deferred,/--expected-version','0\.13\.0'/);assert.match(paritySource,/deadbyte\.r41-parity\.v1/);
|
|
29
|
+
for(const source of [writer,verifier]){assert.match(source,/DEADBYTE-R41-FINAL-CLOSURE-V1/);assert.match(source,/deadbyte\.r41-final-closure\.v1/);assert.match(source,/R41 DETERMINISTIC MEMORY BASELINE/);}
|
|
30
|
+
assert.equal(typeof verifyFinalClosureObject,'function');assert.match(evidence,/deadbyte\.r41-windows-gate\.v1/);assert.match(suite,/memory-autonomous-integration-r41\.test\.mjs/);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
test('R41 derived memory storage is namespaced by exact release manifest',async()=>{
|
|
35
|
+
const [server,paritySource]=await Promise.all([text('src/mcp-server.mjs'),text('scripts/release-parity-r41.mjs')]);
|
|
36
|
+
assert.match(server,/memoryRoot:path\.join\(autonomousPolicy\.evidence_dir,'memory-r41',packageManifestSha256\)/);
|
|
37
|
+
assert.match(paritySource,/memoryRoot:path\.join\(stateRoot,'evidence','autonomous','memory-r41',candidateManifest\)/);
|
|
38
|
+
});
|
|
@@ -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 { validateParityEvidence,R42_PREDECESSOR_RELEASE_ID,R42_PREDECESSOR_MANIFEST } from '../scripts/release-parity-r42.mjs';
|
|
5
|
+
import { verifyFinalClosureObject } from '../scripts/final-closure-verify-r42.mjs';
|
|
6
|
+
|
|
7
|
+
const root=new URL('../',import.meta.url);const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
8
|
+
function parity(){const manifest='a'.repeat(64);return {schema:'deadbyte.r42-parity.v1',status:'passed',execution_provider:'deadbyte_mcp',rdc_operation_count:0,
|
|
9
|
+
candidate:{release_id:`v0.14.0-${manifest.slice(0,16)}`,version:'0.14.0',manifest_sha256:manifest},
|
|
10
|
+
immutable_slot:{protected:true,release_root:'C:/immutable/r42',development_root:'D:/Projects/deadbyte-mcp/development/deadbyte-mcp-r42-agentic-dev'},
|
|
11
|
+
local_full:{status:'passed',tool_count:80,strict_output_schemas:true},
|
|
12
|
+
public_compact:{status:'passed',tool_count:42,capability_closure:true,gateway_count:6,desktop_armed:false,desktop_observation_receipt_verified:true,desktop_grounding_receipt_verified:true},
|
|
13
|
+
autonomous:{status:'passed',signed_release_verified:true},desktop_guarded:{status:'passed',native_injected:true,replay_performed:false,predispatch_retry_count:0,observation_receipts_verified:1,action_receipts_verified:3},
|
|
14
|
+
deterministic_memory:{status:'passed',goal_count:1,snapshot_count:1,index_count:1},model_eval:{status:'passed',path:'C:/evidence/eval.json',evidence_sha256:'e'.repeat(64),payload_sha256:'f'.repeat(64),suite_sha256:'d'.repeat(64),case_count:3},
|
|
15
|
+
before_rollback_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false,desktop_armed:false},rollback:{state:'completed'},restore:{state:'completed'},stage_restore:{status:'restored',manifest_sha256:manifest},
|
|
16
|
+
predecessor:{release_id:R42_PREDECESSOR_RELEASE_ID,version:'0.13.0',manifest_sha256:R42_PREDECESSOR_MANIFEST},predecessor_disarmed:{status:'passed',tool_count:42,capability_closure:true},
|
|
17
|
+
successor:{release_id:`v0.14.0-${manifest.slice(0,16)}`,version:'0.14.0',manifest_sha256:manifest},successor_disarmed:{status:'passed',capability_closure:true,coding_armed:false,autonomous_armed:false,desktop_armed:false},
|
|
18
|
+
requirements:Object.fromEntries(['tree_read','precondition_mutation','search','owned_process','observation','coding_loop','autonomy','interrupted_recovery','evidence_verification','compact_closure','full_surface','desktop_readonly','desktop_guarded_input','deterministic_memory','model_eval'].map(key=>[key,true]))};}
|
|
19
|
+
|
|
20
|
+
test('R42 parity requires exact R41 predecessor and immutable R42 slot',()=>{const value=parity();assert.equal(validateParityEvidence(value),true);
|
|
21
|
+
assert.throws(()=>validateParityEvidence({...value,predecessor:{...value.predecessor,manifest_sha256:'b'.repeat(64)}}),/predecessor/i);
|
|
22
|
+
assert.throws(()=>validateParityEvidence({...value,immutable_slot:{...value.immutable_slot,development_root:value.immutable_slot.release_root}}),/immutable-slot/i);});
|
|
23
|
+
|
|
24
|
+
test('R42 release machinery binds 0.14.0, R41 predecessor, memory gates and R42 domains',async()=>{const [gate,deferred,paritySource,writer,verifier,evidence,suite]=await Promise.all([
|
|
25
|
+
text('scripts/gate-windows-r42.ps1'),text('scripts/deferred-slot-operation-r42.mjs'),text('scripts/release-parity-r42.mjs'),text('scripts/final-closure-r42.mjs'),text('scripts/final-closure-verify-r42.mjs'),text('scripts/windows-gate-evidence-r42.mjs'),text('scripts/release-parity-tests-r42.ps1')]);
|
|
26
|
+
assert.equal(R42_PREDECESSOR_RELEASE_ID,'v0.13.0-3255be10de4daf08');assert.equal(R42_PREDECESSOR_MANIFEST,'3255be10de4daf0837d67d1ab1913b785b8b8215bc7405823c2ff46968c4b98f');
|
|
27
|
+
assert.match(gate,/r42-parent-verify/);assert.match(gate,/r42-model-backed-eval/);assert.match(gate,/memory-history-r41\.test\.mjs/);assert.match(gate,/DEADBYTE V0\.14\.0 \/ R42 WINDOWS BATCH GATE: PASS/);
|
|
28
|
+
assert.match(deferred,/--expected-version','0\.14\.0'/);assert.match(paritySource,/deadbyte\.r42-parity\.v1/);
|
|
29
|
+
for(const source of [writer,verifier]){assert.match(source,/DEADBYTE-R42-FINAL-CLOSURE-V1/);assert.match(source,/deadbyte\.r42-final-closure\.v1/);assert.match(source,/R42 AGENTIC GOVERNANCE BASELINE/);}
|
|
30
|
+
assert.equal(typeof verifyFinalClosureObject,'function');assert.match(evidence,/deadbyte\.r42-windows-gate\.v1/);assert.match(suite,/memory-autonomous-integration-r41\.test\.mjs/);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
test('R42 preserves release-namespaced deterministic memory storage',async()=>{
|
|
35
|
+
const [server,paritySource]=await Promise.all([text('src/mcp-server.mjs'),text('scripts/release-parity-r42.mjs')]);
|
|
36
|
+
assert.match(server,/memoryRoot:path\.join\(autonomousPolicy\.evidence_dir,'memory-r41',packageManifestSha256\)/);
|
|
37
|
+
assert.match(paritySource,/memoryRoot:path\.join\(stateRoot,'evidence','autonomous','memory-r41',candidateManifest\)/);
|
|
38
|
+
});
|
|
@@ -3,21 +3,22 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import { readFile } from 'node:fs/promises';
|
|
4
4
|
import { createHash } from 'node:crypto';
|
|
5
5
|
const root=new URL('../',import.meta.url);const text=rel=>readFile(new URL(rel,root),'utf8');
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
test('
|
|
6
|
+
const R42_PREDECESSOR_RELEASE_ID='v0.13.0-3255be10de4daf08';
|
|
7
|
+
const R42_PREDECESSOR_MANIFEST='3255be10de4daf0837d67d1ab1913b785b8b8215bc7405823c2ff46968c4b98f';
|
|
8
|
+
test('R42 authority agrees on V0.14.0 and preserves exact sealed public R41 predecessor',async()=>{
|
|
9
9
|
const pkg=JSON.parse(await text('package.json'));
|
|
10
|
-
const [version,controller,gate,readme,architecture,controllerReadme,deferred,parity,closure,closureVerify,windowsGate,semanticConfig]=await Promise.all([
|
|
11
|
-
text('src/version.mjs'),text('controller/deadbyte-controller.ps1'),text('scripts/gate-windows-
|
|
12
|
-
assert.equal(pkg.version,'0.
|
|
13
|
-
assert.equal(pkg.scripts['self-update:deferred'],'node scripts/deferred-slot-operation-
|
|
14
|
-
assert.equal(pkg.scripts['release:final:write'],'node scripts/final-closure-
|
|
10
|
+
const [version,controller,gate,readme,architecture,controllerReadme,deferred,parity,closure,closureVerify,windowsGate,parent,semanticConfig]=await Promise.all([
|
|
11
|
+
text('src/version.mjs'),text('controller/deadbyte-controller.ps1'),text('scripts/gate-windows-r42.ps1'),text('README.txt'),text('docs/ARCHITECTURE.md'),text('controller/README.TXT'),text('scripts/deferred-slot-operation-r42.mjs'),text('scripts/release-parity-r42.mjs'),text('scripts/final-closure-r42.mjs'),text('scripts/final-closure-verify-r42.mjs'),text('scripts/windows-gate-evidence-r42.mjs'),text('R42-PARENT.json'),text('controller/deadbyte-semantic-lsp-config.json')]);
|
|
12
|
+
assert.equal(pkg.version,'0.14.0');assert.equal(pkg.scripts['gate:windows'],'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r42.ps1');
|
|
13
|
+
assert.equal(pkg.scripts['self-update:deferred'],'node scripts/deferred-slot-operation-r42.mjs');assert.equal(pkg.scripts['release:parity'],'node scripts/release-parity-r42.mjs');
|
|
14
|
+
assert.equal(pkg.scripts['release:final:write'],'node scripts/final-closure-r42.mjs');assert.equal(pkg.scripts['release:final:verify'],'node scripts/final-closure-verify-r42.mjs');
|
|
15
15
|
assert.equal(pkg.scripts['desktop:policy:refresh'],'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/init-desktop-policy-r40.ps1');
|
|
16
|
-
assert.match(version,/DEADBYTE_VERSION = '0\.
|
|
17
|
-
assert.match(readme,/^DEADBYTE MCP V0\.
|
|
18
|
-
assert.match(deferred,/--expected-version','0\.
|
|
19
|
-
assert.match(parity,/version==='0\.
|
|
20
|
-
assert.equal(
|
|
16
|
+
assert.match(version,/DEADBYTE_VERSION = '0\.14\.0'/);assert.match(controller,/CONTROLLER V0\.14\.0 \/ R42/);assert.match(gate,/DEADBYTE V0\.14\.0 \/ R42 WINDOWS BATCH GATE: PASS/);
|
|
17
|
+
assert.match(readme,/^DEADBYTE MCP V0\.14\.0 \/ R42 AGENTIC GOVERNANCE BASELINE$/m);assert.match(architecture,/^# DEADBYTE MCP V0\.14\.0 \/ R42 ARCHITECTURE$/m);assert.match(controllerReadme,/^DEADBYTE MCP V0\.14\.0 \/ R42 CONTROLLER$/m);
|
|
18
|
+
assert.match(deferred,/--expected-version','0\.14\.0'/);assert.match(deferred,/--enable-desktop/);assert.match(parity,/R42_PREDECESSOR_RELEASE_ID='v0\.13\.0-3255be10de4daf08'/);assert.match(parity,new RegExp(R42_PREDECESSOR_MANIFEST));
|
|
19
|
+
assert.match(parity,/version==='0\.14\.0'|version:'0\.14\.0'/);assert.match(closure,/version:'0\.14\.0'/);assert.match(closureVerify,/DEADBYTE V0\.14\.0 \/ R42 WINDOWS BATCH GATE: PASS/);assert.match(windowsGate,/version:'0\.14\.0'/);
|
|
20
|
+
assert.equal(JSON.parse(parent).parent_manifest_sha256,R42_PREDECESSOR_MANIFEST);
|
|
21
|
+
assert.equal(createHash('sha256').update(Buffer.from(semanticConfig,'utf8')).digest('hex'),'d274b099a298c1033fea8f1e8849751693bbc0448778d619400acb82d4f53a3b');assert.equal(R42_PREDECESSOR_RELEASE_ID,'v0.13.0-3255be10de4daf08');
|
|
21
22
|
});
|
|
22
23
|
test('R40 keeps ONLINE reuse and PowerShell Host collision fix while Desktop stays explicit',async()=>{const [cli,controller]=await Promise.all([text('src/deadbyte-cli.mjs'),text('controller/deadbyte-controller.ps1')]);assert.match(cli,/controllerRuntimeReady/);assert.match(cli,/Runtime already ONLINE; reusing verified bridge\/cloud\/supervisor/);const start=controller.indexOf('function Recover-AutonomousSupervisor'),end=controller.indexOf('function Show-State',start);assert.ok(start>=0&&end>start);const block=controller.slice(start,end);assert.doesNotMatch(block,/\$host\s*=/i);assert.match(block,/\$hostStatus\s*=\s*Get-HostArmStatus/);assert.match(controller,/armdesktop/);assert.match(controller,/disarmdesktop/);});
|
|
23
24
|
test('sealed R39 tooling remains historical 0.11.3 authority with exact 0.11.2 predecessor',async()=>{const [parity,gate,closure]=await Promise.all([text('scripts/release-parity-r39.mjs'),text('scripts/gate-windows-r39.ps1'),text('scripts/final-closure-r39.mjs')]);assert.match(parity,/R39_PREDECESSOR_RELEASE_ID='v0\.11\.2-058605dfccaa3035'/);assert.match(parity,/version==='0\.11\.3'|version:'0\.11\.3'/);assert.match(gate,/DEADBYTE V0\.11\.3 \/ R39 WINDOWS BATCH GATE: PASS/);assert.match(closure,/version:'0\.11\.3'/);});
|