deadbyte-mcp 0.9.0 → 0.10.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/MANIFEST.SHA256 +119 -91
- package/README.txt +16 -11
- package/bench/fixtures/corpus.json +32 -13
- package/bench/fixtures/r36/case-map.json +8 -0
- package/bin/WORKER-REGISTRY.txt +3 -3
- package/bin/appcontainer-stage.exe +0 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.exe +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.exe +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.exe +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.exe +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.exe +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.exe +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.exe +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.exe +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.exe +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.exe +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.exe +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.exe +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +8 -6
- package/controller/deadbyte-controller.ps1 +48 -2
- package/controller/deadbyte-process-policy.json +5 -5
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/R36-CAPABILITY-EVIDENCE.md +43 -0
- package/docs/superpowers/plans/2026-09-18-r36-zero-loss-autonomy.md +739 -0
- package/docs/superpowers/specs/2026-09-18-r36-zero-loss-autonomy-design.md +640 -0
- package/package.json +1 -1
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/scripts/deferred-slot-operation.mjs +53 -15
- package/scripts/final-closure-verify.mjs +88 -39
- package/scripts/final-closure.mjs +63 -56
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/release-parity-tests.ps1 +9 -0
- package/scripts/release-parity.mjs +149 -139
- package/scripts/windows-gate-evidence.mjs +5 -5
- package/src/autonomous-context-engine.mjs +2 -1
- package/src/autonomous-mcp-tools.mjs +5 -1
- package/src/autonomous-output-contracts.mjs +4 -4
- package/src/autonomous-planner-contracts.mjs +36 -1
- package/src/autonomous-planner.mjs +25 -3
- package/src/autonomous-runtime.mjs +191 -21
- package/src/capability-benchmark-runner.mjs +86 -1
- package/src/capability-benchmark.mjs +45 -0
- package/src/capability-ledger.mjs +158 -0
- package/src/coding-mcp-tools.mjs +31 -17
- package/src/coding-output-contracts.mjs +48 -10
- package/src/coding-plane.mjs +45 -9
- package/src/coding-search.mjs +130 -47
- package/src/compact-gateway-mcp-tools.mjs +128 -0
- package/src/compact-gateway-output-contracts.mjs +16 -0
- package/src/deadbyte-cli.mjs +51 -28
- package/src/machine-fs-smoke-client.mjs +1 -1
- package/src/machine-fs.mjs +51 -8
- package/src/mcp-server.mjs +32 -9
- package/src/native-diff-v2.mjs +337 -0
- package/src/native-diff.mjs +50 -2
- package/src/observation-smoke-client.mjs +1 -1
- package/src/operator-surface.mjs +7 -1
- package/src/process-runtime.mjs +98 -11
- package/src/process-smoke-client.mjs +11 -3
- package/src/r36-compact-disarmed-probe.mjs +50 -0
- package/src/r36-full-surface-probe.mjs +56 -0
- package/src/remote-live-log.mjs +76 -0
- package/src/remote-mcp-autonomous-smoke-client.mjs +7 -3
- package/src/remote-mcp-coding-smoke-client.mjs +1 -1
- package/src/remote-mcp-r36-parity-client.mjs +175 -0
- package/src/remote-mcp-smoke-client.mjs +112 -56
- package/src/runtime-update.mjs +51 -1
- package/src/search-cursor.mjs +45 -0
- package/src/semantic-code.mjs +72 -5
- package/src/semantic-lsp-backend.mjs +39 -3
- package/src/version.mjs +1 -1
- package/test/autonomous-capability-r36.test.mjs +151 -0
- package/test/autonomous-runtime.test.mjs +2 -2
- package/test/capability-benchmark-r36.test.mjs +107 -0
- package/test/capability-benchmark-semantic-r36.test.mjs +52 -0
- package/test/capability-claims-r36.test.mjs +23 -0
- package/test/capability-ledger-r36.test.mjs +102 -0
- package/test/coding-catalog-consistency.test.mjs +2 -2
- package/test/coding-plane.test.mjs +2 -2
- package/test/coding-runtime.test.mjs +16 -0
- package/test/coding-search-r36.test.mjs +90 -0
- package/test/compact-catalog-r36.test.mjs +37 -0
- package/test/compact-gateway-r36.test.mjs +66 -0
- package/test/contained.test.mjs +1 -1
- package/test/core.test.mjs +1 -1
- package/test/deferred-slot-operation.test.mjs +9 -0
- package/test/fixtures/lsp-framed-server.mjs +2 -0
- package/test/helpers/autonomous-r34-fixture.mjs +5 -3
- package/test/multi-file-read.test.mjs +3 -0
- package/test/native-diff-topology-r36.test.mjs +105 -0
- package/test/package-boundary.test.mjs +6 -0
- package/test/process-longrun-r36.test.mjs +82 -0
- package/test/process-release-gate.test.mjs +9 -0
- package/test/production-docs.test.mjs +3 -3
- package/test/prompts-resources.test.mjs +7 -1
- package/test/r33-closeout-regression.test.mjs +4 -3
- package/test/r33-finalization.test.mjs +14 -9
- package/test/r36-finalization.test.mjs +104 -0
- package/test/r36-release-identity.test.mjs +52 -0
- package/test/release-version.test.mjs +18 -15
- package/test/remote-live-log-r36.test.mjs +37 -0
- package/test/remote-live-log-recovery-r36.test.mjs +41 -0
- package/test/remote-r24-catalog.test.mjs +13 -0
- package/test/remote-session-cli.test.mjs +40 -30
- package/test/runtime-self-update.test.mjs +58 -1
- package/test/semantic-lsp-backend.test.mjs +9 -0
- package/test/semantic-r36-rename.test.mjs +82 -0
- package/deadbyte-mcp-0.8.9.tgz +0 -0
|
@@ -11,6 +11,7 @@ import { deriveLoopState, repairFingerprint } from './autonomous-loop-state.mjs'
|
|
|
11
11
|
import { judgeProgress, stallDisposition } from './autonomous-progress.mjs';
|
|
12
12
|
import { classifyProviderFailure, deriveCircuit, providerCallDisposition, providerCircuitId } from './provider-circuit.mjs';
|
|
13
13
|
import { verifyObservationReceiptFile } from './observation-runtime.mjs';
|
|
14
|
+
import { R36_CAPABILITY_LEDGER } from './capability-ledger.mjs';
|
|
14
15
|
|
|
15
16
|
export const AUTONOMOUS_GOAL_SCHEMA = 'deadbyte.autonomous-goal.v1';
|
|
16
17
|
export const AUTONOMOUS_EVENT_SCHEMA = 'deadbyte.autonomous-event.v1';
|
|
@@ -318,17 +319,38 @@ function normalizeGoal(policy, { submissionId, rootId, title = '', goal, accepta
|
|
|
318
319
|
return Object.freeze({ ...body, goal_sha256:sha256Object(body) });
|
|
319
320
|
}
|
|
320
321
|
|
|
321
|
-
|
|
322
|
+
function configuredCapabilityManifest({machineFsRuntime,observationRuntime,processRuntime,semanticRuntime}) {
|
|
323
|
+
const plannerReachable=id => id === 'coding.stat' || id === 'coding.search' || id === 'coding.files_read' ||
|
|
324
|
+
id.startsWith('semantic.') || id.startsWith('native_diff.') || id.startsWith('process.') ||
|
|
325
|
+
id.startsWith('machine_fs.') || id.startsWith('observation.') || id === 'autonomous.release_gate';
|
|
326
|
+
const runtimeEnabled=entry => {
|
|
327
|
+
if (entry.runtime_flag === 'DEADBYTE_CODING_RUNTIME' || entry.runtime_flag === 'DEADBYTE_AUTONOMOUS_RUNTIME') return true;
|
|
328
|
+
if (entry.runtime_flag === 'DEADBYTE_MACHINE_FS_RUNTIME') return Boolean(machineFsRuntime);
|
|
329
|
+
if (entry.runtime_flag === 'DEADBYTE_PROCESS_RUNTIME') return Boolean(processRuntime);
|
|
330
|
+
if (entry.runtime_flag === 'DEADBYTE_OBSERVATION_RUNTIME') return Boolean(observationRuntime);
|
|
331
|
+
return entry.runtime_flag === null;
|
|
332
|
+
};
|
|
333
|
+
const entries=R36_CAPABILITY_LEDGER.entries
|
|
334
|
+
.filter(entry=>entry.production && !entry.host_only && plannerReachable(entry.id) && runtimeEnabled(entry))
|
|
335
|
+
.filter(entry=>!entry.id.startsWith('semantic.') || Boolean(semanticRuntime))
|
|
336
|
+
.map(entry=>({id:entry.id,authority:entry.authority,mutating:entry.mutating,full_tool:entry.full_tool,
|
|
337
|
+
compact_tool:entry.compact_tool,compact_op:entry.compact_op}));
|
|
338
|
+
return Object.freeze({schema:'deadbyte.capability-manifest.v1',ledger_sha256:R36_CAPABILITY_LEDGER.ledger_sha256,
|
|
339
|
+
entries:Object.freeze(entries)});
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async function plannerView(goal, state, codingRuntime, capabilityManifest) {
|
|
322
343
|
const tree = await codingRuntime.tree({ rootId:goal.root_id, path:'.', maxDepth:4, maxEntries:600 });
|
|
323
344
|
return { mutation_epoch:state.mutation_epoch, planner_round:state.planner_round, tree:tree.entries,
|
|
324
345
|
contexts:state.contexts.slice(-16), observations:state.observations.slice(-24), active_plan:state.active_plan,
|
|
346
|
+
capabilities:capabilityManifest,
|
|
325
347
|
recent_decisions:state.decisions.slice(-8).map(item => ({ planner_round:item.planner_round,
|
|
326
348
|
action:item.decision?.action, summary:item.decision?.summary })) };
|
|
327
349
|
}
|
|
328
350
|
function requestIdFor(goalId, plannerRound, journalHead) {
|
|
329
351
|
return sha256Object({ schema:'deadbyte.autonomous-planner-request.v1', goal_id:goalId, planner_round:plannerRound, journal_head_sha256:journalHead });
|
|
330
352
|
}
|
|
331
|
-
async function requestPlanner(ctx, goal, events, state, policy, codingRuntime, signingKeyPath) {
|
|
353
|
+
async function requestPlanner(ctx, goal, events, state, policy, codingRuntime, capabilityManifest, signingKeyPath) {
|
|
332
354
|
if (state.pending_request) return state.pending_request;
|
|
333
355
|
const round = state.planner_round + 1;
|
|
334
356
|
if (round > goal.max_iterations) {
|
|
@@ -339,7 +361,7 @@ async function requestPlanner(ctx, goal, events, state, policy, codingRuntime, s
|
|
|
339
361
|
await appendEvent(ctx,events,signingKeyPath,'goal_paused',{ reason:'wall_time_limit', max_wall_ms:policy.limits.max_wall_ms });
|
|
340
362
|
return null;
|
|
341
363
|
}
|
|
342
|
-
const view = await plannerView(goal,state,codingRuntime);
|
|
364
|
+
const view = await plannerView(goal,state,codingRuntime,capabilityManifest);
|
|
343
365
|
let prompt = buildPlannerPrompt({ goal:{ title:goal.title, goal:goal.goal, acceptance:goal.acceptance }, policy, view });
|
|
344
366
|
const repair = [...(state.planner_rejections ?? [])].reverse().find(item => item.planner_round === round) ?? null;
|
|
345
367
|
if (repair) {
|
|
@@ -476,9 +498,9 @@ async function requestProviderWithCircuit({ctx,events,goal,policy,pending,signin
|
|
|
476
498
|
throw error;
|
|
477
499
|
}
|
|
478
500
|
}
|
|
479
|
-
async function acceptPlannerDecision({ ctx, events, goal, state, policy, codingRuntime, signingKeyPath, plannerResponse }) {
|
|
501
|
+
async function acceptPlannerDecision({ ctx, events, goal, state, policy, codingRuntime, capabilityManifest, signingKeyPath, plannerResponse }) {
|
|
480
502
|
let currentState = state;
|
|
481
|
-
let pending = currentState.pending_request ?? await requestPlanner(ctx,goal,events,currentState,policy,codingRuntime,signingKeyPath);
|
|
503
|
+
let pending = currentState.pending_request ?? await requestPlanner(ctx,goal,events,currentState,policy,codingRuntime,capabilityManifest,signingKeyPath);
|
|
482
504
|
if (!pending) return null;
|
|
483
505
|
let suppliedResponse = plannerResponse;
|
|
484
506
|
while (pending) {
|
|
@@ -517,7 +539,7 @@ async function acceptPlannerDecision({ ctx, events, goal, state, policy, codingR
|
|
|
517
539
|
return { needs_planner:false, rejected:true, paused:true };
|
|
518
540
|
}
|
|
519
541
|
currentState = deriveState(goal,events);
|
|
520
|
-
pending = await requestPlanner(ctx,goal,events,currentState,policy,codingRuntime,signingKeyPath);
|
|
542
|
+
pending = await requestPlanner(ctx,goal,events,currentState,policy,codingRuntime,capabilityManifest,signingKeyPath);
|
|
521
543
|
if (!pending) return null;
|
|
522
544
|
if (policy.planner.backend === 'client_sampling') return { needs_planner:true, request:pending };
|
|
523
545
|
continue;
|
|
@@ -557,6 +579,18 @@ async function executeInspect({ ctx, events, goal, decisionEvent, decision, codi
|
|
|
557
579
|
}
|
|
558
580
|
|
|
559
581
|
const DELEGATED_MUTATIONS = new Set(['process_start','process_action','process_terminate','observation_search_cancel']);
|
|
582
|
+
const CAPABILITY_BY_ACTION=Object.freeze({
|
|
583
|
+
search:'coding.search',stat:'coding.stat',multi_read:'coding.files_read',
|
|
584
|
+
semantic_outline:'semantic.outline',semantic_definition:'semantic.definition',semantic_references:'semantic.references',
|
|
585
|
+
semantic_diagnostics:'semantic.diagnostics',semantic_implementations:'semantic.implementations',semantic_rename_preview:'semantic.rename_preview',
|
|
586
|
+
native_diff_apply:'native_diff.apply',native_diff_verify:'native_diff.verify',
|
|
587
|
+
process_start:'process.start',process_read:'process.read',process_status:'process.status',process_list:'process.list',process_action:'process.action',process_terminate:'process.terminate',
|
|
588
|
+
machine_fs_stat:'machine_fs.stat',machine_fs_list:'machine_fs.list',machine_fs_read:'machine_fs.read',machine_fs_mkdir:'machine_fs.mkdir',machine_fs_move:'machine_fs.move',machine_fs_delete:'machine_fs.delete',
|
|
589
|
+
machine_stat:'machine_fs.stat',machine_list:'machine_fs.list',machine_read:'machine_fs.read',
|
|
590
|
+
observation_search_start:'observation.search_start',observation_search_status:'observation.search_status',observation_search_page:'observation.search_page',observation_search_cancel:'observation.search_cancel',
|
|
591
|
+
observation_process_list:'observation.process_list',observation_system_status:'observation.system_status'
|
|
592
|
+
});
|
|
593
|
+
function capabilityIdForOperation(operation){return CAPABILITY_BY_ACTION[operation?.kind]??null;}
|
|
560
594
|
function assertDelegatedIdentity(events, operation) {
|
|
561
595
|
if (['observation_search_status','observation_search_page','observation_search_cancel'].includes(operation.kind)) {
|
|
562
596
|
const owned = events.some(event => event.type === 'delegated_action_completed' &&
|
|
@@ -570,8 +604,45 @@ function assertDelegatedIdentity(events, operation) {
|
|
|
570
604
|
}
|
|
571
605
|
}
|
|
572
606
|
async function invokeDelegatedOperation(goal, operation, runtimes) {
|
|
573
|
-
const { machineFsRuntime, observationRuntime, processRuntime } = runtimes;
|
|
607
|
+
const { codingRuntime, semanticRuntime, nativeDiffRuntime, machineFsRuntime, observationRuntime, processRuntime } = runtimes;
|
|
574
608
|
switch (operation.kind) {
|
|
609
|
+
case 'stat':
|
|
610
|
+
return codingRuntime.stat({rootId:goal.root_id,relativePath:operation.path,hash:operation.hash});
|
|
611
|
+
case 'search':
|
|
612
|
+
return codingRuntime.search({rootId:goal.root_id,path:operation.path,pattern:operation.pattern,target:operation.target,mode:operation.mode,
|
|
613
|
+
caseSensitive:operation.case_sensitive,maxResults:operation.max_results,maxFileBytes:operation.max_file_bytes,
|
|
614
|
+
maxScanBytes:operation.max_scan_bytes,pageSize:operation.page_size,cursor:operation.cursor});
|
|
615
|
+
case 'multi_read':
|
|
616
|
+
return codingRuntime.filesRead({rootId:goal.root_id,files:operation.files,maxTotalBytes:operation.max_total_bytes});
|
|
617
|
+
case 'semantic_outline':
|
|
618
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
619
|
+
return semanticRuntime.outline({rootId:goal.root_id,relativePath:operation.path,maxSymbols:operation.max_symbols});
|
|
620
|
+
case 'semantic_definition':
|
|
621
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
622
|
+
return semanticRuntime.definition({rootId:goal.root_id,relativePath:operation.path,line:operation.line,column:operation.column,maxResults:operation.max_results});
|
|
623
|
+
case 'semantic_references':
|
|
624
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
625
|
+
return semanticRuntime.references({rootId:goal.root_id,relativePath:operation.path,line:operation.line,column:operation.column,maxResults:operation.max_results});
|
|
626
|
+
case 'semantic_diagnostics':
|
|
627
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
628
|
+
return semanticRuntime.diagnostics({rootId:goal.root_id,relativePath:operation.path,maxResults:operation.max_results});
|
|
629
|
+
case 'semantic_implementations':
|
|
630
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
631
|
+
return semanticRuntime.implementations({rootId:goal.root_id,relativePath:operation.path,line:operation.line,column:operation.column,maxResults:operation.max_results});
|
|
632
|
+
case 'semantic_rename_preview':
|
|
633
|
+
if (!semanticRuntime) throw new Error('semantic runtime unavailable');
|
|
634
|
+
return semanticRuntime.renamePreview({rootId:goal.root_id,relativePath:operation.path,line:operation.line,column:operation.column,newName:operation.new_name});
|
|
635
|
+
case 'native_diff_verify':
|
|
636
|
+
return nativeDiffRuntime.verify({diffId:operation.diff_id});
|
|
637
|
+
case 'machine_fs_stat':
|
|
638
|
+
if (!machineFsRuntime) throw new Error('machine filesystem runtime unavailable');
|
|
639
|
+
return machineFsRuntime.stat({rootId:goal.root_id,relativePath:operation.path,hash:operation.hash});
|
|
640
|
+
case 'machine_fs_list':
|
|
641
|
+
if (!machineFsRuntime) throw new Error('machine filesystem runtime unavailable');
|
|
642
|
+
return machineFsRuntime.list({rootId:goal.root_id,relativePath:operation.path,cursor:operation.cursor,limit:operation.limit,hashFiles:operation.hash_files});
|
|
643
|
+
case 'machine_fs_read':
|
|
644
|
+
if (!machineFsRuntime) throw new Error('machine filesystem runtime unavailable');
|
|
645
|
+
return machineFsRuntime.read({rootId:goal.root_id,relativePath:operation.path,offset:operation.offset,maxBytes:operation.max_bytes,hashFile:operation.hash_file});
|
|
575
646
|
case 'machine_stat':
|
|
576
647
|
if (!machineFsRuntime) throw new Error('machine filesystem runtime unavailable');
|
|
577
648
|
return machineFsRuntime.stat({ rootId:goal.root_id, relativePath:operation.path, hash:operation.hash });
|
|
@@ -605,7 +676,7 @@ async function invokeDelegatedOperation(goal, operation, runtimes) {
|
|
|
605
676
|
return observationRuntime.systemStatus();
|
|
606
677
|
case 'process_start':
|
|
607
678
|
if (!processRuntime) throw new Error('process runtime unavailable');
|
|
608
|
-
return processRuntime.start({ profileId:operation.profile_id, rootId:goal.root_id, cwd:operation.cwd, args:[] });
|
|
679
|
+
return processRuntime.start({ profileId:operation.profile_id, rootId:goal.root_id, cwd:operation.cwd, args:operation.args??[] });
|
|
609
680
|
case 'process_read':
|
|
610
681
|
if (!processRuntime) throw new Error('process runtime unavailable');
|
|
611
682
|
return processRuntime.read({ sessionId:operation.session_id, offset:operation.offset, maxBytes:operation.max_bytes });
|
|
@@ -647,7 +718,9 @@ async function verifyDelegatedEvidence(operation, result, runtimes, verifyKeyPat
|
|
|
647
718
|
}
|
|
648
719
|
async function executeDelegate({ ctx, events, goal, decisionEvent, decision, policy, runtimes, assertRunAuthority,
|
|
649
720
|
signingKeyPath, verifyKeyPath }) {
|
|
650
|
-
const
|
|
721
|
+
const capabilityId=capabilityIdForOperation(decision.operation);
|
|
722
|
+
if(!capabilityId) throw new Error(`unsupported typed capability action '${String(decision.operation?.kind)}'`);
|
|
723
|
+
const actionKey = `capability-${decisionEvent.event_sha256}`;
|
|
651
724
|
const prior = [...events].reverse().find(event => event.type === 'delegated_action_completed' && event.payload?.action_key === actionKey);
|
|
652
725
|
if (prior) return { status:'completed', result:prior.payload.result, existing:true };
|
|
653
726
|
const started = [...events].reverse().find(event => event.type === 'delegated_action_started' && event.payload?.action_key === actionKey);
|
|
@@ -656,7 +729,7 @@ async function executeDelegate({ ctx, events, goal, decisionEvent, decision, pol
|
|
|
656
729
|
operation_kind:decision.operation.kind });
|
|
657
730
|
return { status:'paused' };
|
|
658
731
|
}
|
|
659
|
-
await appendEvent(ctx,events,signingKeyPath,'delegated_action_started',{ action_key:actionKey,
|
|
732
|
+
await appendEvent(ctx,events,signingKeyPath,'delegated_action_started',{ action_key:actionKey, capability_id:capabilityId,
|
|
660
733
|
decision_event_sha256:decisionEvent.event_sha256, operation:decision.operation });
|
|
661
734
|
try {
|
|
662
735
|
assertDelegatedIdentity(events,decision.operation);
|
|
@@ -666,7 +739,7 @@ async function executeDelegate({ ctx, events, goal, decisionEvent, decision, pol
|
|
|
666
739
|
throw new Error('delegated result exceeds autonomous context bound');
|
|
667
740
|
}
|
|
668
741
|
const evidence = await verifyDelegatedEvidence(decision.operation,result,runtimes,verifyKeyPath);
|
|
669
|
-
await appendEvent(ctx,events,signingKeyPath,'delegated_action_completed',{ action_key:actionKey,
|
|
742
|
+
await appendEvent(ctx,events,signingKeyPath,'delegated_action_completed',{ action_key:actionKey, capability_id:capabilityId,
|
|
670
743
|
decision_event_sha256:decisionEvent.event_sha256, operation:decision.operation, result, evidence });
|
|
671
744
|
return { status:'completed', result, evidence };
|
|
672
745
|
} catch (error) {
|
|
@@ -729,11 +802,17 @@ async function appendPatchCommit({ctx,events,signingKeyPath,started,decisionEven
|
|
|
729
802
|
const prior = patchCommitForAction(events,actionId);
|
|
730
803
|
if (prior) return prior;
|
|
731
804
|
const action = started.payload.action;
|
|
805
|
+
const verifiedPaths=[...new Set((verified.final_states??[]).flatMap(item=>[
|
|
806
|
+
typeof item?.path==='string'?item.path:null,
|
|
807
|
+
typeof item?.source_path==='string'?item.source_path:null,
|
|
808
|
+
typeof item?.destination_path==='string'?item.destination_path:null
|
|
809
|
+
].filter(Boolean)))].sort((a,b)=>a.localeCompare(b,'en'));
|
|
732
810
|
return appendEvent(ctx,events,signingKeyPath,'native_diff_committed',{
|
|
733
811
|
action_id:actionId, decision_event_sha256:decisionEvent.event_sha256, diff_id:action.diff_id,
|
|
734
812
|
diff_receipt_sha256:verified.receipt_sha256, mutation_epoch:started.payload.target_mutation_epoch,
|
|
735
813
|
mutation_count:started.payload.mutation_count, operation_count:action.operation_count,
|
|
736
|
-
paths:action.paths
|
|
814
|
+
paths:Array.isArray(action.paths)&&action.paths.length>0?action.paths:verifiedPaths,
|
|
815
|
+
coding_receipts_verified:verified.coding_receipts_verified,
|
|
737
816
|
...(recovered ? { recovered:true } : {})
|
|
738
817
|
});
|
|
739
818
|
}
|
|
@@ -826,6 +905,67 @@ async function executePatch({ ctx, events, goal, state, decisionEvent, decision,
|
|
|
826
905
|
return { status:profiles.some(item => item.status === 'paused') ? 'paused' : 'completed',
|
|
827
906
|
diff_id:diffId, mutation_epoch:epoch, profiles, recovered };
|
|
828
907
|
}
|
|
908
|
+
async function executePreparedDiff({ctx,events,goal,state,decisionEvent,diffId,expectedOperationCount,
|
|
909
|
+
policy,codingRuntime,nativeDiffRuntime,signingKeyPath}) {
|
|
910
|
+
let started=patchStartedForDecision(events,decisionEvent.event_sha256);
|
|
911
|
+
if(!started&&state.mutation_count+expectedOperationCount>policy.limits.max_mutations){
|
|
912
|
+
await appendEvent(ctx,events,signingKeyPath,'goal_paused',{reason:'mutation_limit',max_mutations:policy.limits.max_mutations});
|
|
913
|
+
return {status:'paused'};
|
|
914
|
+
}
|
|
915
|
+
if(!started){
|
|
916
|
+
const coordinates=patchActionCoordinates(state);
|
|
917
|
+
const action={kind:'patch',diff_id:diffId,operation_count:expectedOperationCount,paths:[]};
|
|
918
|
+
const identity=actionIdentity({goalId:goal.goal_id,planId:coordinates.planId,planVersion:coordinates.planVersion,
|
|
919
|
+
stepId:coordinates.stepId,mutationEpoch:state.mutation_epoch,decisionEventSha:decisionEvent.event_sha256,action});
|
|
920
|
+
started=await appendEvent(ctx,events,signingKeyPath,'action_started',{
|
|
921
|
+
...identity,decision_event_sha256:decisionEvent.event_sha256,plan_id:coordinates.planId,
|
|
922
|
+
plan_version:coordinates.planVersion,step_id:coordinates.stepId,mutation_epoch:state.mutation_epoch,
|
|
923
|
+
target_mutation_epoch:state.mutation_epoch+1,mutation_count:expectedOperationCount,action
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
const actionId=started.payload.action_id;
|
|
927
|
+
const existingCompletion=patchCompletionForAction(events,actionId);
|
|
928
|
+
if(existingCompletion){
|
|
929
|
+
const committed=patchCommitForAction(events,actionId);
|
|
930
|
+
if(!committed) throw new Error('completed prepared diff action missing native diff commit');
|
|
931
|
+
const epoch=committed.payload.mutation_epoch;
|
|
932
|
+
const profiles=await runMutationProfiles({ctx,events,goal,epoch,actionKey:`mutation-${epoch}`,policy,codingRuntime,signingKeyPath});
|
|
933
|
+
return {status:profiles.some(item=>item.status==='paused')?'paused':'completed',diff_id:diffId,mutation_epoch:epoch,profiles,recovered:true};
|
|
934
|
+
}
|
|
935
|
+
const reconciliation=await reconcileStartedAction({startedEvent:started,journal:events,runtimes:{nativeDiffRuntime,codingRuntime}});
|
|
936
|
+
if(reconciliation.classification==='ambiguous'){
|
|
937
|
+
if(!events.some(event=>event.type==='waiting_entered'&&event.payload?.action_id===actionId)){
|
|
938
|
+
await appendEvent(ctx,events,signingKeyPath,'waiting_entered',{reason:'ambiguous_interrupted_action',action_id:actionId,
|
|
939
|
+
decision_event_sha256:decisionEvent.event_sha256,detail:truncated(reconciliation.reason,512)});
|
|
940
|
+
}
|
|
941
|
+
await appendEvent(ctx,events,signingKeyPath,'goal_paused',{reason:'ambiguous_interrupted_action',action_id:actionId,
|
|
942
|
+
decision_event_sha256:decisionEvent.event_sha256});
|
|
943
|
+
return {status:'paused',reason:'ambiguous_interrupted_action'};
|
|
944
|
+
}
|
|
945
|
+
let verified; let recovered=false;
|
|
946
|
+
if(reconciliation.classification==='executed_verified'){
|
|
947
|
+
recovered=true;
|
|
948
|
+
verified=await verifyPatchDiff(nativeDiffRuntime,diffId);
|
|
949
|
+
if(verified.operation_count!==expectedOperationCount) throw new Error(`prepared native diff operation count mismatch: expected ${expectedOperationCount}, verified ${verified.operation_count}`);
|
|
950
|
+
if(!events.some(event=>event.type==='action_reconciled'&&event.payload?.action_id===actionId)){
|
|
951
|
+
await appendEvent(ctx,events,signingKeyPath,'action_reconciled',{action_id:actionId,request_sha256:started.payload.request_sha256,
|
|
952
|
+
decision_event_sha256:decisionEvent.event_sha256,classification:reconciliation.classification,evidence:reconciliation.evidence});
|
|
953
|
+
}
|
|
954
|
+
}else{
|
|
955
|
+
await nativeDiffRuntime.apply({diffId,expectedOperationCount});
|
|
956
|
+
verified=await verifyPatchDiff(nativeDiffRuntime,diffId);
|
|
957
|
+
if(verified.operation_count!==expectedOperationCount) throw new Error(`prepared native diff operation count mismatch: expected ${expectedOperationCount}, verified ${verified.operation_count}`);
|
|
958
|
+
}
|
|
959
|
+
const committed=await appendPatchCommit({ctx,events,signingKeyPath,started,decisionEvent,verified,recovered});
|
|
960
|
+
if(!patchCompletionForAction(events,actionId)){
|
|
961
|
+
await appendEvent(ctx,events,signingKeyPath,'action_completed',{action_id:actionId,request_sha256:started.payload.request_sha256,
|
|
962
|
+
decision_event_sha256:decisionEvent.event_sha256,classification:'executed_verified',diff_id:diffId,
|
|
963
|
+
receipt_sha256:verified.receipt_sha256,recovered});
|
|
964
|
+
}
|
|
965
|
+
const epoch=committed.payload.mutation_epoch;
|
|
966
|
+
const profiles=await runMutationProfiles({ctx,events,goal,epoch,actionKey:`mutation-${epoch}`,policy,codingRuntime,signingKeyPath});
|
|
967
|
+
return {status:profiles.some(item=>item.status==='paused')?'paused':'completed',diff_id:diffId,mutation_epoch:epoch,profiles,recovered};
|
|
968
|
+
}
|
|
829
969
|
async function runRequiredReleaseProfiles({ ctx, events, goal, state, policy, codingRuntime, signingKeyPath }) {
|
|
830
970
|
const requiredIds = Object.entries(policy.profiles)
|
|
831
971
|
.filter(([,profile]) => profile.required_for_release)
|
|
@@ -1012,7 +1152,7 @@ function r34ReasonHash(goal,decisionEvent,reason) {
|
|
|
1012
1152
|
decision_event_sha256:decisionEvent.event_sha256,reason:String(reason ?? '')});
|
|
1013
1153
|
}
|
|
1014
1154
|
async function executeR34Decision({ctx,events,goal,state,decisionEvent,decision,policy,codingRuntime,
|
|
1015
|
-
nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime,assertRunAuthority,
|
|
1155
|
+
nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime,semanticRuntime,assertRunAuthority,
|
|
1016
1156
|
signingKeyPath,verifyKeyPath}) {
|
|
1017
1157
|
let loop=deriveLoopState(goal,events);
|
|
1018
1158
|
if (decision.kind === 'plan_create') {
|
|
@@ -1075,7 +1215,36 @@ async function executeR34Decision({ctx,events,goal,state,decisionEvent,decision,
|
|
|
1075
1215
|
} else if (decision.action.kind === 'delegate') {
|
|
1076
1216
|
outcome=await executeDelegate({ctx,events,goal,decisionEvent,
|
|
1077
1217
|
decision:{operation:decision.action.operation},policy,
|
|
1078
|
-
runtimes:{machineFsRuntime,observationRuntime,processRuntime},assertRunAuthority,signingKeyPath,verifyKeyPath});
|
|
1218
|
+
runtimes:{codingRuntime,semanticRuntime,nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime},assertRunAuthority,signingKeyPath,verifyKeyPath});
|
|
1219
|
+
} else if (decision.action.kind === 'native_diff_apply') {
|
|
1220
|
+
await assertRunAuthority(goal.root_id);
|
|
1221
|
+
outcome=await executePreparedDiff({ctx,events,goal,state,decisionEvent,diffId:decision.action.diff_id,
|
|
1222
|
+
expectedOperationCount:decision.action.expected_operation_count,policy,codingRuntime,nativeDiffRuntime,signingKeyPath});
|
|
1223
|
+
} else if (['machine_fs_mkdir','machine_fs_move','machine_fs_delete'].includes(decision.action.kind)) {
|
|
1224
|
+
await assertRunAuthority(goal.root_id);
|
|
1225
|
+
if(!machineFsRuntime) throw new Error('machine filesystem runtime unavailable');
|
|
1226
|
+
let operations;
|
|
1227
|
+
if(decision.action.kind==='machine_fs_mkdir') {
|
|
1228
|
+
operations=[{kind:'mkdir',path:decision.action.path}];
|
|
1229
|
+
} else if(decision.action.kind==='machine_fs_move') {
|
|
1230
|
+
operations=[{kind:'move',source_path:decision.action.source_path,destination_path:decision.action.destination_path,
|
|
1231
|
+
expected_source_identity:decision.action.expected_source_identity}];
|
|
1232
|
+
} else {
|
|
1233
|
+
const topology=await machineFsRuntime.state({rootId:goal.root_id,relativePath:decision.action.path});
|
|
1234
|
+
if(!topology.exists||topology.identity_sha256!==decision.action.expected_source_identity) throw new Error(`machine fs delete identity precondition mismatch '${decision.action.path}'`);
|
|
1235
|
+
if(topology.kind==='directory') operations=[{kind:'rmdir',path:decision.action.path,expected_source_identity:decision.action.expected_source_identity}];
|
|
1236
|
+
else {
|
|
1237
|
+
const file=await codingRuntime.fileState({rootId:goal.root_id,relativePath:decision.action.path});
|
|
1238
|
+
if(!file.exists||!SHA256_RE.test(file.sha256??'')) throw new Error(`machine fs delete file precondition unavailable '${decision.action.path}'`);
|
|
1239
|
+
operations=[{kind:'delete',path:decision.action.path,expected_sha256:file.sha256}];
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
outcome=await executePatch({ctx,events,goal,state,decisionEvent,decision:{operations,summary:`R36 ${decision.action.kind}`},
|
|
1243
|
+
nativeDiffRuntime,policy,codingRuntime,signingKeyPath});
|
|
1244
|
+
} else if (capabilityIdForOperation(decision.action)) {
|
|
1245
|
+
outcome=await executeDelegate({ctx,events,goal,decisionEvent,
|
|
1246
|
+
decision:{operation:decision.action},policy,
|
|
1247
|
+
runtimes:{codingRuntime,semanticRuntime,nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime},assertRunAuthority,signingKeyPath,verifyKeyPath});
|
|
1079
1248
|
} else {
|
|
1080
1249
|
throw new Error(`unsupported R34 action '${String(decision.action.kind)}'`);
|
|
1081
1250
|
}
|
|
@@ -1087,10 +1256,10 @@ async function executeR34Decision({ctx,events,goal,state,decisionEvent,decision,
|
|
|
1087
1256
|
evidence_head:loop.evidence_head_sha256,release_ready:false,
|
|
1088
1257
|
acceptance_failures:afterState.observations.filter(item=>item?.passed===false).length};
|
|
1089
1258
|
const evidence={
|
|
1090
|
-
native_diff_verified:decision.action.kind
|
|
1259
|
+
native_diff_verified:['patch','native_diff_apply','machine_fs_mkdir','machine_fs_move','machine_fs_delete'].includes(decision.action.kind) && afterState.mutation_epoch > state.mutation_epoch,
|
|
1091
1260
|
new_profile_evidence:decision.action.kind === 'run_profile' && outcome.status === 'passed' &&
|
|
1092
1261
|
afterState.observations.length > state.observations.length,
|
|
1093
|
-
diagnostic_narrowed:decision.action.kind === 'delegate' && afterState.observations.length > state.observations.length,
|
|
1262
|
+
diagnostic_narrowed:(decision.action.kind === 'delegate' || capabilityIdForOperation(decision.action)) && afterState.observations.length > state.observations.length,
|
|
1094
1263
|
interrupted_action_recovered:outcome.recovered === true
|
|
1095
1264
|
};
|
|
1096
1265
|
const progress=judgeProgress({before,after,decision,evidence});
|
|
@@ -1179,12 +1348,12 @@ async function executeR34Decision({ctx,events,goal,state,decisionEvent,decision,
|
|
|
1179
1348
|
}
|
|
1180
1349
|
|
|
1181
1350
|
async function executeDecision({ ctx, events, goal, state, decisionEvent, policy, codingRuntime,
|
|
1182
|
-
nativeDiffRuntime, machineFsRuntime, observationRuntime, processRuntime, assertRunAuthority,
|
|
1351
|
+
nativeDiffRuntime, machineFsRuntime, observationRuntime, processRuntime, semanticRuntime, assertRunAuthority,
|
|
1183
1352
|
signingKeyPath, verifyKeyPath }) {
|
|
1184
1353
|
const decision = decisionEvent.decision;
|
|
1185
1354
|
if (decision?.schema === 'deadbyte.autonomous-decision.v2') {
|
|
1186
1355
|
const outcome=await executeR34Decision({ctx,events,goal,state,decisionEvent,decision,policy,codingRuntime,
|
|
1187
|
-
nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime,assertRunAuthority,
|
|
1356
|
+
nativeDiffRuntime,machineFsRuntime,observationRuntime,processRuntime,semanticRuntime,assertRunAuthority,
|
|
1188
1357
|
signingKeyPath,verifyKeyPath});
|
|
1189
1358
|
await appendEvent(ctx,events,signingKeyPath,'decision_completed',{
|
|
1190
1359
|
decision_event_sha256:decisionEvent.event_sha256,action:decision.kind,
|
|
@@ -1269,9 +1438,10 @@ function isAuthorityUnavailable(error) {
|
|
|
1269
1438
|
}
|
|
1270
1439
|
|
|
1271
1440
|
export function createAutonomousRuntime({ policy, codingRuntime, nativeDiffRuntime, machineFsRuntime = null,
|
|
1272
|
-
observationRuntime = null, processRuntime = null, signingKeyPath, verifyKeyPath }) {
|
|
1441
|
+
observationRuntime = null, processRuntime = null, semanticRuntime = null, signingKeyPath, verifyKeyPath }) {
|
|
1273
1442
|
if (!policy || !codingRuntime || !nativeDiffRuntime) throw new Error('autonomous runtime requires policy/coding/native-diff runtimes');
|
|
1274
1443
|
if (!signingKeyPath || !verifyKeyPath) throw new Error('autonomous runtime requires trust keys');
|
|
1444
|
+
const capabilityManifest=configuredCapabilityManifest({machineFsRuntime,observationRuntime,processRuntime,semanticRuntime});
|
|
1275
1445
|
async function sessionStatus() {
|
|
1276
1446
|
const autonomous = await autonomousSessionStatus(policy);
|
|
1277
1447
|
const coding = await codingRuntime.sessionStatus();
|
|
@@ -1488,7 +1658,7 @@ export function createAutonomousRuntime({ policy, codingRuntime, nativeDiffRunti
|
|
|
1488
1658
|
try {
|
|
1489
1659
|
outcome = await executeDecision({ ctx,events:journal,goal,state,
|
|
1490
1660
|
decisionEvent:state.pending_decision,policy,codingRuntime,nativeDiffRuntime,machineFsRuntime,
|
|
1491
|
-
observationRuntime,processRuntime,assertRunAuthority,signingKeyPath,verifyKeyPath });
|
|
1661
|
+
observationRuntime,processRuntime,semanticRuntime,assertRunAuthority,signingKeyPath,verifyKeyPath });
|
|
1492
1662
|
} catch (error) {
|
|
1493
1663
|
const loop=loopStateOrNull(goal,journal);
|
|
1494
1664
|
if (!loop || loop.pending_action || !isAuthorityUnavailable(error)) throw error;
|
|
@@ -1512,7 +1682,7 @@ export function createAutonomousRuntime({ policy, codingRuntime, nativeDiffRunti
|
|
|
1512
1682
|
}
|
|
1513
1683
|
continue;
|
|
1514
1684
|
}
|
|
1515
|
-
const accepted = await acceptPlannerDecision({ ctx,events:journal,goal,state,policy,codingRuntime,
|
|
1685
|
+
const accepted = await acceptPlannerDecision({ ctx,events:journal,goal,state,policy,codingRuntime,capabilityManifest,
|
|
1516
1686
|
signingKeyPath,plannerResponse:suppliedResponse });
|
|
1517
1687
|
suppliedResponse = null;
|
|
1518
1688
|
if (accepted?.needs_planner) {
|
|
@@ -4,7 +4,7 @@ import { readdir, readFile, stat } from 'node:fs/promises';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { canonicalJson } from './canonical-json.mjs';
|
|
7
|
-
import { buildCapabilityBenchmark } from './capability-benchmark.mjs';
|
|
7
|
+
import { buildCapabilityBenchmark, buildR36CapabilityBenchmark } from './capability-benchmark.mjs';
|
|
8
8
|
|
|
9
9
|
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
10
10
|
const TEST_TIMEOUT_MS=180_000;
|
|
@@ -106,3 +106,88 @@ export async function runCapabilityBenchmark({rootUrl,definitions=benchmarkCaseD
|
|
|
106
106
|
}
|
|
107
107
|
return buildCapabilityBenchmark({suite_id:'r35-offline-v1',cases});
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
export const R36_BENCHMARK_CASE_IDS=Object.freeze([
|
|
111
|
+
'repository_tree_exploration','literal_content_search','regex_content_search','filename_path_search',
|
|
112
|
+
'deterministic_search_paging_cancel','bounded_multi_file_read','rich_stat_reparse_handling','stale_edit_race_rejection',
|
|
113
|
+
'transactional_multi_file_native_diff','topology_mkdir_move_delete_rollback','semantic_typescript_navigation',
|
|
114
|
+
'semantic_python_navigation','semantic_rust_navigation','semantic_cpp_navigation','diagnostics_normalization',
|
|
115
|
+
'implementation_lookup','cross_file_rename_transaction','long_process_lifecycle','policy_defined_process_action',
|
|
116
|
+
'process_crash_reconciliation','autonomous_failing_test_repair','autonomous_search_semantic_patch_test',
|
|
117
|
+
'release_gate_finish_without_evidence_refusal','provider_bridge_interruption_recovery','remote_result_replay_deduplication',
|
|
118
|
+
'compact_connector_capability_closure','live_log_request_before_result','live_log_redaction',
|
|
119
|
+
'forged_stale_receipt_rejection','rollback_r35_restore_r36'
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
const r36Def=(case_id,purpose,test_files,fixture_files,{test_name_pattern=null,pass_witness=null,round_trips=2,stale_rejected=false,recovery_success=true,release_gate_result='not_applicable'}={})=>Object.freeze({
|
|
123
|
+
case_id,purpose,test_files:Object.freeze([...test_files]),fixture_files:Object.freeze([...fixture_files]),
|
|
124
|
+
...(test_name_pattern?{test_name_pattern}:{}),...(pass_witness?{pass_witness}:{}),round_trips,stale_rejected,recovery_success,
|
|
125
|
+
capability_reachable:true,evidence_verified:true,release_gate_result
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const R36_DEFINITIONS=Object.freeze([
|
|
129
|
+
r36Def('repository_tree_exploration','repository tree exploration',['test/coding-plane.test.mjs'],['test/coding-plane.test.mjs'],{round_trips:1}),
|
|
130
|
+
r36Def('literal_content_search','literal content search',['test/coding-search-r36.test.mjs'],['test/coding-search-r36.test.mjs'],{test_name_pattern:'R36 regex search returns multiple matches',pass_witness:'R36 regex search returns multiple matches',round_trips:2}),
|
|
131
|
+
r36Def('regex_content_search','regex content search',['test/coding-search-r36.test.mjs'],['test/coding-search-r36.test.mjs'],{test_name_pattern:'R36 regex search returns multiple matches',pass_witness:'R36 regex search returns multiple matches',round_trips:2}),
|
|
132
|
+
r36Def('filename_path_search','filename/path search',['test/coding-search-r36.test.mjs'],['test/coding-search-r36.test.mjs'],{test_name_pattern:'R36 path search does not decode',pass_witness:'R36 path search does not decode',round_trips:2}),
|
|
133
|
+
r36Def('deterministic_search_paging_cancel','deterministic paging/cancel',['test/coding-search-r36.test.mjs','test/observation-runtime.test.mjs'],['test/coding-search-r36.test.mjs','test/observation-runtime.test.mjs'],{round_trips:4}),
|
|
134
|
+
r36Def('bounded_multi_file_read','bounded multi-file read',['test/multi-file-read.test.mjs'],['test/multi-file-read.test.mjs'],{round_trips:1}),
|
|
135
|
+
r36Def('rich_stat_reparse_handling','rich stat and reparse denial',['test/coding-runtime.test.mjs','test/native-diff-topology-r36.test.mjs'],['test/coding-runtime.test.mjs','test/native-diff-topology-r36.test.mjs'],{test_name_pattern:'(?:R36 coding stat exposes|R36 Native Diff V2 denies topology through reparse)',round_trips:3,stale_rejected:true}),
|
|
136
|
+
r36Def('stale_edit_race_rejection','stale-edit race rejection',['test/coding-runtime.test.mjs','test/native-diff-topology-r36.test.mjs'],['test/coding-runtime.test.mjs','test/native-diff-topology-r36.test.mjs'],{test_name_pattern:'(?:rejects mutation when lease is absent or precondition is stale|rejects stale move identity)',round_trips:3,stale_rejected:true}),
|
|
137
|
+
r36Def('transactional_multi_file_native_diff','transactional multi-file Native Diff',['test/native-diff.test.mjs'],['test/native-diff.test.mjs'],{test_name_pattern:'native diff commits exact preconditioned edits',pass_witness:'native diff commits exact preconditioned edits',round_trips:4,stale_rejected:true}),
|
|
138
|
+
r36Def('topology_mkdir_move_delete_rollback','topology transaction and rollback',['test/native-diff-topology-r36.test.mjs'],['test/native-diff-topology-r36.test.mjs'],{round_trips:5,stale_rejected:true}),
|
|
139
|
+
r36Def('semantic_typescript_navigation','TypeScript symbol navigation',['test/semantic-code.test.mjs'],['test/semantic-code.test.mjs','test/fixtures/semantic/typescript'],{round_trips:4,stale_rejected:true}),
|
|
140
|
+
r36Def('semantic_python_navigation','Python symbol navigation through hermetic LSP adapter',['test/capability-benchmark-semantic-r36.test.mjs'],['test/capability-benchmark-semantic-r36.test.mjs','test/fixtures/lsp-framed-server.mjs'],{test_name_pattern:'R36 benchmark Python symbol navigation',pass_witness:'R36 benchmark Python symbol navigation',round_trips:4}),
|
|
141
|
+
r36Def('semantic_rust_navigation','Rust symbol navigation through hermetic LSP adapter',['test/capability-benchmark-semantic-r36.test.mjs'],['test/capability-benchmark-semantic-r36.test.mjs','test/fixtures/lsp-framed-server.mjs'],{test_name_pattern:'R36 benchmark Rust symbol navigation',pass_witness:'R36 benchmark Rust symbol navigation',round_trips:4}),
|
|
142
|
+
r36Def('semantic_cpp_navigation','C/C++ symbol navigation through hermetic LSP adapter',['test/capability-benchmark-semantic-r36.test.mjs'],['test/capability-benchmark-semantic-r36.test.mjs','test/fixtures/lsp-framed-server.mjs'],{test_name_pattern:'R36 benchmark Cpp symbol navigation',pass_witness:'R36 benchmark Cpp symbol navigation',round_trips:4}),
|
|
143
|
+
r36Def('diagnostics_normalization','diagnostics normalization',['test/semantic-r36-rename.test.mjs'],['test/semantic-r36-rename.test.mjs'],{test_name_pattern:'R36 TypeScript diagnostics carry',pass_witness:'R36 TypeScript diagnostics carry',round_trips:2}),
|
|
144
|
+
r36Def('implementation_lookup','implementation lookup',['test/semantic-r36-rename.test.mjs'],['test/semantic-r36-rename.test.mjs'],{test_name_pattern:'R36 TypeScript implementations normalize',pass_witness:'R36 TypeScript implementations normalize',round_trips:2}),
|
|
145
|
+
r36Def('cross_file_rename_transaction','cross-file rename through Native Diff',['test/semantic-r36-rename.test.mjs'],['test/semantic-r36-rename.test.mjs'],{test_name_pattern:'R36 cross-file rename preview',pass_witness:'R36 cross-file rename preview',round_trips:5,stale_rejected:true}),
|
|
146
|
+
r36Def('long_process_lifecycle','long process start/output/status/terminate',['test/process-longrun-r36.test.mjs','test/process-runtime.test.mjs'],['test/process-longrun-r36.test.mjs','test/process-runtime.test.mjs'],{test_name_pattern:'(?:R36 long process returns before exit|R31 runtime lists, reports and terminates)',round_trips:6,recovery_success:true}),
|
|
147
|
+
r36Def('policy_defined_process_action','policy-defined named process action',['test/process-runtime.test.mjs'],['test/process-runtime.test.mjs'],{test_name_pattern:'R32 runtime executes one policy-defined named action',pass_witness:'R32 runtime executes one policy-defined named action',round_trips:3}),
|
|
148
|
+
r36Def('process_crash_reconciliation','terminal process journal/output recovery',['test/process-longrun-r36.test.mjs'],['test/process-longrun-r36.test.mjs'],{test_name_pattern:'R36 terminal process session is recovered',pass_witness:'R36 terminal process session is recovered',round_trips:4,recovery_success:true}),
|
|
149
|
+
r36Def('autonomous_failing_test_repair','autonomous failing-test critic/repair/release',['test/autonomous-r34-e2e.test.mjs','test/autonomous-loop-v2.test.mjs'],['test/autonomous-r34-e2e.test.mjs','test/autonomous-loop-v2.test.mjs','test/helpers/autonomous-r34-fixture.mjs'],{test_name_pattern:'(?:multi-step fail replan repair finish|failed VERIFY enters CRITIC|REPAIR must change)',round_trips:8,stale_rejected:true,release_gate_result:'passed'}),
|
|
150
|
+
r36Def('autonomous_search_semantic_patch_test','capability-aware planner inspection/mutation loop',['test/autonomous-capability-r36.test.mjs','test/semantic-r36-rename.test.mjs','test/autonomous-r34-e2e.test.mjs'],['test/autonomous-capability-r36.test.mjs','test/semantic-r36-rename.test.mjs','test/autonomous-r34-e2e.test.mjs','test/helpers/autonomous-r34-fixture.mjs'],{test_name_pattern:'(?:planner parses first-class capability actions|typed native_diff_apply|cross-file rename preview|multi-step fail replan repair finish)',round_trips:8,stale_rejected:true,release_gate_result:'passed'}),
|
|
151
|
+
r36Def('release_gate_finish_without_evidence_refusal','finish claim cannot bypass objective release evidence',['test/autonomous-r34-e2e.test.mjs'],['test/autonomous-r34-e2e.test.mjs'],{test_name_pattern:'R34 finish is blocked while the active plan is incomplete',pass_witness:'R34 finish is blocked while the active plan is incomplete',round_trips:3,release_gate_result:'blocked'}),
|
|
152
|
+
r36Def('provider_bridge_interruption_recovery','provider circuit and remote-session interruption recovery',['test/provider-circuit.test.mjs','test/remote-session-cli.test.mjs'],['test/provider-circuit.test.mjs','test/remote-session-cli.test.mjs'],{test_name_pattern:'(?:OPEN becomes HALF_OPEN|bare remote recovers a stale crashed session)',round_trips:4,recovery_success:true}),
|
|
153
|
+
r36Def('remote_result_replay_deduplication','remote result replay/dedupe',['test/remote-result-journal.test.mjs','test/remote-session-cli.test.mjs'],['test/remote-result-journal.test.mjs','test/remote-session-cli.test.mjs'],{test_name_pattern:'(?:remote result journal is monotonic|remote --resume replays only terminal results)',round_trips:4,recovery_success:true}),
|
|
154
|
+
r36Def('compact_connector_capability_closure','compact connector <=42 with production capability closure',['test/compact-catalog-r36.test.mjs','test/capability-ledger-r36.test.mjs'],['test/compact-catalog-r36.test.mjs','test/capability-ledger-r36.test.mjs'],{test_name_pattern:'(?:real compact stdio catalog stays <=42|compact closure covers every production non-host capability)',round_trips:2}),
|
|
155
|
+
r36Def('live_log_request_before_result','live activity request-before-result ordering',['test/remote-live-log-recovery-r36.test.mjs'],['test/remote-live-log-recovery-r36.test.mjs','src/remote-live-log.mjs'],{test_name_pattern:'R36 live activity tracker prints RUN before terminal result',pass_witness:'R36 live activity tracker prints RUN before terminal result',round_trips:2,recovery_success:true}),
|
|
156
|
+
r36Def('live_log_redaction','live activity secret/payload redaction',['test/remote-live-log-r36.test.mjs','test/remote-session-cli.test.mjs'],['test/remote-live-log-r36.test.mjs','test/remote-session-cli.test.mjs','src/remote-live-log.mjs'],{test_name_pattern:'compact live activity shows request context without payload or secret values',pass_witness:'compact live activity shows request context without payload or secret values',round_trips:1}),
|
|
157
|
+
r36Def('forged_stale_receipt_rejection','forged/stale receipt and precondition rejection',['test/autonomous-r34-e2e.test.mjs','test/coding-plane-adversarial.test.mjs'],['test/autonomous-r34-e2e.test.mjs','test/coding-plane-adversarial.test.mjs'],{test_name_pattern:'(?:forged profile receipt substitution|signed autonomous journal tamper|coding task adopts a signed command receipt)',round_trips:4,stale_rejected:true,recovery_success:true}),
|
|
158
|
+
r36Def('rollback_r35_restore_r36','hermetic signed predecessor rollback and exact slot restore mechanism',['test/runtime-self-update.test.mjs','test/release-slot.test.mjs'],['test/runtime-self-update.test.mjs','test/release-slot.test.mjs'],{test_name_pattern:'(?:R31 explicit rollback restores the exact signed prior pointer|release slot materialization copies only manifest-bound files)',round_trips:5,recovery_success:true})
|
|
159
|
+
]);
|
|
160
|
+
|
|
161
|
+
export function r36BenchmarkCaseDefinitions(){
|
|
162
|
+
return R36_DEFINITIONS.map(item=>({...structuredClone(item),fixture_files:['bench/fixtures/corpus.json','bench/fixtures/r36/case-map.json',...item.fixture_files]}));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function hasPassingWitness(stdout,witness){
|
|
166
|
+
if(!witness) return true;
|
|
167
|
+
const text=Buffer.isBuffer(stdout)?stdout.toString('utf8'):String(stdout??'');
|
|
168
|
+
return text.split(/\r?\n/).some(line=>line.includes(witness)&&!/\bSKIP\b/i.test(line)&&/(?:✔|\bok\b)/i.test(line));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export async function runR36CapabilityBenchmark({rootUrl,definitions=r36BenchmarkCaseDefinitions(),env={},timeoutMs=TEST_TIMEOUT_MS}={}){
|
|
172
|
+
const root=typeof rootUrl==='string'?path.resolve(rootUrl):fileURLToPath(rootUrl??new URL('../',import.meta.url));
|
|
173
|
+
if(!Array.isArray(definitions)||definitions.length<1) throw new Error('R36 benchmark definitions invalid');
|
|
174
|
+
if(!Number.isInteger(timeoutMs)||timeoutMs<1000||timeoutMs>600000) throw new Error('R36 benchmark timeout invalid');
|
|
175
|
+
const cases=[];
|
|
176
|
+
for(const definition of definitions){
|
|
177
|
+
const fixture_sha256=await fixtureIdentityForCase({rootUrl:root,definition});
|
|
178
|
+
let result;
|
|
179
|
+
try{result=await runNodeTest({root,definition,env,timeoutMs});}
|
|
180
|
+
catch(error){result={exit_code:null,timed_out:false,error:String(error),stdout:Buffer.alloc(0),stderr:Buffer.alloc(0),bytes:0,elapsed_ms:0};}
|
|
181
|
+
const witnessOk=hasPassingWitness(result.stdout,definition.pass_witness??null);
|
|
182
|
+
const correct=result.exit_code===0&&!result.timed_out&&!result.error&&witnessOk;
|
|
183
|
+
const evidence={schema:'deadbyte.r36-benchmark-case-evidence.v1',case_id:definition.case_id,exit_code:result.exit_code,
|
|
184
|
+
timed_out:result.timed_out===true,signal:result.signal??null,error:result.error??null,pass_witness:definition.pass_witness??null,
|
|
185
|
+
pass_witness_observed:witnessOk,stdout_sha256:sha256(result.stdout??Buffer.alloc(0)),stderr_sha256:sha256(result.stderr??Buffer.alloc(0))};
|
|
186
|
+
cases.push({case_id:definition.case_id,fixture_sha256,correct,round_trips:definition.round_trips,
|
|
187
|
+
bytes_returned:result.bytes??0,elapsed_ms:result.elapsed_ms??0,stale_rejected:correct&&definition.stale_rejected===true,
|
|
188
|
+
recovery_success:correct&&definition.recovery_success===true,duplicate_side_effects:correct?0:1,
|
|
189
|
+
capability_reachable:correct&&definition.capability_reachable===true,evidence_verified:correct&&definition.evidence_verified===true,
|
|
190
|
+
release_gate_result:correct?definition.release_gate_result:'blocked',evidence_sha256:sha256(Buffer.from(canonicalJson(evidence),'utf8'))});
|
|
191
|
+
}
|
|
192
|
+
return buildR36CapabilityBenchmark({suite_id:'r36-production-coding-v1',cases});
|
|
193
|
+
}
|
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { canonicalJson } from './canonical-json.mjs';
|
|
3
3
|
|
|
4
4
|
export const CAPABILITY_BENCHMARK_SCHEMA='deadbyte.r35-capability-benchmark.v1';
|
|
5
|
+
export const R36_CAPABILITY_BENCHMARK_SCHEMA='deadbyte.r36-capability-benchmark.v1';
|
|
5
6
|
const HEX64=/^[0-9a-f]{64}$/;
|
|
6
7
|
const CASE_ID=/^[A-Za-z0-9._-]{1,96}$/;
|
|
7
8
|
const SUITE_ID=/^[A-Za-z0-9._-]{1,96}$/;
|
|
@@ -48,3 +49,47 @@ export function buildCapabilityBenchmark({suite_id:rawSuiteId,cases:rawCases}={}
|
|
|
48
49
|
observation_sha256:sha256(observation)
|
|
49
50
|
});
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
const R36_RELEASE_GATE_RESULTS=new Set(['passed','blocked','not_applicable']);
|
|
54
|
+
export function normalizeR36BenchmarkCase(raw){
|
|
55
|
+
const base=normalizeBenchmarkCase(raw);
|
|
56
|
+
if(typeof raw.capability_reachable!=='boolean') throw new Error('benchmark capability_reachable invalid');
|
|
57
|
+
if(typeof raw.evidence_verified!=='boolean') throw new Error('benchmark evidence_verified invalid');
|
|
58
|
+
if(typeof raw.release_gate_result!=='string'||!R36_RELEASE_GATE_RESULTS.has(raw.release_gate_result)) throw new Error('benchmark release_gate_result invalid');
|
|
59
|
+
return Object.freeze({...base,
|
|
60
|
+
capability_reachable:raw.capability_reachable,
|
|
61
|
+
evidence_verified:raw.evidence_verified,
|
|
62
|
+
release_gate_result:raw.release_gate_result
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function buildR36CapabilityBenchmark({suite_id:rawSuiteId,cases:rawCases}={}){
|
|
67
|
+
if(typeof rawSuiteId!=='string'||!SUITE_ID.test(rawSuiteId)) throw new Error('benchmark suite_id invalid');
|
|
68
|
+
if(!Array.isArray(rawCases)||rawCases.length<1||rawCases.length>128) throw new Error('benchmark cases invalid');
|
|
69
|
+
const cases=rawCases.map(normalizeR36BenchmarkCase).sort((a,b)=>a.case_id.localeCompare(b.case_id));
|
|
70
|
+
const seen=new Set();
|
|
71
|
+
for(const item of cases){if(seen.has(item.case_id)) throw new Error(`duplicate case '${item.case_id}'`);seen.add(item.case_id);}
|
|
72
|
+
const fixtureIdentity={schema:'deadbyte.r36-capability-fixtures.v1',suite_id:rawSuiteId,
|
|
73
|
+
fixtures:cases.map(item=>({case_id:item.case_id,fixture_sha256:item.fixture_sha256}))};
|
|
74
|
+
const fixture_identity_sha256=sha256(fixtureIdentity);
|
|
75
|
+
const observation={schema:R36_CAPABILITY_BENCHMARK_SCHEMA,suite_id:rawSuiteId,fixture_identity_sha256,cases};
|
|
76
|
+
const capability_closure=cases.every(item=>item.capability_reachable);
|
|
77
|
+
const evidence_closure=cases.every(item=>item.evidence_verified);
|
|
78
|
+
const verdictIdentity={
|
|
79
|
+
schema:'deadbyte.r36-capability-verdict.v1',suite_id:rawSuiteId,fixture_identity_sha256,
|
|
80
|
+
cases:cases.map(item=>({
|
|
81
|
+
case_id:item.case_id,fixture_sha256:item.fixture_sha256,correct:item.correct,
|
|
82
|
+
stale_rejected:item.stale_rejected,recovery_success:item.recovery_success,
|
|
83
|
+
duplicate_side_effects:item.duplicate_side_effects,capability_reachable:item.capability_reachable,
|
|
84
|
+
evidence_verified:item.evidence_verified,release_gate_result:item.release_gate_result
|
|
85
|
+
}))
|
|
86
|
+
};
|
|
87
|
+
return Object.freeze({
|
|
88
|
+
...observation,
|
|
89
|
+
capability_closure,
|
|
90
|
+
evidence_closure,
|
|
91
|
+
overall_correct:cases.every(item=>item.correct)&&capability_closure&&evidence_closure,
|
|
92
|
+
verdict_identity_sha256:sha256(verdictIdentity),
|
|
93
|
+
observation_sha256:sha256(observation)
|
|
94
|
+
});
|
|
95
|
+
}
|