deadbyte-mcp 0.15.35 → 0.15.37
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 +91 -46
- package/PROVENANCE.json +76 -30
- package/README.txt +62 -8
- package/RELEASE.json +78 -23
- package/SBOM.cdx.json +10 -25
- package/TEST-MATRIX.json +109 -44
- package/bridge/package.json +4 -2
- package/bridge/src/bridge-health-r59.mjs +53 -0
- package/bridge/src/bridge.mjs +158 -26
- package/bridge/src/canonical-json-r60.mjs +13 -0
- package/bridge/src/r40-governor.mjs +56 -10
- package/bridge/src/reconnect-delay-r60.mjs +31 -0
- package/bridge/src/remote-call-claims-r60.mjs +157 -0
- package/bridge/src/remote-dispatch-r60.mjs +75 -0
- package/controller/deadbyte-controller.ps1 +76 -13
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/R59-PROVENANCE.json +87 -0
- package/docs/R59-RELEASE.json +187 -0
- package/docs/R59-SBOM.cdx.json +68 -0
- package/docs/R59-TASK-CONTRACT.md +26 -0
- package/docs/R59-TEST-MATRIX.json +258 -0
- package/docs/R59-bridge-package.json +13 -0
- package/docs/R59-package-lock.json +184 -0
- package/docs/R59-package.json +106 -0
- package/docs/R59-version.mjs +6 -0
- package/docs/R60-TASK-CONTRACT.md +22 -0
- package/package.json +7 -3
- package/proof/r59-full-regression-current.json +13 -0
- package/proof/r59-full-regression-current.stderr.log +0 -0
- package/proof/r59-full-regression-current.stdout.log +1268 -0
- package/scripts/full-regression-r60.mjs +32 -0
- package/scripts/gate-windows-r59-prepublish.ps1 +41 -0
- package/scripts/gate-windows-r60-prepublish.ps1 +74 -0
- package/scripts/r59-full-regression-capture.mjs +35 -0
- package/src/capability-resolver.mjs +25 -7
- package/src/capability-snapshot.mjs +56 -0
- package/src/compact-gateway-mcp-tools.mjs +10 -11
- package/src/deadbyte-cli.mjs +80 -34
- package/src/mcp-server.mjs +179 -118
- package/src/r40-compact-disarmed-probe.mjs +1 -1
- package/src/r44-compact-disarmed-probe.mjs +1 -1
- package/src/r45-compact-disarmed-probe.mjs +1 -1
- package/src/remote-authority.mjs +56 -0
- package/src/remote-enforcement-probe-r60.mjs +17 -0
- package/src/remote-live-log.mjs +19 -2
- package/src/remote-log-decode-r60.mjs +32 -0
- package/src/remote-mcp-machine-smoke-client.mjs +19 -1
- package/src/remote-mcp-r40-parity-client.mjs +1 -1
- package/src/remote-mcp-r44-parity-client.mjs +1 -1
- package/src/remote-mcp-r45-parity-client.mjs +1 -1
- package/src/remote-mcp-smoke-client.mjs +1 -1
- package/src/remote-session-guardian.mjs +20 -3
- package/src/runtime-plane-registry.mjs +74 -0
- package/src/tool-audit.mjs +5 -0
- package/src/version.mjs +1 -1
- package/test/bridge-runtime-r59.test.mjs +60 -0
- package/test/capability-resolver.test.mjs +16 -0
- package/test/capability-snapshot-r59.test.mjs +39 -0
- package/test/compact-gateway-r36.test.mjs +22 -2
- package/test/compact-max-catalog-r44.test.mjs +1 -1
- package/test/compact-max-catalog-r45.test.mjs +1 -1
- package/test/contained.test.mjs +2 -1
- package/test/controller-policy-preflight-r59.test.mjs +39 -0
- package/test/fixtures/r59-compact-surface-v0.15.35.json +222 -0
- package/test/observation-integration.test.mjs +2 -3
- package/test/optional-plane-degraded-r59.test.mjs +44 -0
- package/test/r48-release-contract.test.mjs +1 -1
- package/test/r49-windows-gate.test.mjs +1 -1
- package/test/r51-runtime-coherence.test.mjs +2 -2
- package/test/r58-bundled-bridge.test.mjs +3 -1
- package/test/r58-cleanup-retention.test.mjs +9 -3
- package/test/r58-concurrent-recovery.test.mjs +9 -3
- package/test/r58-controller-live-local.test.mjs +36 -4
- package/test/r58-controller-state-coherence.test.mjs +1 -1
- package/test/r58-release-contract.test.mjs +3 -2
- package/test/r58-stale-owner.test.mjs +2 -2
- package/test/r58-windows-gate.test.mjs +2 -1
- package/test/r59-release-contract.test.mjs +61 -0
- package/test/r59-tool-surface-compat.test.mjs +90 -0
- package/test/r60-authority-coherence.test.mjs +36 -0
- package/test/r60-authority-enforcement.test.mjs +28 -0
- package/test/r60-bridge-dispatch.test.mjs +119 -0
- package/test/r60-clock-discipline.test.mjs +15 -0
- package/test/r60-live-timeline.test.mjs +29 -0
- package/test/r60-reconnect-errors.test.mjs +21 -0
- package/test/r60-reconnect-jitter.test.mjs +18 -0
- package/test/r60-release-contract.test.mjs +81 -0
- package/test/r60-remote-call-recovery.test.mjs +170 -0
- package/test/r60-windows-log-decode.test.mjs +25 -0
- package/test/remote-live-log-r37.test.mjs +1 -1
- package/test/remote-session-cli.test.mjs +200 -43
- package/test/runtime-plane-registry-r59.test.mjs +40 -0
package/src/mcp-server.mjs
CHANGED
|
@@ -66,6 +66,7 @@ import { capabilityProfileFromEnv, COMPACT_SURFACE_TOOL_LIMIT, R36_CAPABILITY_LE
|
|
|
66
66
|
import { registerCompactGatewayTools } from './compact-gateway-mcp-tools.mjs';
|
|
67
67
|
import { createSkillPlane } from './skill-plane-r44.mjs';
|
|
68
68
|
import { registerSkillToolsR44 } from './skill-mcp-tools-r44.mjs';
|
|
69
|
+
import { createRuntimePlaneRegistry, createUnavailableRuntime, RuntimePlaneUnavailableError } from './runtime-plane-registry.mjs';
|
|
69
70
|
import {
|
|
70
71
|
containedTransformOutputSchema,
|
|
71
72
|
evidenceVerifyOutputSchema,
|
|
@@ -86,6 +87,7 @@ const verifyKeyPath = process.env.DEADBYTE_VERIFY_KEY ?? defaultPublicKeyPath();
|
|
|
86
87
|
const auditRuntimeMode = process.env.DEADBYTE_AUDIT_RUNTIME ?? '0';
|
|
87
88
|
if (!['0','1'].includes(auditRuntimeMode)) throw new Error('DEADBYTE_AUDIT_RUNTIME must be 0 or 1');
|
|
88
89
|
const runtimeStateRoot = path.resolve(process.env.DEADBYTE_STATE_ROOT || path.join(os.homedir(),'.deadbyte-mcp'));
|
|
90
|
+
const planeRegistry=createRuntimePlaneRegistry();
|
|
89
91
|
const interruptedUpdateRecovery = await recoverInterruptedSlotUpdates({ stateRoot: runtimeStateRoot });
|
|
90
92
|
if (interruptedUpdateRecovery.launched > 0) {
|
|
91
93
|
console.error(`[runtime-update-recovery] launched ${interruptedUpdateRecovery.launched} detached supervisor(s)`);
|
|
@@ -103,15 +105,16 @@ if (!privilegedPolicyExplicit) {
|
|
|
103
105
|
if (error?.code !== 'ENOENT') throw error;
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
|
-
|
|
108
|
+
planeRegistry.define('host',{configured:Boolean(privilegedPolicyPath),required:false});
|
|
109
|
+
const hostPolicy=await planeRegistry.initialize('host',async()=>loadHostPolicy(privilegedPolicyPath));
|
|
107
110
|
const machineRuntimeMode = process.env.DEADBYTE_MACHINE_RUNTIME ?? '0';
|
|
108
111
|
if (!['0', '1'].includes(machineRuntimeMode)) throw new Error('DEADBYTE_MACHINE_RUNTIME must be 0 or 1');
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
: null;
|
|
112
|
+
planeRegistry.define('machine',{configured:machineRuntimeMode==='1',required:true});
|
|
113
|
+
const machineRuntime=await planeRegistry.initialize('machine',async()=>createMachineRuntime({stateRoot:runtimeStateRoot}));
|
|
112
114
|
const agentRuntimeMode = process.env.DEADBYTE_AGENT_RUNTIME ?? '0';
|
|
113
115
|
if (!['0', '1'].includes(agentRuntimeMode)) throw new Error('DEADBYTE_AGENT_RUNTIME must be 0 or 1');
|
|
114
|
-
|
|
116
|
+
planeRegistry.define('agent',{configured:agentRuntimeMode==='1',required:false});
|
|
117
|
+
const agentRuntime=await planeRegistry.initialize('agent',async()=>createAgentRuntime({signingKeyPath,verifyKeyPath}));
|
|
115
118
|
|
|
116
119
|
const processRuntimeMode = process.env.DEADBYTE_PROCESS_RUNTIME ?? '0';
|
|
117
120
|
if (!['0', '1'].includes(processRuntimeMode)) throw new Error('DEADBYTE_PROCESS_RUNTIME must be 0 or 1');
|
|
@@ -121,9 +124,14 @@ if (processRuntimeMode === '1' && !processPolicyPath) {
|
|
|
121
124
|
try { await access(localProcessPolicyPath); processPolicyPath = localProcessPolicyPath; }
|
|
122
125
|
catch (error) { if (error?.code !== 'ENOENT') throw error; }
|
|
123
126
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const processRuntime
|
|
127
|
+
planeRegistry.define('process',{configured:processRuntimeMode==='1',required:false});
|
|
128
|
+
let processPolicy=null;
|
|
129
|
+
const processRuntime=await planeRegistry.initialize('process',async()=>{
|
|
130
|
+
if(!processPolicyPath) throw new Error('DEADBYTE_PROCESS_RUNTIME=1 requires a process policy');
|
|
131
|
+
processPolicy=await loadProcessPolicy(processPolicyPath);
|
|
132
|
+
return createProcessRuntime({policy:processPolicy,signingKeyPath,verifyKeyPath});
|
|
133
|
+
});
|
|
134
|
+
if(!processRuntime) processPolicy=null;
|
|
127
135
|
|
|
128
136
|
const codingRuntimeMode = process.env.DEADBYTE_CODING_RUNTIME ?? '0';
|
|
129
137
|
if (!['0', '1'].includes(codingRuntimeMode)) throw new Error('DEADBYTE_CODING_RUNTIME must be 0 or 1');
|
|
@@ -133,29 +141,32 @@ if (codingRuntimeMode === '1' && !codingPolicyPath) {
|
|
|
133
141
|
try { await access(localCodingPolicyPath); codingPolicyPath = localCodingPolicyPath; }
|
|
134
142
|
catch (error) { if (error?.code !== 'ENOENT') throw error; }
|
|
135
143
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const codingRuntime
|
|
139
|
-
|
|
144
|
+
planeRegistry.define('coding',{configured:codingRuntimeMode==='1',required:false});
|
|
145
|
+
let codingPolicy=null;
|
|
146
|
+
const codingRuntime=await planeRegistry.initialize('coding',async()=>{
|
|
147
|
+
if(!codingPolicyPath) throw new Error('DEADBYTE_CODING_RUNTIME=1 requires a coding policy');
|
|
148
|
+
codingPolicy=await loadCodingPolicy(codingPolicyPath);
|
|
149
|
+
return createCodingRuntime({policy:codingPolicy,signingKeyPath,verifyKeyPath});
|
|
150
|
+
});
|
|
151
|
+
if(!codingRuntime) codingPolicy=null;
|
|
152
|
+
const codingTaskRuntime=codingRuntime?createCodingTaskRuntime({codingRuntime,signingKeyPath,verifyKeyPath}):null;
|
|
140
153
|
const semanticLspBinding = semanticConfigBindingFromEnv(process.env);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
planeRegistry.define('semantic',{configured:codingRuntimeMode==='1',required:false,dependencies:['coding']});
|
|
155
|
+
let semanticLsp={backends:[],required_ids:[]};
|
|
156
|
+
let semanticRuntime=await planeRegistry.initialize('semantic',async()=>{
|
|
157
|
+
semanticLsp=semanticLspBinding?await loadSemanticLspBackends({...semanticLspBinding,codingRuntime}):semanticLsp;
|
|
158
|
+
return createSemanticCodeRuntime({codingRuntime,backends:semanticLsp.backends,nativeDiffRuntime:null});
|
|
159
|
+
});
|
|
145
160
|
const machineFsRuntimeMode = process.env.DEADBYTE_MACHINE_FS_RUNTIME ?? '0';
|
|
146
161
|
if (!['0','1'].includes(machineFsRuntimeMode)) throw new Error('DEADBYTE_MACHINE_FS_RUNTIME must be 0 or 1');
|
|
147
|
-
|
|
148
|
-
const machineFsRuntime
|
|
149
|
-
? createMachineFsRuntime({ policy: codingPolicy, signingKeyPath, verifyKeyPath })
|
|
150
|
-
: null;
|
|
162
|
+
planeRegistry.define('machine_fs',{configured:machineFsRuntimeMode==='1',required:false,dependencies:['coding']});
|
|
163
|
+
const machineFsRuntime=await planeRegistry.initialize('machine_fs',async()=>createMachineFsRuntime({policy:codingPolicy,signingKeyPath,verifyKeyPath}));
|
|
151
164
|
const observationRuntimeMode = process.env.DEADBYTE_OBSERVATION_RUNTIME ?? '0';
|
|
152
165
|
if (!['0','1'].includes(observationRuntimeMode)) throw new Error('DEADBYTE_OBSERVATION_RUNTIME must be 0 or 1');
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
stateRoot: runtimeStateRoot })
|
|
158
|
-
: null;
|
|
166
|
+
planeRegistry.define('observation',{configured:observationRuntimeMode==='1',required:false,dependencies:['machine','coding']});
|
|
167
|
+
const observationRuntime=await planeRegistry.initialize('observation',async()=>createObservationRuntime({
|
|
168
|
+
policy:codingPolicy,processRuntime,signingKeyPath,verifyKeyPath,stateRoot:runtimeStateRoot
|
|
169
|
+
}));
|
|
159
170
|
|
|
160
171
|
const desktopRuntimeMode=process.env.DEADBYTE_DESKTOP_RUNTIME??'0';
|
|
161
172
|
if(!['0','1'].includes(desktopRuntimeMode)) throw new Error('DEADBYTE_DESKTOP_RUNTIME must be 0 or 1');
|
|
@@ -165,35 +176,37 @@ if(desktopRuntimeMode==='1'&&!desktopPolicyPath){
|
|
|
165
176
|
try{await access(localDesktopPolicyPath);desktopPolicyPath=localDesktopPolicyPath;}
|
|
166
177
|
catch(error){if(error?.code!=='ENOENT')throw error;}
|
|
167
178
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
})
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
})
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
})
|
|
179
|
+
planeRegistry.define('desktop',{configured:desktopRuntimeMode==='1',required:false});
|
|
180
|
+
let desktopPolicy=null;
|
|
181
|
+
let desktopMemoryProvider=null;
|
|
182
|
+
const desktopRuntime=await planeRegistry.initialize('desktop',async()=>{
|
|
183
|
+
if(!desktopPolicyPath) throw new Error('DEADBYTE_DESKTOP_RUNTIME=1 requires a desktop policy');
|
|
184
|
+
desktopPolicy=await loadDesktopPolicy(desktopPolicyPath);
|
|
185
|
+
const observerRuntime=createDesktopObserverRuntime({
|
|
186
|
+
observerPath:desktopPolicy.observer.executable,expectedObserverSha256:desktopPolicy.observer.sha256,
|
|
187
|
+
maxFrameBytes:desktopPolicy.limits.max_frame_bytes,timeoutMs:desktopPolicy.limits.capture_timeout_ms,
|
|
188
|
+
allowInputDesktops:desktopPolicy.allowed_input_desktops
|
|
189
|
+
});
|
|
190
|
+
const inputProvider=createNativeDesktopInputProvider({
|
|
191
|
+
inputPath:desktopPolicy.input.executable,expectedInputSha256:desktopPolicy.input.sha256,
|
|
192
|
+
timeoutMs:desktopPolicy.limits.input_timeout_ms
|
|
193
|
+
});
|
|
194
|
+
const grounderProvider=createNativeDesktopGrounder({
|
|
195
|
+
grounderPath:desktopPolicy.grounder.executable,expectedGrounderSha256:desktopPolicy.grounder.sha256,
|
|
196
|
+
timeoutMs:desktopPolicy.limits.ground_timeout_ms
|
|
197
|
+
});
|
|
198
|
+
const signingKey=await loadPrivateSigningKey(signingKeyPath);
|
|
199
|
+
const verifyKey=await loadPublicVerifyKey(verifyKeyPath);
|
|
200
|
+
if(signingKey.keyId!==verifyKey.keyId) throw new Error('Desktop signing/verify key mismatch');
|
|
201
|
+
desktopMemoryProvider=createDesktopMemoryProvider({
|
|
202
|
+
evidenceDir:desktopPolicy.evidence_dir,snapshotPath:path.join(desktopPolicy.evidence_dir,'desktop-memory.json'),
|
|
203
|
+
policySha256:desktopPolicy.policy_sha256,privateKey:signingKey.privateKey,
|
|
204
|
+
publicKey:verifyKey.publicKey,keyId:signingKey.keyId
|
|
205
|
+
});
|
|
206
|
+
return createDesktopRuntime({policy:desktopPolicy,observerRuntime,inputProvider,grounderProvider,
|
|
207
|
+
privateKey:signingKey.privateKey,publicKey:verifyKey.publicKey,keyId:signingKey.keyId});
|
|
208
|
+
});
|
|
209
|
+
if(!desktopRuntime){desktopPolicy=null;desktopMemoryProvider=null;}
|
|
197
210
|
|
|
198
211
|
const autonomousRuntimeMode = process.env.DEADBYTE_AUTONOMOUS_RUNTIME ?? '0';
|
|
199
212
|
if (!['0','1'].includes(autonomousRuntimeMode)) throw new Error('DEADBYTE_AUTONOMOUS_RUNTIME must be 0 or 1');
|
|
@@ -201,53 +214,55 @@ const autonomousSupervisorMode = process.env.DEADBYTE_AUTONOMOUS_SUPERVISOR_MODE
|
|
|
201
214
|
if (!['in_process','external'].includes(autonomousSupervisorMode)) {
|
|
202
215
|
throw new Error('DEADBYTE_AUTONOMOUS_SUPERVISOR_MODE must be in_process or external');
|
|
203
216
|
}
|
|
204
|
-
if (autonomousRuntimeMode === '1' && !codingRuntime) throw new Error('DEADBYTE_AUTONOMOUS_RUNTIME=1 requires DEADBYTE_CODING_RUNTIME=1');
|
|
205
217
|
const localAutonomousPolicyPath = path.join(packageRoot,'controller','deadbyte-autonomous-policy.json');
|
|
206
218
|
let autonomousPolicyPath = process.env.DEADBYTE_AUTONOMOUS_POLICY ?? '';
|
|
207
219
|
if (autonomousRuntimeMode === '1' && !autonomousPolicyPath) {
|
|
208
220
|
try { await access(localAutonomousPolicyPath); autonomousPolicyPath = localAutonomousPolicyPath; }
|
|
209
221
|
catch (error) { if (error?.code !== 'ENOENT') throw error; }
|
|
210
222
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
223
|
+
planeRegistry.define('autonomous',{configured:autonomousRuntimeMode==='1',required:false,dependencies:['coding']});
|
|
224
|
+
let autonomousPolicy=null;
|
|
225
|
+
let nativeDiffRuntime=null;
|
|
226
|
+
const autonomousRuntime=await planeRegistry.initialize('autonomous',async()=>{
|
|
227
|
+
if(!autonomousPolicyPath) throw new Error('DEADBYTE_AUTONOMOUS_RUNTIME=1 requires an autonomous policy');
|
|
228
|
+
autonomousPolicy=await loadAutonomousPolicy(autonomousPolicyPath,codingPolicy);
|
|
229
|
+
nativeDiffRuntime=createNativeDiffRuntime({policy:autonomousPolicy,codingRuntime,machineFsRuntime,signingKeyPath,verifyKeyPath});
|
|
230
|
+
semanticRuntime=createSemanticCodeRuntime({codingRuntime,backends:semanticLsp.backends,nativeDiffRuntime});
|
|
231
|
+
const memorySigningKey=await loadPrivateSigningKey(signingKeyPath);
|
|
232
|
+
const memoryVerifyKey=await loadPublicVerifyKey(verifyKeyPath);
|
|
233
|
+
if(memorySigningKey.keyId!==memoryVerifyKey.keyId) throw new Error('R41 memory signing/verify key mismatch');
|
|
234
|
+
const memoryProvider=createR41MemoryProvider({
|
|
235
|
+
memoryRoot:path.join(autonomousPolicy.evidence_dir,'memory-r41',packageManifestSha256),sourceReleaseManifest:packageManifestSha256,
|
|
236
|
+
journalRoot:path.join(autonomousPolicy.evidence_dir,'goals'),writerVersion:DEADBYTE_VERSION,
|
|
237
|
+
privateKey:memorySigningKey.privateKey,publicKey:memoryVerifyKey.publicKey,keyId:memorySigningKey.keyId,
|
|
238
|
+
byteBudget:Math.min(262144,Math.max(65536,Math.floor(autonomousPolicy.limits.max_context_bytes/2))),semantic:{enabled:false}
|
|
239
|
+
});
|
|
240
|
+
const plannerProviderRuntime=autonomousPolicy.planner.backend==='codex_app_server'
|
|
241
|
+
? await createCodexAppServerR44({stateDir:path.join(autonomousPolicy.evidence_dir,'provider-r44','codex-app-server'),
|
|
242
|
+
model:autonomousPolicy.planner.model,cwd:codingPolicy.roots[autonomousPolicy.planner.root_id].real_path,
|
|
243
|
+
clientVersion:DEADBYTE_VERSION,executable:autonomousPolicy.planner.executable,
|
|
244
|
+
executableSha256:autonomousPolicy.planner.executable_sha256,args:autonomousPolicy.planner.args})
|
|
245
|
+
: null;
|
|
246
|
+
return createAutonomousRuntime({policy:autonomousPolicy,codingRuntime,nativeDiffRuntime,machineFsRuntime,
|
|
247
|
+
observationRuntime,processRuntime,semanticRuntime,desktopRuntime,desktopMemoryProvider,memoryProvider,
|
|
248
|
+
plannerProviderRuntime,signingKeyPath,verifyKeyPath});
|
|
249
|
+
});
|
|
250
|
+
if(!autonomousRuntime){autonomousPolicy=null;nativeDiffRuntime=null;}
|
|
236
251
|
const autonomousSupervisor = autonomousRuntime && ['openai_compatible','openai_responses','codex_app_server'].includes(autonomousPolicy.planner.backend) &&
|
|
237
252
|
autonomousSupervisorMode === 'in_process'
|
|
238
253
|
? startAutonomousSupervisor({ runtime: autonomousRuntime, policy: autonomousPolicy })
|
|
239
254
|
: null;
|
|
240
255
|
void autonomousSupervisor;
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
stateRoot:runtimeStateRoot,packageRoot,machineRuntime,
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}) : null;
|
|
256
|
+
planeRegistry.define('audit',{configured:auditRuntimeMode==='1',required:false,dependencies:['machine']});
|
|
257
|
+
const toolAudit=await planeRegistry.initialize('audit',async()=>{
|
|
258
|
+
const contextProvider=createAuditContextProvider({stateRoot:runtimeStateRoot,packageRoot,machineRuntime,
|
|
259
|
+
processPolicy,codingRuntime,autonomousRuntime,hostPolicy});
|
|
260
|
+
return createToolAudit({stateRoot:runtimeStateRoot,signingKeyPath,contextProvider});
|
|
261
|
+
});
|
|
248
262
|
const skillRoot=path.join(runtimeStateRoot,'skills');
|
|
249
263
|
await mkdir(skillRoot,{recursive:true});
|
|
250
|
-
|
|
264
|
+
planeRegistry.define('skill',{configured:true,required:false});
|
|
265
|
+
const skillRuntime=await planeRegistry.initialize('skill',async()=>createSkillPlane({root:skillRoot,verifyKeyPath}));
|
|
251
266
|
const commanderExtendedRuntime=createCommanderExtendedRuntime({stateRoot:runtimeStateRoot});
|
|
252
267
|
const commanderExternalProcessRuntime=observationRuntime?createCommanderExternalProcessRuntime({
|
|
253
268
|
observationRuntime,hostPolicy,hostExecInlineFn:hostExecInline
|
|
@@ -259,6 +274,48 @@ const remoteCapabilities=new Set(String(process.env.DEADBYTE_REMOTE_CAPABILITIES
|
|
|
259
274
|
const remoteRelay=remoteRelayEndpoint?await createCommanderRemoteRelayR47({endpoint:remoteRelayEndpoint}):null;
|
|
260
275
|
const remoteDevicePlane=remoteRelay?await createRemoteDevicePlaneR44({stateDir:path.join(runtimeStateRoot,'remote-device-r44'),relay:remoteRelay,authorizeCapability:async capability=>remoteCapabilities.has(capability)}):null;
|
|
261
276
|
|
|
277
|
+
function runtimeForRegistration(plane,runtime){
|
|
278
|
+
const state=planeRegistry.state(plane);
|
|
279
|
+
return runtime??(state.configured?createUnavailableRuntime(plane,state.diagnostic??{}):null);
|
|
280
|
+
}
|
|
281
|
+
function requirePlane(plane,runtime){
|
|
282
|
+
if(runtime) return runtime;
|
|
283
|
+
const state=planeRegistry.state(plane);
|
|
284
|
+
throw new RuntimePlaneUnavailableError(plane,state.diagnostic??{});
|
|
285
|
+
}
|
|
286
|
+
function capabilityPlaneSnapshot(){
|
|
287
|
+
const planes=planeRegistry.snapshot().planes;
|
|
288
|
+
return {
|
|
289
|
+
DEADBYTE_MACHINE_RUNTIME:planes.machine,
|
|
290
|
+
DEADBYTE_PROCESS_RUNTIME:planes.process,
|
|
291
|
+
DEADBYTE_CODING_RUNTIME:planes.coding,
|
|
292
|
+
DEADBYTE_MACHINE_FS_RUNTIME:planes.machine_fs,
|
|
293
|
+
DEADBYTE_OBSERVATION_RUNTIME:planes.observation,
|
|
294
|
+
DEADBYTE_DESKTOP_RUNTIME:planes.desktop,
|
|
295
|
+
DEADBYTE_AUTONOMOUS_RUNTIME:planes.autonomous,
|
|
296
|
+
DEADBYTE_PRIVILEGED_POLICY:planes.host
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
async function currentReleaseBindings(){
|
|
300
|
+
if(machineRuntime){
|
|
301
|
+
try{return await machineRuntime.status();}catch{}
|
|
302
|
+
}
|
|
303
|
+
return {release_id:`package-${packageManifestSha256.slice(0,16)}`,
|
|
304
|
+
release_manifest_sha256:packageManifestSha256,generation_manifest_sha256:null};
|
|
305
|
+
}
|
|
306
|
+
const registeredMachineRuntime=runtimeForRegistration('machine',machineRuntime);
|
|
307
|
+
const registeredAgentRuntime=runtimeForRegistration('agent',agentRuntime);
|
|
308
|
+
const registeredProcessRuntime=runtimeForRegistration('process',processRuntime);
|
|
309
|
+
const registeredCodingRuntime=runtimeForRegistration('coding',codingRuntime);
|
|
310
|
+
const registeredCodingTaskRuntime=codingTaskRuntime??(planeRegistry.state('coding').configured?createUnavailableRuntime('coding',planeRegistry.state('coding').diagnostic??{}):null);
|
|
311
|
+
const registeredSemanticRuntime=runtimeForRegistration('semantic',semanticRuntime);
|
|
312
|
+
const registeredMachineFsRuntime=runtimeForRegistration('machine_fs',machineFsRuntime);
|
|
313
|
+
const registeredObservationRuntime=runtimeForRegistration('observation',observationRuntime);
|
|
314
|
+
const registeredDesktopRuntime=runtimeForRegistration('desktop',desktopRuntime);
|
|
315
|
+
const registeredAutonomousRuntime=runtimeForRegistration('autonomous',autonomousRuntime);
|
|
316
|
+
const registeredNativeDiffRuntime=nativeDiffRuntime??(planeRegistry.state('autonomous').configured?createUnavailableRuntime('autonomous',planeRegistry.state('autonomous').diagnostic??{}):null);
|
|
317
|
+
const registeredSkillRuntime=runtimeForRegistration('skill',skillRuntime);
|
|
318
|
+
|
|
262
319
|
installStdioConsoleGuard();
|
|
263
320
|
if (process.env.DEADBYTE_STDIO_CONSOLE_GUARD_PROBE === '1') console.log('DEADBYTE_STDIO_CONSOLE_GUARD_PROBE');
|
|
264
321
|
|
|
@@ -437,54 +494,58 @@ serveStdio(() => {
|
|
|
437
494
|
}
|
|
438
495
|
);
|
|
439
496
|
|
|
440
|
-
if (
|
|
497
|
+
if (registeredMachineRuntime) {
|
|
441
498
|
registerMachineTools(toolServer, {
|
|
442
|
-
runtime:
|
|
499
|
+
runtime: registeredMachineRuntime,
|
|
443
500
|
assertRevokeAuthority: async () => {
|
|
444
501
|
if (!hostPolicy) throw new Error('privileged host plane is not configured');
|
|
445
|
-
await assertHostArmed(hostPolicy);
|
|
502
|
+
await assertHostArmed(requirePlane('host',hostPolicy));
|
|
446
503
|
}
|
|
447
504
|
});
|
|
448
505
|
}
|
|
449
506
|
|
|
450
|
-
if (
|
|
451
|
-
registerAgentTools(toolServer, { runtime:
|
|
507
|
+
if (registeredAgentRuntime && surfaceProfile === 'full') {
|
|
508
|
+
registerAgentTools(toolServer, { runtime: registeredAgentRuntime, workspacePathFromId });
|
|
452
509
|
}
|
|
453
510
|
|
|
454
|
-
if (
|
|
455
|
-
registerProcessTools(toolServer, { runtime:
|
|
511
|
+
if (registeredProcessRuntime && surfaceProfile === 'full') {
|
|
512
|
+
registerProcessTools(toolServer, { runtime: registeredProcessRuntime });
|
|
456
513
|
}
|
|
457
514
|
|
|
458
|
-
if (
|
|
515
|
+
if (registeredCodingRuntime && registeredCodingTaskRuntime && registeredSemanticRuntime) {
|
|
459
516
|
const codingServer=surfaceProfile==='full'?toolServer:filteredToolServer(toolServer,COMPACT_CODING_DIRECT_TOOLS);
|
|
460
|
-
registerCodingTools(codingServer, { codingRuntime, taskRuntime:
|
|
517
|
+
registerCodingTools(codingServer, { codingRuntime:registeredCodingRuntime, taskRuntime:registeredCodingTaskRuntime, semanticRuntime:registeredSemanticRuntime });
|
|
461
518
|
}
|
|
462
519
|
|
|
463
|
-
if (
|
|
464
|
-
registerMachineFsTools(toolServer, { runtime:
|
|
520
|
+
if (registeredMachineFsRuntime && surfaceProfile === 'full') {
|
|
521
|
+
registerMachineFsTools(toolServer, { runtime: registeredMachineFsRuntime });
|
|
465
522
|
}
|
|
466
523
|
|
|
467
|
-
if (
|
|
468
|
-
registerObservationTools(toolServer, { runtime:
|
|
524
|
+
if (registeredObservationRuntime && surfaceProfile === 'full') {
|
|
525
|
+
registerObservationTools(toolServer, { runtime: registeredObservationRuntime });
|
|
469
526
|
}
|
|
470
527
|
|
|
471
|
-
if (
|
|
472
|
-
registerDesktopTools(toolServer,{runtime:
|
|
528
|
+
if (registeredDesktopRuntime && surfaceProfile === 'full') {
|
|
529
|
+
registerDesktopTools(toolServer,{runtime:registeredDesktopRuntime});
|
|
473
530
|
}
|
|
474
531
|
|
|
475
|
-
if (
|
|
476
|
-
registerAutonomousTools(toolServer, { autonomousRuntime, nativeDiffRuntime });
|
|
532
|
+
if (registeredAutonomousRuntime && registeredNativeDiffRuntime) {
|
|
533
|
+
registerAutonomousTools(toolServer, { autonomousRuntime:registeredAutonomousRuntime, nativeDiffRuntime:registeredNativeDiffRuntime });
|
|
477
534
|
}
|
|
478
535
|
|
|
479
|
-
registerSkillToolsR44(toolServer,{runtime:
|
|
536
|
+
registerSkillToolsR44(toolServer,{runtime:registeredSkillRuntime});
|
|
480
537
|
|
|
481
538
|
registerCompactGatewayTools(toolServer,{
|
|
482
|
-
profile:surfaceProfile,ledger:R36_CAPABILITY_LEDGER,codingRuntime,
|
|
483
|
-
|
|
484
|
-
|
|
539
|
+
profile:surfaceProfile,ledger:R36_CAPABILITY_LEDGER,codingRuntime:registeredCodingRuntime,
|
|
540
|
+
semanticRuntime:registeredSemanticRuntime,machineFsRuntime:registeredMachineFsRuntime,
|
|
541
|
+
processRuntime:registeredProcessRuntime,observationRuntime:registeredObservationRuntime,
|
|
542
|
+
machineRuntime:registeredMachineRuntime,desktopRuntime:registeredDesktopRuntime,
|
|
543
|
+
skillRuntime:registeredSkillRuntime,autonomousRuntime:registeredAutonomousRuntime,hostPolicy,
|
|
544
|
+
catalogProvider:()=>[...registeredToolNames],runtimePlanes:capabilityPlaneSnapshot,
|
|
545
|
+
releaseBindingProvider:currentReleaseBindings
|
|
485
546
|
});
|
|
486
547
|
|
|
487
|
-
if (
|
|
548
|
+
if (planeRegistry.state('host').configured) {
|
|
488
549
|
toolServer.registerTool(
|
|
489
550
|
'host_file_read',
|
|
490
551
|
{
|
|
@@ -498,7 +559,7 @@ serveStdio(() => {
|
|
|
498
559
|
},
|
|
499
560
|
async ({ root_id, path: relativePath, encoding }) => {
|
|
500
561
|
try {
|
|
501
|
-
const result = await hostFileRead(hostPolicy, { rootId: root_id, relativePath, encoding });
|
|
562
|
+
const result = await hostFileRead(requirePlane('host',hostPolicy), { rootId: root_id, relativePath, encoding });
|
|
502
563
|
return textResult(hostFileReadOutputSchema, { status: 'ok', root_id, path: relativePath, ...result });
|
|
503
564
|
} catch (error) {
|
|
504
565
|
return textResult(hostFileReadOutputSchema, { status: 'denied', error: String(error) }, true);
|
|
@@ -521,7 +582,7 @@ serveStdio(() => {
|
|
|
521
582
|
},
|
|
522
583
|
async ({ root_id, path: relativePath, content, encoding, expected_sha256 }) => {
|
|
523
584
|
try {
|
|
524
|
-
const result = await hostFileWrite(hostPolicy, {
|
|
585
|
+
const result = await hostFileWrite(requirePlane('host',hostPolicy), {
|
|
525
586
|
rootId: root_id,
|
|
526
587
|
relativePath,
|
|
527
588
|
content,
|
|
@@ -585,7 +646,7 @@ serveStdio(() => {
|
|
|
585
646
|
try {
|
|
586
647
|
let result;
|
|
587
648
|
if (args.mode === 'inline') {
|
|
588
|
-
result = await hostExecInline(hostPolicy, {
|
|
649
|
+
result = await hostExecInline(requirePlane('host',hostPolicy), {
|
|
589
650
|
commandId: args.command_id,
|
|
590
651
|
rootId: args.root_id,
|
|
591
652
|
command: args.command,
|
|
@@ -593,7 +654,7 @@ serveStdio(() => {
|
|
|
593
654
|
timeoutMs: args.timeout_ms
|
|
594
655
|
});
|
|
595
656
|
} else if (args.mode === 'native') {
|
|
596
|
-
result = await hostExecNative(hostPolicy, {
|
|
657
|
+
result = await hostExecNative(requirePlane('host',hostPolicy), {
|
|
597
658
|
rootId: args.root_id,
|
|
598
659
|
executable: args.executable,
|
|
599
660
|
executableSha256: args.executable_sha256,
|
|
@@ -602,7 +663,7 @@ serveStdio(() => {
|
|
|
602
663
|
timeoutMs: args.timeout_ms
|
|
603
664
|
});
|
|
604
665
|
} else {
|
|
605
|
-
result = await hostExec(hostPolicy, {
|
|
666
|
+
result = await hostExec(requirePlane('host',hostPolicy), {
|
|
606
667
|
commandId: args.command_id,
|
|
607
668
|
rootId: args.root_id,
|
|
608
669
|
scriptPath: args.script_path,
|
|
@@ -622,8 +683,8 @@ serveStdio(() => {
|
|
|
622
683
|
}
|
|
623
684
|
|
|
624
685
|
if (surfaceProfile === 'full') {
|
|
625
|
-
registerCommanderCoreBridge(toolServer,{machineFsRuntime,processRuntime,searchRuntime:
|
|
626
|
-
registerCommanderExtendedBridge(toolServer,{extendedRuntime:commanderExtendedRuntime,observability:commanderObservability,skillPlane:
|
|
686
|
+
registerCommanderCoreBridge(toolServer,{machineFsRuntime:registeredMachineFsRuntime,processRuntime:registeredProcessRuntime,searchRuntime:registeredCodingRuntime?.search??null,extendedRuntime:commanderExtendedRuntime,externalProcessRuntime:commanderExternalProcessRuntime,includeMarkdownEditor:true});
|
|
687
|
+
registerCommanderExtendedBridge(toolServer,{extendedRuntime:commanderExtendedRuntime,observability:commanderObservability,skillPlane:registeredSkillRuntime});
|
|
627
688
|
registerCommanderRemoteBridge(toolServer,{remoteDevicePlane});
|
|
628
689
|
registerCommanderHiddenUiDispatch(server);
|
|
629
690
|
registerCommanderUiResources(server);
|
|
@@ -41,7 +41,7 @@ export async function probeR40CompactDisarmed(endpointText){
|
|
|
41
41
|
for(const name of R40_COMPACT_GATEWAYS)if(!names.includes(name))throw new Error('R40 compact gateway missing '+name);
|
|
42
42
|
for(const tool of listed.tools)if(tool.outputSchema?.type!=='object'||tool.outputSchema?.additionalProperties!==false||!tool.outputSchema?.properties)throw new Error('tool '+tool.name+' missing strict output schema');
|
|
43
43
|
const manifest=gateway(await client.callTool({name:'capability_manifest',arguments:{}}),'capability_manifest');
|
|
44
|
-
if(manifest.
|
|
44
|
+
if(!['deadbyte.capability-manifest.v2','deadbyte.capability-manifest.v3'].includes(manifest.schema)||manifest.profile!=='compact'||manifest.tool_count!==names.length||
|
|
45
45
|
JSON.stringify(manifest.tool_catalog)!==JSON.stringify(names))throw new Error('R40 compact manifest malformed');
|
|
46
46
|
const required=manifest.capabilities.filter(x=>x?.production===true&&x?.host_only!==true);
|
|
47
47
|
for(const item of required)if(typeof item.compact_tool!=='string'||!names.includes(item.compact_tool))throw new Error('compact route missing '+String(item.id));
|
|
@@ -41,7 +41,7 @@ export async function probeR44CompactDisarmed(endpointText){
|
|
|
41
41
|
for(const name of R44_COMPACT_GATEWAYS)if(!names.includes(name))throw new Error('R44 compact gateway missing '+name);
|
|
42
42
|
for(const tool of listed.tools)if(tool.outputSchema?.type!=='object'||tool.outputSchema?.additionalProperties!==false||!tool.outputSchema?.properties)throw new Error('tool '+tool.name+' missing strict output schema');
|
|
43
43
|
const manifest=gateway(await client.callTool({name:'capability_manifest',arguments:{}}),'capability_manifest');
|
|
44
|
-
if(manifest.
|
|
44
|
+
if(!['deadbyte.capability-manifest.v2','deadbyte.capability-manifest.v3'].includes(manifest.schema)||manifest.profile!=='compact'||manifest.tool_count!==names.length||
|
|
45
45
|
JSON.stringify(manifest.tool_catalog)!==JSON.stringify(names))throw new Error('R44 compact manifest malformed');
|
|
46
46
|
const required=manifest.capabilities.filter(x=>x?.production===true&&x?.host_only!==true);
|
|
47
47
|
for(const item of required)if(typeof item.compact_tool!=='string'||!names.includes(item.compact_tool))throw new Error('compact route missing '+String(item.id));
|
|
@@ -41,7 +41,7 @@ export async function probeR45CompactDisarmed(endpointText){
|
|
|
41
41
|
for(const name of R45_COMPACT_GATEWAYS)if(!names.includes(name))throw new Error('R45 compact gateway missing '+name);
|
|
42
42
|
for(const tool of listed.tools)if(tool.outputSchema?.type!=='object'||tool.outputSchema?.additionalProperties!==false||!tool.outputSchema?.properties)throw new Error('tool '+tool.name+' missing strict output schema');
|
|
43
43
|
const manifest=gateway(await client.callTool({name:'capability_manifest',arguments:{}}),'capability_manifest');
|
|
44
|
-
if(manifest.
|
|
44
|
+
if(!['deadbyte.capability-manifest.v2','deadbyte.capability-manifest.v3'].includes(manifest.schema)||manifest.profile!=='compact'||manifest.tool_count!==names.length||
|
|
45
45
|
JSON.stringify(manifest.tool_catalog)!==JSON.stringify(names))throw new Error('R45 compact manifest malformed');
|
|
46
46
|
const required=manifest.capabilities.filter(x=>x?.production===true&&x?.host_only!==true);
|
|
47
47
|
for(const item of required)if(typeof item.compact_tool!=='string'||!names.includes(item.compact_tool))throw new Error('compact route missing '+String(item.id));
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
export const AUTHORITY_PLANES=Object.freeze(['process','coding','autonomous','desktop','host']);
|
|
4
|
+
|
|
5
|
+
export function authorityVector(mode='default'){
|
|
6
|
+
if(!['default','desktop','host','full'].includes(mode)) throw new Error('remote authority mode invalid');
|
|
7
|
+
return Object.freeze({
|
|
8
|
+
process:true,coding:true,autonomous:true,
|
|
9
|
+
desktop:mode==='desktop'||mode==='full',
|
|
10
|
+
host:mode==='host'||mode==='full'
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function parseAuthorityObservation(raw){
|
|
15
|
+
let value;
|
|
16
|
+
try{value=typeof raw==='string'?JSON.parse(raw.replace(/^\uFEFF/,'')):raw;}
|
|
17
|
+
catch{throw new Error('controller observation JSON invalid');}
|
|
18
|
+
if(value?.schema!=='deadbyte.controller-observation.v1'||!value.authority||typeof value.authority!=='object'||Array.isArray(value.authority))
|
|
19
|
+
throw new Error('controller observation schema invalid');
|
|
20
|
+
const authority={};
|
|
21
|
+
for(const plane of AUTHORITY_PLANES){
|
|
22
|
+
const entry=value.authority[plane];
|
|
23
|
+
if(!entry||typeof entry!=='object'||typeof entry.armed!=='boolean'||typeof entry.configured!=='boolean'||typeof entry.reason!=='string')
|
|
24
|
+
throw new Error(`controller authority ${plane} observation invalid`);
|
|
25
|
+
authority[plane]=Object.freeze({configured:entry.configured,armed:entry.armed,reason:entry.reason.slice(0,128)});
|
|
26
|
+
}
|
|
27
|
+
return Object.freeze({...value,authority:Object.freeze(authority)});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function assertAuthorityVector(snapshot,expected){
|
|
31
|
+
for(const plane of AUTHORITY_PLANES){
|
|
32
|
+
const entry=snapshot?.authority?.[plane];
|
|
33
|
+
if(!entry||typeof expected?.[plane]!=='boolean') throw new Error(`authority ${plane} observation or expectation invalid`);
|
|
34
|
+
if(entry.armed!==expected[plane]) throw new Error(`${plane} authority expected ${expected[plane]?'ARMED':'DISARMED'}; observed ${entry.armed?'ARMED':'DISARMED'} (${entry.reason})`);
|
|
35
|
+
if(expected[plane]&&!entry.configured) throw new Error(`${plane} authority unconfigured`);
|
|
36
|
+
}
|
|
37
|
+
return snapshot;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function authorityBanner(snapshot){
|
|
41
|
+
return AUTHORITY_PLANES.map(plane=>`${plane} ${snapshot.authority[plane].armed?'ARMED':'DISARMED'}`).join(' | ');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function assertRuntimeReadyObservation(snapshot,{coreRoot=null}={}){
|
|
45
|
+
if(snapshot?.state!=='ONLINE') throw new Error(`runtime state not ONLINE: ${String(snapshot?.state)}`);
|
|
46
|
+
for(const name of ['bridge','core','cloud']){
|
|
47
|
+
if(snapshot[name]?.alive!==true||snapshot[name]?.reason!=='verified') throw new Error(`${name} runtime identity unverified`);
|
|
48
|
+
}
|
|
49
|
+
if(snapshot.local_ready!==true) throw new Error('local MCP readiness unverified');
|
|
50
|
+
if(snapshot.supervisor?.running!==true) throw new Error('autonomous supervisor not running');
|
|
51
|
+
if(coreRoot!==null){
|
|
52
|
+
if(typeof snapshot.core_root!=='string'||path.win32.resolve(snapshot.core_root).toLowerCase()!==path.win32.resolve(coreRoot).toLowerCase())
|
|
53
|
+
throw new Error('core root does not match active release');
|
|
54
|
+
}
|
|
55
|
+
return snapshot;
|
|
56
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { authorityVector } from './remote-authority.mjs';
|
|
2
|
+
|
|
3
|
+
export async function probeRemoteEnforcement({client,mode='default'}={}){
|
|
4
|
+
if(!client||typeof client.callTool!=='function')throw new Error('remote enforcement client invalid');
|
|
5
|
+
const expected=mode==='revoked'?{desktop:false,host:false}:authorityVector(mode);
|
|
6
|
+
const desktop=await client.callTool({name:'desktop_control',arguments:{op:'status'}});
|
|
7
|
+
const desktopValue=desktop?.structuredContent;
|
|
8
|
+
const desktopArmed=desktop?.isError===false&&desktopValue?.status==='ok'&&desktopValue?.result?.armed===true;
|
|
9
|
+
const desktopUnavailable=desktop?.isError===true&&desktopValue?.status==='unavailable';
|
|
10
|
+
if(expected.desktop?!desktopArmed:desktopArmed||(!desktopUnavailable&&desktopValue?.result?.armed!==false))
|
|
11
|
+
throw new Error('Desktop enforcement does not match requested authority');
|
|
12
|
+
const host=await client.callTool({name:'host_file_read',arguments:{root_id:'core',path:'package.json',encoding:'utf8'}});
|
|
13
|
+
const hostArmed=host?.isError===false&&host?.structuredContent?.status==='ok'&&/^[0-9a-f]{64}$/.test(String(host.structuredContent.sha256??''));
|
|
14
|
+
const hostDenied=host?.isError===true&&host?.structuredContent?.status==='denied';
|
|
15
|
+
if(expected.host?!hostArmed:!hostDenied) throw new Error('Host enforcement does not match requested authority');
|
|
16
|
+
return Object.freeze({desktop_armed:desktopArmed,host_armed:hostArmed});
|
|
17
|
+
}
|
package/src/remote-live-log.mjs
CHANGED
|
@@ -319,19 +319,21 @@ export function createLiveTimelineWriter({stream=process.stdout,displayMode='uni
|
|
|
319
319
|
return Object.freeze({write,flush,pending(){return active?{...active}:null;}});
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
export function createLiveTimelineTracker({clock=()=>Date.now(),verbose=false,heartbeatBurstLimit=10,heartbeatWindowMs=3000,displayMode='unicode',rootPaths={},trace=false,slowCallMs=1000}={}){
|
|
322
|
+
export function createLiveTimelineTracker({clock=()=>Date.now(),verbose=false,foldHeartbeats=false,heartbeatBurstLimit=10,heartbeatWindowMs=3000,displayMode='unicode',rootPaths={},trace=false,slowCallMs=1000}={}){
|
|
323
323
|
if(typeof clock!=='function') throw new Error('live timeline clock must be a function');
|
|
324
324
|
if(!REMOTE_DISPLAY_MODES.includes(displayMode)) throw new Error('remote display mode invalid');
|
|
325
325
|
if(!Number.isInteger(heartbeatBurstLimit)||heartbeatBurstLimit<2||heartbeatBurstLimit>100) throw new Error('heartbeatBurstLimit invalid');
|
|
326
326
|
if(!Number.isInteger(heartbeatWindowMs)||heartbeatWindowMs<250||heartbeatWindowMs>60000) throw new Error('heartbeatWindowMs invalid');
|
|
327
327
|
if(!rootPaths||typeof rootPaths!=='object'||Array.isArray(rootPaths)) throw new Error('live timeline rootPaths invalid');
|
|
328
328
|
if(typeof trace!=='boolean') throw new Error('live timeline trace invalid');
|
|
329
|
+
if(typeof foldHeartbeats!=='boolean') throw new Error('live timeline foldHeartbeats invalid');
|
|
329
330
|
if(!Number.isInteger(slowCallMs)||slowCallMs<100||slowCallMs>600000) throw new Error('live timeline slowCallMs invalid');
|
|
330
331
|
const pending=new Map();
|
|
331
332
|
const completed=new Set();
|
|
332
333
|
const toolCounts=new Map();
|
|
333
334
|
const durationSamples=[];
|
|
334
335
|
let resultCount=0,okCount=0,errorCount=0,unknownCount=0,mutationCount=0,totalDurationMs=0,slowest=null,burst=null,foldedHeartbeatLines=0,peakInFlight=0;
|
|
336
|
+
let lastCapability=null,suppressedCapability=0,suppressedCapabilityReported=false;
|
|
335
337
|
|
|
336
338
|
function eventPrefix(event,sequence,{displayTool=null,icon=null}={}){
|
|
337
339
|
const seq=Number.isSafeInteger(sequence)&&sequence>0?'#'+sequence+' ':'';
|
|
@@ -419,7 +421,18 @@ export function createLiveTimelineTracker({clock=()=>Date.now(),verbose=false,he
|
|
|
419
421
|
addStats(event,span);
|
|
420
422
|
const error=event.outcome?.is_error===true;
|
|
421
423
|
const nowMs=eventMs(event,clock);
|
|
422
|
-
if(
|
|
424
|
+
if(tool==='capability_manifest'&&!error){
|
|
425
|
+
const snapshot=event.outcome?.snapshot_id,epoch=event.outcome?.state_epoch;
|
|
426
|
+
if(/^[0-9a-f]{64}$/.test(String(snapshot??''))&&Number.isInteger(epoch)&&epoch>0){
|
|
427
|
+
const identity=`${snapshot}:${epoch}`;
|
|
428
|
+
if(identity===lastCapability){suppressedCapability++;return null;}
|
|
429
|
+
lastCapability=identity;
|
|
430
|
+
const prior=flushBurst();
|
|
431
|
+
const line=resultLine(event,span,sequence)+` snapshot=${snapshot.slice(0,8)} epoch=${epoch}`;
|
|
432
|
+
return prior?[prior,line]:line;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if(foldHeartbeats&&HEARTBEAT_TOOLS.has(tool)&&!error){
|
|
423
436
|
const duration=Number(event.outcome?.duration_ms);
|
|
424
437
|
if(burst&&burst.tool===tool&&nowMs-burst.last_ms<=heartbeatWindowMs){
|
|
425
438
|
burst.count++;
|
|
@@ -449,6 +462,10 @@ export function createLiveTimelineTracker({clock=()=>Date.now(),verbose=false,he
|
|
|
449
462
|
const lines=[];
|
|
450
463
|
const folded=flushBurst();
|
|
451
464
|
if(folded) lines.push(folded);
|
|
465
|
+
if(suppressedCapability>0&&!suppressedCapabilityReported){
|
|
466
|
+
lines.push(remoteDisplayText(`capability_manifest ×${suppressedCapability} unchanged suppressed`,displayMode));
|
|
467
|
+
suppressedCapabilityReported=true;
|
|
468
|
+
}
|
|
452
469
|
for(const item of pending.values()) lines.push(remoteDisplayText((displayMode==='ascii'?'[WARN]':'⚠')+' ['+shortSpanId(item.request_id)+'] OUTCOME_UNKNOWN '+item.tool+' — '+suffix+'; inspect state before retry',displayMode));
|
|
453
470
|
pending.clear();
|
|
454
471
|
return lines;
|