Files
MikrotikManager/backend/src/services/bandwidth-execution-host.ts
T

270 lines
22 KiB
TypeScript

/** Trusted internal execution composition only. No enrollment, default source,
* production activation or model-supplied transport/authority callbacks. Raw
* results are for the complete internal workflow, never a public readiness API. */
import { isDeepStrictEqual } from "node:util"
import { performance } from "node:perf_hooks"
import { z } from "zod"
import { BANDWIDTH_CALLER_KINDS, createBandwidthAdmission, type BandwidthAdmissionInput, type BandwidthBinding, type BandwidthJournal, type BandwidthScope, type BandwidthTransition } from "./bandwidth-admission.js"
import { createBandwidthAdmissionSqlJournal } from "./bandwidth-admission-storage.js"
import { createBandwidthNodeRegistry, type BandwidthNodeRegistryReceipt } from "./bandwidth-node-registry.js"
import type { createConfiguredBandwidthControlSource, BandwidthControlDispatchFence } from "./bandwidth-control-source.js"
import type { createConfiguredBandwidthNodeSource } from "./bandwidth-node-source.js"
import type { createBandwidthNodeObservationReader, BandwidthNodeObservationEvidence } from "./bandwidth-node-observation.js"
import type { ProbeStorageConnection } from "./server-probe-journal-maintenance.js"
type Core = ReturnType<typeof createConfiguredBandwidthControlSource>
type Nodes = ReturnType<typeof createConfiguredBandwidthNodeSource>
type Observer = ReturnType<typeof createBandwidthNodeObservationReader>
type NodeSession = Awaited<ReturnType<Nodes["open"]>>
type NodeBinding = Awaited<ReturnType<NodeSession["binding"]>>
const hash = z.string().regex(/^[a-f0-9]{64}$/), label = z.string().regex(/^[a-zA-Z0-9_.:-]{1,200}$/)
const positive = z.number().int().positive().safe()
const intentSchema = z.object({ attemptId: z.string().uuid(), operationId: label, callerKind: z.enum(BANDWIDTH_CALLER_KINDS),
sourceServerId: positive, actualRemoteServerId: positive, credentialServerId: positive,
request: z.record(z.string(), z.unknown()).transform(value => value as BandwidthAdmissionInput["request"]), nativeBody: z.record(z.string(), z.string()),
durationSec: z.number().int().min(3).max(2147483647), socketTimeoutMs: z.number().int().min(1).max(2147483647),
authorityProof: hash, authorityGeneration: label, expiresAt: positive }).strict()
export type BandwidthExecutionIntent = Readonly<z.infer<typeof intentSchema>>
export interface BandwidthExecutionRemoteEvidence {
readonly sourceEvidence: Readonly<BandwidthNodeObservationEvidence>
readonly remoteEvidence: Readonly<BandwidthNodeObservationEvidence>
readonly sourceReceipt: Readonly<BandwidthNodeRegistryReceipt>
readonly remoteReceipt: Readonly<BandwidthNodeRegistryReceipt>
}
export interface BandwidthExecutionHostDependencies {
coreSource: Core
nodeSource: Nodes
observer: Observer
/** Fixed server-owned original human/scheduler/MCP context verifier. Every
* read authenticates exact sealed intent AND current rights to ALL THREE IDs,
* current source/destination credentials and original nonrenewed expiry. */
readOriginal(originalContext: unknown, scope: Readonly<BandwidthScope>): Promise<BandwidthExecutionIntent>
/** Independently authenticate wire address/VRF/zone against the ACTUAL remote
* canonical receipt. Credential provider identity alone is insufficient. */
verifyRemote(originalContext: unknown, intent: BandwidthExecutionIntent, evidence: Readonly<BandwidthExecutionRemoteEvidence>, scope: Readonly<BandwidthScope>): Promise<{ proof: string; expiresAt: number }>
}
export class BandwidthExecutionHostError extends Error {
readonly automaticReplay = false
constructor(readonly code: "REFUSED" | "OUTCOME_UNKNOWN",readonly phase?:BandwidthExecutionPhase) { super("Bandwidth execution " + code) }
}
type BandwidthExecutionPhase="original-context"|"source-observation"|"remote-observation"|"source-resolution"|"remote-resolution"|"remote-policy"|"participant-proof"|"strict-client"|"reserve-arm"|"native-send"|"terminal-proof"|BandwidthTransition
function refuse(): never { throw new BandwidthExecutionHostError("REFUSED") }
function freeze<T>(value: T): T {
if (value && typeof value === "object") { Object.values(value).forEach(freeze); Object.freeze(value) }
return value
}
/** Reject getters, serializers, symbols and non-JSON values before any await. */
function capture(value: unknown, limit = 1048576): unknown {
const seen = new Set<object>()
const walk = (item: unknown, depth: number): unknown => {
if (depth > 32) refuse()
if (item === null || typeof item === "string" || typeof item === "boolean") return item
if (typeof item === "number") { if (!Number.isFinite(item) || Number.isInteger(item) && !Number.isSafeInteger(item)) refuse(); return item }
if (!item || typeof item !== "object" || seen.has(item)) refuse()
seen.add(item)
try {
if (Array.isArray(item)) {
const descriptors = Object.getOwnPropertyDescriptors(item)
if (Reflect.ownKeys(item).length !== item.length + 1 || Object.keys(descriptors).some(key => key !== "length" && (!/^(0|[1-9][0-9]*)$/.test(key) || !("value" in descriptors[key])))) refuse()
return Array.from({ length: item.length }, (_, index) => walk(descriptors[String(index)].value, depth + 1))
}
if (Object.getPrototypeOf(item) !== Object.prototype) refuse()
const descriptors = Object.getOwnPropertyDescriptors(item)
if (Reflect.ownKeys(item).length !== Object.keys(descriptors).length || Object.values(descriptors).some(entry => !("value" in entry) || !entry.enumerable)) refuse()
return Object.fromEntries(Object.entries(descriptors).map(([key, entry]) => [key, walk(entry.value, depth + 1)]))
} finally { seen.delete(item) }
}
const result = walk(value, 0)
if (Buffer.byteLength(JSON.stringify(result)) > limit) refuse()
return freeze(result)
}
const readIntent = (value: unknown): BandwidthExecutionIntent => {
const parsed = intentSchema.parse(capture(value))
if (parsed.nativeBody.duration !== `${parsed.durationSec}s` || !parsed.nativeBody.address?.trim()) refuse()
return freeze(parsed)
}
const nodeSubject=(value:Readonly<BandwidthNodeObservationEvidence>)=>({version:value.version,serverId:value.serverId,sourceProof:value.sourceProof,
authorityGeneration:value.authorityGeneration,routingEndpointEpoch:value.routingEndpointEpoch,claims:value.claims,
physicalUniquenessVerified:value.physicalUniquenessVerified,cloneResistanceVerified:value.cloneResistanceVerified})
export function createBandwidthExecutionHost(dependencies: BandwidthExecutionHostDependencies) {
// Capture the trusted assembly once; request values never choose providers.
const readOriginal = dependencies.readOriginal.bind(dependencies), verifyRemote = dependencies.verifyRemote.bind(dependencies)
const core = Object.freeze({ connect: dependencies.coreSource.connect.bind(dependencies.coreSource),
admissionProof: dependencies.coreSource.admissionProof.bind(dependencies.coreSource), eventProof: dependencies.coreSource.eventProofOnConnection.bind(dependencies.coreSource) })
const nodes = Object.freeze({ open: dependencies.nodeSource.open.bind(dependencies.nodeSource), assertResolvedOnFence: dependencies.nodeSource.assertResolvedOnFence.bind(dependencies.nodeSource) })
const observer = Object.freeze({ observe: dependencies.observer.observe.bind(dependencies.observer), inspect: dependencies.observer.inspect.bind(dependencies.observer), strictClient: dependencies.observer.strictClient.bind(dependencies.observer) })
return Object.freeze({ async execute(originalContext: unknown, inputScope: BandwidthScope) {
if (!inputScope || !Number.isSafeInteger(inputScope.deadlineAt) || inputScope.signal !== undefined && !(inputScope.signal instanceof AbortSignal)) refuse()
const entered = Date.now(), enteredMonotonic=performance.now(), controller = new AbortController()
let monotonicEnd=enteredMonotonic+Math.max(0,inputScope.deadlineAt-entered),mutationPossible=false
let phase:BandwidthExecutionPhase="original-context"
const parentDeadline = inputScope.deadlineAt, parentSignal = inputScope.signal
let running = true, intent: BandwidthExecutionIntent | undefined, timer: ReturnType<typeof setTimeout> | undefined
const abort = () => controller.abort()
parentSignal?.addEventListener("abort", abort, { once: true }); if (parentSignal?.aborted) abort()
const scope: BandwidthScope = Object.freeze({ deadlineAt: parentDeadline, signal: controller.signal })
let rejectStopped!: (error: BandwidthExecutionHostError) => void
const stopped = new Promise<never>((_resolve, reject) => { rejectStopped = reject })
const stop = () => { if (!running) return; controller.abort(); rejectStopped(new BandwidthExecutionHostError(mutationPossible?"OUTCOME_UNKNOWN":"REFUSED")) }
controller.signal.addEventListener("abort", stop, { once: true })
const live = (current: BandwidthScope = scope) => {
if (!running || current.signal?.aborted || controller.signal.aborted || Date.now() >= Math.min(current.deadlineAt, intent?.expiresAt ?? Infinity) || performance.now() >= monotonicEnd) refuse()
}
const schedule = () => {
clearTimeout(timer)
const remaining = Math.min(Math.min(parentDeadline, intent?.expiresAt ?? Infinity) - Date.now(), monotonicEnd - performance.now())
timer = setTimeout(() => { if (remaining > 2147483647) schedule(); else stop() }, Math.max(1, Math.min(2147483647, remaining)))
}
schedule()
const work = async () => {
live(); intent = readIntent(await readOriginal(originalContext, scope))
monotonicEnd=Math.min(monotonicEnd,enteredMonotonic+Math.max(0,intent.expiresAt-entered))
live(); schedule()
const original = intent, executeScope = Object.freeze({ deadlineAt: Math.min(parentDeadline, original.expiresAt), signal: controller.signal })
const actor = async (current: BandwidthScope) => { live(current); const fresh = readIntent(await readOriginal(originalContext, current)); live(current); if (!isDeepStrictEqual(fresh, original)) refuse() }
await actor(executeScope)
phase="source-observation";let sourceToken = await observer.observe(original.sourceServerId, executeScope); live()
phase="remote-observation";let remoteToken = await observer.observe(original.actualRemoteServerId, executeScope); live()
let sourceEvidence = freeze(await observer.inspect(sourceToken, executeScope)), remoteEvidence = freeze(await observer.inspect(remoteToken, executeScope))
const originalSourceSubject=freeze(structuredClone(nodeSubject(sourceEvidence))),originalRemoteSubject=freeze(structuredClone(nodeSubject(remoteEvidence)))
let preScope = Object.freeze({ deadlineAt: Math.min(executeScope.deadlineAt, sourceEvidence.expiresAt, remoteEvidence.expiresAt), signal: controller.signal })
// Each short phase obtains NEW real observations of the SAME original
// approved subjects. Expired capabilities are never inspected/adopted;
// actor/peer expiry, credentials, epochs and claims cannot be renewed.
// Call only between transitions, with no journal/registry lease held.
const observePhase=async()=>{
await actor(executeScope)
const tokens=await Promise.all([observer.observe(original.sourceServerId,executeScope),observer.observe(original.actualRemoteServerId,executeScope)])
const evidence=await Promise.all(tokens.map(token=>observer.inspect(token,executeScope)))
if(!isDeepStrictEqual(nodeSubject(evidence[0]),originalSourceSubject)||!isDeepStrictEqual(nodeSubject(evidence[1]),originalRemoteSubject))refuse()
live()
sourceToken=tokens[0];remoteToken=tokens[1];sourceEvidence=freeze(evidence[0]);remoteEvidence=freeze(evidence[1])
preScope=Object.freeze({deadlineAt:Math.min(executeScope.deadlineAt,sourceEvidence.expiresAt,remoteEvidence.expiresAt),signal:controller.signal})
await actor(preScope)
}
const nativeFresh = async (current: BandwidthScope) => {
live(current)
if (!isDeepStrictEqual(await observer.inspect(sourceToken, current), sourceEvidence) || !isDeepStrictEqual(await observer.inspect(remoteToken, current), remoteEvidence)) refuse()
live(current)
}
const originalGuard = async () => { await nativeFresh(preScope); await actor(preScope) }
let pin: NodeBinding | undefined
const resolve = async (token: unknown, evidence: Readonly<BandwidthNodeObservationEvidence>) => {
await originalGuard(); const session = await nodes.open(preScope, originalGuard)
try {
const binding = freeze(await session.binding()); if (pin && !isDeepStrictEqual(pin, binding)) refuse(); pin ??= binding
const registry = createBandwidthNodeRegistry({ now: Date.now, connect: async () => session.connection,
inspect: (value, current) => observer.inspect(value, current), keyedProof: (purpose, value) => session.keyedProof(purpose, value), keyedProofs: inputs => session.keyedProofs(inputs),
authorize: async (action, id, current, genuine) => {
if (action !== "resolve" || id !== evidence.serverId || !isDeepStrictEqual(genuine, evidence)) refuse()
if (!isDeepStrictEqual(await session.binding(), pin)) refuse()
await nativeFresh(current); await actor(current)
return { installationId: binding.installationId, issuerKeySha256: binding.issuerKeySha256, quiescenceProof: binding.quiescenceProof,
authorityProof: original.authorityProof, authorityGeneration: original.authorityGeneration, expiresAt: original.expiresAt }
} })
const receipt = freeze(await registry.resolve(token, preScope)); if (receipt.outcome !== "existing" || receipt.status !== "active") refuse()
return receipt
} finally { session.close() }
}
phase="source-resolution";const sourceReceipt = await resolve(sourceToken, sourceEvidence)
await observePhase()
phase="remote-resolution";const remoteReceipt = await resolve(remoteToken, remoteEvidence)
if (!pin || sourceReceipt.canonicalNodeId === remoteReceipt.canonicalNodeId) refuse()
const originalPin = pin
const participants = ()=>freeze({ sourceEvidence, remoteEvidence, sourceReceipt, remoteReceipt })
const remoteSchema = z.object({ proof: hash, expiresAt: positive }).strict()
await observePhase()
phase="remote-policy";const peer = freeze(remoteSchema.parse(capture(await verifyRemote(originalContext, original, participants(), preScope))))
if (peer.expiresAt <= Date.now()) refuse()
const peerMonotonicEnd=enteredMonotonic+Math.max(0,peer.expiresAt-entered)
const beforeDispatch = async () => {
await nativeFresh(preScope)
const currentPeer = remoteSchema.parse(capture(await verifyRemote(originalContext, original, participants(), preScope)))
if (!isDeepStrictEqual(currentPeer, peer) || Date.now() >= peer.expiresAt || performance.now()>=peerMonotonicEnd) refuse()
await actor(preScope)
}
const identityMatches = (value: { installationId: string; controlGeneration: string; sourceRecordSha256: string }) => {
if (value.installationId !== originalPin.installationId || value.controlGeneration !== originalPin.controlGeneration || value.sourceRecordSha256 !== originalPin.sourceRecordSha256) refuse()
}
const aliasFence = (fence: BandwidthControlDispatchFence, current: BandwidthScope) => nodes.assertResolvedOnFence(fence, {
binding: originalPin, participants: [{ evidence: sourceEvidence, receipt: sourceReceipt }, { evidence: remoteEvidence, receipt: remoteReceipt }],
}, current)
const dispatchGuard = (current: BandwidthScope, execute: boolean) => async (fence: BandwidthControlDispatchFence) => {
identityMatches(await fence.sourceIdentity())
if (execute) { await aliasFence(fence, current); await beforeDispatch() }
}
const endpointProof = async (receipt: BandwidthNodeRegistryReceipt, evidence: BandwidthNodeObservationEvidence) => core.admissionProof("bandwidth-endpoint-v1", { receipt, subject:nodeSubject(evidence), peer, sourceRecordSha256: originalPin.sourceRecordSha256 }, originalPin.sourceRecordSha256, preScope)
phase="participant-proof";const source = { canonicalNodeId: sourceReceipt.canonicalNodeId, endpointProof: await endpointProof(sourceReceipt, sourceEvidence) }
const destination = { canonicalNodeId: remoteReceipt.canonicalNodeId, endpointProof: await endpointProof(remoteReceipt, remoteEvidence) }
phase="strict-client";const client = await observer.strictClient(sourceToken, preScope); await beforeDispatch()
let activeJournal: { connection: ProbeStorageConnection; scope: BandwidthScope } | undefined
let originalBinding: Readonly<BandwidthBinding> | undefined, sendInvocations = 0, terminal: { bindingProof: string; proof: string } | undefined
let transition: BandwidthTransition | undefined
const own = (binding: Readonly<BandwidthBinding>) => {
if (originalBinding && !isDeepStrictEqual(originalBinding, binding)) refuse()
originalBinding ??= freeze(structuredClone(binding))
}
const baseJournal = createBandwidthAdmissionSqlJournal({ now: Date.now,
connect: async current => {
if (activeJournal) refuse()
const connection = await core.connect(current, dispatchGuard(current, transition === "reserve" || transition === "arm"))
activeJournal = { connection, scope: current }
return { query: (text, values, options) => connection.query(text, values, options), release(unsafe) { activeJournal = undefined; connection.release(unsafe) } }
},
authorize: async (binding, current, transition) => { own(binding); if (transition === "reserve" || transition === "arm") await beforeDispatch(); else if (current.signal?.aborted || Date.now() >= current.deadlineAt) refuse() },
verifyEvidence: async (transition, binding, evidence) => {
own(binding)
if (transition === "complete") { if (!terminal || terminal.bindingProof !== binding.bindingProof || !isDeepStrictEqual(evidence, { terminalProof: terminal.proof })) refuse() }
else if (transition === "release-before-dispatch") { if (sendInvocations !== 0 || !evidence || !["reserved", "armed"].includes((evidence as { from: string }).from) || (evidence as { proof: string }).proof !== "private-no-send") refuse() }
else if (evidence !== undefined) refuse()
},
eventProof: async event => { const current = activeJournal; if (!current) refuse(); return core.eventProof(event, current.connection, current.scope) },
})
// Track the transition explicitly: cleanup scopes intentionally do NOT
// inherit expired execute/native-observation authority or cancellation.
const inTransition = async <T>(kind: BandwidthTransition, work: () => Promise<T>) => {
if (transition) refuse(); transition = kind;phase=kind
try { return await work() } finally { transition = undefined }
}
const journal: BandwidthJournal = Object.freeze<BandwidthJournal>({
reserve: async(binding, current) => {await observePhase();mutationPossible=true;return inTransition("reserve", () => baseJournal.reserve(binding, current))},
arm: async(binding, current) => {await observePhase();return inTransition("arm", () => baseJournal.arm(binding, current))},
complete: (binding, evidence, current) => inTransition("complete", () => baseJournal.complete(binding, evidence, current)),
releaseBeforeDispatch: (binding, evidence, current) => inTransition("release-before-dispatch", () => baseJournal.releaseBeforeDispatch(binding, evidence, current)),
quarantine: (binding, current) => inTransition("quarantine", () => baseJournal.quarantine(binding, current)),
})
const admissionInput: BandwidthAdmissionInput = { attemptId: original.attemptId, callerKind: original.callerKind, operationId: original.operationId,
request: { originalRequest: original.request, context: { sourceServerId: original.sourceServerId, actualRemoteServerId: original.actualRemoteServerId, credentialServerId: original.credentialServerId,
socketTimeoutMs: original.socketTimeoutMs, peerProof: peer.proof } }, source, destination, authorityProof: original.authorityProof,
authorityGeneration: original.authorityGeneration, controlGeneration: originalPin.controlGeneration, expiresAt: original.expiresAt, durationSec: original.durationSec, nativeBody: original.nativeBody }
const admission = createBandwidthAdmission(admissionInput, { now: Date.now, cleanupBudgetMs: 10000, nativeClient: client, journal,
authorize: async (_binding, current) => { await beforeDispatch(); live(current); return { authorityProof: original.authorityProof, authorityGeneration: original.authorityGeneration, controlGeneration: originalPin.controlGeneration, expiresAt: original.expiresAt } },
endpoints: async () => { await beforeDispatch(); return { source, destination } },
keyedProof: async (purpose, value) => {
const current = purpose === "bandwidth-terminal-v1" ? { deadlineAt: Date.now() + 10000 } : preScope
const proof = await core.admissionProof(purpose, value, originalPin.sourceRecordSha256, current)
if (purpose === "bandwidth-terminal-v1") { phase="terminal-proof";if (!originalBinding) refuse(); terminal = { bindingProof: originalBinding.bindingProof, proof } }
return proof
},
send: async (_binding, body, current, permit) => {
// A send invocation is already potentially ambiguous. No later
// transport exception can fabricate private no-send evidence.
sendInvocations++
phase="native-send"
return client.post("/tool/bandwidth-test", { ...body }, original.socketTimeoutMs, current.signal, async () => {
await observePhase()
const lease = await core.connect(preScope, dispatchGuard(preScope, true))
try { await lease.query("SELECT 1"); await beforeDispatch() } finally { lease.release(true) }
}, permit)
} })
phase="reserve-arm";const capability=await admission.reserveAndArm(executeScope)
try{await observePhase()}catch(error){await admission.cancel(capability);throw error}
return admission.dispatch(capability)
}
try { return await Promise.race([work(), stopped]) }
catch { throw new BandwidthExecutionHostError(mutationPossible?"OUTCOME_UNKNOWN":"REFUSED",phase) }
finally { running = false; clearTimeout(timer); parentSignal?.removeEventListener("abort", abort); controller.signal.removeEventListener("abort", stop); controller.abort() }
} })
}