/** * design/98 §2.5 / §E.2 (S8b, security core) — the DEFAULT-DENY governance for a sub-agent an LLM-authored * workflow script spawns. The child spec is BUILT (complete-by-construction) from the deployment's trusted * {@link WorkflowGovernanceBaseline} + a strict WHITELIST of safe work-fields the script may set — NEVER by * stripping a denylist off the untrusted spec (codex BLOCKER2: a missed control-plane field would leak). * * The script's spec is UNTRUSTED. Only {@link WHITELIST_KEYS} are ever read from it; every other field * (toolPolicy / onAsk / hooks / principal / tools / mcp / skills / lspManager / checkpointStore / * getApiKeyAndHeaders / promptProvider / sessionId / signal / …) is structurally never copied. The model is * chosen by NAME ONLY (resolved against an allowlist to a deploy-configured `Model` — the script never sees a * `Model` object, which carries `baseUrl`/`headers` = an exfil surface, codex v3 BLOCKER). Resource limits * are CLAMPED to the baseline + workflow ceilings (`tightenTaskSpec` only covers the safety knobs, not * cost/token caps — codex Q4). */ import type { Model } from "../internal/llm.js"; import type { ImageInput, TaskSpec, ThinkingLevel, WorkflowGovernanceBaseline } from "../core/types.js"; /** Thrown when an LLM-authored script picks a `modelName` not in the workflow model allowlist (or no * allowlist is configured). FAIL-CLOSED: a script can only ever name a model the deployment pre-approved. */ export declare class WorkflowModelNotAllowedError extends Error { readonly modelName: string; readonly code = "workflow.model_not_allowed"; constructor(modelName: string, reason: string); } /** * The SAFE fields an LLM-authored workflow script may set per sub-agent — the WORK, never the control plane. * `model` is a NAME (string), NOT a `ModelRef`/`Model` object (codex v3 BLOCKER: a `Model` carries * `baseUrl`/`headers`/`extraBody` = endpoint + auth-header injection). No `modelRole`/`roles` (a `roles.select` * conditional selector is its own vector). The engine resolves `modelName` against the allowlist. */ export interface WorkflowAgentSpec { objective: string; modelName?: string; thinking?: ThinkingLevel; systemPrompt?: string; images?: ImageInput[]; limits?: { maxTurns?: number; timeoutSec?: number; }; maxCostUsd?: number; maxTokens?: number; } /** * The SINGLE source of truth for the whitelist (a test pins that it contains no control-plane key). `objective` * + `modelName` are handled explicitly in {@link buildGovernedChildSpec}; the rest map 1:1 onto `TaskSpec`. */ export declare const WHITELIST_KEYS: readonly ["objective", "modelName", "thinking", "systemPrompt", "images", "limits", "maxCostUsd", "maxTokens"]; /** Per-child workflow ceilings the engine forces onto every spawned agent (design/98 §D.6), independent of * what the script asks for. The child's effective limits = min(script, baseline, these). */ export interface WorkflowChildCaps { perAgentTimeoutSec?: number; childMaxCostUsd?: number; childMaxTokens?: number; childMaxTurns?: number; } /** Resolve an LLM-supplied model NAME to a deploy-configured `Model`, FAIL-CLOSED against the allowlist. * Throws (never falls open to the whole catalog) when no allowlist is configured or the name is not on it. */ export declare function resolveModelName(name: string, allowlist: string[] | undefined, models: Record | undefined): Model; /** * Build a TRUSTED child `TaskSpec` for an LLM-authored sub-agent (design/98 §2.5). Complete-by-construction: * 1. read ONLY the whitelist work-fields off the untrusted script spec (type-checked); * 2. resolve `modelName` → a deploy `Model` against the allowlist (fail-closed); * 3. clamp resource limits to the baseline + workflow ceilings; * 4. `tightenTaskSpec(baseline.base, safe)` → the child spec (baseline governance FIRST, safe work-fields * overlay; safety fields can only equal-or-tighten — belt-and-suspenders over the whitelist). * Every governance/control-plane field of the result comes from `baseline.base` (the deployment's trusted * config), never from the script. */ export declare function buildGovernedChildSpec(scriptSpec: unknown, baseline: WorkflowGovernanceBaseline, models: Record | undefined, caps?: WorkflowChildCaps): TaskSpec; //# sourceMappingURL=workflow-governance.d.ts.map