deadbyte-mcp 0.15.10 → 0.15.11
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 +11 -8
- package/PROVENANCE.json +1 -1
- package/README.txt +6 -6
- package/RELEASE.json +1 -1
- package/package.json +1 -1
- package/scripts/sign-adaptive-skill.mjs +86 -0
- package/src/capability-resolver.mjs +303 -0
- package/src/compact-gateway-mcp-tools.mjs +13 -3
- package/src/mcp-server.mjs +2 -1
- package/src/process-runtime.mjs +15 -0
- package/src/runtime-update.mjs +3 -3
- package/src/version.mjs +1 -1
- package/test/capability-resolver.test.mjs +133 -0
package/MANIFEST.SHA256
CHANGED
|
@@ -1328,7 +1328,7 @@ db605a698f917c4006462596e6526fe6a9c6eff9b8409e8472fe545d4b70027c node_modules/z
|
|
|
1328
1328
|
f67a25ded944912bd4621b68df17c7c70a52aae117278c076c0aabbc32a3abba node_modules/zod/v4/mini/schemas.d.ts
|
|
1329
1329
|
51b3a7869df2d3a1bd98acb9d5b6a61bbccc7653d7a3d8fca7f0e0db7e84e284 node_modules/zod/v4/mini/schemas.js
|
|
1330
1330
|
3e3125b5a537a24c3632c1c5c09640ce7bcb3935901b127ad8ae3c37a27f133f node_modules/zod/v4/package.json
|
|
1331
|
-
|
|
1331
|
+
34e5345b9f07fad9e3f7f54c496f3cf0cc4ff07c34c938c35244a9e1f209eeeb package.json
|
|
1332
1332
|
8177e3a354721a73df889f386a97e7744a2e017d150aecf4bf309f5177d18690 proof/CONTAINMENT-BUILD.txt
|
|
1333
1333
|
a8efa13e44ff50902aee64cfca542d19605a1ae23db95280ad2d44b324f3eae7 proof/MCP-SMOKE-STATUS.txt
|
|
1334
1334
|
7c115069cc4a343ca21b0ebdee74bd8f544b02d4aa906ffa13308725825d891a proof/NODE-SYNTAX.txt
|
|
@@ -1388,7 +1388,7 @@ d433aaea5cccd1e184775ac4d915f34e0b39c6c99916dddd009731ad5fd6443f proof/V073-WIN
|
|
|
1388
1388
|
bd0773a9e02e8ab11475c9cc5a7db29a8313233b7eab7f837922737e75ec5938 proof/VERIFY.txt
|
|
1389
1389
|
2c821808d4596965c577f40191daee224d3aea81989778c4af97f53a83b487db proof/WINDOWS-CONTAINED-STATUS.txt
|
|
1390
1390
|
f8bc839c7b4fcb0ea7b7e7ad9448847c3beae6f95f2eb4d407d1b284aaa4ff68 proof/WINDOWS-CONTAINMENT-STATUS.txt
|
|
1391
|
-
|
|
1391
|
+
c7a11729f77023dd1d741d61b35ea0b75cca061a28f3a4cbe0062ca6a536f4ab PROVENANCE.json
|
|
1392
1392
|
27ca0f3c9ee3a1b6374a9c8dd98008decdd0c7659c7a569c70ad7b9734c74655 R34-BASELINE.json
|
|
1393
1393
|
0b7ec5ee347ddfa6cca59740fc7a8fe3fc5d51406265bb12189e82fa106319d2 R41-PARENT.json
|
|
1394
1394
|
bd2a789b0aab5663f0d208af2ca8e4ec98179bc8c7b57e70a962d4e06a3dcfc4 R42-PARENT.json
|
|
@@ -1397,7 +1397,7 @@ f932ef78b7a72b1bb0d7aedb5fe42fbb9951c2492eb528b72442f46ddff81a6c R44-DONORS.jso
|
|
|
1397
1397
|
731b4c559fc0d25dea701e4474f02400b27e8e3f4cac9f230d5214497d4490a9 R44-PARENT.json
|
|
1398
1398
|
d33ec5d167dd44800ba4e68372b08db43deb8d01df2ef71dd435ff004ac66c8b R45-PARENT.json
|
|
1399
1399
|
4d8bc9d61d7558a484269cc13263b42bb39417700bb3858069d64a2d1ae190e8 README.txt
|
|
1400
|
-
|
|
1400
|
+
be4640a1d9e47f904e758e0b88b6e2ef7ee8b1921c90a95e404d28d1eb01a69b RELEASE.json
|
|
1401
1401
|
507a42441c8fbb0b1bef63a13fad9e1680262cd6d34cc176b7ed0c5423ddbcc7 SBOM.cdx.json
|
|
1402
1402
|
bd138fe5a64088e8e1a7a5bf6104c5b17317bdc8cf3ad8191ea00ed82ace7d9b scripts/agent-eval-r42.mjs
|
|
1403
1403
|
8d90256a6863f3bbbff02e95cb12389fc6f9e8dbcb77bf1c20c902de371425e8 scripts/archive-source-zips.mjs
|
|
@@ -1522,6 +1522,7 @@ cabfa63d5edb83f32b3e6e5ce22e76223644d81a3361d52a28de2dbc07e59a54 scripts/run-r4
|
|
|
1522
1522
|
abf8ac3074e8964c9648b5b60069730c255faa5f4169f3aefc7a9eff350a1efc scripts/run-skill-creator-scaffold.mjs
|
|
1523
1523
|
caac2867971dfdf56456528b816ff56282a11cbba81510c13e1723accffac678 scripts/runtime-self-update.mjs
|
|
1524
1524
|
b0cc75c38e0163dbcf7fb1b0d21f2dc34c71f2d0e2a156a53e570ff84afc64e6 scripts/semantic-preflight.ps1
|
|
1525
|
+
bf54d2dfa2a77c2c13cc0b8a9ac2eb926132ecd331ad56ebbf88cc5cc4280a96 scripts/sign-adaptive-skill.mjs
|
|
1525
1526
|
0a115aa9829576c86cc247f754cae69ae09ba146b637d3a1c9fbc16420d20a5d scripts/tool-surface-snapshot.mjs
|
|
1526
1527
|
f8d9c6718cbe20e02e517297e8f35f51c7dcd51b62b8b4a483630a9cd3b1f788 scripts/verify-memory-r41.mjs
|
|
1527
1528
|
e552634ca1f8673f5daaaf5e45302d2a7fc4b1a1eac256f60bed2c9136bafa05 scripts/verify-package.ps1
|
|
@@ -1577,13 +1578,14 @@ e5f944a310ed957e3b8f7b1cab54c082acf1b35f8fdd7d9b672ebe1a80dc37ac src/canonical-
|
|
|
1577
1578
|
da5181cec30034ddf089baa5358becb5651da238a2e7cf0888007a4c60b4ea6b src/capability-benchmark-runner.mjs
|
|
1578
1579
|
2b62295591f142ca4b3bc5b03e6434f7fc3c51d9502f9a40ef8a03d1f72a8899 src/capability-benchmark.mjs
|
|
1579
1580
|
160199b25f45bd0490f6b21a9fa8194313e9673c4b2699afce68249d3d249a7b src/capability-ledger.mjs
|
|
1581
|
+
1b0ba08c5d5a75d95953a84a00b551af8ba1ee21cf1995255daa198368017760 src/capability-resolver.mjs
|
|
1580
1582
|
94e5aeff2453cdc0239aee4d547dbbefee183c71933cb84e5e8a418fa99bc1e8 src/codex-app-server-r44.mjs
|
|
1581
1583
|
6d0a80daaa2711e67e2597bff3db5bd2802682f559107a492f3cd89b9c6785ed src/coding-mcp-tools.mjs
|
|
1582
1584
|
d6fc395575f49abbbf60bf6f6ef5ee9ad51034a7e770a381e6ec34f869788306 src/coding-output-contracts.mjs
|
|
1583
1585
|
0857a458e9c5101eee94c0596b7699adc34c50687455688fe38d03d241d27935 src/coding-plane.mjs
|
|
1584
1586
|
38a1b4e9f5aa14cd5fd9058345c3480ae72c4a6a6eeccdc46e71297c68b5b5a6 src/coding-search.mjs
|
|
1585
1587
|
f87284dc71c167f6a17575b93730c258ed6c433831013c776bf2d14e2b77767f src/coding-task-runtime.mjs
|
|
1586
|
-
|
|
1588
|
+
8478ef1f7b3dc89480c4310a20268048f581041bddcc0b7de9298fa2bfc654ca src/compact-gateway-mcp-tools.mjs
|
|
1587
1589
|
4218d1d1478d9e9a044d9b61c5ae205cd2ca0651a314900fad03992d0b12d286 src/compact-gateway-output-contracts.mjs
|
|
1588
1590
|
40ac70ece531de7709d3c51686b36b48e0ae60283d1fb18d0adc037bfe6f9063 src/contained-cli.mjs
|
|
1589
1591
|
d2bacef2443705e372071d0de3c72d45d57febb1dcbb11e369fce8a78bf0bf3e src/contained-executor.mjs
|
|
@@ -1632,7 +1634,7 @@ ad4ca3635cb228b57b5b98e9518f379380ee1a03ad07ab4d12f8b7f324be2517 src/machine-mc
|
|
|
1632
1634
|
e81b3ac2955e5dfafe308c82da24356a14da396230cb9fc47b231ab672d5be48 src/machine-output-contracts.mjs
|
|
1633
1635
|
ed85d41c494a334117661ddec8191d34974fe28cb2a3378f3c04ee0e4c5d3ccc src/mcp-contained-smoke-client.mjs
|
|
1634
1636
|
b705345aa432b6a6ebbf62aabce1f78ba7e392bdfe998e79217eba8289ed0a7e src/mcp-host-smoke-client.mjs
|
|
1635
|
-
|
|
1637
|
+
3300d50f8a015bb090d5820dafe42edcc3d16a741e3ff12232ec03aadf115158 src/mcp-server.mjs
|
|
1636
1638
|
b490c4152b16adae658b3af20a4827847866cec352e1b0c9eb6b36094116b83b src/mcp-smoke-client.mjs
|
|
1637
1639
|
cde7c813f5a2e9a69f09849455d1504e766963845a1f4b201ecc84090fa260d5 src/memory-r41.mjs
|
|
1638
1640
|
9525aee66944023603f6d1ebb0768b8e8ab8bb93582a10dd7f9cd4459ee07454 src/native-diff-v2.mjs
|
|
@@ -1649,7 +1651,7 @@ b8e4e38fc38bd8d2efb01b58028944bc8133dcc42de12b1035784c5e01beca35 src/output-con
|
|
|
1649
1651
|
974b5e9a5f60c4b2ac8bed629fb39a4e3c06b591995bec3f5f4756da8f3fd2e1 src/process-mcp-tools.mjs
|
|
1650
1652
|
4c90265628194d989ac78f2b06eadbfffceb9c006d5b6c2e982f5667f7a385ed src/process-output-contracts.mjs
|
|
1651
1653
|
f5322664c669bc193214a803f9723e3728053f60bc008530db39a9af7f7bab75 src/process-policy.mjs
|
|
1652
|
-
|
|
1654
|
+
622b984e577932ed0c342a6d7e0e8a17d08e888caa2ca67c5ecc1bbcca16042a src/process-runtime.mjs
|
|
1653
1655
|
65d81b6cbdf4f4ce34ccef11793e79cfed6883288288915d077c11674f0873bb src/process-smoke-client.mjs
|
|
1654
1656
|
bb4d1532684b8f81a42377c4b0a9d4c61207856edfff496e878ffbb885b52442 src/proof-cli.mjs
|
|
1655
1657
|
be4a4f7f16e473ac842559a5a18eccb59e3693bded59a1abc71e75ff448cc755 src/proof-worker.mjs
|
|
@@ -1686,7 +1688,7 @@ c8fd6fd3e49e866f2c3be326ab07222b36a44528ee0fc3f7b371c34a60e3c45b src/remote-ses
|
|
|
1686
1688
|
827b156eac01cc9ec6f5ca9a49219612f0da511fde770a9eb1235aa913b5e514 src/request-identity.mjs
|
|
1687
1689
|
39251ab165bb0a0b8ea9b4c533aa0cd674934c0fa2c7f63145eac680d1d67be9 src/resource-identity.mjs
|
|
1688
1690
|
ce2223bf6075e96cc02505c1439acce18bb1f204c5e86cf9152bb7194daf3cd2 src/runtime-identity.mjs
|
|
1689
|
-
|
|
1691
|
+
88fe013cc2474e7e015235df39e54c3c6cd8afb8ac50a97b15a9dee590fed541 src/runtime-update.mjs
|
|
1690
1692
|
c61335adb38bfc415fe1cdabfe2c0a87e61579dfd1e52cce91c44d6993479457 src/search-cursor.mjs
|
|
1691
1693
|
fc5407ef8338ebeeede16225b3249166dc4d45e903d873eb46c15c3df07dc9ad src/semantic-backend-registry.mjs
|
|
1692
1694
|
686e9b55b9f4352b941579f186a9b9d348d86af53d052cbd5da953e7d15470ff src/semantic-code.mjs
|
|
@@ -1704,7 +1706,7 @@ bac271c6f5218752ac5ff4decf5249e3893ddb35c63c092ce17238c27fc4d35b src/trust-init
|
|
|
1704
1706
|
16df134040e3ff1e73df722b568d3e8ac0a6923b097696cead7580da75aa8d2a src/tunnel-stdio-compat.mjs
|
|
1705
1707
|
642cb67d1854850e336ee73fbd71b329056bdcbdab35cea19c1a995a155ff5d9 src/verifier-cli.mjs
|
|
1706
1708
|
8f818a4852ce3be3a380cd4736c3073a7a3e0e45cd7c7ca90588a6b843d3d022 src/verifier.mjs
|
|
1707
|
-
|
|
1709
|
+
87f3f4370c3e0e8db4ce0816a205836bb7736000b95d6fd24348944bb739bf6a src/version.mjs
|
|
1708
1710
|
7e09c57a97289360aabfaf3d531208e54872efbfb3182f3c18203d2cb88c46b5 src/worker-registry.mjs
|
|
1709
1711
|
76361d5ae9a710273cf64a7525082197b692236bf23689875e5fd1ef4aa96d2b src/worker-scheduler.mjs
|
|
1710
1712
|
4da1b32f5198bb089bc68b7eb6de21ea296678b5020018a73742bf0df57d62fa src/workload-substrate.mjs
|
|
@@ -1745,6 +1747,7 @@ bad448d7bfd0c66b8d0dc0fa601fc22d69ccc3f447140ed0f77b68957984daea test/capabilit
|
|
|
1745
1747
|
c343906ca0878e13c576cd9f615802b1139c693bf6769a780dfb052637cf0d83 test/capability-benchmark.test.mjs
|
|
1746
1748
|
b9a8faa4b86683ac5aea891fe6bc95f8e425fb31635176aa4603f9d582b52a79 test/capability-claims-r36.test.mjs
|
|
1747
1749
|
a466a490759d438a8ac68919f79ddcb52253bdbecb5e4448a4fbf62af118184e test/capability-ledger-r36.test.mjs
|
|
1750
|
+
5cdf20eace97fa87563c6b139390e6bd8ccbe80215f53aacd041579bfbad20d6 test/capability-resolver.test.mjs
|
|
1748
1751
|
84eefe1a43474927fdc6fb7ef269309c662cefb229d6af2c91d9e2f0b9ba5c23 test/cli-entrypoint.test.mjs
|
|
1749
1752
|
bec565ffa8550d56a5bb21927177c37d9d05f8353e3bc2541fc156886fe23688 test/codex-app-server-r44.test.mjs
|
|
1750
1753
|
c43105a78ee4c93417d720ee660cfebc75b17f142a6484568e3cbaa583457f8c test/codex-autonomous-r44.test.mjs
|
package/PROVENANCE.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.provenance.v1",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.11",
|
|
4
4
|
"builder": "deadbyte-r46-fileless-powershell",
|
|
5
5
|
"source_model": "development-root -> MANIFEST.SHA256 -> immutable release slot -> generation bundle -> signed final closure",
|
|
6
6
|
"signing": "ed25519",
|
package/README.txt
CHANGED
|
@@ -7,12 +7,12 @@ NPX PRIMARY OPERATOR UX
|
|
|
7
7
|
------------------------
|
|
8
8
|
Use the npm CLI entry point instead of the legacy CMD convenience wrapper:
|
|
9
9
|
|
|
10
|
-
npx -y deadbyte-mcp@0.15.
|
|
11
|
-
npx -y deadbyte-mcp@0.15.
|
|
12
|
-
npx -y deadbyte-mcp@0.15.
|
|
13
|
-
npx -y deadbyte-mcp@0.15.
|
|
14
|
-
npx -y deadbyte-mcp@0.15.
|
|
15
|
-
npx -y deadbyte-mcp@0.15.
|
|
10
|
+
npx -y deadbyte-mcp@0.15.11 mcp
|
|
11
|
+
npx -y deadbyte-mcp@0.15.11 remote
|
|
12
|
+
npx -y deadbyte-mcp@0.15.11 remote status
|
|
13
|
+
npx -y deadbyte-mcp@0.15.11 remote restart
|
|
14
|
+
npx -y deadbyte-mcp@0.15.11 audit status
|
|
15
|
+
npx -y deadbyte-mcp@0.15.11 audit verify
|
|
16
16
|
|
|
17
17
|
The `mcp` command is the quiet stdio server entry for local MCP clients; stdout is reserved for MCP.
|
|
18
18
|
The remote CLI invokes the stable active-release PowerShell launcher directly with shell=false.
|
package/RELEASE.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { createHash, createPrivateKey, createPublicKey, sign } from 'node:crypto';
|
|
5
|
+
import { createSkillPlane } from '../src/skill-plane-r44.mjs';
|
|
6
|
+
|
|
7
|
+
const home = os.homedir();
|
|
8
|
+
const stateDir = path.join(home, '.deadbyte-mcp');
|
|
9
|
+
const skillDir = path.join(stateDir, 'skills', 'deadbyte-adaptive-reverse-engineering');
|
|
10
|
+
const sha = b => createHash('sha256').update(b).digest('hex');
|
|
11
|
+
function canonical(v) {
|
|
12
|
+
return Array.isArray(v) ? v.map(canonical) : v && typeof v === 'object'
|
|
13
|
+
? Object.fromEntries(Object.keys(v).sort((a, b) => a.localeCompare(b, 'en')).map(k => [k, canonical(v[k])])) : v;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const skillBytes = await readFile(path.join(skillDir, 'SKILL.md'));
|
|
17
|
+
const skillText = new TextDecoder('utf-8').decode(skillBytes);
|
|
18
|
+
const skillSha = sha(skillBytes);
|
|
19
|
+
|
|
20
|
+
const refFiles = ['references/adaptive-routing.md', 'references/evidence-correlation.md'].sort((a, b) => a.localeCompare(b, 'en'));
|
|
21
|
+
const resources = [];
|
|
22
|
+
for (const rel of refFiles) {
|
|
23
|
+
const bytes = await readFile(path.join(skillDir, ...rel.split('/')));
|
|
24
|
+
resources.push({
|
|
25
|
+
path: rel,
|
|
26
|
+
sha256: sha(bytes),
|
|
27
|
+
kind: 'reference'
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const body = {
|
|
32
|
+
schema: 'deadbyte.skill-manifest.v1',
|
|
33
|
+
name: 'deadbyte-adaptive-reverse-engineering',
|
|
34
|
+
version: '1.1.0',
|
|
35
|
+
description: 'Adaptive evidence-driven low-level reverse-engineering workflow that selects the smallest discriminating analysis path, allocates evidence budget by information gain, tracks contradictions, correlates bytes with semantics, and closes every claim with fresh verification.',
|
|
36
|
+
audience: 'agent',
|
|
37
|
+
skill_md_sha256: skillSha,
|
|
38
|
+
resources,
|
|
39
|
+
required_capabilities: [],
|
|
40
|
+
authority_planes: ['coding'],
|
|
41
|
+
provenance: {
|
|
42
|
+
source: 'skill-creator',
|
|
43
|
+
origin_url: null,
|
|
44
|
+
source_revision: 'local-draft-2026-09-24-v1.1'
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const bodyBytes = Buffer.from(JSON.stringify(canonical(body)), 'utf8');
|
|
49
|
+
const bodySha256 = sha(bodyBytes);
|
|
50
|
+
|
|
51
|
+
const privPem = await readFile(path.join(stateDir, 'trust', 'ed25519-private.pem'));
|
|
52
|
+
const priv = createPrivateKey(privPem);
|
|
53
|
+
const pub = createPublicKey(priv);
|
|
54
|
+
const keyId = sha(pub.export({ type: 'spki', format: 'der' }));
|
|
55
|
+
|
|
56
|
+
const DOMAIN = Buffer.from('DEADBYTE-SKILL-MANIFEST-V1\0', 'utf8');
|
|
57
|
+
const signature = sign(null, Buffer.concat([DOMAIN, bodyBytes]), priv);
|
|
58
|
+
const attestation = {
|
|
59
|
+
algorithm: 'ed25519',
|
|
60
|
+
domain: 'DEADBYTE-SKILL-MANIFEST-V1',
|
|
61
|
+
key_id: keyId,
|
|
62
|
+
signature_base64: signature.toString('base64')
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const unsigned = { body, body_sha256: bodySha256, attestation };
|
|
66
|
+
const envelope = {
|
|
67
|
+
...unsigned,
|
|
68
|
+
manifest_sha256: sha(Buffer.from(JSON.stringify(canonical(unsigned)), 'utf8'))
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
await writeFile(path.join(skillDir, 'skill.json'), JSON.stringify(envelope, null, 2), 'utf8');
|
|
72
|
+
console.log('Skill envelope written successfully:', envelope.manifest_sha256);
|
|
73
|
+
|
|
74
|
+
// Verify with createSkillPlane
|
|
75
|
+
const plane = await createSkillPlane({
|
|
76
|
+
root: path.join(stateDir, 'skills'),
|
|
77
|
+
verifyKeyPath: path.join(stateDir, 'trust', 'ed25519-public.pem')
|
|
78
|
+
});
|
|
79
|
+
const list = await plane.list();
|
|
80
|
+
console.log('Skill plane list result: skills=' + list.skills.length + ' invalid=' + list.invalid_skills.length);
|
|
81
|
+
if (list.invalid_skills.length > 0) {
|
|
82
|
+
console.error('Invalid skills remain:', list.invalid_skills);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const loaded = await plane.load({ name: 'deadbyte-adaptive-reverse-engineering' });
|
|
86
|
+
console.log('Skill loaded OK: name=' + loaded.name + ' verified=' + loaded.verified);
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
export const CAPABILITY_STATES = Object.freeze({
|
|
2
|
+
AVAILABLE: 'AVAILABLE',
|
|
3
|
+
DEGRADED: 'DEGRADED',
|
|
4
|
+
DISABLED: 'DISABLED',
|
|
5
|
+
DENIED: 'DENIED',
|
|
6
|
+
UNAVAILABLE: 'UNAVAILABLE'
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const CAPABILITY_OPERATIONS = Object.freeze({
|
|
10
|
+
'skill.catalog': ['list', 'load', 'resource'],
|
|
11
|
+
'machine.list': ['machine_list'],
|
|
12
|
+
'machine.status': ['machine_status'],
|
|
13
|
+
'machine.ping': ['machine_ping'],
|
|
14
|
+
'machine.revoke': ['machine_revoke'],
|
|
15
|
+
'process.start': ['start'],
|
|
16
|
+
'process.read': ['read'],
|
|
17
|
+
'process.write': ['write'],
|
|
18
|
+
'process.status': ['status'],
|
|
19
|
+
'process.list': ['list'],
|
|
20
|
+
'process.action': ['action'],
|
|
21
|
+
'process.terminate': ['terminate'],
|
|
22
|
+
'coding.session_status': ['coding_session_status'],
|
|
23
|
+
'coding.tree': ['coding_tree'],
|
|
24
|
+
'coding.stat': ['stat'],
|
|
25
|
+
'coding.search': ['search'],
|
|
26
|
+
'coding.files_read': ['files_read'],
|
|
27
|
+
'coding.file_read': ['coding_file_read'],
|
|
28
|
+
'coding.file_write': ['coding_file_write'],
|
|
29
|
+
'coding.text_replace': ['coding_text_replace'],
|
|
30
|
+
'coding.command_run': ['coding_command_run'],
|
|
31
|
+
'coding.benchmark_run': ['coding_benchmark_run'],
|
|
32
|
+
'coding.receipt_verify': ['coding_receipt_verify'],
|
|
33
|
+
'coding.task_submit': ['coding_task_submit'],
|
|
34
|
+
'coding.task_run': ['coding_task_run'],
|
|
35
|
+
'coding.task_status': ['coding_task_status'],
|
|
36
|
+
'coding.task_events': ['coding_task_events'],
|
|
37
|
+
'coding.task_cancel': ['coding_task_cancel'],
|
|
38
|
+
'coding.task_approve': ['coding_task_approve'],
|
|
39
|
+
'coding.task_verify': ['coding_task_verify'],
|
|
40
|
+
'semantic.outline': ['symbol_outline'],
|
|
41
|
+
'semantic.definition': ['symbol_definition'],
|
|
42
|
+
'semantic.references': ['symbol_references'],
|
|
43
|
+
'semantic.diagnostics': ['symbol_diagnostics'],
|
|
44
|
+
'semantic.implementations': ['symbol_implementations'],
|
|
45
|
+
'semantic.rename_preview': ['symbol_rename_preview'],
|
|
46
|
+
'semantic.replace': ['coding_symbol_replace'],
|
|
47
|
+
'machine_fs.stat': ['stat'],
|
|
48
|
+
'machine_fs.list': ['list'],
|
|
49
|
+
'machine_fs.read': ['read'],
|
|
50
|
+
'machine_fs.write': ['write'],
|
|
51
|
+
'machine_fs.edit_exact': ['edit_exact'],
|
|
52
|
+
'machine_fs.mkdir': ['mkdir'],
|
|
53
|
+
'machine_fs.move': ['move'],
|
|
54
|
+
'machine_fs.delete': ['delete'],
|
|
55
|
+
'observation.search_start': ['search_start'],
|
|
56
|
+
'observation.search_page': ['search_page'],
|
|
57
|
+
'observation.search_status': ['search_status'],
|
|
58
|
+
'observation.search_cancel': ['search_cancel'],
|
|
59
|
+
'observation.process_list': ['process_list'],
|
|
60
|
+
'observation.system_status': ['system_status'],
|
|
61
|
+
'observation.hardware_query': ['hardware_query'],
|
|
62
|
+
'desktop.status': ['status'],
|
|
63
|
+
'desktop.observe': ['observe'],
|
|
64
|
+
'desktop.target': ['target'],
|
|
65
|
+
'desktop.action': ['action'],
|
|
66
|
+
'autonomous.session_status': ['autonomous_session_status'],
|
|
67
|
+
'native_diff.preview': ['native_diff_preview'],
|
|
68
|
+
'native_diff.apply': ['native_diff_apply'],
|
|
69
|
+
'native_diff.verify': ['native_diff_verify'],
|
|
70
|
+
'autonomous.goal_submit': ['autonomous_goal_submit'],
|
|
71
|
+
'autonomous.goal_run': ['autonomous_goal_run'],
|
|
72
|
+
'autonomous.goal_status': ['autonomous_goal_status'],
|
|
73
|
+
'autonomous.goal_events': ['autonomous_goal_events'],
|
|
74
|
+
'autonomous.goal_cancel': ['autonomous_goal_cancel'],
|
|
75
|
+
'autonomous.goal_approve': ['autonomous_goal_approve'],
|
|
76
|
+
'autonomous.goal_verify': ['autonomous_goal_verify'],
|
|
77
|
+
'autonomous.release_gate': ['autonomous_release_gate'],
|
|
78
|
+
'host.file_read': ['host_file_read'],
|
|
79
|
+
'host.file_write': ['host_file_write'],
|
|
80
|
+
'host.exec': ['host_exec'],
|
|
81
|
+
'evidence.verify': ['evidence_verify']
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export function deriveCapabilityRequirements(capability) {
|
|
85
|
+
const reqs = [];
|
|
86
|
+
if (capability.runtime_flag) reqs.push(capability.runtime_flag);
|
|
87
|
+
if (capability.id === 'skill.catalog') {
|
|
88
|
+
reqs.push('skill_plane.valid');
|
|
89
|
+
return reqs;
|
|
90
|
+
}
|
|
91
|
+
if (capability.authority === 'coding') {
|
|
92
|
+
if (capability.mutating) {
|
|
93
|
+
reqs.push('coding_session.armed', 'policy.write');
|
|
94
|
+
} else {
|
|
95
|
+
reqs.push('coding_runtime.ready');
|
|
96
|
+
}
|
|
97
|
+
} else if (capability.authority === 'process') {
|
|
98
|
+
if (capability.mutating) {
|
|
99
|
+
reqs.push('process_session.armed');
|
|
100
|
+
} else {
|
|
101
|
+
reqs.push('process_runtime.ready');
|
|
102
|
+
}
|
|
103
|
+
} else if (capability.authority === 'autonomous') {
|
|
104
|
+
if (capability.mutating) {
|
|
105
|
+
reqs.push('autonomous_session.armed');
|
|
106
|
+
} else {
|
|
107
|
+
reqs.push('autonomous_runtime.ready');
|
|
108
|
+
}
|
|
109
|
+
} else if (capability.authority === 'desktop') {
|
|
110
|
+
if (capability.mutating) {
|
|
111
|
+
reqs.push('desktop_control.armed', 'policy.desktop');
|
|
112
|
+
} else {
|
|
113
|
+
reqs.push('desktop_runtime.ready');
|
|
114
|
+
}
|
|
115
|
+
} else if (capability.authority === 'host' || capability.host_only) {
|
|
116
|
+
if (capability.mutating) {
|
|
117
|
+
reqs.push('host_policy.armed');
|
|
118
|
+
} else {
|
|
119
|
+
reqs.push('host_policy.configured');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return reqs;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function resolveCapabilityStates({
|
|
126
|
+
ledger,
|
|
127
|
+
toolCatalog = [],
|
|
128
|
+
profile = 'full',
|
|
129
|
+
env = process.env,
|
|
130
|
+
codingRuntime = null,
|
|
131
|
+
processRuntime = null,
|
|
132
|
+
processPolicy = null,
|
|
133
|
+
machineFsRuntime = null,
|
|
134
|
+
observationRuntime = null,
|
|
135
|
+
desktopRuntime = null,
|
|
136
|
+
desktopPolicy = null,
|
|
137
|
+
autonomousRuntime = null,
|
|
138
|
+
skillRuntime = null,
|
|
139
|
+
hostPolicy = null
|
|
140
|
+
} = {}) {
|
|
141
|
+
const capabilities = ledger?.entries ?? [];
|
|
142
|
+
const resolved = [];
|
|
143
|
+
const catalogSet = new Set(toolCatalog);
|
|
144
|
+
|
|
145
|
+
// Probe session authorities asynchronously
|
|
146
|
+
let codingStatus = null;
|
|
147
|
+
if (codingRuntime?.sessionStatus) {
|
|
148
|
+
try { codingStatus = await codingRuntime.sessionStatus(); } catch {}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let autonomousStatus = null;
|
|
152
|
+
if (autonomousRuntime?.sessionStatus) {
|
|
153
|
+
try { autonomousStatus = await autonomousRuntime.sessionStatus(); } catch {}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
let skillListResult = null;
|
|
157
|
+
if (skillRuntime?.list) {
|
|
158
|
+
try { skillListResult = await skillRuntime.list(); } catch (err) {
|
|
159
|
+
skillListResult = { invalid_skills: [{ name: '*', error: String(err) }] };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
for (const cap of capabilities) {
|
|
164
|
+
const activeTool = profile === 'compact' ? (cap.compact_tool || cap.full_tool) : cap.full_tool;
|
|
165
|
+
const activeOp = profile === 'compact' ? (cap.compact_op || 'direct') : 'direct';
|
|
166
|
+
const ops = CAPABILITY_OPERATIONS[cap.id] ?? [activeOp];
|
|
167
|
+
const requires = deriveCapabilityRequirements(cap);
|
|
168
|
+
|
|
169
|
+
let state = CAPABILITY_STATES.AVAILABLE;
|
|
170
|
+
let ready = true;
|
|
171
|
+
let diagnostic = null;
|
|
172
|
+
|
|
173
|
+
// 1. Runtime Flag Disabled check
|
|
174
|
+
if (cap.runtime_flag && env[cap.runtime_flag] === '0') {
|
|
175
|
+
state = CAPABILITY_STATES.DISABLED;
|
|
176
|
+
ready = false;
|
|
177
|
+
diagnostic = {
|
|
178
|
+
code: 'RUNTIME_FLAG_DISABLED',
|
|
179
|
+
reason: `Runtime flag ${cap.runtime_flag}=0 is disarmed`,
|
|
180
|
+
recoverable: false
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// 2. Tool presence check
|
|
184
|
+
else if (!catalogSet.has(activeTool)) {
|
|
185
|
+
state = CAPABILITY_STATES.UNAVAILABLE;
|
|
186
|
+
ready = false;
|
|
187
|
+
diagnostic = {
|
|
188
|
+
code: 'TOOL_NOT_REGISTERED',
|
|
189
|
+
reason: `Tool '${activeTool}' is not registered in the active tool catalog`,
|
|
190
|
+
recoverable: false
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// 3. Subsystem runtime instantiation check
|
|
194
|
+
else if (cap.id.startsWith('machine_fs.') && !machineFsRuntime) {
|
|
195
|
+
state = CAPABILITY_STATES.UNAVAILABLE;
|
|
196
|
+
ready = false;
|
|
197
|
+
diagnostic = {
|
|
198
|
+
code: 'MACHINE_FS_NOT_INSTANTIATED',
|
|
199
|
+
reason: 'Machine filesystem runtime is uninitialized',
|
|
200
|
+
recoverable: false
|
|
201
|
+
};
|
|
202
|
+
} else if (cap.id.startsWith('observation.') && !observationRuntime) {
|
|
203
|
+
state = CAPABILITY_STATES.UNAVAILABLE;
|
|
204
|
+
ready = false;
|
|
205
|
+
diagnostic = {
|
|
206
|
+
code: 'OBSERVATION_NOT_INSTANTIATED',
|
|
207
|
+
reason: 'Observation runtime is uninitialized',
|
|
208
|
+
recoverable: false
|
|
209
|
+
};
|
|
210
|
+
} else if (cap.id.startsWith('desktop.') && !desktopRuntime) {
|
|
211
|
+
state = CAPABILITY_STATES.UNAVAILABLE;
|
|
212
|
+
ready = false;
|
|
213
|
+
diagnostic = {
|
|
214
|
+
code: 'DESKTOP_NOT_INSTANTIATED',
|
|
215
|
+
reason: 'Desktop runtime is uninitialized',
|
|
216
|
+
recoverable: false
|
|
217
|
+
};
|
|
218
|
+
} else if ((cap.authority === 'host' || cap.host_only) && !hostPolicy) {
|
|
219
|
+
state = CAPABILITY_STATES.DENIED;
|
|
220
|
+
ready = false;
|
|
221
|
+
diagnostic = {
|
|
222
|
+
code: 'HOST_POLICY_DISARMED',
|
|
223
|
+
reason: 'Privileged host policy is not configured or disarmed',
|
|
224
|
+
recoverable: true
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// 4. Session Authority Checks
|
|
228
|
+
else if (cap.authority === 'coding' && cap.mutating && codingStatus && !codingStatus.armed) {
|
|
229
|
+
state = CAPABILITY_STATES.DENIED;
|
|
230
|
+
ready = false;
|
|
231
|
+
diagnostic = {
|
|
232
|
+
code: 'CODING_SESSION_DISARMED',
|
|
233
|
+
reason: codingStatus.reason || 'Coding session is not armed for mutation',
|
|
234
|
+
recoverable: true
|
|
235
|
+
};
|
|
236
|
+
} else if (cap.authority === 'autonomous' && cap.mutating && autonomousStatus && !autonomousStatus.armed) {
|
|
237
|
+
state = CAPABILITY_STATES.DENIED;
|
|
238
|
+
ready = false;
|
|
239
|
+
diagnostic = {
|
|
240
|
+
code: 'AUTONOMOUS_SESSION_DISARMED',
|
|
241
|
+
reason: autonomousStatus.reason || 'Autonomous session is not armed for mutation',
|
|
242
|
+
recoverable: true
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// 5. Subsystem Health Probes (e.g. Skill Plane envelope verification)
|
|
246
|
+
else if (cap.id === 'skill.catalog') {
|
|
247
|
+
if (skillListResult?.invalid_skills && skillListResult.invalid_skills.length > 0) {
|
|
248
|
+
state = CAPABILITY_STATES.DEGRADED;
|
|
249
|
+
ready = false;
|
|
250
|
+
diagnostic = {
|
|
251
|
+
code: 'SKILL_ENVELOPE_MISMATCH',
|
|
252
|
+
reason: `Skill registry rejected envelope for: ${skillListResult.invalid_skills.map(s => s.name).join(', ')}`,
|
|
253
|
+
recoverable: true
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
resolved.push(Object.freeze({
|
|
259
|
+
id: cap.id,
|
|
260
|
+
tool: activeTool,
|
|
261
|
+
compact_tool: cap.compact_tool,
|
|
262
|
+
compact_op: cap.compact_op,
|
|
263
|
+
operations: ops,
|
|
264
|
+
authority: cap.authority,
|
|
265
|
+
mutating: cap.mutating,
|
|
266
|
+
production: cap.production,
|
|
267
|
+
runtime_flag: cap.runtime_flag,
|
|
268
|
+
requires,
|
|
269
|
+
state,
|
|
270
|
+
ready,
|
|
271
|
+
diagnostic
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const effectiveCapabilities = resolved
|
|
276
|
+
.filter(c => c.state === CAPABILITY_STATES.AVAILABLE)
|
|
277
|
+
.map(c => c.id);
|
|
278
|
+
|
|
279
|
+
const unavailableCapabilities = resolved
|
|
280
|
+
.filter(c => c.state === CAPABILITY_STATES.UNAVAILABLE || c.state === CAPABILITY_STATES.DISABLED || c.state === CAPABILITY_STATES.DENIED)
|
|
281
|
+
.map(c => ({
|
|
282
|
+
id: c.id,
|
|
283
|
+
state: c.state,
|
|
284
|
+
reason_code: c.diagnostic?.code ?? 'UNAVAILABLE',
|
|
285
|
+
reason: c.diagnostic?.reason ?? 'Capability not available'
|
|
286
|
+
}));
|
|
287
|
+
|
|
288
|
+
const degradedCapabilities = resolved
|
|
289
|
+
.filter(c => c.state === CAPABILITY_STATES.DEGRADED)
|
|
290
|
+
.map(c => ({
|
|
291
|
+
id: c.id,
|
|
292
|
+
state: c.state,
|
|
293
|
+
reason_code: c.diagnostic?.code ?? 'DEGRADED',
|
|
294
|
+
reason: c.diagnostic?.reason ?? 'Capability operating in degraded mode'
|
|
295
|
+
}));
|
|
296
|
+
|
|
297
|
+
return Object.freeze({
|
|
298
|
+
capabilities: resolved,
|
|
299
|
+
effective_capabilities: effectiveCapabilities,
|
|
300
|
+
unavailable_capabilities: unavailableCapabilities,
|
|
301
|
+
degraded_capabilities: degradedCapabilities
|
|
302
|
+
});
|
|
303
|
+
}
|
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import * as z from 'zod/v4';
|
|
3
3
|
import { compactGatewayOutputSchema, compactGatewayResult } from './compact-gateway-output-contracts.mjs';
|
|
4
4
|
import { desktopControlInputSchema,invokeDesktopOperation } from './desktop-mcp-tools-r40.mjs';
|
|
5
|
+
import { resolveCapabilityStates } from './capability-resolver.mjs';
|
|
5
6
|
|
|
6
7
|
const id=z.string().regex(/^[A-Za-z0-9._-]{1,64}$/);
|
|
7
8
|
const rel=z.string().min(1).max(2048);
|
|
@@ -123,17 +124,26 @@ async function machineObserve(args,machineRuntime,observationRuntime){
|
|
|
123
124
|
return invoke(args.op,observationRuntime,'observation',map[args.op]);
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
export function registerCompactGatewayTools(server,{profile,ledger,codingRuntime,semanticRuntime,machineFsRuntime,processRuntime,observationRuntime,machineRuntime,desktopRuntime,catalogProvider}){
|
|
127
|
+
export function registerCompactGatewayTools(server,{profile,ledger,codingRuntime,semanticRuntime,machineFsRuntime,processRuntime,observationRuntime,machineRuntime,desktopRuntime,skillRuntime,autonomousRuntime,hostPolicy,env=process.env,catalogProvider}){
|
|
127
128
|
if(!server) throw new Error('compact gateway registration requires server');
|
|
128
129
|
if(profile!=='compact') return;
|
|
129
130
|
if(typeof catalogProvider!=='function') throw new Error('compact gateway requires catalogProvider');
|
|
130
|
-
server.registerTool('capability_manifest',{description:'Read the canonical capability ledger and exact active compact tool catalog.',inputSchema:capabilityManifestInputSchema,outputSchema:compactGatewayOutputSchema},async()=>{
|
|
131
|
+
server.registerTool('capability_manifest',{description:'Read the canonical capability ledger and exact active compact tool catalog with runtime-aware resolution.',inputSchema:capabilityManifestInputSchema,outputSchema:compactGatewayOutputSchema},async()=>{
|
|
131
132
|
const toolCatalog=[...catalogProvider()].map(String).sort();
|
|
132
133
|
if(toolCatalog.length<1||new Set(toolCatalog).size!==toolCatalog.length) throw new Error('compact catalog provider returned invalid catalog');
|
|
133
134
|
const catalogSha256=createHash('sha256').update(JSON.stringify(toolCatalog),'utf8').digest('hex');
|
|
135
|
+
const dynamicResolution = await resolveCapabilityStates({
|
|
136
|
+
ledger, toolCatalog, profile, env,
|
|
137
|
+
codingRuntime, processRuntime, machineFsRuntime, observationRuntime, desktopRuntime,
|
|
138
|
+
autonomousRuntime, skillRuntime, hostPolicy
|
|
139
|
+
});
|
|
134
140
|
return compactGatewayResult({status:'ok',op:'manifest',result:{
|
|
135
141
|
schema:'deadbyte.capability-manifest.v2',profile,ledger_sha256:ledger?.ledger_sha256??null,
|
|
136
|
-
tool_catalog:toolCatalog,tool_count:toolCatalog.length,catalog_sha256:catalogSha256,
|
|
142
|
+
tool_catalog:toolCatalog,tool_count:toolCatalog.length,catalog_sha256:catalogSha256,
|
|
143
|
+
capabilities:dynamicResolution.capabilities,
|
|
144
|
+
effective_capabilities:dynamicResolution.effective_capabilities,
|
|
145
|
+
unavailable_capabilities:dynamicResolution.unavailable_capabilities,
|
|
146
|
+
degraded_capabilities:dynamicResolution.degraded_capabilities
|
|
137
147
|
}},false);
|
|
138
148
|
});
|
|
139
149
|
server.registerTool('coding_inspect',{description:'Typed compact coding inspection and semantic navigation gateway. No arbitrary tool dispatch.',inputSchema:codingInspectInputSchema,outputSchema:compactGatewayOutputSchema},args=>codingInspect(args,codingRuntime,semanticRuntime));
|
package/src/mcp-server.mjs
CHANGED
|
@@ -459,7 +459,8 @@ serveStdio(() => {
|
|
|
459
459
|
|
|
460
460
|
registerCompactGatewayTools(toolServer,{
|
|
461
461
|
profile:surfaceProfile,ledger:R36_CAPABILITY_LEDGER,codingRuntime,semanticRuntime,machineFsRuntime,
|
|
462
|
-
processRuntime,observationRuntime,machineRuntime,desktopRuntime,
|
|
462
|
+
processRuntime,observationRuntime,machineRuntime,desktopRuntime,skillRuntime,autonomousRuntime,hostPolicy,
|
|
463
|
+
catalogProvider:()=>[...registeredToolNames]
|
|
463
464
|
});
|
|
464
465
|
|
|
465
466
|
if (hostPolicy) {
|
package/src/process-runtime.mjs
CHANGED
|
@@ -20,12 +20,27 @@ const TERMINAL_RECOVERY_SCHEMA = 'deadbyte.process-terminal.v1';
|
|
|
20
20
|
const sha256Bytes = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
21
21
|
const nowUtc = () => new Date().toISOString();
|
|
22
22
|
|
|
23
|
+
const STANDARD_PATHEXT = '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC';
|
|
24
|
+
|
|
25
|
+
export function getRepairedPathExt() {
|
|
26
|
+
const current = process.env.PATHEXT;
|
|
27
|
+
if (!current) return STANDARD_PATHEXT;
|
|
28
|
+
const exts = current.split(';').map(e => e.trim().toUpperCase()).filter(Boolean);
|
|
29
|
+
if (!exts.includes('.EXE')) {
|
|
30
|
+
return [...new Set([...STANDARD_PATHEXT.split(';'), ...exts])].join(';');
|
|
31
|
+
}
|
|
32
|
+
return current;
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
function processEnvironment(profile) {
|
|
24
36
|
const allow = new Set(profile.env_allow.map(name => name.toLowerCase()));
|
|
25
37
|
const env = {};
|
|
26
38
|
for (const [key, value] of Object.entries(process.env)) {
|
|
27
39
|
if (allow.has(key.toLowerCase()) && typeof value === 'string') env[key] = value;
|
|
28
40
|
}
|
|
41
|
+
if (process.platform === 'win32') {
|
|
42
|
+
env.PATHEXT = getRepairedPathExt();
|
|
43
|
+
}
|
|
29
44
|
return env;
|
|
30
45
|
}
|
|
31
46
|
async function resolveCwd(policy, grant, profile, rootId, cwd) {
|
package/src/runtime-update.mjs
CHANGED
|
@@ -1157,15 +1157,15 @@ async function resumeSlotUpdate({handoffPath}){
|
|
|
1157
1157
|
const stableMcpUrl=body.stable_mcp_url?{...body.stable_mcp_url}:releaseState.stable_mcp_url?{...releaseState.stable_mcp_url}:null;
|
|
1158
1158
|
const mcpUrlSnapshot=body.mcp_url_snapshot?decodeSnapshot(body.mcp_url_snapshot,'MCP URL'):{exists:false,bytes:null,sha256:null};
|
|
1159
1159
|
const cleanup=await acquireSupervisorLease(absoluteHandoff);
|
|
1160
|
+
const journal=releaseState;
|
|
1161
|
+
let pointerCommitted=phaseRank(phase)>=phaseRank('pointer_committed')||samePublicPointer(currentPointer,candidatePointer);
|
|
1162
|
+
let stopped=phaseRank(phase)>=phaseRank('old_runtime_stopped');
|
|
1160
1163
|
try{
|
|
1161
|
-
const journal=releaseState;
|
|
1162
1164
|
if(phaseRank(phase)<phaseRank('supervisor_spawned')){
|
|
1163
1165
|
await writeState(statePath,journal,'supervisor_spawned',{supervisor_pid:process.pid,supervisor_script:body.supervisor_script,supervisor_script_sha256:body.supervisor_script_sha256});
|
|
1164
1166
|
phase='supervisor_spawned';
|
|
1165
1167
|
}
|
|
1166
1168
|
let revoked=phaseRank(phase)>=phaseRank('authority_revoked')||journal.revoked_before_switch===true;
|
|
1167
|
-
let stopped=phaseRank(phase)>=phaseRank('old_runtime_stopped');
|
|
1168
|
-
let pointerCommitted=phaseRank(phase)>=phaseRank('pointer_committed')||samePublicPointer(currentPointer,candidatePointer);
|
|
1169
1169
|
let newRuntime=null,stabilization=null;
|
|
1170
1170
|
|
|
1171
1171
|
if(phaseRank(phase)<phaseRank('authority_revoked')){
|
package/src/version.mjs
CHANGED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {
|
|
4
|
+
CAPABILITY_STATES,
|
|
5
|
+
deriveCapabilityRequirements,
|
|
6
|
+
resolveCapabilityStates
|
|
7
|
+
} from '../src/capability-resolver.mjs';
|
|
8
|
+
import { R36_CAPABILITY_LEDGER } from '../src/capability-ledger.mjs';
|
|
9
|
+
|
|
10
|
+
test('capability resolver enforces 5 canonical states', () => {
|
|
11
|
+
assert.equal(CAPABILITY_STATES.AVAILABLE, 'AVAILABLE');
|
|
12
|
+
assert.equal(CAPABILITY_STATES.DEGRADED, 'DEGRADED');
|
|
13
|
+
assert.equal(CAPABILITY_STATES.DISABLED, 'DISABLED');
|
|
14
|
+
assert.equal(CAPABILITY_STATES.DENIED, 'DENIED');
|
|
15
|
+
assert.equal(CAPABILITY_STATES.UNAVAILABLE, 'UNAVAILABLE');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('deriveCapabilityRequirements maps dependencies accurately', () => {
|
|
19
|
+
const reqCodingRead = deriveCapabilityRequirements({
|
|
20
|
+
id: 'coding.search',
|
|
21
|
+
authority: 'coding',
|
|
22
|
+
mutating: false,
|
|
23
|
+
runtime_flag: 'DEADBYTE_CODING_RUNTIME'
|
|
24
|
+
});
|
|
25
|
+
assert.deepEqual(reqCodingRead, ['DEADBYTE_CODING_RUNTIME', 'coding_runtime.ready']);
|
|
26
|
+
|
|
27
|
+
const reqCodingWrite = deriveCapabilityRequirements({
|
|
28
|
+
id: 'coding.file_write',
|
|
29
|
+
authority: 'coding',
|
|
30
|
+
mutating: true,
|
|
31
|
+
runtime_flag: 'DEADBYTE_CODING_RUNTIME'
|
|
32
|
+
});
|
|
33
|
+
assert.deepEqual(reqCodingWrite, ['DEADBYTE_CODING_RUNTIME', 'coding_session.armed', 'policy.write']);
|
|
34
|
+
|
|
35
|
+
const reqSkill = deriveCapabilityRequirements({
|
|
36
|
+
id: 'skill.catalog',
|
|
37
|
+
authority: 'operator',
|
|
38
|
+
mutating: false
|
|
39
|
+
});
|
|
40
|
+
assert.deepEqual(reqSkill, ['skill_plane.valid']);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('resolveCapabilityStates resolves all 5 states correctly', async () => {
|
|
44
|
+
const allCompactTools = [
|
|
45
|
+
'capability_manifest',
|
|
46
|
+
'coding_inspect',
|
|
47
|
+
'machine_fs',
|
|
48
|
+
'process_session',
|
|
49
|
+
'machine_observe',
|
|
50
|
+
'desktop_control',
|
|
51
|
+
'skill_catalog'
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
// 1. Fully available & armed state
|
|
55
|
+
const armedRes = await resolveCapabilityStates({
|
|
56
|
+
ledger: R36_CAPABILITY_LEDGER,
|
|
57
|
+
toolCatalog: allCompactTools,
|
|
58
|
+
profile: 'compact',
|
|
59
|
+
env: {},
|
|
60
|
+
codingRuntime: { sessionStatus: async () => ({ armed: true }) },
|
|
61
|
+
processRuntime: {},
|
|
62
|
+
machineFsRuntime: {},
|
|
63
|
+
observationRuntime: {},
|
|
64
|
+
desktopRuntime: {},
|
|
65
|
+
autonomousRuntime: { sessionStatus: async () => ({ armed: true }) },
|
|
66
|
+
skillRuntime: { list: async () => ({ invalid_skills: [] }) },
|
|
67
|
+
hostPolicy: {}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
assert.ok(armedRes.capabilities.length > 0);
|
|
71
|
+
assert.ok(armedRes.effective_capabilities.includes('coding.search'));
|
|
72
|
+
assert.ok(armedRes.effective_capabilities.includes('skill.catalog'));
|
|
73
|
+
|
|
74
|
+
// 2. Disabled by runtime flag
|
|
75
|
+
const disabledRes = await resolveCapabilityStates({
|
|
76
|
+
ledger: R36_CAPABILITY_LEDGER,
|
|
77
|
+
toolCatalog: allCompactTools,
|
|
78
|
+
profile: 'compact',
|
|
79
|
+
env: { DEADBYTE_CODING_RUNTIME: '0' },
|
|
80
|
+
codingRuntime: { sessionStatus: async () => ({ armed: true }) },
|
|
81
|
+
processRuntime: {},
|
|
82
|
+
machineFsRuntime: {},
|
|
83
|
+
observationRuntime: {},
|
|
84
|
+
desktopRuntime: {},
|
|
85
|
+
skillRuntime: { list: async () => ({ invalid_skills: [] }) }
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const codingSearch = disabledRes.capabilities.find(c => c.id === 'coding.search');
|
|
89
|
+
assert.equal(codingSearch.state, CAPABILITY_STATES.DISABLED);
|
|
90
|
+
assert.equal(codingSearch.diagnostic.code, 'RUNTIME_FLAG_DISABLED');
|
|
91
|
+
assert.ok(disabledRes.unavailable_capabilities.some(u => u.id === 'coding.search' && u.state === CAPABILITY_STATES.DISABLED));
|
|
92
|
+
|
|
93
|
+
// 3. Unavailable due to uninstantiated subsystem
|
|
94
|
+
const uninstantiatedRes = await resolveCapabilityStates({
|
|
95
|
+
ledger: R36_CAPABILITY_LEDGER,
|
|
96
|
+
toolCatalog: allCompactTools,
|
|
97
|
+
profile: 'compact',
|
|
98
|
+
env: {},
|
|
99
|
+
machineFsRuntime: null
|
|
100
|
+
});
|
|
101
|
+
const fsStat = uninstantiatedRes.capabilities.find(c => c.id === 'machine_fs.stat');
|
|
102
|
+
assert.equal(fsStat.state, CAPABILITY_STATES.UNAVAILABLE);
|
|
103
|
+
assert.equal(fsStat.diagnostic.code, 'MACHINE_FS_NOT_INSTANTIATED');
|
|
104
|
+
|
|
105
|
+
// 4. Denied when coding session is disarmed for mutating operations in full profile
|
|
106
|
+
const disarmedRes = await resolveCapabilityStates({
|
|
107
|
+
ledger: R36_CAPABILITY_LEDGER,
|
|
108
|
+
toolCatalog: ['coding_file_write', 'coding_search'],
|
|
109
|
+
profile: 'full',
|
|
110
|
+
env: {},
|
|
111
|
+
codingRuntime: { sessionStatus: async () => ({ armed: false, reason: 'policy grant not confirmed' }) },
|
|
112
|
+
machineFsRuntime: {},
|
|
113
|
+
skillRuntime: { list: async () => ({ invalid_skills: [] }) }
|
|
114
|
+
});
|
|
115
|
+
const fileWrite = disarmedRes.capabilities.find(c => c.id === 'coding.file_write');
|
|
116
|
+
assert.equal(fileWrite.state, CAPABILITY_STATES.DENIED);
|
|
117
|
+
assert.equal(fileWrite.diagnostic.code, 'CODING_SESSION_DISARMED');
|
|
118
|
+
|
|
119
|
+
// 5. Degraded when skill plane reports envelope mismatch
|
|
120
|
+
const degradedRes = await resolveCapabilityStates({
|
|
121
|
+
ledger: R36_CAPABILITY_LEDGER,
|
|
122
|
+
toolCatalog: allCompactTools,
|
|
123
|
+
profile: 'compact',
|
|
124
|
+
env: {},
|
|
125
|
+
codingRuntime: { sessionStatus: async () => ({ armed: true }) },
|
|
126
|
+
machineFsRuntime: {},
|
|
127
|
+
skillRuntime: { list: async () => ({ invalid_skills: [{ name: 'test-broken', error: 'envelope mismatch' }] }) }
|
|
128
|
+
});
|
|
129
|
+
const skillCap = degradedRes.capabilities.find(c => c.id === 'skill.catalog');
|
|
130
|
+
assert.equal(skillCap.state, CAPABILITY_STATES.DEGRADED);
|
|
131
|
+
assert.equal(skillCap.diagnostic.code, 'SKILL_ENVELOPE_MISMATCH');
|
|
132
|
+
assert.ok(degradedRes.degraded_capabilities.some(d => d.id === 'skill.catalog'));
|
|
133
|
+
});
|