deadbyte-mcp 0.15.43 → 0.15.45
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 +160 -161
- package/PROVENANCE.json +257 -232
- package/README.txt +18 -18
- package/RELEASE.json +348 -320
- package/SBOM.cdx.json +14 -2
- package/TEST-MATRIX.json +503 -460
- package/bin/deadbyte-native-inspect-r67.exe +0 -0
- package/bridge/package.json +1 -1
- package/controller/deadbyte-controller.ps1 +1857 -1769
- package/controller/deadbyte-desktop-policy.json +6 -6
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/R67-ALPHA-REFERENCE-DIFFERENTIAL.md +42 -0
- package/docs/R67-ALPHA-STATIC-COMPARISON.json +205 -0
- package/docs/R67-CANDIDATE-PARENT.json +10 -0
- package/docs/R67-EVIDENCE-RECONCILE-CLOSEOUT-20261011.md +64 -0
- package/docs/R67-FULL-REGRESSION-UNKNOWN.json +27 -0
- package/docs/R67-NATIVE-INSPECT-BINARY.json +11 -0
- package/docs/R67-NPM-EXDEV-PRESERVATION-20261011.md +39 -0
- package/docs/R67-OBSERVATION-TRUTH.md +82 -0
- package/docs/R67-REFERENCE-GAP-MATRIX.json +57 -0
- package/docs/R67-REGRESSION-CLOSURE-20261011.md +24 -0
- package/docs/R68-COMPAT-HOST-EXEC-CANDIDATE.md +63 -0
- package/docs/R69-LIVE-OUTCOME-R70-POLICY-TRANSFER.md +136 -0
- package/docs/R70-CODING-DIGEST-SUPERVISOR-CHECKPOINT-20261013.md +42 -0
- package/docs/R70-FINITE-GRANT-OWNER-BOUNDARY-20261013.md +80 -0
- package/docs/R70-OWNER-BOOTSTRAP-CHECKPOINT-20261013.md +60 -0
- package/docs/R70-REFERENCE-MECHANISMS.json +95 -0
- package/docs/R70-TRUST-GUARD-EXPIRY-CHECKPOINT-20261013.md +47 -0
- package/native/deadbyte-native-inspect-r67.cpp +252 -0
- package/package.json +6 -3
- package/scripts/benchmark-l0-r71.mjs +76 -0
- package/scripts/build-native-inspector-r67.ps1 +28 -0
- package/scripts/gate-windows-r67.ps1 +56 -0
- package/scripts/gate-windows-r71.ps1 +64 -0
- package/scripts/npm-preserve-artifact-r67.mjs +99 -0
- package/scripts/npm-release-r48.mjs +12 -2
- package/scripts/npm-release-readiness-r67.mjs +26 -0
- package/scripts/npm-release-readiness-r71.mjs +21 -0
- package/scripts/r67-acquire-alpha-reference.mjs +95 -0
- package/scripts/r67-audit-nonpass-source.mjs +39 -0
- package/scripts/r67-compare-desktop-alpha.mjs +48 -0
- package/scripts/r67-diagnose-failed-shard.mjs +23 -0
- package/scripts/r67-durable-batch.mjs +42 -0
- package/scripts/r67-focused-gate.mjs +58 -0
- package/scripts/r67-full-regression.mjs +28 -0
- package/scripts/r67-independent-observation-verify.mjs +36 -0
- package/scripts/r67-independent-runtime-observation-verify.mjs +63 -0
- package/scripts/r67-nonpass-adjudicate.mjs +20 -0
- package/scripts/r67-publish-boundary-audit.mjs +32 -0
- package/scripts/r67-regression-reconcile.mjs +10 -0
- package/scripts/r67-regression-shard-run.mjs +70 -0
- package/scripts/r67-run-shard-batch.mjs +18 -0
- package/scripts/r67-stage-candidate.mjs +30 -0
- package/scripts/r67-verify-parent-ping.mjs +22 -0
- package/scripts/release-manifest.mjs +1 -0
- package/scripts/verify-r70-full-regression.ps1 +72 -0
- package/src/activation-continuity-engine-r65.mjs +2 -1
- package/src/authority-continuity-r65.mjs +28 -8
- package/src/autonomous-mcp-tools.mjs +1 -1
- package/src/autonomous-output-contracts.mjs +4 -1
- package/src/autonomous-policy.mjs +54 -7
- package/src/autonomous-runtime.mjs +1 -1
- package/src/capability-ledger.mjs +1 -1
- package/src/capability-resolver.mjs +2 -1
- package/src/commander-compat-runtime.mjs +30 -2
- package/src/deadbyte-cli.mjs +41 -7
- package/src/machine-fs-smoke-client.mjs +13 -5
- package/src/machine-identity.mjs +59 -2
- package/src/machine-mcp-tools.mjs +8 -0
- package/src/mcp-server.mjs +11 -2
- package/src/native-diff-v2.mjs +18 -5
- package/src/native-diff.mjs +21 -5
- package/src/native-inspector-r67.mjs +66 -0
- package/src/r67-diagnostic-export.mjs +118 -0
- package/src/r67-diagnostics-verify.mjs +82 -0
- package/src/r67-evidence-reconcile.mjs +128 -0
- package/src/r67-native-observation-authority.mjs +45 -0
- package/src/r67-observation-receipt.mjs +43 -0
- package/src/r67-regression-shards.mjs +176 -0
- package/src/r70-owner-approval.mjs +78 -0
- package/src/remote-live-log.mjs +62 -24
- package/src/remote-result-journal.mjs +1 -1
- package/src/runtime-update.mjs +2051 -1891
- package/src/tool-audit.mjs +3 -1
- package/src/version.mjs +1 -1
- package/test/agent-runtime.test.mjs +1 -1
- package/test/autonomous-local-supervisor.test.mjs +2 -1
- package/test/autonomous-loop.test.mjs +11 -6
- package/test/autonomous-output-contract.test.mjs +17 -1
- package/test/autonomous-runtime.test.mjs +1 -1
- package/test/autonomous-supervisor-integration.test.mjs +2 -1
- package/test/capability-resolver.test.mjs +17 -0
- package/test/codex-autonomous-r44.test.mjs +1 -1
- package/test/coding-plane.test.mjs +1 -1
- package/test/commander-compat-runtime.test.mjs +42 -0
- package/test/controller-policy-preflight-r59.test.mjs +1 -0
- package/test/full-max-catalog-r46.test.mjs +1 -1
- package/test/native-diff-topology-r36.test.mjs +35 -2
- package/test/native-diff.test.mjs +83 -3
- package/test/output-schema.test.mjs +1 -1
- package/test/r51-live-log-polling.test.mjs +12 -0
- package/test/r53-release-contract.test.mjs +1 -1
- package/test/r54-release-contract.test.mjs +1 -1
- package/test/r55-release-contract.test.mjs +1 -1
- package/test/r56-release-contract.test.mjs +1 -1
- package/test/r57-release-contract.test.mjs +1 -1
- package/test/r58-bundled-bridge.test.mjs +1 -1
- package/test/r58-release-contract.test.mjs +2 -2
- package/test/r58-windows-gate.test.mjs +1 -1
- package/test/r59-tool-surface-compat.test.mjs +9 -5
- package/test/r60-release-contract.test.mjs +3 -3
- package/test/r61-release-contract.test.mjs +1 -1
- package/test/r62-release-contract.test.mjs +1 -1
- package/test/r63-release-contract.test.mjs +1 -1
- package/test/r64-release-contract.test.mjs +1 -1
- package/test/r65-authority-runtime-epoch.test.mjs +9 -1
- package/test/r65-epoch-native-activation-integration.test.mjs +4 -4
- package/test/r65-release-contract.test.mjs +1 -1
- package/test/r66-release-contract.test.mjs +2 -1
- package/test/r67-cli-integration.test.mjs +41 -0
- package/test/r67-diagnostics-cli.test.mjs +60 -0
- package/test/r67-diagnostics-verify.test.mjs +49 -0
- package/test/r67-diagnostics-zip-oracle.test.mjs +38 -0
- package/test/r67-diagnostics.test.mjs +60 -0
- package/test/r67-evidence-reconcile.test.mjs +186 -0
- package/test/r67-isolated-slot-rollback-restore.test.mjs +63 -0
- package/test/r67-live-log-secret-canary.test.mjs +44 -0
- package/test/r67-machine-fs-smoke-epoch.test.mjs +22 -0
- package/test/r67-native-inspector.test.mjs +131 -0
- package/test/r67-native-observation-authority.test.mjs +49 -0
- package/test/r67-npm-cross-volume.test.mjs +74 -0
- package/test/r67-npm-publish-gate.test.mjs +40 -0
- package/test/r67-regression-shards.test.mjs +184 -0
- package/test/r67-release-contract.test.mjs +45 -0
- package/test/r67-runtime-observation-binding.test.mjs +86 -0
- package/test/r67-server-observation-wiring.test.mjs +12 -0
- package/test/r67-signed-receipt.test.mjs +66 -0
- package/test/r67-skip-rationale.test.mjs +31 -0
- package/test/r67-tool-annotations.test.mjs +21 -0
- package/test/r67-windows-gate-argv.test.mjs +13 -0
- package/test/r69-live-outcome.test.mjs +137 -0
- package/test/r70-autonomous-grant-expiry.test.mjs +89 -0
- package/test/r70-autonomous-policy-bootstrap.test.mjs +166 -0
- package/test/r70-controller-autonomous-root.test.mjs +104 -0
- package/test/r70-controller-grant-subset.test.mjs +28 -0
- package/test/r70-controller-owner-issue-boundary.test.mjs +80 -0
- package/test/r70-controller-policy-snapshot.test.mjs +66 -0
- package/test/r70-owner-approval.test.mjs +67 -0
- package/test/r71-full-verifier-artifact.test.mjs +28 -0
- package/test/r71-isolated-slot-rollback-restore.test.mjs +62 -0
- package/test/r71-native-diff-mcp-wire.test.mjs +75 -0
- package/test/r71-publish-fence.test.mjs +38 -0
- package/test/r71-release-identity.test.mjs +31 -0
- package/test/release-version.test.mjs +1 -1
- package/test/remote-live-log-r36.test.mjs +10 -0
- package/test/remote-live-log-r37.test.mjs +29 -0
- package/test/remote-result-journal.test.mjs +12 -0
- package/test/remote-session-cli.test.mjs +2 -1
- package/test/semantic-multilang.test.mjs +1 -1
- package/test/standing-grants.test.mjs +2 -2
- package/test/tool-audit.test.mjs +14 -0
- 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-desktop-input-r40.obj +0 -0
- package/bin/deadbyte-desktop-observer-r40.obj +0 -0
- package/bin/deadbyte-desktop-uia-r40.obj +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-hardware-observer-r45.obj +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/conpty-input-observer.obj +0 -0
- package/miniconpty.obj +0 -0
- package/proof/CONTAINMENT-BUILD.txt +0 -163
- package/proof/MCP-SMOKE-STATUS.txt +0 -9
- package/proof/NODE-SYNTAX.txt +0 -4
- package/proof/PROOF.txt +0 -6
- package/proof/R34-TASK8-SUPERVISOR-CHECKPOINT.json +0 -29
- package/proof/R34-TASK9-MCP-SURFACE-CHECKPOINT.json +0 -28
- package/proof/SECRET-SCAN.txt +0 -4
- package/proof/SOURCE-GATES.txt +0 -16
- package/proof/STATUS.txt +0 -11
- package/proof/TARGET-V0313-CONTAINMENT-PASS.sha256 +0 -1
- package/proof/TARGET-V0313-CONTAINMENT-PASS.txt +0 -215
- package/proof/TARGET-V040-CONTAINED-IPC-FAIL.sha256 +0 -1
- package/proof/TARGET-V040-CONTAINED-IPC-FAIL.txt +0 -299
- package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
- package/proof/TARGET-V041-CONTAINED-CREATEPROCESS-203.txt +0 -311
- package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
- package/proof/TARGET-V042-CONTAINED-CREATEPROCESS-203.txt +0 -313
- package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.sha256 +0 -1
- package/proof/TARGET-V043-CONTAINED-CREATEPROCESS-203.txt +0 -308
- package/proof/TARGET-V044-CONTAINED-PASS.sha256 +0 -1
- package/proof/TARGET-V044-CONTAINED-PASS.txt +0 -432
- package/proof/TARGET-V045-DUAL-OPERATION-PASS.sha256 +0 -1
- package/proof/TARGET-V045-DUAL-OPERATION-PASS.txt +0 -481
- package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.sha256 +0 -1
- package/proof/TARGET-V046-FIXED-EXECUTABLE-REGISTRY-PASS.txt +0 -610
- package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.sha256 +0 -1
- package/proof/TARGET-V047-RUNTIME-MANIFEST-PASS.txt +0 -642
- package/proof/TARGET-V050-BATCH-GATE-PASS.sha256 +0 -1
- package/proof/TARGET-V050-BATCH-GATE-PASS.txt +0 -713
- package/proof/TESTS.txt +0 -686
- package/proof/TRUST-EPHEMERAL.txt +0 -4
- package/proof/V03-FREEZE.txt +0 -27
- package/proof/V041-IPC-HOTFIX.txt +0 -16
- package/proof/V042-ENV-HOTFIX.txt +0 -15
- package/proof/V043-DRIVE-CWD-HOTFIX.txt +0 -14
- package/proof/V044-LOCALAPPDATA-HOTFIX.txt +0 -18
- package/proof/V045-OPERATION-REGISTRY.txt +0 -7
- package/proof/V046-WORKER-REGISTRY.txt +0 -12
- package/proof/V047-WORKER-MANIFEST.txt +0 -18
- package/proof/V050-BATCH-TRUST-CLOSURE.txt +0 -21
- package/proof/V060-ACTIVE-NETWORK-AUTHORITY.txt +0 -29
- package/proof/V070-NODE-SYNTAX.txt +0 -36
- package/proof/V070-NODE-TESTS.txt +0 -752
- package/proof/V070-PACK-DRY-RUN.txt +0 -126
- package/proof/V070-SOURCE-GATE.txt +0 -30
- package/proof/V070-STATIC-SCAN.txt +0 -4
- package/proof/V070-WINDOWS-GATE-PENDING.txt +0 -25
- package/proof/V071-NODE-SYNTAX.txt +0 -1
- package/proof/V071-NODE-TESTS.txt +0 -796
- package/proof/V071-PACK-DRY-RUN.json +0 -656
- package/proof/V071-SOURCE-GATE.txt +0 -16
- package/proof/V071-WINDOWS-GATE-PENDING.txt +0 -24
- package/proof/V073-NODE-SYNTAX.txt +0 -4
- package/proof/V073-SOURCE-GATE.txt +0 -21
- package/proof/V073-STATIC-SCAN.txt +0 -10
- package/proof/V073-WINDOWS-GATE-PENDING.txt +0 -5
- package/proof/VERIFY.txt +0 -7
- package/proof/WINDOWS-CONTAINED-STATUS.txt +0 -5
- package/proof/WINDOWS-CONTAINMENT-STATUS.txt +0 -3
- package/proof/commander-closure-20260927/CONTINUATION.json +0 -43
- package/proof/commander-closure-20260927/RESULT.json +0 -30
- package/proof/commander-closure-20260927/SEARCH-CONTINUATION.json +0 -30
- package/proof/commander-closure-20260927/XLS-REFERENCE-PROBE.json +0 -13
- package/proof/commander-closure-20260928/DIFFERENTIAL-CHECKPOINT.json +0 -122
- package/proof/r59-full-regression-current.json +0 -13
- package/proof/r59-full-regression-current.stderr.log +0 -0
- package/proof/r59-full-regression-current.stdout.log +0 -1268
package/src/tool-audit.mjs
CHANGED
|
@@ -21,7 +21,7 @@ const secretExactKeys=new Set([
|
|
|
21
21
|
]);
|
|
22
22
|
const secretSuffixes=['_password','_passwd','_secret','_token','_credential','_credentials','_cookie','_cookies','_private_key','_recovery_code','_api_key'];
|
|
23
23
|
const payloadKeys=new Set(['content','file_text','text','body','new_string','old_string','raw_input','raw_text','data_base64']);
|
|
24
|
-
const secretValuePattern=/(?:^|[^a-z])(bearer\s+\S+|(?:api[-_]?key|access[-_]?token|refresh[-_]?token|token|password|secret)\s*[=:]\s*\S
|
|
24
|
+
const secretValuePattern=/(?:^|[^a-z])(bearer\s+\S+|(?:api[-_]?key|access[-_]?token|refresh[-_]?token|token|password|secret)\s*[=:]\s*\S+|sk-(?:proj-|svcacct-|admin-)?[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9_]{12,}|github_pat_[A-Za-z0-9_]{12,}|-----BEGIN [^-]*PRIVATE KEY-----)/i;
|
|
25
25
|
const sha256=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
26
26
|
const utf8Bytes=value=>Buffer.from(typeof value==='string'?value:canonicalJson(value),'utf8');
|
|
27
27
|
const byteCount=value=>utf8Bytes(value).length;
|
|
@@ -116,11 +116,13 @@ function summarizeOutcome(result,error,durationMs){
|
|
|
116
116
|
const structured=result?.structuredContent;
|
|
117
117
|
const status=typeof structured?.status==='string'?structured.status:(result?.isError===true?'error':'ok');
|
|
118
118
|
const isError=result?.isError===true;
|
|
119
|
+
const unknownSideEffect=structured?.side_effect_state==='unknown'||structured?.result?.side_effect_state==='unknown';
|
|
119
120
|
const capability=structured?.result;
|
|
120
121
|
const snapshot=capability?.schema==='deadbyte.capability-manifest.v3'&&HEX64.test(String(capability.snapshot_id??''))&&
|
|
121
122
|
Number.isInteger(capability.state_epoch)&&capability.state_epoch>0
|
|
122
123
|
?{snapshot_id:capability.snapshot_id,state_epoch:capability.state_epoch}:{};
|
|
123
124
|
return {status:String(status).slice(0,128),is_error:isError,duration_ms:duration,receipt_sha256s:outcomeReceiptHashes(result),
|
|
125
|
+
...(unknownSideEffect?{side_effect_state:'unknown'}:{}),
|
|
124
126
|
...snapshot,
|
|
125
127
|
...(isError?{reason:resultOutcomeReason(result)}:{})};
|
|
126
128
|
}
|
package/src/version.mjs
CHANGED
|
@@ -69,7 +69,7 @@ async function cleanup(f, client) {
|
|
|
69
69
|
await rm(f.trust, { recursive: true, force: true }).catch(() => {});
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
test
|
|
72
|
+
test('R44 historical agent catalog contract is frozen; current R47 runtime supersedes its base surface',{skip:'Historical R44 13-tool catalog deliberately superseded by R47; not applicable to current release'}, async () => {
|
|
73
73
|
const f = await fixture();
|
|
74
74
|
let client;
|
|
75
75
|
try {
|
|
@@ -53,7 +53,8 @@ async function createProviderHostFixture(){
|
|
|
53
53
|
planner:{backend:'openai_compatible',endpoint:`http://127.0.0.1:${planner.address().port}/v1/chat/completions`,model:'r34-host-test',max_tokens:2048,timeout_ms:30000,max_response_bytes:262144},
|
|
54
54
|
limits:{max_iterations:8,max_mutations:8,max_wall_ms:null,max_context_bytes:262144,max_diff_bytes:262144,max_files_per_diff:4},profiles:{}}));
|
|
55
55
|
const autonomousPolicy=await loadAutonomousPolicy(autonomousPath,codingPolicy);
|
|
56
|
-
await writeBoundStandingGrant('autonomous', autonomousPolicy.lease_file, {schema:'deadbyte.autonomous-grant.v2',policy_sha256:autonomousPolicy.policy_sha256,
|
|
56
|
+
await writeBoundStandingGrant('autonomous', autonomousPolicy.lease_file, {schema:'deadbyte.autonomous-grant.v2',policy_sha256:autonomousPolicy.policy_sha256,
|
|
57
|
+
coding_policy_sha256:codingPolicy.policy_sha256,
|
|
57
58
|
instance_nonce:nonce(),root_ids:['project'],granted_at_utc:new Date().toISOString()});
|
|
58
59
|
const codingRuntime=createCodingRuntime({policy:codingPolicy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
|
|
59
60
|
const nativeDiffRuntime=createNativeDiffRuntime({policy:autonomousPolicy,codingRuntime,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
|
|
@@ -123,7 +123,7 @@ test('R24 autonomous goal diagnoses a failing test, replans with native diff, be
|
|
|
123
123
|
maxIterations:10 });
|
|
124
124
|
assert.equal(submitted.status,'accepted');
|
|
125
125
|
const result = await f.runtime.run({ goalId:submitted.goal_id, maxCycles:16 });
|
|
126
|
-
assert.equal(result.status,'completed');
|
|
126
|
+
assert.equal(result.status,'completed',JSON.stringify({status:result.status,reason:result.reason??null,loop_phase:result.loop?.phase??null}));
|
|
127
127
|
assert.equal(await readFile(f.program,'utf8'),"export const value = 'fixed';\n");
|
|
128
128
|
const status = await f.runtime.status({ goalId:submitted.goal_id });
|
|
129
129
|
assert.equal(status.state,'succeeded');
|
|
@@ -154,7 +154,7 @@ test('historical autonomous release verification survives source drift and disar
|
|
|
154
154
|
title:'repair program', goal:'make exported value equal fixed', acceptance:'release evidence must remain verifiable',
|
|
155
155
|
maxIterations:10 });
|
|
156
156
|
const result = await f.runtime.run({ goalId:submitted.goal_id, maxCycles:16 });
|
|
157
|
-
assert.equal(result.status,'completed');
|
|
157
|
+
assert.equal(result.status,'completed',JSON.stringify({status:result.status,reason:result.reason??null,loop_phase:result.loop?.phase??null}));
|
|
158
158
|
assert.equal((await f.runtime.verify({ goalId:submitted.goal_id })).ok,true);
|
|
159
159
|
|
|
160
160
|
await writeFile(f.program,"export const value = 'rolled-back';\n");
|
|
@@ -196,7 +196,7 @@ test('autonomous profile execution is capped by the absolute autonomous lease wi
|
|
|
196
196
|
title:'deadline-bound profiles',goal:'make exported value equal fixed',
|
|
197
197
|
acceptance:'build, test, and benchmark must pass',maxIterations:10});
|
|
198
198
|
const result=await f.runtime.run({goalId:submitted.goal_id,maxCycles:16});
|
|
199
|
-
assert.equal(result.status,'completed');
|
|
199
|
+
assert.equal(result.status,'completed',JSON.stringify({status:result.status,reason:result.reason??null,loop_phase:result.loop?.phase??null}));
|
|
200
200
|
assert.ok(calls.length>=3);
|
|
201
201
|
assert.ok(calls.every(call=>typeof call.deadline==='string'&&Number.isFinite(Date.parse(call.deadline))));
|
|
202
202
|
assert.ok(calls.every(call=>call.has_precheck===true));
|
|
@@ -239,7 +239,12 @@ test('autonomous profile nonce rotation immediately before spawn fails closed wi
|
|
|
239
239
|
const started=journal.events.find(event=>event.type==='profile_started'&&event.payload?.profile_id==='build');
|
|
240
240
|
assert.ok(started);
|
|
241
241
|
assert.match(started.payload.authority_instance_nonce,/^[0-9a-f]{64}$/);
|
|
242
|
-
|
|
242
|
+
const pause=journal.events.find(event=>event.type==='goal_paused'&&event.payload?.reason==='profile_execution_without_receipt');
|
|
243
|
+
assert.ok(pause);
|
|
244
|
+
assert.equal(pause.payload.receipt_id,started.payload.receipt_id);
|
|
245
|
+
assert.equal(pause.payload.request_sha256,started.payload.request_sha256);
|
|
246
|
+
assert.equal(typeof pause.payload.detail,'string');
|
|
247
|
+
assert.ok(pause.payload.detail.length>0&&pause.payload.detail.length<=512);
|
|
243
248
|
assert.equal(journal.events.some(event=>event.type==='profile_completed'&&event.payload?.profile_id==='build'),false);
|
|
244
249
|
assert.equal((await f.codingRuntime.verifyReceiptDetailed(started.payload.receipt_id)).ok,false);
|
|
245
250
|
} finally {
|
|
@@ -255,7 +260,7 @@ test('provider planner repairs an invalid structured decision inside the same ru
|
|
|
255
260
|
title:'repair after planner contract error', goal:'make exported value equal fixed',
|
|
256
261
|
acceptance:'build, test, and benchmark must pass', maxIterations:10 });
|
|
257
262
|
const result = await f.runtime.run({ goalId:submitted.goal_id, maxCycles:16 });
|
|
258
|
-
assert.equal(result.status,'completed');
|
|
263
|
+
assert.equal(result.status,'completed',JSON.stringify({status:result.status,reason:result.reason??null,loop_phase:result.loop?.phase??null}));
|
|
259
264
|
assert.equal(await readFile(f.program,'utf8'),"export const value = 'fixed';\n");
|
|
260
265
|
assert.equal(f.planner.prompts.length,6);
|
|
261
266
|
assert.match(f.planner.prompts[1],/PREVIOUS_RESPONSE_REJECTED/);
|
|
@@ -337,7 +342,7 @@ test('provider supervisor adopts an OPEN circuit after restart and resumes only
|
|
|
337
342
|
if(status.state==='cancelled') throw new Error('provider circuit supervisor cancelled goal');
|
|
338
343
|
await new Promise(resolve=>setTimeout(resolve,25));
|
|
339
344
|
} while(Date.now()<deadline);
|
|
340
|
-
assert.equal(status.state,'succeeded');
|
|
345
|
+
assert.equal(status.state,'succeeded',JSON.stringify({state:status.state,reason:status.reason??null,loop_phase:status.loop?.phase??null}));
|
|
341
346
|
assert.ok(f.planner.prompts.length>3);
|
|
342
347
|
const journal=await f.runtime.events({goalId:submitted.goal_id,fromSeq:1,limit:200});
|
|
343
348
|
assert.equal(journal.events.filter(event=>event.type==='provider_probe_started').length,1);
|
|
@@ -2,10 +2,26 @@ import test from 'node:test';
|
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import {
|
|
4
4
|
autonomousGoalApproveOutputSchema, autonomousGoalRunOutputSchema, autonomousGoalStatusOutputSchema,
|
|
5
|
-
autonomousGoalVerifyOutputSchema,
|
|
5
|
+
autonomousGoalVerifyOutputSchema, nativeDiffPreviewOutputSchema,
|
|
6
6
|
autonomousStructuredResult
|
|
7
7
|
} from '../src/autonomous-output-contracts.mjs';
|
|
8
8
|
|
|
9
|
+
test('R71 preview-only MCP output cannot masquerade as a signed ready-to-apply diff',()=>{
|
|
10
|
+
const base={root_id:'preview',operation_count:1,payload_bytes:0,paths:['a.txt'],
|
|
11
|
+
operations:[{kind:'delete',path:'a.txt',expected_sha256:'a'.repeat(64)}]};
|
|
12
|
+
const unsigned=autonomousStructuredResult(nativeDiffPreviewOutputSchema,{
|
|
13
|
+
status:'preview_only',schema:'deadbyte.native-diff.v1',...base
|
|
14
|
+
});
|
|
15
|
+
assert.equal(unsigned.structuredContent.status,'preview_only');
|
|
16
|
+
assert.equal(unsigned.structuredContent.diff_id,undefined);
|
|
17
|
+
assert.throws(()=>autonomousStructuredResult(nativeDiffPreviewOutputSchema,{
|
|
18
|
+
status:'preview_only',diff_id:'b'.repeat(64),...base
|
|
19
|
+
}),/autonomous output contract violation/);
|
|
20
|
+
assert.throws(()=>autonomousStructuredResult(nativeDiffPreviewOutputSchema,{
|
|
21
|
+
status:'ready',...base
|
|
22
|
+
}),/autonomous output contract violation/);
|
|
23
|
+
});
|
|
24
|
+
|
|
9
25
|
test('autonomous_goal_verify structured contract preserves delegated action evidence count', () => {
|
|
10
26
|
const value = {
|
|
11
27
|
ok:true,
|
|
@@ -76,7 +76,7 @@ async function fixture() {
|
|
|
76
76
|
return { root, client, transport };
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
test
|
|
79
|
+
test('R44 historical hermetic autonomous catalog is frozen at 50; current R47 runtime supersedes it',{skip:'Historical R44 autonomous catalog frozen at 50; current R47+ has a different catalog'}, async () => {
|
|
80
80
|
const f = await fixture();
|
|
81
81
|
try {
|
|
82
82
|
await f.client.connect(f.transport);
|
|
@@ -73,7 +73,8 @@ async function startPlanner() {
|
|
|
73
73
|
}));
|
|
74
74
|
const autonomousSha = sha(await readFile(autonomousPath));
|
|
75
75
|
await writeBoundStandingGrant('autonomous', path.join(root, 'runtime', 'autonomous-grant.json'), {
|
|
76
|
-
schema:'deadbyte.autonomous-grant.v2', policy_sha256:autonomousSha,
|
|
76
|
+
schema:'deadbyte.autonomous-grant.v2', policy_sha256:autonomousSha,
|
|
77
|
+
coding_policy_sha256:codingSha,
|
|
77
78
|
instance_nonce:nonce(), root_ids:['project'], granted_at_utc:new Date().toISOString()
|
|
78
79
|
});
|
|
79
80
|
const client = new Client({ name:'deadbyte-supervisor-integration', version:'0.8.0' },
|
|
@@ -37,6 +37,10 @@ test('R59 live plane state can only reduce signed capability availability', asyn
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
test('deriveCapabilityRequirements maps dependencies accurately', () => {
|
|
40
|
+
const preview=R36_CAPABILITY_LEDGER.entries.find(item=>item.id==='native_diff.preview');
|
|
41
|
+
assert.equal(preview.authority,'coding');
|
|
42
|
+
assert.equal(preview.mutating,false);
|
|
43
|
+
assert.deepEqual(deriveCapabilityRequirements(preview),['DEADBYTE_AUTONOMOUS_RUNTIME','coding_session.armed']);
|
|
40
44
|
const reqCodingRead = deriveCapabilityRequirements({
|
|
41
45
|
id: 'coding.search',
|
|
42
46
|
authority: 'coding',
|
|
@@ -61,6 +65,19 @@ test('deriveCapabilityRequirements maps dependencies accurately', () => {
|
|
|
61
65
|
assert.deepEqual(reqSkill, ['skill_plane.valid']);
|
|
62
66
|
});
|
|
63
67
|
|
|
68
|
+
test('Native Diff preview is available under Coding read while apply remains Autonomous denied',async()=>{
|
|
69
|
+
const preview=R36_CAPABILITY_LEDGER.entries.find(item=>item.id==='native_diff.preview');
|
|
70
|
+
const apply=R36_CAPABILITY_LEDGER.entries.find(item=>item.id==='native_diff.apply');
|
|
71
|
+
const result=await resolveCapabilityStates({ledger:{entries:[preview,apply]},
|
|
72
|
+
toolCatalog:['native_diff_preview','native_diff_apply'],profile:'full',
|
|
73
|
+
env:{DEADBYTE_AUTONOMOUS_RUNTIME:'1'},
|
|
74
|
+
codingRuntime:{sessionStatus:async()=>({armed:true,root_ids:['project']})},
|
|
75
|
+
autonomousRuntime:{sessionStatus:async()=>({armed:false,reason:'disarmed'})}});
|
|
76
|
+
const byId=id=>result.capabilities.find(item=>item.id===id);
|
|
77
|
+
assert.equal(byId('native_diff.preview').state,CAPABILITY_STATES.AVAILABLE);
|
|
78
|
+
assert.equal(byId('native_diff.apply').state,CAPABILITY_STATES.DENIED);
|
|
79
|
+
});
|
|
80
|
+
|
|
64
81
|
test('resolveCapabilityStates resolves all 5 states correctly', async () => {
|
|
65
82
|
const allCompactTools = [
|
|
66
83
|
'capability_manifest',
|
|
@@ -38,7 +38,7 @@ async function fixture(){
|
|
|
38
38
|
const policy=await loadAutonomousPolicy(autonomousPath,codingPolicy);
|
|
39
39
|
await writeBoundStandingGrant('coding', codingPolicy.lease_file, {schema:'deadbyte.coding-grant.v2',policy_sha256:codingPolicy.policy_sha256,
|
|
40
40
|
instance_nonce:nonce(),root_ids:['project'],armed_at_utc:new Date().toISOString()});
|
|
41
|
-
await writeBoundStandingGrant('autonomous', policy.lease_file, {schema:'deadbyte.autonomous-grant.v2',policy_sha256:policy.policy_sha256,
|
|
41
|
+
await writeBoundStandingGrant('autonomous', policy.lease_file, {schema:'deadbyte.autonomous-grant.v2',policy_sha256:policy.policy_sha256,coding_policy_sha256:codingPolicy.policy_sha256,
|
|
42
42
|
instance_nonce:nonce(),root_ids:['project'],armed_at_utc:new Date().toISOString()});
|
|
43
43
|
const codingRuntime=createCodingRuntime({policy:codingPolicy,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
|
|
44
44
|
const nativeDiffRuntime=createNativeDiffRuntime({policy,codingRuntime,signingKeyPath:keys.privateKeyPath,verifyKeyPath:keys.publicKeyPath});
|
|
@@ -70,7 +70,7 @@ async function fixture() {
|
|
|
70
70
|
return { root, client, transport };
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
test
|
|
73
|
+
test('R44 historical hermetic coding catalog is frozen at 38; current R47 runtime supersedes it',{skip:'Historical R44 coding catalog frozen at 38; current R47+ supersedes it'}, async () => {
|
|
74
74
|
const f = await fixture();
|
|
75
75
|
try {
|
|
76
76
|
await f.client.connect(f.transport);
|
|
@@ -32,3 +32,45 @@ test('native source rejects a Commander package dependency', () => {
|
|
|
32
32
|
assertNoCommanderDependency("import x from './machine-fs.mjs';");
|
|
33
33
|
assert.throws(()=>assertNoCommanderDependency("import x from '@wonderwhy-er/desktop-commander';"),/must not depend/);
|
|
34
34
|
});
|
|
35
|
+
|
|
36
|
+
test('host_exec script, inline, and native have independent required fields', () => {
|
|
37
|
+
const sha='a'.repeat(64);
|
|
38
|
+
const script={root_id:'core',command_id:'powershell_script',script_path:'scripts/check.ps1',script_sha256:sha};
|
|
39
|
+
const inline={mode:'inline',root_id:'core',command_id:'powershell_inline',command:'Write-Output ok'};
|
|
40
|
+
const native={mode:'native',root_id:'core',executable:'C:\\Windows\\System32\\whoami.exe',executable_sha256:sha};
|
|
41
|
+
for(const args of [script,inline,native]){
|
|
42
|
+
const validated=validateCommanderRequest('host_exec',args);
|
|
43
|
+
assert.equal(validated.native_tool,'host.exec');
|
|
44
|
+
assert.deepEqual(validated.args,args);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('compat adapter routes only validated host_exec modes to the native operation', async () => {
|
|
49
|
+
const calls=[];
|
|
50
|
+
const rt=createCommanderCompatibilityRuntime({
|
|
51
|
+
invoke:async(native,args)=>{calls.push({native,args});return {status:'passed',mode:args.mode};}
|
|
52
|
+
});
|
|
53
|
+
const inline={mode:'inline',root_id:'core',command_id:'powershell_inline',command:'Write-Output ok'};
|
|
54
|
+
const result=await rt.call('host_exec',inline);
|
|
55
|
+
assert.equal(result.status,'ok');
|
|
56
|
+
assert.equal(calls.length,1);
|
|
57
|
+
assert.deepEqual(calls[0],{native:'host.exec',args:inline});
|
|
58
|
+
await assert.rejects(()=>rt.call('host_exec',{...inline,script_path:'stray.ps1'}),/unexpected fields/);
|
|
59
|
+
assert.equal(calls.length,1,'rejected requests must never reach native invoke');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('host_exec rejects cross-mode parameters and malformed authority inputs', () => {
|
|
63
|
+
const sha='a'.repeat(64);
|
|
64
|
+
const inline={mode:'inline',root_id:'core',command_id:'powershell_inline',command:'Write-Output ok'};
|
|
65
|
+
const native={mode:'native',root_id:'core',executable:'C:\\Windows\\System32\\whoami.exe',executable_sha256:sha};
|
|
66
|
+
const reject=args=>assert.throws(()=>validateCommanderRequest('host_exec',args));
|
|
67
|
+
reject({...inline,script_sha256:sha});
|
|
68
|
+
reject({...native,command_id:'powershell_inline'});
|
|
69
|
+
reject({...native,executable_sha256:'bad'});
|
|
70
|
+
reject({...inline,command:'a'+String.fromCharCode(0)+'b'});
|
|
71
|
+
reject({...inline,command:''});
|
|
72
|
+
reject({mode:'inline',root_id:'core',command_id:'powershell_inline'});
|
|
73
|
+
reject({mode:'native',root_id:'core',executable:'x.exe'});
|
|
74
|
+
reject({mode:'superuser',root_id:'core',command:'x'});
|
|
75
|
+
reject({root_id:'core',command_id:'powershell_script',script_path:'scripts/check.ps1',script_sha256:'bad'});
|
|
76
|
+
});
|
|
@@ -26,6 +26,7 @@ test('R59 controller refuses to arm process or coding policy with a missing root
|
|
|
26
26
|
const source=await readFile(controllerPath,'utf8');
|
|
27
27
|
const blocks=[functionBlock(source,'Assert-PolicyRootsAvailable','Get-HostPolicyMetadata'),
|
|
28
28
|
functionBlock(source,'Get-ProcessPolicyMetadata','Get-ProcessGrantStatus'),
|
|
29
|
+
functionBlock(source,'Read-ControllerPolicySnapshot','Get-CodingPolicyMetadata'),
|
|
29
30
|
functionBlock(source,'Get-CodingPolicyMetadata','Get-CodingLeaseStatus')].join('\n');
|
|
30
31
|
const script=`$ErrorActionPreference='Stop';$RuntimeDir=${quote(runtime)};function Fail([string]$m){throw $m};function Get-ExecutableHash($p){return '${'a'.repeat(64)}'};${blocks};`+
|
|
31
32
|
`$errors=@();foreach($case in @(@{kind='process';cfg=@{ProcessPolicyFile=${quote(processPolicy)}}},@{kind='coding';cfg=@{CodingPolicyFile=${quote(coding)}}})){try{if($case.kind -eq 'process'){Get-ProcessPolicyMetadata $case.cfg|Out-Null}else{Get-CodingPolicyMetadata $case.cfg|Out-Null};throw 'unexpected pass'}catch{$errors+=$_.Exception.Message}};$errors|ConvertTo-Json -Compress`;
|
|
@@ -15,7 +15,7 @@ const desktopPolicyPath=path.join(repoRoot,'controller','deadbyte-desktop-policy
|
|
|
15
15
|
const sha=bytes=>createHash('sha256').update(bytes).digest('hex');
|
|
16
16
|
const absent=async p=>{try{await access(p);return false;}catch(e){if(e?.code==='ENOENT')return true;throw e;}};
|
|
17
17
|
|
|
18
|
-
test
|
|
18
|
+
test('R46 historical max-runtime full stdio catalog contract is frozen at 84; current R47 runtime intentionally supersedes it',{skip:'Historical R46 max-runtime catalog frozen at 84; current R47+ intentionally supersedes it'},async()=>{
|
|
19
19
|
const f=await createR34Fixture({authority:'disarmed'});
|
|
20
20
|
const processPolicyPath=path.join(f.root,'process-policy.json');
|
|
21
21
|
const processGrant=path.join(f.root,'process-grant.json');
|
|
@@ -18,9 +18,9 @@ async function fixture(){
|
|
|
18
18
|
await mkdir(project); await mkdir(trust);
|
|
19
19
|
const keys=await generateTrustKeypair({privateKeyPath:path.join(trust,'private.pem'),publicKeyPath:path.join(trust,'public.pem')});
|
|
20
20
|
const codingPath=path.join(root,'coding-policy.json');
|
|
21
|
-
await writeFile(codingPath,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:path.join(root,'coding-lease.json'),evidence_dir:path.join(root,'coding-evidence'),roots:{project:{path:project,read:true,write:true,exec:false,deny_paths:[]}},commands:{},max_read_bytes:524288,max_write_bytes:2097152}));
|
|
21
|
+
await writeFile(codingPath,JSON.stringify({schema:'deadbyte.coding-policy.v1',enabled:true,lease_file:path.join(root,'coding-lease.json'),evidence_dir:path.join(root,'coding-evidence'),roots:{project:{path:project,read:true,write:true,exec:false,deny_paths:[]},preview:{path:project,read:true,write:false,exec:false,deny_paths:[]}},commands:{},max_read_bytes:524288,max_write_bytes:2097152}));
|
|
22
22
|
const codingPolicy=await loadCodingPolicy(codingPath);
|
|
23
|
-
await writeFile(codingPolicy.lease_file,JSON.stringify({schema:'deadbyte.coding-lease.v1',policy_sha256:codingPolicy.policy_sha256,instance_nonce:randomBytes(32).toString('hex'),root_ids:['project'],armed_at_utc:new Date().toISOString(),expires_at_utc:new Date(Date.now()+3600000).toISOString()}));
|
|
23
|
+
await writeFile(codingPolicy.lease_file,JSON.stringify({schema:'deadbyte.coding-lease.v1',policy_sha256:codingPolicy.policy_sha256,instance_nonce:randomBytes(32).toString('hex'),root_ids:['project','preview'],armed_at_utc:new Date().toISOString(),expires_at_utc:new Date(Date.now()+3600000).toISOString()}));
|
|
24
24
|
const autoPath=path.join(root,'autonomous-policy.json');
|
|
25
25
|
await writeFile(autoPath,JSON.stringify({schema:'deadbyte.autonomous-policy.v1',enabled:true,lease_file:path.join(root,'auto-lease.json'),evidence_dir:path.join(root,'auto-evidence'),root_ids:['project'],coding_policy_sha256:codingPolicy.policy_sha256,planner:{backend:'client_sampling',max_tokens:2048},profiles:{},limits:{max_files_per_diff:12,max_diff_bytes:1048576}}));
|
|
26
26
|
const policy=await loadAutonomousPolicy(autoPath,codingPolicy);
|
|
@@ -31,6 +31,39 @@ async function fixture(){
|
|
|
31
31
|
return {root,project,keys,policy,codingRuntime,machineFsRuntime,nativeDiff};
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
test('R71 Native Diff V2 Coding-only topology preview is non-applicable',async()=>{
|
|
35
|
+
const f=await fixture();
|
|
36
|
+
try{
|
|
37
|
+
const preview=await f.nativeDiff.preview({rootId:'preview',title:'read-only topology',operations:[
|
|
38
|
+
{kind:'mkdir',path:'candidate/newdir'}
|
|
39
|
+
]});
|
|
40
|
+
assert.equal(preview.status,'preview_only');
|
|
41
|
+
assert.equal(preview.schema,NATIVE_DIFF_V2_SCHEMA);
|
|
42
|
+
assert.equal(preview.diff_id,undefined);
|
|
43
|
+
assert.equal(preview.root_id,'preview');
|
|
44
|
+
assert.equal(preview.operation_count,1);
|
|
45
|
+
assert.equal(await exists(path.join(f.project,'candidate')),false);
|
|
46
|
+
assert.equal(await exists(path.join(f.policy.evidence_dir,'native-diffs')),false);
|
|
47
|
+
await assert.rejects(f.nativeDiff.apply({diffId:'0'.repeat(64)}));
|
|
48
|
+
await rm(f.codingRuntime.policy.lease_file);
|
|
49
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'preview',operations:[
|
|
50
|
+
{kind:'mkdir',path:'after-revoke'}
|
|
51
|
+
]}),/coding plane is disarmed/);
|
|
52
|
+
}finally{await rm(f.root,{recursive:true,force:true});}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('V2 topology preview on an Autonomous root remains non-applicable after Autonomous revocation',async()=>{
|
|
56
|
+
const f=await fixture();
|
|
57
|
+
try{
|
|
58
|
+
await rm(f.policy.lease_file);
|
|
59
|
+
const preview=await f.nativeDiff.preview({rootId:'project',operations:[{kind:'mkdir',path:'still-read-only'}]});
|
|
60
|
+
assert.equal(preview.status,'preview_only');
|
|
61
|
+
assert.equal(preview.diff_id,undefined);
|
|
62
|
+
assert.equal(await exists(path.join(f.project,'still-read-only')),false);
|
|
63
|
+
assert.equal(await exists(path.join(f.policy.evidence_dir,'native-diffs')),false);
|
|
64
|
+
}finally{await rm(f.root,{recursive:true,force:true});}
|
|
65
|
+
});
|
|
66
|
+
|
|
34
67
|
test('R36 Native Diff V2 commits mkdir write move and independently verifies mixed receipts',async()=>{
|
|
35
68
|
const f=await fixture(); try{
|
|
36
69
|
await writeFile(path.join(f.project,'seed.txt'),'seed\n');
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { createHash, randomBytes } from 'node:crypto';
|
|
4
|
-
import { access, mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { access, mkdtemp, mkdir, readFile, rm, symlink, writeFile } from 'node:fs/promises';
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import { generateTrustKeypair } from '../src/trust.mjs';
|
|
8
8
|
import { createCodingRuntime, loadCodingPolicy } from '../src/coding-plane.mjs';
|
|
9
9
|
import { loadAutonomousPolicy } from '../src/autonomous-policy.mjs';
|
|
10
10
|
import { createNativeDiffRuntime } from '../src/native-diff.mjs';
|
|
11
|
+
import { registerAutonomousTools } from '../src/autonomous-mcp-tools.mjs';
|
|
11
12
|
|
|
12
13
|
const sha = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
13
14
|
const exists = file => access(file).then(() => true, () => false);
|
|
@@ -19,10 +20,11 @@ async function fixture() {
|
|
|
19
20
|
const codingPolicyPath = path.join(root, 'coding-policy.json');
|
|
20
21
|
await writeFile(codingPolicyPath, JSON.stringify({ schema:'deadbyte.coding-policy.v1', enabled:true,
|
|
21
22
|
lease_file:path.join(root,'coding-lease.json'), evidence_dir:path.join(root,'coding-evidence'),
|
|
22
|
-
roots:{ project:{ path:project, read:true, write:true, exec:true, deny_paths:[] }
|
|
23
|
+
roots:{ project:{ path:project, read:true, write:true, exec:true, deny_paths:[] },
|
|
24
|
+
preview:{ path:project, read:true, write:false, exec:false, deny_paths:[] } }, commands:{} }, null, 2));
|
|
23
25
|
const codingPolicy = await loadCodingPolicy(codingPolicyPath);
|
|
24
26
|
await writeFile(codingPolicy.lease_file, JSON.stringify({ schema:'deadbyte.coding-lease.v1', policy_sha256:codingPolicy.policy_sha256,
|
|
25
|
-
instance_nonce:randomBytes(32).toString('hex'), root_ids:['project'], armed_at_utc:new Date().toISOString(),
|
|
27
|
+
instance_nonce:randomBytes(32).toString('hex'), root_ids:['project','preview'], armed_at_utc:new Date().toISOString(),
|
|
26
28
|
expires_at_utc:new Date(Date.now()+3600000).toISOString() }));
|
|
27
29
|
const autonomousPolicyPath = path.join(root, 'autonomous-policy.json');
|
|
28
30
|
await writeFile(autonomousPolicyPath, JSON.stringify({ schema:'deadbyte.autonomous-policy.v1', enabled:true,
|
|
@@ -38,6 +40,84 @@ async function fixture() {
|
|
|
38
40
|
return { root, project, keys, policy, codingRuntime, nativeDiff };
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
test('R71 Coding-only native_diff_preview does not create an applicable signed diff',async()=>{
|
|
44
|
+
const f=await fixture();
|
|
45
|
+
try{
|
|
46
|
+
const file=path.join(f.project,'only-preview.txt');
|
|
47
|
+
await writeFile(file,'original text\n');
|
|
48
|
+
const before=sha(await readFile(file));
|
|
49
|
+
const preview=await f.nativeDiff.preview({rootId:'preview',title:'read-only project preview',operations:[
|
|
50
|
+
{kind:'replace',path:'only-preview.txt',expected_sha256:before,old_string:'original',new_string:'updated',expected_replacements:1}
|
|
51
|
+
]});
|
|
52
|
+
assert.equal(preview.status,'preview_only');
|
|
53
|
+
assert.equal(preview.diff_id,undefined);
|
|
54
|
+
assert.equal(preview.root_id,'preview');
|
|
55
|
+
assert.equal(preview.operation_count,1);
|
|
56
|
+
assert.equal((await readFile(file,'utf8')),'original text\n');
|
|
57
|
+
assert.equal(await exists(path.join(f.policy.evidence_dir,'native-diffs')),false);
|
|
58
|
+
await assert.rejects(f.nativeDiff.apply({diffId:'0'.repeat(64)}));
|
|
59
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'ungranted',operations:[
|
|
60
|
+
{kind:'write',path:'not-allowed.txt',content:'abc',expected_sha256:'absent'}
|
|
61
|
+
]}),/not allowed|disarmed|denied|root/);
|
|
62
|
+
await rm(f.codingRuntime.policy.lease_file);
|
|
63
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'preview',operations:[
|
|
64
|
+
{kind:'replace',path:'only-preview.txt',expected_sha256:before,old_string:'original',new_string:'updated'}
|
|
65
|
+
]}),/coding plane is disarmed/);
|
|
66
|
+
}finally{await rm(f.root,{recursive:true,force:true});}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('MCP preview on an Autonomous-policy root remains read-only with only Coding authority',async()=>{
|
|
70
|
+
const f=await fixture();
|
|
71
|
+
try{
|
|
72
|
+
const file=path.join(f.project,'mcp-preview.txt');
|
|
73
|
+
await writeFile(file,'old\n');
|
|
74
|
+
const before=sha(await readFile(file));
|
|
75
|
+
await rm(f.policy.lease_file);
|
|
76
|
+
const handlers=new Map();
|
|
77
|
+
const contracts=new Map();
|
|
78
|
+
registerAutonomousTools({registerTool:(name,contract,handler)=>{handlers.set(name,handler);contracts.set(name,contract);}},
|
|
79
|
+
{autonomousRuntime:{},nativeDiffRuntime:f.nativeDiff});
|
|
80
|
+
assert.match(contracts.get('native_diff_preview').description,/Coding read authority/i);
|
|
81
|
+
assert.match(contracts.get('native_diff_preview').description,/preview.only/i);
|
|
82
|
+
const response=await handlers.get('native_diff_preview')({root_id:'project',title:'read only',operations:[
|
|
83
|
+
{kind:'replace',path:'mcp-preview.txt',expected_sha256:before,old_string:'old',new_string:'new',expected_replacements:1}
|
|
84
|
+
]});
|
|
85
|
+
assert.equal(response.isError,false);
|
|
86
|
+
assert.equal(response.structuredContent.status,'preview_only');
|
|
87
|
+
assert.equal(response.structuredContent.diff_id,undefined);
|
|
88
|
+
assert.equal(sha(await readFile(file)),before);
|
|
89
|
+
assert.equal(await exists(path.join(f.policy.evidence_dir,'native-diffs')),false);
|
|
90
|
+
}finally{await rm(f.root,{recursive:true,force:true});}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('Coding-only preview denies escaped, reparse, and expired authority without changing targets',async()=>{
|
|
94
|
+
const f=await fixture();
|
|
95
|
+
try{
|
|
96
|
+
await rm(f.policy.lease_file);
|
|
97
|
+
const outside=path.join(f.root,'outside.txt');
|
|
98
|
+
await writeFile(outside,'outside\n');
|
|
99
|
+
const outsideSha=sha(await readFile(outside));
|
|
100
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'project',operations:[
|
|
101
|
+
{kind:'replace',path:'../outside.txt',expected_sha256:outsideSha,old_string:'outside',new_string:'changed'}
|
|
102
|
+
]}),/path|escape|outside|relative/i);
|
|
103
|
+
const link=path.join(f.project,'linked');
|
|
104
|
+
const target=path.join(f.root,'external');
|
|
105
|
+
await mkdir(target);
|
|
106
|
+
await writeFile(path.join(target,'target.txt'),'outside\n');
|
|
107
|
+
await symlink(target,link,process.platform==='win32'?'junction':'dir');
|
|
108
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'project',operations:[
|
|
109
|
+
{kind:'replace',path:'linked/target.txt',expected_sha256:outsideSha,old_string:'outside',new_string:'changed'}
|
|
110
|
+
]}),/reparse|symlink|path|outside|root/i);
|
|
111
|
+
const lease=JSON.parse(await readFile(f.codingRuntime.policy.lease_file,'utf8'));
|
|
112
|
+
await writeFile(f.codingRuntime.policy.lease_file,JSON.stringify({...lease,expires_at_utc:new Date(Date.now()-1000).toISOString()}));
|
|
113
|
+
await assert.rejects(f.nativeDiff.preview({rootId:'project',operations:[
|
|
114
|
+
{kind:'write',path:'new.txt',content:'new',expected_sha256:'absent'}
|
|
115
|
+
]}),/coding plane is disarmed: expired/);
|
|
116
|
+
assert.equal(sha(await readFile(outside)),outsideSha);
|
|
117
|
+
assert.equal(sha(await readFile(path.join(target,'target.txt'))),outsideSha);
|
|
118
|
+
}finally{await rm(f.root,{recursive:true,force:true});}
|
|
119
|
+
});
|
|
120
|
+
|
|
41
121
|
test('native diff commits exact preconditioned edits and independently verifies coding receipts', async () => {
|
|
42
122
|
const f = await fixture();
|
|
43
123
|
try {
|
|
@@ -48,7 +48,7 @@ async function fixture() {
|
|
|
48
48
|
return { trust, client, transport };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
test
|
|
51
|
+
test('R44 historical base-plus-agent catalog is frozen at 13; current R47 runtime supersedes it',{skip:'Historical R44 base-plus-agent catalog frozen at 13; current R47+ supersedes it'}, async () => {
|
|
52
52
|
const f = await fixture();
|
|
53
53
|
try {
|
|
54
54
|
await f.client.connect(f.transport);
|
|
@@ -26,3 +26,15 @@ test('R51 live tail parses each audit line once and reuses the decoded event',as
|
|
|
26
26
|
assert.match(cli,/auditTimelineRecord\(file,line,auditEvent\)/);
|
|
27
27
|
assert.match(cli,/formatLogLine\(file,line,\{auditEvent,/);
|
|
28
28
|
});
|
|
29
|
+
|
|
30
|
+
test('R67 live log selection is bounded, deduplicated and rejects path traversal/drive prefixes',()=>{
|
|
31
|
+
const runtimeNames=['bridge.stdout.log','bridge.stdout.log','../private.log','..\\private.log','C:\\token.log','.hidden.log',
|
|
32
|
+
...Array.from({length:180},(_,i)=>'remote-'+String(i).padStart(3,'0')+'.log')];
|
|
33
|
+
const auditNames=['segment-00000001.jsonl','segment-00000002.jsonl','segment-00000002.jsonl','segment-00000003.jsonl'];
|
|
34
|
+
const selected=selectLiveLogNames({auditNames,runtimeNames});
|
|
35
|
+
assert.deepEqual(selected.audit,['segment-00000002.jsonl','segment-00000003.jsonl']);
|
|
36
|
+
assert.ok(selected.runtime.length<=64,'cap runtime readers to a finite budget');
|
|
37
|
+
assert.equal(new Set(selected.runtime).size,selected.runtime.length);
|
|
38
|
+
assert.ok(selected.runtime.every(name=>/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.log$/.test(name)));
|
|
39
|
+
assert.ok(selected.runtime.includes('remote-179.log'));
|
|
40
|
+
});
|
|
@@ -6,7 +6,7 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
8
|
const currentPackage=await json('package.json');
|
|
9
|
-
const r53test=currentPackage.version==='0.15.30'?test:test.
|
|
9
|
+
const r53test=currentPackage.version==='0.15.30'?test:(name,fn)=>test(name,{skip:'Historical R53 release contract requires 0.15.30; current '+currentPackage.version},fn);
|
|
10
10
|
|
|
11
11
|
r53test('R53 current release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
12
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
@@ -6,7 +6,7 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
8
|
const currentPackage=await json('package.json');
|
|
9
|
-
const r54test=currentPackage.version==='0.15.31'?test:test.
|
|
9
|
+
const r54test=currentPackage.version==='0.15.31'?test:(name,fn)=>test(name,{skip:'Historical R54 release contract requires 0.15.31; current '+currentPackage.version},fn);
|
|
10
10
|
|
|
11
11
|
r54test('R54 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
12
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
@@ -6,7 +6,7 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
8
|
const currentPackage=await json('package.json');
|
|
9
|
-
const r55test=currentPackage.version==='0.15.32'?test:test.
|
|
9
|
+
const r55test=currentPackage.version==='0.15.32'?test:(name,fn)=>test(name,{skip:'Historical R55 release contract requires 0.15.32; current '+currentPackage.version},fn);
|
|
10
10
|
|
|
11
11
|
r55test('R55 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
12
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
@@ -6,7 +6,7 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
8
|
const currentPackage=await json('package.json');
|
|
9
|
-
const r56test=currentPackage.version==='0.15.33'?test:test.
|
|
9
|
+
const r56test=currentPackage.version==='0.15.33'?test:(name,fn)=>test(name,{skip:'Historical R56 release contract requires 0.15.33; current '+currentPackage.version},fn);
|
|
10
10
|
|
|
11
11
|
r56test('R56 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
12
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
@@ -6,7 +6,7 @@ const root=new URL('../',import.meta.url);
|
|
|
6
6
|
const read=rel=>readFile(new URL(rel,root),'utf8');
|
|
7
7
|
const json=rel=>read(rel).then(JSON.parse);
|
|
8
8
|
const currentPackage=await json('package.json');
|
|
9
|
-
const r57test=currentPackage.version==='0.15.34'?test:test.
|
|
9
|
+
const r57test=currentPackage.version==='0.15.34'?test:(name,fn)=>test(name,{skip:'Historical R57 release contract requires 0.15.34; current '+currentPackage.version},fn);
|
|
10
10
|
|
|
11
11
|
r57test('R57 release identity is coherent across package lock source metadata SBOM and gate',async()=>{
|
|
12
12
|
const [pkg,lock,release,provenance,matrix,sbom,versionSource]=await Promise.all([
|
|
@@ -11,7 +11,7 @@ test('R58 deployment activates the bridge bundled inside the candidate release,
|
|
|
11
11
|
assert.match(deploy,/const bridgeScript=path\.join\(bridgeRoot,'src','bridge\.mjs'\)/);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
test('R58 bundled bridge package is present and version-bound to 0.15.35',{skip:currentPackage.version!=='0.15.35'},async()=>{
|
|
14
|
+
test('R58 bundled bridge package is present and version-bound to 0.15.35',{skip:currentPackage.version!=='0.15.35' ? 'Historical R58 bridge artifact requires 0.15.35; current '+currentPackage.version : false},async()=>{
|
|
15
15
|
const [pkg,bridgePkg,bridge]=await Promise.all([
|
|
16
16
|
readFile(new URL('../package.json',import.meta.url),'utf8').then(JSON.parse),
|
|
17
17
|
readFile(new URL('../bridge/package.json',import.meta.url),'utf8').then(JSON.parse),
|
|
@@ -6,7 +6,7 @@ const read=rel=>readFile(new URL('../'+rel,import.meta.url),'utf8');
|
|
|
6
6
|
const json=rel=>read(rel).then(JSON.parse);
|
|
7
7
|
const currentPackage=await json('package.json');
|
|
8
8
|
|
|
9
|
-
test('R58 identity is coherent and parent is exact production-accepted 0.15.34',{skip:currentPackage.version!=='0.15.35'},async()=>{
|
|
9
|
+
test('R58 identity is coherent and parent is exact production-accepted 0.15.34',{skip:currentPackage.version!=='0.15.35' ? 'Historical R58 release contract requires 0.15.35; current '+currentPackage.version : false},async()=>{
|
|
10
10
|
const [pkg,lock,release,prov,matrix,sbom,version,bridgePkg]=await Promise.all([
|
|
11
11
|
json('package.json'),json('package-lock.json'),json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json'),json('SBOM.cdx.json'),read('src/version.mjs'),json('bridge/package.json')
|
|
12
12
|
]);
|
|
@@ -29,7 +29,7 @@ test('R58 identity is coherent and parent is exact production-accepted 0.15.34',
|
|
|
29
29
|
assert.equal(release.parent.tarball_sha256,'a6f7b21faf34793ca17dfb6d0e9ec03320f1468d011e75d8349098df82fc2639');
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
test('R58 consolidation evidence preserves fail-closed and non-final claims',{skip:currentPackage.version!=='0.15.35'},async()=>{
|
|
32
|
+
test('R58 consolidation evidence preserves fail-closed and non-final claims',{skip:currentPackage.version!=='0.15.35' ? 'Historical R58 release contract requires 0.15.35; current '+currentPackage.version : false},async()=>{
|
|
33
33
|
const [release,prov,matrix]=await Promise.all([json('RELEASE.json'),json('PROVENANCE.json'),json('TEST-MATRIX.json')]);
|
|
34
34
|
assert.equal(release.consolidation.bridge_bundled_inside_release,true);
|
|
35
35
|
assert.equal(release.consolidation.bridge_recursive_local_dependency_binding,true);
|
|
@@ -5,7 +5,7 @@ import {readFile} from 'node:fs/promises';
|
|
|
5
5
|
const read=rel=>readFile(new URL('../'+rel,import.meta.url),'utf8');
|
|
6
6
|
const currentPackage=JSON.parse(await read('package.json'));
|
|
7
7
|
|
|
8
|
-
test('R58 canonical Windows gate is final-candidate bound and leaves historical gates immutable',{skip:currentPackage.version!=='0.15.35'},async()=>{
|
|
8
|
+
test('R58 canonical Windows gate is final-candidate bound and leaves historical gates immutable',{skip:currentPackage.version!=='0.15.35' ? 'Historical R58 Windows gate requires 0.15.35; current '+currentPackage.version : false},async()=>{
|
|
9
9
|
const [pkgText,gate,evidence,r57Gate,r57Evidence]=await Promise.all([
|
|
10
10
|
read('package.json'),read('scripts/gate-windows-r58.ps1'),read('scripts/windows-gate-evidence-r58.mjs'),
|
|
11
11
|
read('scripts/gate-windows-r57.ps1'),read('scripts/windows-gate-evidence-r57.mjs')
|
|
@@ -71,7 +71,7 @@ async function captureCurrentSurface(){
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
test('
|
|
74
|
+
test('R71 compact baseline permits only R64 read offset and authorized coding-only preview output',async()=>{
|
|
75
75
|
const raw=JSON.parse(await readFile(fixturePath,'utf8'));
|
|
76
76
|
assert.equal(raw.schema,'deadbyte.tool-surface-baseline.v1');
|
|
77
77
|
assert.equal(raw.release_id,'v0.15.35-1b5715b276facbc0');
|
|
@@ -83,13 +83,17 @@ test('R59 compact baseline changes only at the explicitly authorized R64 read-of
|
|
|
83
83
|
assert.deepEqual(diff.added,[]);
|
|
84
84
|
assert.deepEqual(diff.removed,[]);
|
|
85
85
|
const packageVersion=JSON.parse(await readFile(path.join(repoRoot,'package.json'),'utf8')).version;
|
|
86
|
-
if(['0.15.41','0.15.42','0.15.43'].includes(packageVersion)){
|
|
87
|
-
assert.deepEqual(diff.schema_changed,['machine_fs']);
|
|
88
|
-
assert.equal(diff.unchanged.length,
|
|
86
|
+
if(['0.15.41','0.15.42','0.15.43','0.15.44','0.15.45'].includes(packageVersion)){
|
|
87
|
+
assert.deepEqual([...diff.schema_changed].sort(),['machine_fs','native_diff_preview']);
|
|
88
|
+
assert.equal(diff.unchanged.length,41);
|
|
89
89
|
const prior=baseline.tools.find(tool=>tool.name==='machine_fs');
|
|
90
90
|
const present=current.tools.find(tool=>tool.name==='machine_fs');
|
|
91
|
-
assert.equal(present.output_sha256,prior.output_sha256,'output contract must remain unchanged');
|
|
91
|
+
assert.equal(present.output_sha256,prior.output_sha256,'machine_fs output contract must remain unchanged');
|
|
92
92
|
assert.notEqual(present.input_sha256,prior.input_sha256,'R64 must expose the widened read offset');
|
|
93
|
+
const previewBefore=baseline.tools.find(tool=>tool.name==='native_diff_preview');
|
|
94
|
+
const previewAfter=current.tools.find(tool=>tool.name==='native_diff_preview');
|
|
95
|
+
assert.equal(previewAfter.input_sha256,previewBefore.input_sha256,'preview-only must not change input permissions or tool selection');
|
|
96
|
+
assert.notEqual(previewAfter.output_sha256,previewBefore.output_sha256,'preview-only output must be declared in MCP schema');
|
|
93
97
|
}else{
|
|
94
98
|
assert.deepEqual(diff.schema_changed,[]);
|
|
95
99
|
assert.equal(diff.unchanged.length,43);
|