/*
capability-bridge — client-side proxy that delegates to CapabilityBroker providers (RFC-1035).
- Does not implement the broker itself — that lives in broker/broker.ts.
- Does not implement sandbox spawning — that lives in isolation-manager.ts.
- RFC-1035: initial implementation of CapabilityBridge extending CapabilityBrokerV1.
- RFC-1097: sweep — werkstatt-engine clean
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.
*/
import type { CapabilityId } from "@warpgogol/werkstatt-shared/component";
import type {
CapabilityBridgeRequestV1,
CapabilityBridgeResponseV1,
CapabilityBridge as ICapabilityBridge,
IsolationPolicy,
TerminationReportV1,
} from "./contracts.ts";
import type { CapabilityBrokerV1, BrokerInvocationContextV1 } from "./broker/broker.ts";
const VIOLATION_WINDOW_MS = 60_000;
const VIOLATION_THRESHOLD = 3;
export interface CapabilityBridgeOptions {
readonly sandboxId: string;
readonly broker: CapabilityBrokerV1;
readonly policy: IsolationPolicy;
readonly brokerContext: BrokerInvocationContextV1;
readonly onViolation?: (sandboxId: string, reason: string) => void;
readonly onTerminate?: (sandboxId: string, reason: string) => void;
}
interface ViolationRecord {
readonly timestamp: number;
readonly reason: string;
}
export function createCapabilityBridge(opts: CapabilityBridgeOptions): ICapabilityBridge {
const violations: ViolationRecord[] = [];
let terminated = false;
function pruneViolations(now: number): void {
const cutoff = now - VIOLATION_WINDOW_MS;
while (violations.length > 0 && violations[0]!.timestamp < cutoff) {
violations.shift();
}
}
function recordViolation(reason: string): void {
const now = Date.now();
pruneViolations(now);
violations.push({ timestamp: now, reason });
opts.onViolation?.(opts.sandboxId, reason);
if (violations.length >= VIOLATION_THRESHOLD) {
terminated = true;
opts.onTerminate?.(opts.sandboxId, `violation threshold exceeded: ${reason}`);
}
}
function checkPolicy(command: CapabilityId): CapabilityBridgeResponseV1 | null {
if (terminated) {
return {
schema: "werkstatt/capability-bridge-response@1",
requestId: "bridge-terminated",
status: "error",
payload: new Uint8Array(0),
diagnostics: ["bridge is terminated due to violation threshold"],
};
}
const granted = opts.policy.grantedCommands.some((c) => String(c) === String(command));
if (!granted) {
const response: CapabilityBridgeResponseV1 = {
schema: "werkstatt/capability-bridge-response@1",
requestId: "policy-check",
status: "denied",
payload: new Uint8Array(0),
diagnostics: [`ISOLATION-01: command "${String(command)}" not in grantedCommands`],
};
recordViolation(`command not granted: ${String(command)}`);
return response;
}
return null;
}
return {
async call(command: CapabilityId, input: Uint8Array): Promise {
const policyViolation = checkPolicy(command);
if (policyViolation) {
return policyViolation;
}
const requestId = `bridge-${opts.sandboxId}-${Date.now()}`;
const deadline = Date.now() + opts.policy.timeoutMs;
const request: CapabilityBridgeRequestV1 = {
schema: "werkstatt/capability-bridge-request@1",
requestId,
capability: command,
grant: {
scope: "read",
resource: "sandbox",
maxDuration: opts.policy.timeoutMs,
maxOperations: 100,
},
payload: input,
deadline,
};
const timeoutPromise = new Promise((resolve) => {
setTimeout(() => {
resolve({
schema: "werkstatt/capability-bridge-response@1",
requestId,
status: "timeout",
payload: new Uint8Array(0),
diagnostics: [`ISOLATION-02: timeout exceeded ${opts.policy.timeoutMs}ms`],
});
}, opts.policy.timeoutMs);
});
const brokerPromise = opts.broker.invoke(request, opts.brokerContext);
const response = await Promise.race([brokerPromise, timeoutPromise]);
if (response.status === "timeout") {
recordViolation(`timeout: ${String(command)}`);
}
return response;
},
async ping(): Promise {
return !terminated;
},
async terminate(reason: string): Promise {
terminated = true;
return {
schema: "werkstatt/termination-report@1",
workloadId: opts.sandboxId,
reason,
terminated: true,
quarantined: violations.length >= VIOLATION_THRESHOLD,
diagnostics: [],
};
},
};
}