deadbyte-mcp 0.15.1 → 0.15.2
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 +54 -44
- package/PROVENANCE.json +6 -5
- package/README.txt +36 -20
- package/RELEASE.json +24 -8
- package/SBOM.cdx.json +3 -3
- package/controller/README.TXT +2 -2
- package/controller/deadbyte-controller.ps1 +50 -2
- package/controller/deadbyte-process-policy.json +63 -1
- package/docs/ARCHITECTURE.md +3 -4
- package/package.json +9 -7
- package/scripts/deferred-slot-operation-r46.mjs +126 -0
- package/scripts/final-closure-r46.mjs +98 -0
- package/scripts/final-closure-verify-r46.mjs +119 -0
- package/scripts/full-regression-r46.mjs +20 -0
- package/scripts/gate-windows-r46.ps1 +56 -0
- package/scripts/refresh-process-policy.mjs +64 -7
- package/scripts/release-parity-r46.mjs +187 -0
- package/scripts/windows-gate-evidence-r46.mjs +110 -0
- package/src/capability-ledger.mjs +1 -0
- package/src/compact-gateway-mcp-tools.mjs +7 -5
- package/src/deadbyte-cli.mjs +7 -3
- package/src/machine-fs-mcp-tools.mjs +3 -3
- package/src/machine-fs-output-contracts.mjs +1 -1
- package/src/machine-fs-read-worker.mjs +46 -0
- package/src/machine-fs.mjs +63 -10
- package/src/mcp-server.mjs +4 -0
- package/src/mcp-smoke-client.mjs +4 -1
- package/src/observation-runtime.mjs +25 -4
- package/src/process-mcp-tools.mjs +18 -5
- package/src/process-output-contracts.mjs +20 -3
- package/src/process-policy.mjs +3 -1
- package/src/process-runtime.mjs +99 -19
- package/src/process-smoke-client.mjs +67 -22
- package/src/release-generation.mjs +22 -3
- package/src/remote-device-r44.mjs +53 -15
- package/src/remote-mcp-smoke-client.mjs +1 -1
- package/src/stdio-console-guard.mjs +24 -0
- package/src/version.mjs +1 -1
- package/test/cli-entrypoint.test.mjs +3 -3
- package/test/compact-gateway-r36.test.mjs +28 -0
- package/test/core.test.mjs +1 -1
- package/test/full-max-catalog-r46.test.mjs +92 -0
- package/test/machine-fs-mcp-tools.test.mjs +4 -1
- package/test/machine-fs-runtime.test.mjs +18 -2
- package/test/observation-runtime.test.mjs +29 -2
- package/test/process-mcp-tools.test.mjs +23 -5
- package/test/process-policy-refresh.test.mjs +87 -10
- package/test/process-runtime.test.mjs +111 -1
- package/test/process-supervision.test.mjs +4 -2
- package/test/production-docs.test.mjs +3 -3
- package/test/r33-finalization.test.mjs +3 -3
- package/test/release-generation.test.mjs +25 -11
- package/test/release-version.test.mjs +99 -44
- package/test/remote-device-r44.test.mjs +75 -0
- package/test/remote-r24-catalog.test.mjs +2 -2
|
@@ -102,3 +102,78 @@ test('R44 remote state corruption fails closed',async()=>{
|
|
|
102
102
|
await assert.rejects(createRemoteDevicePlaneR44({stateDir:root,relay:new FakeRelay(),authorizeCapability:async()=>true}),/state JSON invalid/);
|
|
103
103
|
}finally{await rm(root,{recursive:true,force:true});}
|
|
104
104
|
});
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
test('R46 remote readiness probe retries only the idempotent probe and remains bounded by timeout',async()=>{
|
|
108
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r46-remote-probe-timeout-'));
|
|
109
|
+
const key=deviceKey();
|
|
110
|
+
let attempts=0;
|
|
111
|
+
const relay={
|
|
112
|
+
requests:[],
|
|
113
|
+
async probe(value){
|
|
114
|
+
attempts+=1;
|
|
115
|
+
if(attempts===1) return await new Promise(()=>{});
|
|
116
|
+
return {device_id:value.device_id,epoch:value.epoch,nonce:value.nonce,ready:true};
|
|
117
|
+
},
|
|
118
|
+
async request(value){this.requests.push(value);return {ack:'accepted',request_id:value.request_id,terminal:{status:'completed',result_sha256:'a'.repeat(64)}};}
|
|
119
|
+
};
|
|
120
|
+
try{
|
|
121
|
+
const plane=await createRemoteDevicePlaneR44({
|
|
122
|
+
stateDir:root,relay,authorizeCapability:async()=>true,
|
|
123
|
+
relayTimeoutMs:100,probeRetries:1,reachableTtlMs:5000
|
|
124
|
+
});
|
|
125
|
+
await plane.pair({publicKeySpkiBase64:key.spki,displayName:'lab'});
|
|
126
|
+
await plane.reportOnline({deviceId:key.deviceId,epoch:1,connectionId:'retry-c'});
|
|
127
|
+
const ready=await plane.probe({deviceId:key.deviceId,epoch:1});
|
|
128
|
+
assert.equal(attempts,2);
|
|
129
|
+
assert.equal(ready.reachable,true);
|
|
130
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('R46 remote reachability expires after the bounded probe freshness window',async()=>{
|
|
134
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r46-remote-stale-'));
|
|
135
|
+
const relay=new FakeRelay(),key=deviceKey();
|
|
136
|
+
try{
|
|
137
|
+
const plane=await createRemoteDevicePlaneR44({
|
|
138
|
+
stateDir:root,relay,authorizeCapability:async()=>true,
|
|
139
|
+
relayTimeoutMs:1000,probeRetries:0,reachableTtlMs:1000
|
|
140
|
+
});
|
|
141
|
+
await plane.pair({publicKeySpkiBase64:key.spki,displayName:'lab'});
|
|
142
|
+
await plane.reportOnline({deviceId:key.deviceId,epoch:1,connectionId:'stale-c'});
|
|
143
|
+
await plane.probe({deviceId:key.deviceId,epoch:1});
|
|
144
|
+
assert.equal((await plane.status({deviceId:key.deviceId})).reachable,true);
|
|
145
|
+
await new Promise(resolve=>setTimeout(resolve,1100));
|
|
146
|
+
assert.equal((await plane.status({deviceId:key.deviceId})).reachable,false);
|
|
147
|
+
await assert.rejects(
|
|
148
|
+
plane.dispatch({deviceId:key.deviceId,epoch:1,capabilityId:'machine.status',payload:{},requestId:'8'.repeat(64)}),
|
|
149
|
+
/not reachable|stale/i
|
|
150
|
+
);
|
|
151
|
+
assert.equal(relay.requests.length,0);
|
|
152
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('R46 remote dispatch timeout is not retried and downgrades reachability',async()=>{
|
|
156
|
+
const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r46-remote-dispatch-timeout-'));
|
|
157
|
+
const key=deviceKey();
|
|
158
|
+
let requestCount=0;
|
|
159
|
+
const relay={
|
|
160
|
+
async probe(value){return {device_id:value.device_id,epoch:value.epoch,nonce:value.nonce,ready:true};},
|
|
161
|
+
async request(){requestCount+=1;return await new Promise(()=>{});}
|
|
162
|
+
};
|
|
163
|
+
try{
|
|
164
|
+
const plane=await createRemoteDevicePlaneR44({
|
|
165
|
+
stateDir:root,relay,authorizeCapability:async()=>true,
|
|
166
|
+
relayTimeoutMs:100,probeRetries:0,reachableTtlMs:5000
|
|
167
|
+
});
|
|
168
|
+
await plane.pair({publicKeySpkiBase64:key.spki,displayName:'lab'});
|
|
169
|
+
await plane.reportOnline({deviceId:key.deviceId,epoch:1,connectionId:'dispatch-c'});
|
|
170
|
+
await plane.probe({deviceId:key.deviceId,epoch:1});
|
|
171
|
+
const result=await plane.dispatch({
|
|
172
|
+
deviceId:key.deviceId,epoch:1,capabilityId:'coding.file_read',payload:{path:'README.md'},requestId:'9'.repeat(64)
|
|
173
|
+
});
|
|
174
|
+
assert.equal(result.state,'failed');
|
|
175
|
+
assert.equal(result.error_code,'transport_error');
|
|
176
|
+
assert.equal(requestCount,1,'side-effecting dispatch must never auto-retry');
|
|
177
|
+
assert.equal((await plane.status({deviceId:key.deviceId})).reachable,false);
|
|
178
|
+
}finally{await rm(root,{recursive:true,force:true});}
|
|
179
|
+
});
|
|
@@ -32,10 +32,10 @@ test('R29 remote gate accepts machine plane as an exact optional catalog dimensi
|
|
|
32
32
|
assert.match(source, /if \(machine\) items\.push\(\.\.\.machineTools\)/);
|
|
33
33
|
assert.match(source, /machine_runtime: machineRuntime/);
|
|
34
34
|
});
|
|
35
|
-
test('
|
|
35
|
+
test('R46 remote gate accepts seven-tool process supervision as one exact optional catalog dimension', async () => {
|
|
36
36
|
const source = await readFile(sourcePath, 'utf8');
|
|
37
37
|
assert.match(source, /const processTools = \[/);
|
|
38
|
-
for (const name of ['process_session_start','process_session_read','process_session_status','process_session_list','process_session_terminate','process_session_action']) {
|
|
38
|
+
for (const name of ['process_session_start','process_session_read','process_session_status','process_session_list','process_session_terminate','process_session_action','process_session_write']) {
|
|
39
39
|
assert.match(source, new RegExp(`'${name}'`));
|
|
40
40
|
}
|
|
41
41
|
assert.match(source, /for \(const processPlane of \[false, true\]\)/);
|