{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/components/capabilities/broker.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { randomUUID } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { open } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport { isDigest } from \"../../bundle/schema.ts\";\nimport type { EvoPaths } from \"../../paths.ts\";\nimport {\n\tappendJsonLine,\n\tatomicWriteJson,\n\tcanonicalJson,\n\treadJsonIfExists,\n\tsha256,\n\twithFileLock,\n} from \"../../storage.ts\";\nimport { assertEvoCapability, assertEvoComponentId } from \"../manifest.ts\";\nimport { EVO_CAPABILITY_NAMES, type EvoCapabilityName, type EvoCapabilityRequestFrame } from \"./protocol.ts\";\nimport type {\n\tEvoCapabilityComponentIdentity,\n\tEvoCapabilityExecutionResult,\n\tEvoCapabilityResourceUsage,\n\tEvoCapabilityService,\n\tEvoCapabilityServiceContext,\n\tEvoPreparedCapabilityRequest,\n} from \"./service.ts\";\n\ntype BudgetedCapabilityName = Extract<EvoCapabilityName, \"infer\" | \"spawn-agent\">;\ntype CallCapabilityName = Exclude<EvoCapabilityName, BudgetedCapabilityName>;\nconst CAPABILITY_NAMES = new Set<string>(EVO_CAPABILITY_NAMES);\nconst PROCESS_CAPABILITY_SESSION_ID = randomUUID();\nconst DEFAULT_MAX_AUDIT_RESULT_BYTES = 1024 * 1024;\nconst ACTIVE_CAPABILITY_EVENTS = new Set<string>();\n\nexport interface EvoCallCapabilityGrant {\n\tcapability: CallCapabilityName;\n\tmaxCalls: number;\n}\n\nexport interface EvoBudgetedCapabilityGrant {\n\tcapability: BudgetedCapabilityName;\n\tmaxCalls: number;\n\tmodels: string[];\n\tmaxInputTokens: number;\n\tmaxOutputTokens: number;\n\tmaxTotalTokens: number;\n\tmaxCostUsd: number;\n\tmaxOutputTokensPerCall: number;\n\t/** Only meaningful for spawn-agent; omitted for infer. */\n\ttools?: string[];\n}\n\nexport type EvoCapabilityGrant = EvoCallCapabilityGrant | EvoBudgetedCapabilityGrant;\n\nexport interface EvoCapabilityUsage extends EvoCapabilityResourceUsage {\n\tcapability: EvoCapabilityName;\n\tcalls: number;\n}\n\ninterface EvoCapabilityReservation extends EvoCapabilityResourceUsage {\n\teventId: string;\n\tauthorityId: string;\n\tartifactDigest: string;\n\tcapability: BudgetedCapabilityName;\n}\n\ninterface EvoCapabilityOperation {\n\teventId: string;\n\tauthorityId: string;\n\tsessionId: string;\n\townerPid: number;\n\tstartedAt: string;\n\tcomponent: {\n\t\tid: string;\n\t\tabi: string;\n\t\tartifactDigest: string;\n\t};\n\trequest: {\n\t\tinvokeId: number;\n\t\tid: string;\n\t\tcapability: EvoCapabilityName;\n\t};\n}\n\ninterface EvoPendingCapabilityAudit {\n\tauditId: string;\n\tevent: Record<string, unknown>;\n}\n\nexport interface EvoComponentCapabilityState {\n\tauthorityId: string;\n\tid: string;\n\tartifactDigest: string;\n\tgrants: EvoCapabilityGrant[];\n\tusage: EvoCapabilityUsage[];\n}\n\nexport interface EvoCapabilityState {\n\tschemaVersion: 1;\n\tcomponents: EvoComponentCapabilityState[];\n\treservations: EvoCapabilityReservation[];\n\toperations: EvoCapabilityOperation[];\n\tpendingAudit: EvoPendingCapabilityAudit[];\n}\n\nexport type EvoCapabilityBrokerFaultPoint = \"after-state-write\" | \"after-audit-append\";\n\nexport interface EvoCapabilityBrokerOptions {\n\tpaths: EvoPaths;\n\tservices?: Partial<Record<EvoCapabilityName, EvoCapabilityService>>;\n\tnow?: () => string;\n\trandomId?: () => string;\n\tmaxAuditResultBytes?: number;\n\t/** Process-wide by default; injectable only for crash-recovery tests. */\n\tsessionId?: string;\n\t/** Current process id by default; injectable only for crash-recovery tests. */\n\townerPid?: number;\n\t/** Fault injection hook used to verify durable recovery boundaries. */\n\tfaultInjector?: (point: EvoCapabilityBrokerFaultPoint) => void | Promise<void>;\n}\n\nexport class EvoCapabilityDeniedError extends Error {\n\treadonly code: string;\n\n\tconstructor(code: string, message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"EvoCapabilityDeniedError\";\n\t\tthis.code = code;\n\t}\n}\n\nfunction asRecord(value: unknown, label: string): Record<string, unknown> {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${label} must be an object`);\n\t}\n\treturn value as Record<string, unknown>;\n}\n\nfunction rejectUnknownKeys(record: Record<string, unknown>, allowed: readonly string[], label: string): void {\n\tconst allowedKeys = new Set(allowed);\n\tfor (const key of Object.keys(record)) {\n\t\tif (!allowedKeys.has(key)) throw new Error(`${label} has unknown key: ${key}`);\n\t}\n}\n\nfunction positiveInteger(value: unknown, label: string): number {\n\tif (!Number.isSafeInteger(value) || (value as number) <= 0) throw new Error(`${label} must be a positive integer`);\n\treturn value as number;\n}\n\nfunction nonNegativeInteger(value: unknown, label: string): number {\n\tif (!Number.isSafeInteger(value) || (value as number) < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value as number;\n}\n\nfunction nonNegativeNumber(value: unknown, label: string): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative finite number`);\n\t}\n\treturn value;\n}\n\nfunction positiveNumber(value: unknown, label: string): number {\n\tconst number = nonNegativeNumber(value, label);\n\tif (number === 0) throw new Error(`${label} must be positive`);\n\treturn number;\n}\n\nfunction stringArray(value: unknown, label: string, requireOne: boolean): string[] {\n\tif (\n\t\t!Array.isArray(value) ||\n\t\t(requireOne && value.length === 0) ||\n\t\tvalue.some((entry) => typeof entry !== \"string\" || !entry || entry.length > 300)\n\t) {\n\t\tthrow new Error(`${label} must be ${requireOne ? \"a non-empty\" : \"an\"} array of non-empty strings`);\n\t}\n\tconst strings = value as string[];\n\tif (new Set(strings).size !== strings.length) throw new Error(`${label} must not contain duplicates`);\n\treturn [...strings].sort();\n}\n\nfunction isBudgetedCapability(capability: EvoCapabilityName): capability is BudgetedCapabilityName {\n\treturn capability === \"infer\" || capability === \"spawn-agent\";\n}\n\nfunction isBudgetedGrant(grant: EvoCapabilityGrant): grant is EvoBudgetedCapabilityGrant {\n\treturn grant.capability === \"infer\" || grant.capability === \"spawn-agent\";\n}\n\nfunction parseGrant(value: unknown, label: string): EvoCapabilityGrant {\n\tconst record = asRecord(value, label);\n\tif (typeof record.capability !== \"string\") throw new Error(`${label}.capability must be a string`);\n\tassertEvoCapability(record.capability, `${label}.capability`);\n\tif (!CAPABILITY_NAMES.has(record.capability)) throw new Error(`${label}.capability is unsupported`);\n\tif (record.capability !== \"infer\" && record.capability !== \"spawn-agent\") {\n\t\trejectUnknownKeys(record, [\"capability\", \"maxCalls\"], label);\n\t\treturn {\n\t\t\tcapability: record.capability as CallCapabilityName,\n\t\t\tmaxCalls: positiveInteger(record.maxCalls, `${label}.maxCalls`),\n\t\t};\n\t}\n\trejectUnknownKeys(\n\t\trecord,\n\t\t[\n\t\t\t\"capability\",\n\t\t\t\"maxCalls\",\n\t\t\t\"models\",\n\t\t\t\"maxInputTokens\",\n\t\t\t\"maxOutputTokens\",\n\t\t\t\"maxTotalTokens\",\n\t\t\t\"maxCostUsd\",\n\t\t\t\"maxOutputTokensPerCall\",\n\t\t\t\"tools\",\n\t\t],\n\t\tlabel,\n\t);\n\tif (record.capability === \"infer\" && record.tools !== undefined) {\n\t\tthrow new Error(`${label}.tools is only supported for spawn-agent`);\n\t}\n\tconst grant: EvoBudgetedCapabilityGrant = {\n\t\tcapability: record.capability,\n\t\tmaxCalls: positiveInteger(record.maxCalls, `${label}.maxCalls`),\n\t\tmodels: stringArray(record.models, `${label}.models`, true),\n\t\tmaxInputTokens: positiveInteger(record.maxInputTokens, `${label}.maxInputTokens`),\n\t\tmaxOutputTokens: positiveInteger(record.maxOutputTokens, `${label}.maxOutputTokens`),\n\t\tmaxTotalTokens: positiveInteger(record.maxTotalTokens, `${label}.maxTotalTokens`),\n\t\tmaxCostUsd: positiveNumber(record.maxCostUsd, `${label}.maxCostUsd`),\n\t\tmaxOutputTokensPerCall: positiveInteger(record.maxOutputTokensPerCall, `${label}.maxOutputTokensPerCall`),\n\t\t...(record.tools === undefined ? {} : { tools: stringArray(record.tools, `${label}.tools`, false) }),\n\t};\n\tif (grant.maxTotalTokens < grant.maxInputTokens || grant.maxTotalTokens < grant.maxOutputTokens) {\n\t\tthrow new Error(`${label}.maxTotalTokens must cover each token sub-budget`);\n\t}\n\tif (grant.maxOutputTokensPerCall > grant.maxOutputTokens) {\n\t\tthrow new Error(`${label}.maxOutputTokensPerCall exceeds maxOutputTokens`);\n\t}\n\treturn grant;\n}\n\nfunction requireAuthorityId(value: unknown, label: string): string {\n\tif (typeof value !== \"string\" || !isDigest(value)) throw new Error(`${label} must be a sha256 digest`);\n\treturn value;\n}\n\n/**\n * Parse an explicit grant list without touching broker state. Import and\n * proposal code use this to freeze the exact authority a future selection may\n * receive before a component is registered with the broker.\n */\nexport function parseEvoCapabilityGrants(value: unknown, label = \"grants\"): EvoCapabilityGrant[] {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tconst grants = value.map((grant, index) => parseGrant(grant, `${label}[${index}]`));\n\tif (new Set(grants.map((grant) => grant.capability)).size !== grants.length) {\n\t\tthrow new Error(`${label} must not contain duplicate capabilities`);\n\t}\n\treturn grants.sort((left, right) => left.capability.localeCompare(right.capability));\n}\n\nexport function deriveEvoCapabilityAuthorityId(artifactDigest: string, grants: readonly EvoCapabilityGrant[]): string {\n\tif (!isDigest(artifactDigest)) throw new Error(\"capability authority artifactDigest must be a sha256 digest\");\n\tconst parsed = parseEvoCapabilityGrants(grants, \"capability authority grants\");\n\treturn sha256(canonicalJson({ artifactDigest, grants: parsed }));\n}\n\nfunction parseUsage(value: unknown, label: string): EvoCapabilityUsage {\n\tconst record = asRecord(value, label);\n\trejectUnknownKeys(record, [\"capability\", \"calls\", \"inputTokens\", \"outputTokens\", \"totalTokens\", \"costUsd\"], label);\n\tif (typeof record.capability !== \"string\") throw new Error(`${label}.capability must be a string`);\n\tassertEvoCapability(record.capability, `${label}.capability`);\n\tif (!CAPABILITY_NAMES.has(record.capability)) throw new Error(`${label}.capability is unsupported`);\n\treturn {\n\t\tcapability: record.capability as EvoCapabilityName,\n\t\tcalls: nonNegativeInteger(record.calls, `${label}.calls`),\n\t\tinputTokens: nonNegativeInteger(record.inputTokens, `${label}.inputTokens`),\n\t\toutputTokens: nonNegativeInteger(record.outputTokens, `${label}.outputTokens`),\n\t\ttotalTokens: nonNegativeInteger(record.totalTokens, `${label}.totalTokens`),\n\t\tcostUsd: nonNegativeNumber(record.costUsd, `${label}.costUsd`),\n\t};\n}\n\nfunction parseReservation(value: unknown, label: string): EvoCapabilityReservation {\n\tconst record = asRecord(value, label);\n\trejectUnknownKeys(\n\t\trecord,\n\t\t[\n\t\t\t\"eventId\",\n\t\t\t\"authorityId\",\n\t\t\t\"artifactDigest\",\n\t\t\t\"capability\",\n\t\t\t\"inputTokens\",\n\t\t\t\"outputTokens\",\n\t\t\t\"totalTokens\",\n\t\t\t\"costUsd\",\n\t\t],\n\t\tlabel,\n\t);\n\tif (typeof record.eventId !== \"string\" || !record.eventId) throw new Error(`${label}.eventId is invalid`);\n\tif (typeof record.artifactDigest !== \"string\" || !isDigest(record.artifactDigest)) {\n\t\tthrow new Error(`${label}.artifactDigest must be a digest`);\n\t}\n\tif (record.capability !== \"infer\" && record.capability !== \"spawn-agent\") {\n\t\tthrow new Error(`${label}.capability is not budgeted`);\n\t}\n\treturn {\n\t\teventId: record.eventId,\n\t\tauthorityId: requireAuthorityId(record.authorityId, `${label}.authorityId`),\n\t\tartifactDigest: record.artifactDigest,\n\t\tcapability: record.capability,\n\t\tinputTokens: nonNegativeInteger(record.inputTokens, `${label}.inputTokens`),\n\t\toutputTokens: nonNegativeInteger(record.outputTokens, `${label}.outputTokens`),\n\t\ttotalTokens: nonNegativeInteger(record.totalTokens, `${label}.totalTokens`),\n\t\tcostUsd: nonNegativeNumber(record.costUsd, `${label}.costUsd`),\n\t};\n}\n\nfunction parseOperation(value: unknown, label: string): EvoCapabilityOperation {\n\tconst record = asRecord(value, label);\n\trejectUnknownKeys(\n\t\trecord,\n\t\t[\"eventId\", \"authorityId\", \"sessionId\", \"ownerPid\", \"startedAt\", \"component\", \"request\"],\n\t\tlabel,\n\t);\n\tif (typeof record.eventId !== \"string\" || !record.eventId) throw new Error(`${label}.eventId is invalid`);\n\tif (typeof record.sessionId !== \"string\" || !record.sessionId || record.sessionId.length > 300) {\n\t\tthrow new Error(`${label}.sessionId is invalid`);\n\t}\n\tif (\n\t\ttypeof record.startedAt !== \"string\" ||\n\t\t!Number.isFinite(Date.parse(record.startedAt)) ||\n\t\tnew Date(record.startedAt).toISOString() !== record.startedAt\n\t) {\n\t\tthrow new Error(`${label}.startedAt must be an ISO timestamp`);\n\t}\n\tconst component = asRecord(record.component, `${label}.component`);\n\trejectUnknownKeys(component, [\"id\", \"abi\", \"artifactDigest\"], `${label}.component`);\n\tif (typeof component.id !== \"string\") throw new Error(`${label}.component.id must be a string`);\n\tassertEvoComponentId(component.id, `${label}.component.id`);\n\tif (typeof component.abi !== \"string\" || !component.abi) throw new Error(`${label}.component.abi is invalid`);\n\tif (typeof component.artifactDigest !== \"string\" || !isDigest(component.artifactDigest)) {\n\t\tthrow new Error(`${label}.component.artifactDigest must be a digest`);\n\t}\n\tconst request = asRecord(record.request, `${label}.request`);\n\trejectUnknownKeys(request, [\"invokeId\", \"id\", \"capability\"], `${label}.request`);\n\tif (!Number.isSafeInteger(request.invokeId) || (request.invokeId as number) <= 0) {\n\t\tthrow new Error(`${label}.request.invokeId must be a positive safe integer`);\n\t}\n\tif (typeof request.id !== \"string\" || !request.id) throw new Error(`${label}.request.id is invalid`);\n\tif (typeof request.capability !== \"string\") throw new Error(`${label}.request.capability must be a string`);\n\tassertEvoCapability(request.capability, `${label}.request.capability`);\n\tif (!CAPABILITY_NAMES.has(request.capability)) throw new Error(`${label}.request.capability is unsupported`);\n\treturn {\n\t\teventId: record.eventId,\n\t\tauthorityId: requireAuthorityId(record.authorityId, `${label}.authorityId`),\n\t\tsessionId: record.sessionId,\n\t\townerPid: positiveInteger(record.ownerPid, `${label}.ownerPid`),\n\t\tstartedAt: record.startedAt,\n\t\tcomponent: {\n\t\t\tid: component.id,\n\t\t\tabi: component.abi,\n\t\t\tartifactDigest: component.artifactDigest,\n\t\t},\n\t\trequest: {\n\t\t\tinvokeId: request.invokeId as number,\n\t\t\tid: request.id,\n\t\t\tcapability: request.capability as EvoCapabilityName,\n\t\t},\n\t};\n}\n\nfunction parsePendingAudit(value: unknown, label: string): EvoPendingCapabilityAudit {\n\tconst record = asRecord(value, label);\n\trejectUnknownKeys(record, [\"auditId\", \"event\"], label);\n\tconst auditId = requireAuthorityId(record.auditId, `${label}.auditId`);\n\tconst event = asRecord(record.event, `${label}.event`);\n\tif (event.auditId !== auditId) throw new Error(`${label}.event.auditId does not match auditId`);\n\tcanonicalJson(event);\n\treturn { auditId, event };\n}\n\nexport function parseEvoCapabilityState(value: unknown): EvoCapabilityState {\n\tconst root = asRecord(value, \"capability state\");\n\trejectUnknownKeys(\n\t\troot,\n\t\t[\"schemaVersion\", \"components\", \"reservations\", \"operations\", \"pendingAudit\"],\n\t\t\"capability state\",\n\t);\n\tif (root.schemaVersion !== 1) throw new Error(\"capability state.schemaVersion must be 1\");\n\tif (!Array.isArray(root.components)) throw new Error(\"capability state.components must be an array\");\n\tif (!Array.isArray(root.reservations)) throw new Error(\"capability state.reservations must be an array\");\n\tif (root.operations !== undefined && !Array.isArray(root.operations)) {\n\t\tthrow new Error(\"capability state.operations must be an array\");\n\t}\n\tif (root.pendingAudit !== undefined && !Array.isArray(root.pendingAudit)) {\n\t\tthrow new Error(\"capability state.pendingAudit must be an array\");\n\t}\n\tconst components = root.components.map((value, index) => {\n\t\tconst label = `capability state.components[${index}]`;\n\t\tconst record = asRecord(value, label);\n\t\trejectUnknownKeys(record, [\"authorityId\", \"id\", \"artifactDigest\", \"grants\", \"usage\"], label);\n\t\tconst authorityId = requireAuthorityId(record.authorityId, `${label}.authorityId`);\n\t\tif (typeof record.id !== \"string\") throw new Error(`${label}.id must be a string`);\n\t\tassertEvoComponentId(record.id, `${label}.id`);\n\t\tif (typeof record.artifactDigest !== \"string\" || !isDigest(record.artifactDigest)) {\n\t\t\tthrow new Error(`${label}.artifactDigest must be a digest`);\n\t\t}\n\t\tif (!Array.isArray(record.grants)) throw new Error(`${label}.grants must be an array`);\n\t\tif (!Array.isArray(record.usage)) throw new Error(`${label}.usage must be an array`);\n\t\tconst grants = parseEvoCapabilityGrants(record.grants, `${label}.grants`);\n\t\tif (authorityId !== deriveEvoCapabilityAuthorityId(record.artifactDigest, grants)) {\n\t\t\tthrow new Error(`${label}.authorityId does not match its exact artifact and grants`);\n\t\t}\n\t\tconst usage = record.usage.map((entry, usageIndex) => parseUsage(entry, `${label}.usage[${usageIndex}]`));\n\t\tfor (const [entries, entryLabel] of [\n\t\t\t[grants, \"grants\"],\n\t\t\t[usage, \"usage\"],\n\t\t] as const) {\n\t\t\tif (new Set(entries.map((entry) => entry.capability)).size !== entries.length) {\n\t\t\t\tthrow new Error(`${label}.${entryLabel} must not contain duplicate capabilities`);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tauthorityId,\n\t\t\tid: record.id,\n\t\t\tartifactDigest: record.artifactDigest,\n\t\t\tgrants: grants.sort((left, right) => left.capability.localeCompare(right.capability)),\n\t\t\tusage: usage.sort((left, right) => left.capability.localeCompare(right.capability)),\n\t\t};\n\t});\n\tif (new Set(components.map((entry) => entry.authorityId)).size !== components.length) {\n\t\tthrow new Error(\"capability state.components must not contain duplicate authority ids\");\n\t}\n\tconst reservations = root.reservations.map((value, index) =>\n\t\tparseReservation(value, `capability state.reservations[${index}]`),\n\t);\n\tif (new Set(reservations.map((entry) => entry.eventId)).size !== reservations.length) {\n\t\tthrow new Error(\"capability state.reservations must not contain duplicate event ids\");\n\t}\n\tconst operations = (root.operations ?? []).map((value, index) =>\n\t\tparseOperation(value, `capability state.operations[${index}]`),\n\t);\n\tif (new Set(operations.map((entry) => entry.eventId)).size !== operations.length) {\n\t\tthrow new Error(\"capability state.operations must not contain duplicate event ids\");\n\t}\n\tconst pendingAudit = (root.pendingAudit ?? []).map((value, index) =>\n\t\tparsePendingAudit(value, `capability state.pendingAudit[${index}]`),\n\t);\n\tif (new Set(pendingAudit.map((entry) => entry.auditId)).size !== pendingAudit.length) {\n\t\tthrow new Error(\"capability state.pendingAudit must not contain duplicate audit ids\");\n\t}\n\tfor (const [index, reservation] of reservations.entries()) {\n\t\tconst authority = components.find((entry) => entry.authorityId === reservation.authorityId);\n\t\tif (\n\t\t\t!authority ||\n\t\t\tauthority.artifactDigest !== reservation.artifactDigest ||\n\t\t\t!authority.grants.some((grant) => grant.capability === reservation.capability)\n\t\t) {\n\t\t\tthrow new Error(`capability state.reservations[${index}] does not match a granted authority`);\n\t\t}\n\t}\n\tfor (const [index, operation] of operations.entries()) {\n\t\tconst authority = components.find((entry) => entry.authorityId === operation.authorityId);\n\t\tif (\n\t\t\t!authority ||\n\t\t\tauthority.id !== operation.component.id ||\n\t\t\tauthority.artifactDigest !== operation.component.artifactDigest ||\n\t\t\t!authority.grants.some((grant) => grant.capability === operation.request.capability)\n\t\t) {\n\t\t\tthrow new Error(`capability state.operations[${index}] does not match a granted authority`);\n\t\t}\n\t}\n\treturn {\n\t\tschemaVersion: 1,\n\t\tcomponents: components.sort((left, right) => left.authorityId.localeCompare(right.authorityId)),\n\t\treservations: reservations.sort((left, right) => left.eventId.localeCompare(right.eventId)),\n\t\toperations: operations.sort((left, right) => left.eventId.localeCompare(right.eventId)),\n\t\tpendingAudit: pendingAudit.sort((left, right) => left.auditId.localeCompare(right.auditId)),\n\t};\n}\n\nfunction emptyState(): EvoCapabilityState {\n\treturn { schemaVersion: 1, components: [], reservations: [], operations: [], pendingAudit: [] };\n}\n\nfunction emptyUsage(capability: EvoCapabilityName): EvoCapabilityUsage {\n\treturn { capability, calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 };\n}\n\nfunction validateResourceUsage(value: EvoCapabilityResourceUsage, label: string): EvoCapabilityResourceUsage {\n\treturn {\n\t\tinputTokens: nonNegativeInteger(value.inputTokens, `${label}.inputTokens`),\n\t\toutputTokens: nonNegativeInteger(value.outputTokens, `${label}.outputTokens`),\n\t\ttotalTokens: nonNegativeInteger(value.totalTokens, `${label}.totalTokens`),\n\t\tcostUsd: nonNegativeNumber(value.costUsd, `${label}.costUsd`),\n\t};\n}\n\nfunction addUsage(left: EvoCapabilityResourceUsage, right: EvoCapabilityResourceUsage): EvoCapabilityResourceUsage {\n\treturn {\n\t\tinputTokens: left.inputTokens + right.inputTokens,\n\t\toutputTokens: left.outputTokens + right.outputTokens,\n\t\ttotalTokens: left.totalTokens + right.totalTokens,\n\t\tcostUsd: left.costUsd + right.costUsd,\n\t};\n}\n\nfunction isWithinReservation(usage: EvoCapabilityResourceUsage, reservation: EvoCapabilityResourceUsage): boolean {\n\treturn (\n\t\tusage.inputTokens <= reservation.inputTokens &&\n\t\tusage.outputTokens <= reservation.outputTokens &&\n\t\tusage.totalTokens <= reservation.totalTokens &&\n\t\tusage.costUsd <= reservation.costUsd\n\t);\n}\n\nfunction publicError(error: unknown): string {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn message.slice(0, 1_024) || \"Capability service failed\";\n}\n\nfunction errorCode(error: unknown): string | undefined {\n\treturn typeof error === \"object\" && error !== null && \"code\" in error && typeof error.code === \"string\"\n\t\t? error.code\n\t\t: undefined;\n}\n\nfunction processIsAlive(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch (error) {\n\t\treturn errorCode(error) !== \"ESRCH\";\n\t}\n}\n\nexport class EvoCapabilityBroker {\n\tprivate readonly paths: EvoPaths;\n\tprivate readonly services: Partial<Record<EvoCapabilityName, EvoCapabilityService>>;\n\tprivate readonly now: () => string;\n\tprivate readonly randomId: () => string;\n\tprivate readonly statePath: string;\n\tprivate readonly auditPath: string;\n\tprivate readonly maxAuditResultBytes: number;\n\tprivate readonly sessionId: string;\n\tprivate readonly ownerPid: number;\n\tprivate readonly faultInjector: ((point: EvoCapabilityBrokerFaultPoint) => void | Promise<void>) | undefined;\n\n\tconstructor(options: EvoCapabilityBrokerOptions) {\n\t\tthis.paths = options.paths;\n\t\tthis.services = { ...options.services };\n\t\tthis.now = options.now ?? (() => new Date().toISOString());\n\t\tthis.randomId = options.randomId ?? randomUUID;\n\t\tthis.statePath = join(options.paths.registry, \"capability-grants.json\");\n\t\tthis.auditPath = join(options.paths.log, \"capability-audit.jsonl\");\n\t\tthis.maxAuditResultBytes =\n\t\t\toptions.maxAuditResultBytes === undefined\n\t\t\t\t? DEFAULT_MAX_AUDIT_RESULT_BYTES\n\t\t\t\t: positiveInteger(options.maxAuditResultBytes, \"maxAuditResultBytes\");\n\t\tthis.sessionId = options.sessionId ?? PROCESS_CAPABILITY_SESSION_ID;\n\t\tif (!this.sessionId || this.sessionId.length > 300) throw new Error(\"capability broker sessionId is invalid\");\n\t\tthis.ownerPid = options.ownerPid ?? process.pid;\n\t\tpositiveInteger(this.ownerPid, \"capability broker ownerPid\");\n\t\tthis.faultInjector = options.faultInjector;\n\t}\n\n\tasync replaceComponentGrants(\n\t\tcomponent: EvoCapabilityComponentIdentity,\n\t\tgrants: readonly EvoCapabilityGrant[],\n\t): Promise<string> {\n\t\tconst parsed = parseEvoCapabilityGrants(grants);\n\t\tfor (const grant of parsed) {\n\t\t\tif (!component.declaredCapabilities.includes(grant.capability)) {\n\t\t\t\tthrow new Error(`Cannot grant undeclared capability: ${grant.capability}`);\n\t\t\t}\n\t\t\tif (!component.abiCapabilityCeiling.includes(grant.capability)) {\n\t\t\t\tthrow new Error(`Cannot grant capability above ABI ceiling: ${grant.capability}`);\n\t\t\t}\n\t\t}\n\t\tconst authorityId = deriveEvoCapabilityAuthorityId(component.artifactDigest, parsed);\n\t\treturn withFileLock(this.paths, \"capability-broker\", async () => {\n\t\t\tconst state = await this.readRecoveredState();\n\t\t\tlet entry = state.components.find((candidate) => candidate.authorityId === authorityId);\n\t\t\tif (\n\t\t\t\tentry &&\n\t\t\t\t(entry.id !== component.id ||\n\t\t\t\t\tentry.artifactDigest !== component.artifactDigest ||\n\t\t\t\t\tcanonicalJson(entry.grants) !== canonicalJson(parsed))\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Capability authority identity mismatch\");\n\t\t\t}\n\t\t\tif (!entry) {\n\t\t\t\tentry = {\n\t\t\t\t\tauthorityId,\n\t\t\t\t\tid: component.id,\n\t\t\t\t\tartifactDigest: component.artifactDigest,\n\t\t\t\t\tgrants: parsed,\n\t\t\t\t\tusage: [],\n\t\t\t\t};\n\t\t\t\tstate.components.push(entry);\n\t\t\t}\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"authority-registered\",\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: this.auditComponent(component, authorityId),\n\t\t\t\tgrants: entry.grants,\n\t\t\t});\n\t\t\tawait this.persistStateAndAudit(state);\n\t\t\treturn authorityId;\n\t\t});\n\t}\n\n\tasync getState(): Promise<EvoCapabilityState> {\n\t\treturn withFileLock(this.paths, \"capability-broker\", async () => this.readRecoveredState());\n\t}\n\n\tasync request(\n\t\tauthorityId: string,\n\t\tcomponent: EvoCapabilityComponentIdentity,\n\t\tframe: EvoCapabilityRequestFrame,\n\t\tsignal: AbortSignal,\n\t): Promise<unknown> {\n\t\trequireAuthorityId(authorityId, \"capability authority id\");\n\t\tconst eventId = this.randomId();\n\t\tconst context: EvoCapabilityServiceContext = { component, capability: frame.capability, signal };\n\t\tif (signal.aborted) {\n\t\t\treturn this.deny(authorityId, component, frame, eventId, \"aborted\", \"Capability request was already aborted\");\n\t\t}\n\t\tif (!component.declaredCapabilities.includes(frame.capability)) {\n\t\t\treturn this.deny(\n\t\t\t\tauthorityId,\n\t\t\t\tcomponent,\n\t\t\t\tframe,\n\t\t\t\teventId,\n\t\t\t\t\"undeclared\",\n\t\t\t\t\"Component did not declare this capability\",\n\t\t\t);\n\t\t}\n\t\tif (!component.abiCapabilityCeiling.includes(frame.capability)) {\n\t\t\treturn this.deny(\n\t\t\t\tauthorityId,\n\t\t\t\tcomponent,\n\t\t\t\tframe,\n\t\t\t\teventId,\n\t\t\t\t\"ceiling\",\n\t\t\t\t\"Capability exceeds the component ABI ceiling\",\n\t\t\t);\n\t\t}\n\t\tconst service = this.services[frame.capability];\n\t\tif (!service) {\n\t\t\treturn this.deny(authorityId, component, frame, eventId, \"unavailable\", \"Capability service is unavailable\");\n\t\t}\n\n\t\tlet prepared: EvoPreparedCapabilityRequest;\n\t\ttry {\n\t\t\tprepared = service.prepare(frame.payload, context);\n\t\t\tcanonicalJson(prepared.request);\n\t\t\tif (prepared.reservation) {\n\t\t\t\tprepared = {\n\t\t\t\t\t...prepared,\n\t\t\t\t\treservation: validateResourceUsage(prepared.reservation, \"capability reservation\"),\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (error) {\n\t\t\treturn this.deny(authorityId, component, frame, eventId, \"invalid_request\", publicError(error));\n\t\t}\n\n\t\tif (signal.aborted) {\n\t\t\treturn this.deny(authorityId, component, frame, eventId, \"aborted\", \"Capability request was aborted\");\n\t\t}\n\t\tACTIVE_CAPABILITY_EVENTS.add(eventId);\n\t\ttry {\n\t\t\tawait this.authorizeAndReserve(authorityId, component, frame, eventId, prepared);\n\t\t\tif (signal.aborted) {\n\t\t\t\tconst message = \"Capability request was aborted before execution\";\n\t\t\t\tawait this.finalize(authorityId, component, frame, eventId, undefined, undefined, {\n\t\t\t\t\tcode: \"aborted\",\n\t\t\t\t\tmessage,\n\t\t\t\t});\n\t\t\t\tthrow new EvoCapabilityDeniedError(\"aborted\", message);\n\t\t\t}\n\t\t\tlet execution: EvoCapabilityExecutionResult | undefined;\n\t\t\tlet resourceUsage: EvoCapabilityResourceUsage | undefined;\n\t\t\ttry {\n\t\t\t\texecution = await service.execute(prepared.request, context);\n\t\t\t\tcanonicalJson(execution.result);\n\t\t\t\tif (execution.usage) resourceUsage = validateResourceUsage(execution.usage, \"capability usage\");\n\t\t\t\tif (isBudgetedCapability(frame.capability)) {\n\t\t\t\t\tif (!resourceUsage) throw new Error(\"Budgeted capability service did not return resource usage\");\n\t\t\t\t\tif (!prepared.reservation || !isWithinReservation(resourceUsage, prepared.reservation)) {\n\t\t\t\t\t\tthrow new Error(\"Budgeted capability usage exceeded its reservation\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst message = publicError(error);\n\t\t\t\tconst code = signal.aborted ? \"aborted\" : \"service_error\";\n\t\t\t\tawait this.finalize(authorityId, component, frame, eventId, undefined, resourceUsage, { code, message });\n\t\t\t\tthrow new EvoCapabilityDeniedError(code, message, { cause: error });\n\t\t\t}\n\t\t\tawait this.finalize(authorityId, component, frame, eventId, execution.result, resourceUsage);\n\t\t\treturn execution.result;\n\t\t} finally {\n\t\t\tACTIVE_CAPABILITY_EVENTS.delete(eventId);\n\t\t}\n\t}\n\n\tprivate async readState(): Promise<EvoCapabilityState> {\n\t\tconst value = await readJsonIfExists<unknown>(this.statePath);\n\t\treturn value === undefined ? emptyState() : parseEvoCapabilityState(value);\n\t}\n\n\tprivate async writeState(state: EvoCapabilityState): Promise<void> {\n\t\tstate.components.sort((left, right) => left.authorityId.localeCompare(right.authorityId));\n\t\tstate.reservations.sort((left, right) => left.eventId.localeCompare(right.eventId));\n\t\tstate.operations.sort((left, right) => left.eventId.localeCompare(right.eventId));\n\t\tstate.pendingAudit.sort((left, right) => left.auditId.localeCompare(right.auditId));\n\t\tawait atomicWriteJson(this.statePath, state);\n\t}\n\n\tprivate async injectFault(point: EvoCapabilityBrokerFaultPoint): Promise<void> {\n\t\tawait this.faultInjector?.(point);\n\t}\n\n\tprivate queueAudit(state: EvoCapabilityState, event: Record<string, unknown>): void {\n\t\tconst auditId = sha256(`${this.sessionId}\\0${randomUUID()}`);\n\t\tconst audited = { ...event, auditId };\n\t\tcanonicalJson(audited);\n\t\tstate.pendingAudit.push({ auditId, event: audited });\n\t}\n\n\tprivate async repairAuditTail(): Promise<void> {\n\t\tlet handle: Awaited<ReturnType<typeof open>>;\n\t\ttry {\n\t\t\thandle = await open(this.auditPath, \"r+\");\n\t\t} catch (error) {\n\t\t\tif (errorCode(error) === \"ENOENT\") return;\n\t\t\tthrow error;\n\t\t}\n\t\ttry {\n\t\t\tconst size = (await handle.stat()).size;\n\t\t\tif (size === 0) return;\n\t\t\tconst last = Buffer.allocUnsafe(1);\n\t\t\tconst finalRead = await handle.read(last, 0, 1, size - 1);\n\t\t\tif (finalRead.bytesRead === 1 && last[0] === 0x0a) return;\n\t\t\tconst chunk = Buffer.allocUnsafe(64 * 1024);\n\t\t\tlet position = size;\n\t\t\tlet repairedSize = 0;\n\t\t\twhile (position > 0) {\n\t\t\t\tconst length = Math.min(position, chunk.byteLength);\n\t\t\t\tposition -= length;\n\t\t\t\tconst read = await handle.read(chunk, 0, length, position);\n\t\t\t\tconst newline = chunk.subarray(0, read.bytesRead).lastIndexOf(0x0a);\n\t\t\t\tif (newline >= 0) {\n\t\t\t\t\trepairedSize = position + newline + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait handle.truncate(repairedSize);\n\t\t\tawait handle.sync();\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t}\n\n\tprivate async existingAuditIds(pending: ReadonlySet<string>): Promise<Set<string>> {\n\t\tconst existing = new Set<string>();\n\t\tif (pending.size === 0) return existing;\n\t\tawait this.repairAuditTail();\n\t\tconst input = createReadStream(this.auditPath, { encoding: \"utf8\" });\n\t\tconst lines = createInterface({ input, crlfDelay: Number.POSITIVE_INFINITY });\n\t\ttry {\n\t\t\tfor await (const line of lines) {\n\t\t\t\tif (!line) continue;\n\t\t\t\tlet value: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tvalue = JSON.parse(line) as unknown;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new Error(\"Capability audit log contains invalid JSON\", { cause: error });\n\t\t\t\t}\n\t\t\t\tconst record = asRecord(value, \"capability audit event\");\n\t\t\t\tif (typeof record.auditId === \"string\" && pending.has(record.auditId)) existing.add(record.auditId);\n\t\t\t\tif (existing.size === pending.size) break;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (errorCode(error) !== \"ENOENT\") throw error;\n\t\t} finally {\n\t\t\tlines.close();\n\t\t\tinput.destroy();\n\t\t}\n\t\treturn existing;\n\t}\n\n\tprivate async flushPendingAudit(state: EvoCapabilityState, checkExisting: boolean): Promise<void> {\n\t\tif (state.pendingAudit.length === 0) return;\n\t\tconst pendingIds = new Set(state.pendingAudit.map((entry) => entry.auditId));\n\t\tconst existing = checkExisting ? await this.existingAuditIds(pendingIds) : new Set<string>();\n\t\tfor (const pending of state.pendingAudit) {\n\t\t\tif (existing.has(pending.auditId)) continue;\n\t\t\tawait appendJsonLine(this.auditPath, pending.event);\n\t\t\tawait this.injectFault(\"after-audit-append\");\n\t\t}\n\t\tstate.pendingAudit = [];\n\t\tawait this.writeState(state);\n\t}\n\n\tprivate async persistStateAndAudit(state: EvoCapabilityState): Promise<void> {\n\t\tawait this.writeState(state);\n\t\tawait this.injectFault(\"after-state-write\");\n\t\tawait this.flushPendingAudit(state, false);\n\t}\n\n\tprivate chargeReservation(\n\t\tstate: EvoCapabilityState,\n\t\treservation: EvoCapabilityReservation,\n\t): EvoCapabilityResourceUsage {\n\t\tconst entry = state.components.find((candidate) => candidate.authorityId === reservation.authorityId);\n\t\tif (!entry || entry.artifactDigest !== reservation.artifactDigest) {\n\t\t\tthrow new Error(\"Recovered capability reservation has no matching authority\");\n\t\t}\n\t\tlet usage = entry.usage.find((candidate) => candidate.capability === reservation.capability);\n\t\tif (!usage) {\n\t\t\tusage = emptyUsage(reservation.capability);\n\t\t\tentry.usage.push(usage);\n\t\t}\n\t\tusage.inputTokens += reservation.inputTokens;\n\t\tusage.outputTokens += reservation.outputTokens;\n\t\tusage.totalTokens += reservation.totalTokens;\n\t\tusage.costUsd += reservation.costUsd;\n\t\tentry.usage.sort((left, right) => left.capability.localeCompare(right.capability));\n\t\treturn validateResourceUsage(reservation, \"recovered capability reservation\");\n\t}\n\n\tprivate operationIsLive(operation: EvoCapabilityOperation): boolean {\n\t\tif (operation.ownerPid === process.pid) return ACTIVE_CAPABILITY_EVENTS.has(operation.eventId);\n\t\treturn processIsAlive(operation.ownerPid);\n\t}\n\n\tprivate async readRecoveredState(): Promise<EvoCapabilityState> {\n\t\tconst state = await this.readState();\n\t\tif (state.pendingAudit.length > 0) await this.flushPendingAudit(state, true);\n\t\tconst orphaned = state.operations.filter((operation) => !this.operationIsLive(operation));\n\t\tconst orphanedIds = new Set(orphaned.map((operation) => operation.eventId));\n\t\tlet changed = orphaned.length > 0;\n\t\tfor (const operation of orphaned) {\n\t\t\tconst reservationIndex = state.reservations.findIndex(\n\t\t\t\t(candidate) => candidate.eventId === operation.eventId && candidate.authorityId === operation.authorityId,\n\t\t\t);\n\t\t\tconst reservation = reservationIndex < 0 ? undefined : state.reservations[reservationIndex];\n\t\t\tconst usage = reservation ? this.chargeReservation(state, reservation) : undefined;\n\t\t\tif (reservationIndex >= 0) state.reservations.splice(reservationIndex, 1);\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"capability-result\",\n\t\t\t\teventId: operation.eventId,\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: { authorityId: operation.authorityId, ...operation.component },\n\t\t\t\trequest: operation.request,\n\t\t\t\tok: false,\n\t\t\t\trecovered: true,\n\t\t\t\terror: { code: \"host_recovered\", message: \"Capability host stopped before finalization\" },\n\t\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t\t});\n\t\t}\n\t\tstate.operations = state.operations.filter((operation) => !orphanedIds.has(operation.eventId));\n\n\t\tfor (const reservation of [...state.reservations]) {\n\t\t\tif (state.operations.some((operation) => operation.eventId === reservation.eventId)) continue;\n\t\t\tchanged = true;\n\t\t\tconst usage = this.chargeReservation(state, reservation);\n\t\t\tconst entry = state.components.find((candidate) => candidate.authorityId === reservation.authorityId);\n\t\t\tif (!entry) throw new Error(\"Recovered capability reservation has no authority\");\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"capability-result\",\n\t\t\t\teventId: reservation.eventId,\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: {\n\t\t\t\t\tauthorityId: reservation.authorityId,\n\t\t\t\t\tid: entry.id,\n\t\t\t\t\tartifactDigest: entry.artifactDigest,\n\t\t\t\t},\n\t\t\t\trequest: { invokeId: 0, id: reservation.eventId, capability: reservation.capability },\n\t\t\t\tok: false,\n\t\t\t\trecovered: true,\n\t\t\t\terror: { code: \"host_recovered\", message: \"Legacy capability reservation was not finalized\" },\n\t\t\t\tusage,\n\t\t\t});\n\t\t}\n\t\tif (changed) {\n\t\t\tstate.reservations = state.reservations.filter((reservation) =>\n\t\t\t\tstate.operations.some((operation) => operation.eventId === reservation.eventId),\n\t\t\t);\n\t\t\tawait this.persistStateAndAudit(state);\n\t\t}\n\t\treturn state;\n\t}\n\n\tprivate boundedAuditResult(result: unknown): unknown {\n\t\tconst json = canonicalJson(result);\n\t\tconst bytes = Buffer.byteLength(json, \"utf8\");\n\t\tif (bytes <= this.maxAuditResultBytes) return JSON.parse(json) as unknown;\n\t\treturn { omitted: true, reason: \"byte-limit\", bytes, sha256: sha256(json) };\n\t}\n\n\tprivate auditComponent(component: EvoCapabilityComponentIdentity, authorityId: string) {\n\t\treturn {\n\t\t\tauthorityId,\n\t\t\tid: component.id,\n\t\t\tabi: component.abi,\n\t\t\tartifactDigest: component.artifactDigest,\n\t\t};\n\t}\n\n\tprivate async deny(\n\t\tauthorityId: string,\n\t\tcomponent: EvoCapabilityComponentIdentity,\n\t\tframe: EvoCapabilityRequestFrame,\n\t\teventId: string,\n\t\tcode: string,\n\t\tmessage: string,\n\t): Promise<never> {\n\t\tawait withFileLock(this.paths, \"capability-broker\", async () => {\n\t\t\tconst state = await this.readRecoveredState();\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"capability-request\",\n\t\t\t\teventId,\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: this.auditComponent(component, authorityId),\n\t\t\t\trequest: frame,\n\t\t\t\tdecision: \"denied\",\n\t\t\t\terror: { code, message },\n\t\t\t});\n\t\t\tawait this.persistStateAndAudit(state);\n\t\t});\n\t\tthrow new EvoCapabilityDeniedError(code, message);\n\t}\n\n\tprivate async authorizeAndReserve(\n\t\tauthorityId: string,\n\t\tcomponent: EvoCapabilityComponentIdentity,\n\t\tframe: EvoCapabilityRequestFrame,\n\t\teventId: string,\n\t\tprepared: EvoPreparedCapabilityRequest,\n\t): Promise<void> {\n\t\tawait withFileLock(this.paths, \"capability-broker\", async () => {\n\t\t\tconst state = await this.readRecoveredState();\n\t\t\tconst entry = state.components.find((candidate) => candidate.authorityId === authorityId);\n\t\t\tconst grant = entry?.grants.find((candidate) => candidate.capability === frame.capability);\n\t\t\tconst deny = async (code: string, message: string): Promise<never> => {\n\t\t\t\tthis.queueAudit(state, {\n\t\t\t\t\tschemaVersion: 1,\n\t\t\t\t\ttype: \"capability-request\",\n\t\t\t\t\teventId,\n\t\t\t\t\ttimestamp: this.now(),\n\t\t\t\t\tcomponent: this.auditComponent(component, authorityId),\n\t\t\t\t\trequest: frame,\n\t\t\t\t\tdecision: \"denied\",\n\t\t\t\t\terror: { code, message },\n\t\t\t\t});\n\t\t\t\tawait this.persistStateAndAudit(state);\n\t\t\t\tthrow new EvoCapabilityDeniedError(code, message);\n\t\t\t};\n\t\t\tif (!entry || entry.id !== component.id || entry.artifactDigest !== component.artifactDigest || !grant) {\n\t\t\t\treturn deny(\"not_granted\", \"Capability is off until explicitly granted for this artifact\");\n\t\t\t}\n\t\t\tlet usage = entry.usage.find((candidate) => candidate.capability === frame.capability);\n\t\t\tif (!usage) {\n\t\t\t\tusage = emptyUsage(frame.capability);\n\t\t\t\tentry.usage.push(usage);\n\t\t\t}\n\t\t\tif (usage.calls >= grant.maxCalls) return deny(\"call_budget\", \"Capability call budget is exhausted\");\n\n\t\t\tif (isBudgetedCapability(frame.capability)) {\n\t\t\t\tif (!isBudgetedGrant(grant)) throw new Error(\"Capability grant type mismatch\");\n\t\t\t\tconst reservation = prepared.reservation;\n\t\t\t\tconst model = prepared.authorization?.model;\n\t\t\t\tconst maxOutputTokens = prepared.authorization?.maxOutputTokens;\n\t\t\t\tif (!reservation || !model || maxOutputTokens === undefined) {\n\t\t\t\t\treturn deny(\"invalid_service\", \"Budgeted capability service did not provide authorization bounds\");\n\t\t\t\t}\n\t\t\t\tif (!grant.models.includes(model)) return deny(\"model_restricted\", \"Requested model is not granted\");\n\t\t\t\tif (maxOutputTokens > grant.maxOutputTokensPerCall) {\n\t\t\t\t\treturn deny(\"output_budget\", \"Per-call output token budget is exceeded\");\n\t\t\t\t}\n\t\t\t\tconst requestedTools = prepared.authorization?.tools ?? [];\n\t\t\t\tif (requestedTools.some((tool) => !(grant.tools ?? []).includes(tool))) {\n\t\t\t\t\treturn deny(\"tool_restricted\", \"Requested spawn-agent tool is not granted\");\n\t\t\t\t}\n\t\t\t\tconst outstanding = state.reservations\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(candidate) => candidate.authorityId === authorityId && candidate.capability === frame.capability,\n\t\t\t\t\t)\n\t\t\t\t\t.reduce<EvoCapabilityResourceUsage>((total, candidate) => addUsage(total, candidate), {\n\t\t\t\t\t\tinputTokens: 0,\n\t\t\t\t\t\toutputTokens: 0,\n\t\t\t\t\t\ttotalTokens: 0,\n\t\t\t\t\t\tcostUsd: 0,\n\t\t\t\t\t});\n\t\t\t\tconst projected = addUsage(addUsage(usage, outstanding), reservation);\n\t\t\t\tif (projected.inputTokens > grant.maxInputTokens) {\n\t\t\t\t\treturn deny(\"input_budget\", \"Capability input token budget is exhausted\");\n\t\t\t\t}\n\t\t\t\tif (projected.outputTokens > grant.maxOutputTokens) {\n\t\t\t\t\treturn deny(\"output_budget\", \"Capability output token budget is exhausted\");\n\t\t\t\t}\n\t\t\t\tif (projected.totalTokens > grant.maxTotalTokens) {\n\t\t\t\t\treturn deny(\"token_budget\", \"Capability total token budget is exhausted\");\n\t\t\t\t}\n\t\t\t\tif (projected.costUsd > grant.maxCostUsd) {\n\t\t\t\t\treturn deny(\"cost_budget\", \"Capability cost budget is exhausted\");\n\t\t\t\t}\n\t\t\t\tstate.reservations.push({\n\t\t\t\t\teventId,\n\t\t\t\t\tauthorityId,\n\t\t\t\t\tartifactDigest: component.artifactDigest,\n\t\t\t\t\tcapability: frame.capability,\n\t\t\t\t\t...reservation,\n\t\t\t\t});\n\t\t\t}\n\t\t\tusage.calls += 1;\n\t\t\tstate.operations.push({\n\t\t\t\teventId,\n\t\t\t\tauthorityId,\n\t\t\t\tsessionId: this.sessionId,\n\t\t\t\townerPid: this.ownerPid,\n\t\t\t\tstartedAt: this.now(),\n\t\t\t\tcomponent: { id: component.id, abi: component.abi, artifactDigest: component.artifactDigest },\n\t\t\t\trequest: { invokeId: frame.invokeId, id: frame.id, capability: frame.capability },\n\t\t\t});\n\t\t\tentry.usage.sort((left, right) => left.capability.localeCompare(right.capability));\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"capability-request\",\n\t\t\t\teventId,\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: this.auditComponent(component, authorityId),\n\t\t\t\trequest: frame,\n\t\t\t\tdecision: \"allowed\",\n\t\t\t\t...(prepared.reservation === undefined ? {} : { reservation: prepared.reservation }),\n\t\t\t});\n\t\t\tawait this.persistStateAndAudit(state);\n\t\t});\n\t}\n\n\tprivate async finalize(\n\t\tauthorityId: string,\n\t\tcomponent: EvoCapabilityComponentIdentity,\n\t\tframe: EvoCapabilityRequestFrame,\n\t\teventId: string,\n\t\tresult?: unknown,\n\t\tresourceUsage?: EvoCapabilityResourceUsage,\n\t\tfailure?: { code: string; message: string },\n\t): Promise<void> {\n\t\tawait withFileLock(this.paths, \"capability-broker\", async () => {\n\t\t\tconst state = await this.readRecoveredState();\n\t\t\tconst operationIndex = state.operations.findIndex(\n\t\t\t\t(candidate) => candidate.eventId === eventId && candidate.authorityId === authorityId,\n\t\t\t);\n\t\t\tif (operationIndex < 0) throw new Error(\"Capability operation disappeared before finalization\");\n\t\t\tconst reservationIndex = state.reservations.findIndex(\n\t\t\t\t(candidate) => candidate.eventId === eventId && candidate.authorityId === authorityId,\n\t\t\t);\n\t\t\tlet chargedUsage = resourceUsage;\n\t\t\tif (isBudgetedCapability(frame.capability)) {\n\t\t\t\tif (reservationIndex < 0) throw new Error(\"Capability reservation disappeared before finalization\");\n\t\t\t\tconst reservation = state.reservations[reservationIndex];\n\t\t\t\tif (!reservation) throw new Error(\"Capability reservation disappeared before finalization\");\n\t\t\t\tif (failure === undefined) {\n\t\t\t\t\tif (!chargedUsage) throw new Error(\"Successful budgeted capability result is missing usage\");\n\t\t\t\t\tif (!isWithinReservation(chargedUsage, reservation)) {\n\t\t\t\t\t\tthrow new Error(\"Successful budgeted capability usage exceeds its reservation\");\n\t\t\t\t\t}\n\t\t\t\t} else if (!chargedUsage) {\n\t\t\t\t\tchargedUsage = reservation;\n\t\t\t\t}\n\t\t\t\tstate.reservations.splice(reservationIndex, 1);\n\t\t\t}\n\t\t\tstate.operations.splice(operationIndex, 1);\n\t\t\tif (chargedUsage) {\n\t\t\t\tconst entry = state.components.find((candidate) => candidate.authorityId === authorityId);\n\t\t\t\tconst usage = entry?.usage.find((candidate) => candidate.capability === frame.capability);\n\t\t\t\tif (!entry || entry.id !== component.id || entry.artifactDigest !== component.artifactDigest || !usage) {\n\t\t\t\t\tthrow new Error(\"Capability usage disappeared before finalization\");\n\t\t\t\t}\n\t\t\t\tconst validated = validateResourceUsage(chargedUsage, \"capability usage\");\n\t\t\t\tusage.inputTokens += validated.inputTokens;\n\t\t\t\tusage.outputTokens += validated.outputTokens;\n\t\t\t\tusage.totalTokens += validated.totalTokens;\n\t\t\t\tusage.costUsd += validated.costUsd;\n\t\t\t}\n\t\t\tthis.queueAudit(state, {\n\t\t\t\tschemaVersion: 1,\n\t\t\t\ttype: \"capability-result\",\n\t\t\t\teventId,\n\t\t\t\ttimestamp: this.now(),\n\t\t\t\tcomponent: this.auditComponent(component, authorityId),\n\t\t\t\trequest: { invokeId: frame.invokeId, id: frame.id, capability: frame.capability },\n\t\t\t\tok: failure === undefined,\n\t\t\t\t...(failure === undefined ? { result: this.boundedAuditResult(result) } : { error: failure }),\n\t\t\t\t...(chargedUsage === undefined ? {} : { usage: chargedUsage }),\n\t\t\t});\n\t\t\tawait this.persistStateAndAudit(state);\n\t\t});\n\t}\n}\n"]}