deadbyte-mcp 0.13.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 +66 -40
- 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/harness/r42-agent-evals.json +48 -0
- package/harness/task-contract.schema.json +33 -0
- package/package.json +9 -7
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/scripts/agent-eval-r42.mjs +46 -0
- package/scripts/deferred-slot-operation-r42.mjs +126 -0
- package/scripts/final-closure-r42.mjs +116 -0
- package/scripts/final-closure-verify-r42.mjs +223 -0
- package/scripts/gate-windows-r42.ps1 +54 -0
- package/scripts/release-parity-r42.mjs +235 -0
- package/scripts/release-parity-tests-r42.ps1 +6 -0
- package/scripts/verify-r42-parent.mjs +101 -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 +2 -0
- 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 +46 -6
- package/src/autonomous-policy.mjs +10 -2
- package/src/autonomous-runtime.mjs +116 -16
- package/src/autonomous-supervisor.mjs +1 -1
- package/src/evidence-publisher-r42.mjs +76 -0
- package/src/mcp-server.mjs +1 -1
- 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/core.test.mjs +1 -1
- package/test/evidence-publisher-r42.test.mjs +53 -0
- package/test/human-clarification-r42.test.mjs +53 -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 +3 -3
- package/test/r42-finalization.test.mjs +38 -0
- package/test/release-version.test.mjs +13 -13
- package/test/task-contract-r42.test.mjs +41 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { runIsolatedEvaluation, buildFreshCriticContext, triageJudgeResult } from '../src/agent-eval-r42.mjs';
|
|
4
|
+
|
|
5
|
+
const H=value=>String(value).repeat(64).slice(0,64);
|
|
6
|
+
|
|
7
|
+
test('R42 generator never receives judge-only oracle or hidden ground truth',async()=>{
|
|
8
|
+
const oracleToken='ORACLE_ONLY_7fca1b';
|
|
9
|
+
let generatorInput,judgeInput;
|
|
10
|
+
const result=await runIsolatedEvaluation({caseSpec:{schema:'deadbyte.agent-eval-case.v1',case_id:'no-leak',
|
|
11
|
+
task:'Return a safe plan.',allowed_context:{files:['a.mjs']},hidden_oracle:{secret:oracleToken,expected:'bounded'},
|
|
12
|
+
acceptance:['No oracle leakage']},
|
|
13
|
+
generator:async input=>{generatorInput=input;return {artifact:{plan:['inspect','verify']},trace:{private_reasoning:'not shared'}};},
|
|
14
|
+
judge:async input=>{judgeInput=input;return {verdict:'pass',findings:[],evidence_refs:[H('1')]};}
|
|
15
|
+
});
|
|
16
|
+
assert.equal(JSON.stringify(generatorInput).includes(oracleToken),false);
|
|
17
|
+
assert.equal(Object.hasOwn(generatorInput,'hidden_oracle'),false);
|
|
18
|
+
assert.equal(judgeInput.hidden_oracle.secret,oracleToken);
|
|
19
|
+
assert.equal(Object.hasOwn(judgeInput,'generator_trace'),false);
|
|
20
|
+
assert.equal(result.advisory,true);
|
|
21
|
+
assert.match(result.case_sha256,/^[0-9a-f]{64}$/);
|
|
22
|
+
assert.match(result.candidate_sha256,/^[0-9a-f]{64}$/);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('R42 fresh critic context contains artifacts and evidence but no implementer assumptions',()=>{
|
|
26
|
+
const context=buildFreshCriticContext({case_id:'fresh-review',artifact:{files:['x.mjs']},evidence:[{id:H('2'),level:'automated'}],
|
|
27
|
+
criteria:['No authority widening']});
|
|
28
|
+
assert.deepEqual(Object.keys(context).sort(),['artifact','case_id','criteria','evidence','schema']);
|
|
29
|
+
assert.equal(JSON.stringify(context).includes('reasoning'),false);
|
|
30
|
+
assert.throws(()=>buildFreshCriticContext({case_id:'bad',artifact:{},evidence:[],criteria:[],implementer_reasoning:'trust me'}),/unknown field/i);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('R42 judge remains advisory and controller triage owns repair decision',()=>{
|
|
34
|
+
const judge={schema:'deadbyte.agent-eval-judge-result.v1',verdict:'fail',advisory:true,
|
|
35
|
+
findings:[{code:'AUTH_WIDEN',severity:'critical',evidence:'schema admits command'}],evidence_refs:[H('3')]};
|
|
36
|
+
const triage=triageJudgeResult(judge,{critical_action:'pause',noncritical_action:'repair'});
|
|
37
|
+
assert.deepEqual(triage,{action:'pause',reason_codes:['AUTH_WIDEN'],judge_advisory:true});
|
|
38
|
+
assert.throws(()=>triageJudgeResult({...judge,advisory:false},{critical_action:'pause',noncritical_action:'repair'}),/advisory/i);
|
|
39
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { runAgentEvalSuiteR42, readAndVerifyR42EvalEvidence } from '../src/agent-eval-runner-r42.mjs';
|
|
7
|
+
|
|
8
|
+
const H=value=>String(value).repeat(64).slice(0,64);
|
|
9
|
+
const suite={schema:'deadbyte.agent-eval-suite.v1',suite_id:'suite',
|
|
10
|
+
cases:[{schema:'deadbyte.agent-eval-case.v1',case_id:'case-1',task:'Safe action',
|
|
11
|
+
allowed_context:{visible:'YES'},hidden_oracle:{secret:'ORACLE_ONLY',expected:'bounded'},acceptance:['bounded']}]
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
test('R42 model eval keeps hidden oracle out of generator and binds passed evidence to manifest',async()=>{
|
|
15
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-eval-'));
|
|
16
|
+
const calls=[];
|
|
17
|
+
try{
|
|
18
|
+
const run=await runAgentEvalSuiteR42({suite,subjectManifestSha256:H('a'),evidenceRoot:root,
|
|
19
|
+
clock:()=>new Date('2026-09-20T02:00:00.000Z'),
|
|
20
|
+
requestModel:async call=>{
|
|
21
|
+
calls.push(call);
|
|
22
|
+
if(call.role==='generator')return {backend:'fake',model:'fake',response_id:'g1',raw_text:JSON.stringify({artifact:{plan:['inspect','verify']}})};
|
|
23
|
+
return {backend:'fake',model:'fake',response_id:'j1',raw_text:JSON.stringify({schema:'deadbyte.agent-eval-judge-result.v1',
|
|
24
|
+
verdict:'pass',advisory:true,findings:[],evidence_refs:[H('1')]})};
|
|
25
|
+
}});
|
|
26
|
+
assert.equal(calls.length,2);
|
|
27
|
+
assert.equal(calls[0].prompt.includes('ORACLE_ONLY'),false);
|
|
28
|
+
assert.equal(calls[1].prompt.includes('ORACLE_ONLY'),true);
|
|
29
|
+
assert.equal(run.payload.status,'passed');
|
|
30
|
+
assert.equal(run.payload.subject_manifest_sha256,H('a'));
|
|
31
|
+
assert.equal(run.publication.status,'created');
|
|
32
|
+
const verified=await readAndVerifyR42EvalEvidence(run.publication.path,{subjectManifestSha256:H('a'),suiteSha256:run.payload.suite_sha256});
|
|
33
|
+
assert.equal(verified.status,'passed');
|
|
34
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('R42 model eval rejects failed judge and publishes no PASS evidence',async()=>{
|
|
38
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-eval-fail-'));
|
|
39
|
+
try{
|
|
40
|
+
await assert.rejects(runAgentEvalSuiteR42({suite,subjectManifestSha256:H('b'),evidenceRoot:root,
|
|
41
|
+
requestModel:async call=>call.role==='generator'
|
|
42
|
+
?{raw_text:JSON.stringify({artifact:{plan:['unsafe']}})}
|
|
43
|
+
:{raw_text:JSON.stringify({schema:'deadbyte.agent-eval-judge-result.v1',verdict:'fail',advisory:true,
|
|
44
|
+
findings:[{code:'AUTH',severity:'critical',evidence:'authority widening'}],evidence_refs:[H('2')]})}}),/suite failed/i);
|
|
45
|
+
await assert.rejects(readFile(path.join(root,'agent_eval',`r42-${H('b').slice(0,16)}-`),'utf8'));
|
|
46
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('R42 eval evidence tampering fails independent verification',async()=>{
|
|
50
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-eval-tamper-'));
|
|
51
|
+
try{
|
|
52
|
+
const run=await runAgentEvalSuiteR42({suite,subjectManifestSha256:H('c'),evidenceRoot:root,
|
|
53
|
+
requestModel:async call=>call.role==='generator'
|
|
54
|
+
?{raw_text:JSON.stringify({artifact:{plan:['safe']}})}
|
|
55
|
+
:{raw_text:JSON.stringify({schema:'deadbyte.agent-eval-judge-result.v1',verdict:'pass',advisory:true,findings:[],evidence_refs:[H('3')]})}});
|
|
56
|
+
const raw=JSON.parse(await readFile(run.publication.path,'utf8'));
|
|
57
|
+
raw.payload.cases[0].result.verdict='fail';
|
|
58
|
+
await writeFile(run.publication.path,JSON.stringify(raw));
|
|
59
|
+
await assert.rejects(readAndVerifyR42EvalEvidence(run.publication.path,{subjectManifestSha256:H('c')}),/hash mismatch/i);
|
|
60
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
61
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {
|
|
4
|
+
bindApprovalSubject, validateBoundApproval, createTaskDag, invalidateTaskDag,
|
|
5
|
+
createEvidenceClaim, evidenceSatisfies, deriveEffectiveRigor, taskDagFromPlan,
|
|
6
|
+
createDecisionRecord, evaluateDecisionFreshness
|
|
7
|
+
} from '../src/agent-governance-r42.mjs';
|
|
8
|
+
|
|
9
|
+
const H=value=>String(value).repeat(64).slice(0,64);
|
|
10
|
+
|
|
11
|
+
test('R42 approval binds exact artifact, event head, scope and expiry',()=>{
|
|
12
|
+
const subject=bindApprovalSubject({goal_id:H('1'),reviewed_event_seq:9,reviewed_event_sha256:H('2'),
|
|
13
|
+
journal_head_sha256:H('3'),scope:'resume_goal',subject:{diff_id:H('4'),operation_count:2}});
|
|
14
|
+
const approval={schema:'deadbyte.bound-approval.v1',approval_subject_sha256:subject.approval_subject_sha256,
|
|
15
|
+
reviewed_event_seq:9,reviewed_event_sha256:H('2'),journal_head_sha256:H('3'),scope:'resume_goal',
|
|
16
|
+
issued_at_utc:'2026-09-20T01:00:00.000Z',expires_at_utc:'2026-09-20T01:05:00.000Z',provenance:'operator_mcp'};
|
|
17
|
+
assert.equal(validateBoundApproval({approval,subject,now:new Date('2026-09-20T01:01:00Z')}),true);
|
|
18
|
+
assert.throws(()=>validateBoundApproval({approval:{...approval,journal_head_sha256:H('9')},subject,
|
|
19
|
+
now:new Date('2026-09-20T01:01:00Z')}),/journal|subject/i);
|
|
20
|
+
assert.throws(()=>validateBoundApproval({approval,subject:{...subject,subject:{diff_id:H('5'),operation_count:2}},
|
|
21
|
+
now:new Date('2026-09-20T01:01:00Z')}),/subject/i);
|
|
22
|
+
assert.throws(()=>validateBoundApproval({approval,subject,now:new Date('2026-09-20T01:06:00Z')}),/expired/i);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('R42 canonical DAG propagates STALE only through affected descendants',()=>{
|
|
26
|
+
const dag=createTaskDag({run_id:'run-1',goal_id:H('a'),tasks:[
|
|
27
|
+
{task_id:'inspect',depends_on:[],input_artifacts:['source'],output_artifacts:['analysis']},
|
|
28
|
+
{task_id:'patch',depends_on:['inspect'],input_artifacts:['analysis'],output_artifacts:['diff']},
|
|
29
|
+
{task_id:'test',depends_on:['patch'],input_artifacts:['diff'],output_artifacts:['test-result']},
|
|
30
|
+
{task_id:'docs',depends_on:[],input_artifacts:['readme'],output_artifacts:['docs-result']}
|
|
31
|
+
]});
|
|
32
|
+
const next=invalidateTaskDag(dag,{changed_artifact_ids:['analysis']});
|
|
33
|
+
assert.deepEqual(next.tasks.filter(task=>task.state==='STALE').map(task=>task.task_id),['patch','test']);
|
|
34
|
+
assert.equal(next.tasks.find(task=>task.task_id==='inspect').state,'PENDING');
|
|
35
|
+
assert.equal(next.tasks.find(task=>task.task_id==='docs').state,'PENDING');
|
|
36
|
+
assert.throws(()=>createTaskDag({run_id:'x',goal_id:H('a'),tasks:[
|
|
37
|
+
{task_id:'a',depends_on:['b'],input_artifacts:[],output_artifacts:[]},
|
|
38
|
+
{task_id:'b',depends_on:['a'],input_artifacts:[],output_artifacts:[]}
|
|
39
|
+
]}),/cycle/i);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('R42 one canonical DAG is deterministically derived from the authoritative plan',()=>{
|
|
43
|
+
const plan={steps:[{step_id:'inspect',status:'completed'},{step_id:'patch',status:'active'},{step_id:'verify',status:'pending'}]};
|
|
44
|
+
const one=taskDagFromPlan({run_id:H('7'),goal_id:H('7'),plan});
|
|
45
|
+
const two=taskDagFromPlan({run_id:H('7'),goal_id:H('7'),plan});
|
|
46
|
+
assert.equal(one.dag_sha256,two.dag_sha256);
|
|
47
|
+
assert.deepEqual(one.tasks.map(task=>[task.task_id,task.depends_on,task.state]),[
|
|
48
|
+
['inspect',[],'COMPLETE'],['patch',['inspect'],'RUNNING'],['verify',['patch'],'PENDING']
|
|
49
|
+
]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('R42 evidence ladder never lets weak evidence masquerade as runtime proof',()=>{
|
|
53
|
+
const source=createEvidenceClaim({claim_id:'claim-1',statement:'provider shape matches source',level:'source',refs:[H('b')]});
|
|
54
|
+
assert.equal(evidenceSatisfies(source,'source'),true);
|
|
55
|
+
assert.equal(evidenceSatisfies(source,'automated'),false);
|
|
56
|
+
assert.equal(evidenceSatisfies(source,'runtime'),false);
|
|
57
|
+
assert.throws(()=>createEvidenceClaim({claim_id:'claim-2',statement:'bad',level:'runtime',refs:[]}),/reference/i);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('R42 rigor is derived once and cannot downgrade below risk minimum',()=>{
|
|
61
|
+
assert.deepEqual(deriveEffectiveRigor({project_default:'lightweight',risk_level:'high',explicit_override:'structured'}),{
|
|
62
|
+
project_default:'lightweight',risk_minimum:'agentic',explicit_override:'structured',effective_rigor:'agentic'
|
|
63
|
+
});
|
|
64
|
+
assert.equal(deriveEffectiveRigor({project_default:'structured',risk_level:'low',explicit_override:'agentic'}).effective_rigor,'agentic');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('R42 decisions become stale deterministically without deleting history',()=>{
|
|
68
|
+
const record=createDecisionRecord({decision_id:'provider-choice',decision:'Use Responses adapter',reason:'strict bounded JSON',
|
|
69
|
+
evidence_refs:[H('c')],invalidates_if:[
|
|
70
|
+
{kind:'artifact_sha_changed',artifact_id:'provider-contract',expected_sha256:H('d')},
|
|
71
|
+
{kind:'policy_sha_changed',expected_sha256:H('e')}
|
|
72
|
+
]});
|
|
73
|
+
assert.equal(evaluateDecisionFreshness(record,{artifact_sha256:{'provider-contract':H('d')},policy_sha256:H('e')}).state,'CURRENT');
|
|
74
|
+
const stale=evaluateDecisionFreshness(record,{artifact_sha256:{'provider-contract':H('f')},policy_sha256:H('e')});
|
|
75
|
+
assert.equal(stale.state,'STALE');
|
|
76
|
+
assert.deepEqual(stale.invalidated_by,[{kind:'artifact_sha_changed',artifact_id:'provider-contract',expected_sha256:H('d'),observed_sha256:H('f')}]);
|
|
77
|
+
});
|
|
@@ -75,7 +75,8 @@ test('R34 missing authority waits durably and approval resumes the same phase af
|
|
|
75
75
|
assert.equal(journal.events.filter(event=>event.type==='action_started').length,0);
|
|
76
76
|
|
|
77
77
|
await f.arm();
|
|
78
|
-
const approved = await f.runtime.approve({goalId:goal.goal_id,decision:'approve'
|
|
78
|
+
const approved = await f.runtime.approve({goalId:goal.goal_id,decision:'approve',
|
|
79
|
+
approvalSubjectSha256:result.loop.approval_subject.approval_subject_sha256});
|
|
79
80
|
assert.equal(approved.status,'approved');
|
|
80
81
|
assert.equal(approved.loop.phase,'ACTING');
|
|
81
82
|
const resumed = await f.runtime.run({goalId:goal.goal_id,maxCycles:2});
|
|
@@ -21,7 +21,7 @@ test('npx CLI reports the canonical package version through --version, -v and ve
|
|
|
21
21
|
for(const arg of ['--version','-v','version']){
|
|
22
22
|
const result=spawnSync(process.execPath,[cliPath,arg],{cwd:root,encoding:'utf8',windowsHide:true});
|
|
23
23
|
assert.equal(result.status,0,result.stderr);
|
|
24
|
-
assert.equal(result.stdout.trim(),'0.
|
|
24
|
+
assert.equal(result.stdout.trim(),'0.14.0');
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
|
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.14.0');
|
|
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}$/);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import {
|
|
7
|
+
publishEvidenceAtomic, createExecutionReceipt, createVerificationResult
|
|
8
|
+
} from '../src/evidence-publisher-r42.mjs';
|
|
9
|
+
|
|
10
|
+
const H=value=>String(value).repeat(64).slice(0,64);
|
|
11
|
+
|
|
12
|
+
test('R42 evidence publication is atomic, no-clobber and idempotent for identical bytes',async()=>{
|
|
13
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-evidence-'));
|
|
14
|
+
try{
|
|
15
|
+
const one=await publishEvidenceAtomic({root,kind:'eval',evidenceId:'case-1',payload:{status:'passed',score:1}});
|
|
16
|
+
assert.equal(one.status,'created');
|
|
17
|
+
const two=await publishEvidenceAtomic({root,kind:'eval',evidenceId:'case-1',payload:{status:'passed',score:1}});
|
|
18
|
+
assert.equal(two.status,'existing');
|
|
19
|
+
assert.equal(two.evidence_sha256,one.evidence_sha256);
|
|
20
|
+
const bytes=await readFile(one.path);
|
|
21
|
+
assert.equal(H('0')===one.evidence_sha256,false);
|
|
22
|
+
assert.match(bytes.toString('utf8'),/"payload_sha256":"[0-9a-f]{64}"/);
|
|
23
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('R42 conflicting concurrent evidence identity fails closed without overwrite',async()=>{
|
|
27
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r42-evidence-race-'));
|
|
28
|
+
try{
|
|
29
|
+
const settled=await Promise.allSettled([
|
|
30
|
+
publishEvidenceAtomic({root,kind:'closure',evidenceId:'release-final',payload:{candidate:'a'}}),
|
|
31
|
+
publishEvidenceAtomic({root,kind:'closure',evidenceId:'release-final',payload:{candidate:'b'}})
|
|
32
|
+
]);
|
|
33
|
+
assert.equal(settled.filter(item=>item.status==='fulfilled').length,1);
|
|
34
|
+
assert.equal(settled.filter(item=>item.status==='rejected').length,1);
|
|
35
|
+
assert.match(String(settled.find(item=>item.status==='rejected').reason),/EVIDENCE_ID_CONFLICT/);
|
|
36
|
+
const winner=settled.find(item=>item.status==='fulfilled').value;
|
|
37
|
+
const parsed=JSON.parse(await readFile(winner.path,'utf8'));
|
|
38
|
+
assert.ok(['a','b'].includes(parsed.payload.candidate));
|
|
39
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('R42 execution receipt and outcome verification are distinct typed artifacts',()=>{
|
|
43
|
+
const receipt=createExecutionReceipt({execution_id:'exec-1',subject_sha256:H('1'),request_sha256:H('2'),
|
|
44
|
+
observed_exit_code:0,started_at_utc:'2026-09-20T01:00:00.000Z',completed_at_utc:'2026-09-20T01:00:01.000Z'});
|
|
45
|
+
assert.equal(receipt.schema,'deadbyte.execution-receipt.v1');
|
|
46
|
+
assert.equal(Object.hasOwn(receipt,'outcome_passed'),false);
|
|
47
|
+
const verified=createVerificationResult({verification_id:'verify-1',subject_sha256:H('1'),
|
|
48
|
+
execution_receipt_sha256:receipt.receipt_sha256,outcome_passed:true,oracle:'runtime_behavior',evidence_refs:[H('3')]});
|
|
49
|
+
assert.equal(verified.schema,'deadbyte.verification-result.v1');
|
|
50
|
+
assert.equal(verified.outcome_passed,true);
|
|
51
|
+
assert.throws(()=>createExecutionReceipt({execution_id:'exec-2',subject_sha256:H('1'),request_sha256:H('2'),
|
|
52
|
+
observed_exit_code:0,started_at_utc:'2026-09-20T01:00:00.000Z',completed_at_utc:'2026-09-20T01:00:01.000Z',outcome_passed:true}),/unknown field/i);
|
|
53
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createR34Fixture, planCreateDecision, sendPlannerDecision } from './helpers/autonomous-r34-fixture.mjs';
|
|
4
|
+
|
|
5
|
+
async function startPlannedGoal(f) {
|
|
6
|
+
const goal=await f.runtime.submit({submissionId:'r42-clarify',rootId:'project',title:'Clarification',
|
|
7
|
+
goal:'Choose the correct bounded implementation.',acceptance:'Use the operator choice.',maxIterations:8});
|
|
8
|
+
let result=await f.runtime.run({goalId:goal.goal_id,maxCycles:2});
|
|
9
|
+
result=await sendPlannerDecision(f.runtime,goal.goal_id,result,planCreateDecision(),{maxCycles:2});
|
|
10
|
+
return {goal,result};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test('R42 planner can request typed human clarification and resume with signed answer context',async()=>{
|
|
14
|
+
const f=await createR34Fixture();
|
|
15
|
+
try {
|
|
16
|
+
const {goal,result:first}=await startPlannedGoal(f);
|
|
17
|
+
const clarify={schema:'deadbyte.autonomous-decision.v2',kind:'clarify',
|
|
18
|
+
question:'Which compatibility target should be authoritative?',
|
|
19
|
+
choices:['Preserve R41 behavior','Adopt R42 behavior']};
|
|
20
|
+
const paused=await sendPlannerDecision(f.runtime,goal.goal_id,first,clarify,{maxCycles:2});
|
|
21
|
+
assert.equal(paused.status,'paused');
|
|
22
|
+
assert.equal(paused.reason,'human_input_required');
|
|
23
|
+
assert.deepEqual(paused.loop.clarification,{question:clarify.question,choices:clarify.choices});
|
|
24
|
+
const subject=paused.loop.approval_subject.approval_subject_sha256;
|
|
25
|
+
await assert.rejects(f.runtime.approve({goalId:goal.goal_id,decision:'approve',answer:'Preserve R41 behavior',
|
|
26
|
+
approvalSubjectSha256:'f'.repeat(64)}),/approval subject mismatch/i);
|
|
27
|
+
await assert.rejects(f.runtime.approve({goalId:goal.goal_id,decision:'approve',approvalSubjectSha256:subject}),/answer.*required/i);
|
|
28
|
+
const approved=await f.runtime.approve({goalId:goal.goal_id,decision:'approve',answer:'Preserve R41 behavior',
|
|
29
|
+
approvalSubjectSha256:subject});
|
|
30
|
+
assert.equal(approved.status,'approved');
|
|
31
|
+
const next=await f.runtime.run({goalId:goal.goal_id,maxCycles:2});
|
|
32
|
+
assert.equal(next.status,'input_required');
|
|
33
|
+
assert.match(next.planner_request.prompt,/Preserve R41 behavior/);
|
|
34
|
+
const events=await f.runtime.events({goalId:goal.goal_id,fromSeq:1,limit:200});
|
|
35
|
+
const provided=events.events.find(event=>event.type==='human_input_provided');
|
|
36
|
+
assert.equal(provided.payload.answer,'Preserve R41 behavior');
|
|
37
|
+
assert.match(provided.payload.answer_sha256,/^[0-9a-f]{64}$/);
|
|
38
|
+
const approval=events.events.find(event=>event.type==='approval_granted');
|
|
39
|
+
assert.equal(approval.payload.approval_subject_sha256,subject);
|
|
40
|
+
assert.equal(approval.payload.scope,'human_clarification');
|
|
41
|
+
} finally { await f.cleanup(); }
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('R42 clarification contract rejects injected fields and oversized choices',async()=>{
|
|
45
|
+
const f=await createR34Fixture();
|
|
46
|
+
try {
|
|
47
|
+
const {goal,result:first}=await startPlannedGoal(f);
|
|
48
|
+
const injected={schema:'deadbyte.autonomous-decision.v2',kind:'clarify',question:'Choose?',choices:[],command:'cmd.exe'};
|
|
49
|
+
const repaired=await sendPlannerDecision(f.runtime,goal.goal_id,first,injected,{maxCycles:2});
|
|
50
|
+
assert.equal(repaired.status,'input_required');
|
|
51
|
+
assert.match(repaired.planner_request.prompt,/PREVIOUS_RESPONSE_REJECTED/);
|
|
52
|
+
} finally { await f.cleanup(); }
|
|
53
|
+
});
|
|
@@ -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.r41-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
|
});
|
|
@@ -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,22 +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
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-
|
|
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-
|
|
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(JSON.parse(parent).parent_manifest_sha256,
|
|
21
|
-
assert.equal(createHash('sha256').update(Buffer.from(semanticConfig,'utf8')).digest('hex'),'d274b099a298c1033fea8f1e8849751693bbc0448778d619400acb82d4f53a3b');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');
|
|
22
22
|
});
|
|
23
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/);});
|
|
24
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'/);});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { createR34Fixture } from './helpers/autonomous-r34-fixture.mjs';
|
|
4
|
+
|
|
5
|
+
const contract={
|
|
6
|
+
schema:'deadbyte.task-contract.v1',
|
|
7
|
+
scope:['src/autonomous-*','test/*r42*'],
|
|
8
|
+
non_goals:['No generic shell','No implicit grant renewal'],
|
|
9
|
+
constraints:['Preserve R41 compatibility','Use exact preconditions'],
|
|
10
|
+
evidence_requirements:['Focused tests pass','Signed journal verifies'],
|
|
11
|
+
risk_level:'high',
|
|
12
|
+
clarification_policy:'ask_when_blocked',
|
|
13
|
+
project_default:'lightweight',
|
|
14
|
+
explicit_override:'structured'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
test('R42 task contract is identity-bound and visible to every planner round',async()=>{
|
|
18
|
+
const f=await createR34Fixture();
|
|
19
|
+
try {
|
|
20
|
+
const goal=await f.runtime.submit({submissionId:'r42-task-contract',rootId:'project',title:'Contract',
|
|
21
|
+
goal:'Implement bounded behavior.',acceptance:'All required evidence passes.',taskContract:contract,maxIterations:8});
|
|
22
|
+
const status=await f.runtime.status({goalId:goal.goal_id});
|
|
23
|
+
assert.equal(status.state,'pending');
|
|
24
|
+
const run=await f.runtime.run({goalId:goal.goal_id,maxCycles:1});
|
|
25
|
+
assert.equal(run.status,'input_required');
|
|
26
|
+
assert.match(run.planner_request.prompt,/deadbyte\.task-contract\.v1/);
|
|
27
|
+
assert.match(run.planner_request.prompt,/No generic shell/);
|
|
28
|
+
assert.match(run.planner_request.prompt,/Signed journal verifies/);
|
|
29
|
+
assert.match(run.planner_request.prompt,/"effective_rigor":"agentic"/);
|
|
30
|
+
} finally { await f.cleanup(); }
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('R42 task contract rejects authority widening fields and invalid risk',async()=>{
|
|
34
|
+
const f=await createR34Fixture();
|
|
35
|
+
try {
|
|
36
|
+
await assert.rejects(f.runtime.submit({submissionId:'r42-task-injected',rootId:'project',title:'Contract',
|
|
37
|
+
goal:'Reject injection.',acceptance:'Fail closed.',taskContract:{...contract,shell:'cmd.exe'}}),/unknown field|task contract/i);
|
|
38
|
+
await assert.rejects(f.runtime.submit({submissionId:'r42-task-risk',rootId:'project',title:'Contract',
|
|
39
|
+
goal:'Reject risk.',acceptance:'Fail closed.',taskContract:{...contract,risk_level:'unbounded'}}),/risk_level/i);
|
|
40
|
+
} finally { await f.cleanup(); }
|
|
41
|
+
});
|