@rulvar/core 1.51.0 → 1.52.0

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +1253 -1179
  2. package/dist/index.js +278 -11
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -2934,853 +2934,1287 @@ declare function validateEscalationReport(report: EscalationReport): Promise<Iss
2934
2934
  */
2935
2935
  declare function countsAgainstLimit(kind: EscalationKind): boolean;
2936
2936
  //#endregion
2937
- //#region src/runtime/no-progress.d.ts
2938
- /**
2939
- * The no-progress abort class (M3-T08): an engine-defined detector
2940
- * journaled as a first-class terminal abort distinct from user
2941
- * cancellation (a cancelled entry always reruns; a no-progress abort
2942
- * must replay, or every resume would re-pay the stuck turns). The
2943
- * interim heuristic is committed: N consecutive
2944
- * turns without tool calls or artifact deltas, N = 3; the broader
2945
- * heuristic stays OQ-15, revisited on dogfood traces.
2946
- *
2947
- * Encoding: the abort is the agent's
2948
- * terminal entry with status 'limit', an error payload carrying
2949
- * abortClass 'no-progress', and memoizeOutcome stamped by the ENGINE on
2950
- * the terminal entry, so the frozen memoize-limit rule replays it on
2951
- * every subsequent resume without a live rerun. In M3 the runtime has no
2952
- * per-turn artifact channel, so the tool-call test subsumes artifact
2953
- * deltas; per-turn artifact producers arrive with M4 compaction.
2954
- */
2955
- /** The committed no-progress detector N. */
2956
- declare const DEFAULT_NO_PROGRESS_TURNS = 3;
2957
- /**
2958
- * The consumer-visible engine-decided abort classes (FR-424).
2959
- * 'no-progress' is the detector below; 'output-truncated' is a
2960
- * schema-less turn that ended at its output token allowance
2961
- * (finish reason 'max-tokens') without visible output (v1.9.0
2962
- * follow-up review). Both stamp memoizeOutcome on the terminal:
2963
- * the work is paid, so every resume replays the abort instead of
2964
- * re-paying the same bounded failure.
2965
- */
2966
- type AbortClass = "no-progress" | "output-truncated";
2967
- /**
2968
- * Counts consecutive progress-free turns. A turn with at least one tool
2969
- * call (or, later, an artifact delta) resets the streak; a turn with
2970
- * neither lengthens it; the detector trips when the streak reaches the
2971
- * threshold AND the loop would otherwise continue.
2972
- */
2973
- declare class NoProgressDetector {
2974
- private streakInternal;
2975
- private readonly threshold;
2976
- constructor(threshold?: number);
2977
- get streak(): number;
2978
- /** Records one completed model turn. */
2979
- recordTurn(progress: {
2980
- toolCalls: number;
2981
- artifactDeltas?: number;
2982
- }): void;
2983
- get tripped(): boolean;
2984
- describe(): string;
2985
- }
2986
- //#endregion
2987
- //#region src/runtime/usage-limits.d.ts
2988
- interface UsageLimits {
2989
- /** Default 32. */
2990
- maxTurns?: number;
2991
- /** Unlimited by default. */
2992
- maxToolCalls?: number;
2993
- /** Unlimited by default (model caps still apply). */
2994
- maxOutputTokensPerTurn?: number;
2995
- /** Per-agent wall clock; unlimited by default. */
2996
- timeoutMs?: number;
2997
- /** Gap between stream events; default 120000. */
2998
- streamIdleTimeoutMs?: number;
2937
+ //#region src/l0/events.d.ts
2938
+ /** Run lifecycle and core telemetry (M1 subset). */
2939
+ type CoreEvents = {
2940
+ type: "run:start";
2941
+ workflow: string;
2942
+ resumed: boolean;
2943
+ } | {
2944
+ type: "run:end";
2945
+ status: "ok" | "error" | "cancelled" | "exhausted" | "suspended";
2946
+ totalUsd: number;
2999
2947
  /**
3000
- * The no-progress detector N (committed at 3):
3001
- * consecutive turns without tool calls or artifact deltas before the
3002
- * engine aborts with the dedicated class (M3-T08).
2948
+ * Present and true when any priced usage folded into totalUsd is
2949
+ * approximate (a transport cut, a stream the ceiling severed, or an
2950
+ * abort left a turn's usage estimated rather than reported by the
2951
+ * provider), so totalUsd is a lower bound estimate, never an exact
2952
+ * charge. Absent means every contributing turn reported exact usage.
3003
2953
  */
3004
- noProgressTurns?: number;
3005
- }
3006
- declare const DEFAULT_MAX_TURNS = 32;
3007
- declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 12e4;
3008
- interface EffectiveUsageLimits {
3009
- maxTurns: number;
3010
- maxToolCalls?: number;
3011
- maxOutputTokensPerTurn?: number;
3012
- timeoutMs?: number;
3013
- streamIdleTimeoutMs: number;
3014
- /** Default DEFAULT_NO_PROGRESS_TURNS. */
3015
- noProgressTurns?: number;
3016
- }
3017
- /**
3018
- * Limits merge per spawn: AgentOpts.limits over profile limits over engine
3019
- * defaults.limits.
3020
- */
3021
- declare function mergeUsageLimits(call?: UsageLimits, profile?: UsageLimits, engine?: UsageLimits): EffectiveUsageLimits;
2954
+ usageApprox?: boolean;
2955
+ } | {
2956
+ type: "phase:start";
2957
+ phase: string;
2958
+ } | {
2959
+ type: "log";
2960
+ level: "debug" | "info" | "warn" | "error";
2961
+ msg: string;
2962
+ data?: Json;
2963
+ } | {
2964
+ type: "budget:update";
2965
+ spentUsd: number;
2966
+ remainingUsd: number | null;
2967
+ committedReserveUsd: number;
2968
+ } | {
2969
+ type: "external:waiting";
2970
+ key: string;
2971
+ entryRef: number;
2972
+ prompt?: string;
2973
+ deadlineAt?: string;
2974
+ } | {
2975
+ type: "approval:pending";
2976
+ toolName: string;
2977
+ entryRef: number;
2978
+ deadlineAt?: string;
2979
+ } | {
2980
+ type: "child:start";
2981
+ workflow: string;
2982
+ scope: string;
2983
+ } | {
2984
+ type: "child:end";
2985
+ workflow: string;
2986
+ scope: string;
2987
+ status: string;
2988
+ };
3022
2989
  /**
3023
- * Validates one UsageLimits layer at its intake boundary (v1.34.0
3024
- * review P2-3): a malformed field (NaN, Infinity, a negative, a
3025
- * fraction) is a typed ConfigError before the merge, before any journal
3026
- * entry, and before any provider dispatch. `site` names the layer in the
3027
- * error text (e.g. `RunOptions.limits`). Counts are positive integers
3028
- * (maxToolCalls may be 0: a spawn that must not call tools).
3029
- * streamIdleTimeoutMs is handed to setTimeout as-is, so it is bounded by
3030
- * the Node timer maximum like RetryPolicy delays; timeoutMs is a
3031
- * wall-clock comparison, so it has no upper bound. Every present field
3032
- * is checked; absent fields keep their defaults.
2990
+ * The structured exploration summary (RV-210): the engine-side tool
2991
+ * exploration counters for one agent invocation. Attached to the full
2992
+ * AgentResult and to the live `agent:end` event whenever any exploration
2993
+ * guard limit is configured; journaled inside the terminal error payload
2994
+ * (and therefore restored on replay) only when the guard itself ended
2995
+ * the invocation (abortClass 'exploration').
3033
2996
  */
3034
- declare function validateUsageLimits(limits: UsageLimits, site: string): void;
3035
- //#endregion
3036
- //#region src/runtime/agent-loop.d.ts
3037
- type AgentStatus = "ok" | "error" | "limit" | "cancelled" | "skipped" | "escalated";
3038
- /** Artifact: the normative shape of AgentResult.artifacts entries. */
3039
- interface Artifact {
3040
- /** Stable within the result. */
3041
- id: string;
3042
- /** Closed in v1. */
3043
- kind: "file" | "patch" | "json" | "text";
3044
- /** Telemetry only. */
3045
- label?: string;
3046
- /** Changed-file list (kind 'patch': worktree collect()). */
3047
- files?: string[];
3048
- /** TranscriptStore blob ref for offloaded content. */
3049
- ref?: string;
3050
- /** Inline JSON content for small values. */
3051
- data?: Json;
3052
- }
3053
- /** The verdict of one mechanical acceptance gate evaluation. */
3054
- interface MechanicalGateVerdict {
3055
- pass: boolean;
3056
- detail?: string;
2997
+ interface ExplorationSummary {
2998
+ /** Tool executions dispatched by the loop (the loop's own counter). */
2999
+ toolCallsUsed: number;
3000
+ /** Distinct (tool name, canonical args) signatures executed. */
3001
+ distinctSignatures: number;
3002
+ /** Executions of a signature that had already executed before. */
3003
+ repeatedCalls: number;
3004
+ /** Successful executions whose result digest was already seen. */
3005
+ duplicateResultCalls: number;
3006
+ /** Calls denied by the repeated-signature guard (never dispatched). */
3007
+ deniedRepeats: number;
3008
+ /** Executions per tool name. */
3009
+ byTool: Record<string, number>;
3057
3010
  }
3058
3011
  /**
3059
- * A mechanical acceptance gate: an engine-registered NAMED pure function
3060
- * over AgentResult.artifacts.
3061
- * The registry is per engine like every other registry; the
3062
- * ladder driver journals each evaluation as a decision entry, so the
3063
- * ladder fold consumes only journaled verdicts, never live re-evaluation.
3012
+ * Agent lifecycle. One logical agent dispatch emits EXACTLY ONE
3013
+ * `agent:start`/`agent:end` pair on its span (the start carries the
3014
+ * primary role), and each model invocation phase inside the span
3015
+ * (`loop`, then possibly `summarize` activations, `finalize`,
3016
+ * `extract`) emits its own `agent:phase:start`/`agent:phase:end` pair,
3017
+ * so durations, per-phase usage, and attempts are derivable without
3018
+ * heuristics (the RV-207 event-model contract; before it, every phase
3019
+ * emitted an unpaired extra `agent:start` and consumers pairing starts
3020
+ * with the single end computed the LAST phase's duration as the
3021
+ * agent's). `reduceInvocationTable` is the official reducer over this
3022
+ * vocabulary.
3064
3023
  */
3065
- type MechanicalGateProfile = (artifacts: readonly Artifact[]) => MechanicalGateVerdict;
3066
- interface AgentResult<T> {
3067
- status: AgentStatus;
3068
- output: T | null;
3069
- usage: Usage;
3070
- costUsd: number;
3071
- turns: number;
3024
+ type AgentEvents = {
3025
+ type: "agent:queued";
3026
+ agentType: string;
3027
+ label?: string;
3028
+ } | {
3029
+ type: "agent:start";
3030
+ agentType: string;
3031
+ label?: string;
3032
+ model: string;
3033
+ role: string;
3034
+ } | {
3035
+ type: "agent:phase:start";
3036
+ agentType: string;
3037
+ label?: string; /** The invocation role this phase activation runs as. */
3038
+ role: string; /** The model the activation resolved to (fallbacks may serve another; the end event reports the server). */
3039
+ model: string;
3072
3040
  /**
3073
- * The model that actually served the loop phase at the end (M4-T04):
3074
- * differs from the requested spec only under transport failover.
3041
+ * 1-based activation ordinal within the span, unique per
3042
+ * activation (a summarize that fires three times gets three
3043
+ * pairs). Key phases by (spanId, invocation).
3075
3044
  */
3076
- servedBy: ModelRef;
3045
+ invocation: number;
3046
+ } | {
3047
+ type: "agent:phase:end";
3048
+ agentType: string;
3049
+ label?: string;
3050
+ role: string; /** The model that actually served the activation's last attempt. */
3051
+ model: string;
3052
+ invocation: number;
3077
3053
  /**
3078
- * Present only when the call spanned MORE THAN ONE (invocation role,
3079
- * serving model) pair (the loop, extract, finalize, and summarize
3080
- * roles resolve independently): usage split per (role, model), so
3081
- * `costUsd` and every cost bucket price each slice at its own rate
3082
- * and `CostReport.byRole` attributes each phase to its own bucket
3083
- * (v1.19.0 review P1-2). Absent for a single-phase single-model call,
3084
- * which (usage, servedBy) already describes exactly.
3054
+ * Wall-clock activation duration. Live telemetry only: replayed
3055
+ * phase pairs (reconstructed from the terminal entry's usage
3056
+ * slices) carry 0.
3085
3057
  */
3086
- usageByModel?: UsageSlice[];
3087
- transcriptRef: string;
3088
- artifacts?: Artifact[];
3089
- error?: AgentError;
3058
+ durationMs: number; /** The usage this activation added to its (role, model) slices. */
3059
+ usage: Usage; /** That usage priced at each serving model's own rate. */
3060
+ costUsd: number;
3061
+ outcome: "ok" | "error";
3090
3062
  /**
3091
- * Human-readable detail behind `error` (provider message, first schema
3092
- * issue): feeds the journaled WireError message. An additive
3093
- * field; never part of identity.
3063
+ * Transport retries inside this activation. Present only when
3064
+ * greater than zero; live telemetry only (absent on replay).
3094
3065
  */
3095
- errorMessage?: string;
3096
- /** Present if and only if status === 'escalated'. */
3097
- escalation?: EscalationReport;
3066
+ retries?: number;
3067
+ } | {
3068
+ type: "agent:end";
3069
+ agentType: string;
3070
+ label?: string;
3071
+ status: string;
3072
+ usage: Usage;
3073
+ costUsd: number;
3074
+ entryRef: number;
3098
3075
  /**
3099
- * Engine-internal: the accepted escalate request before the runtime
3100
- * fills costToDate and salvage into the full report. The ctx layer
3101
- * consumes and removes it; consumers read `escalation`.
3076
+ * Present and true when this agent's usage is approximate rather
3077
+ * than reported by the provider (the turn was cut by a transport
3078
+ * failure, a ceiling that severed the stream, or an abort). Absent
3079
+ * means the provider reported the usage exactly. Mirrors the
3080
+ * terminal journal entry's usageApprox.
3102
3081
  */
3103
- escalationRequest?: EscalationRequest;
3082
+ usageApprox?: boolean;
3104
3083
  /**
3105
- * The dedicated first-class abort class (M3-T08): present on the
3106
- * engine-decided no-progress abort (status 'limit'), never on user
3107
- * cancellation or ordinary cap hits.
3084
+ * Total transport retries across the span's activations. Present
3085
+ * only when greater than zero; live telemetry only, never
3086
+ * journaled, so a replayed agent:end omits it (absent means "zero
3087
+ * or unknown").
3108
3088
  */
3109
- abortClass?: AbortClass;
3089
+ retryCount?: number;
3110
3090
  /**
3111
- * Transport retries across the span's phase activations, present only
3112
- * when greater than zero. Live telemetry only: the ctx layer surfaces
3113
- * it as `agent:end` retryCount; it is never journaled, so a replayed
3114
- * result omits it (absent means "zero or unknown").
3091
+ * The exploration guard counters (RV-210). Present live whenever
3092
+ * any exploration guard limit was configured for the invocation;
3093
+ * on replay present only when the guard abort journaled it in the
3094
+ * terminal error payload.
3115
3095
  */
3116
- transportRetries?: number;
3117
- }
3118
- type EscalatedResult<T> = AgentResult<T> & {
3119
- status: "escalated";
3120
- escalation: EscalationReport;
3096
+ exploration?: ExplorationSummary;
3097
+ } | {
3098
+ type: "agent:error";
3099
+ agentType: string;
3100
+ label?: string;
3101
+ error: WireError;
3102
+ willRetry: boolean;
3103
+ } | {
3104
+ type: "agent:schema-retry";
3105
+ agentType: string;
3106
+ attempt: number;
3107
+ maxAttempts: number;
3108
+ } | {
3109
+ type: "agent:stream";
3110
+ delta: string;
3121
3111
  };
3122
- declare function isEscalated<T>(r: AgentResult<T>): r is EscalatedResult<T>;
3123
- /** Minimal internal event sink; the typed WorkflowEvent envelope wraps it in M1-T10. */
3124
- interface RuntimeEventSink {
3125
- emit(body: {
3126
- type: string;
3127
- } & Record<string, unknown>): void;
3128
- }
3129
- /** Budget hooks bound by the three-layer budget. */
3130
- interface BudgetHooks {
3131
- /** Layer 2: before every turn; throws BudgetExhaustedError to block dispatch. */
3132
- beforeTurn(): void;
3112
+ /** Tool lifecycle (emitters arrive with the tool system, M3). */
3113
+ type ToolEvents = {
3114
+ type: "tool:start";
3115
+ toolName: string;
3116
+ risk?: Json;
3117
+ } | {
3118
+ type: "tool:end";
3119
+ toolName: string;
3120
+ outcome: "ok" | "error" | "denied";
3121
+ durationMs: number;
3133
3122
  /**
3134
- * Layer 2b, the pre-dispatch output bound: the output tokens the
3135
- * remaining budget still affords from `servedBy` for a prompt of
3136
- * `estimatedInputTokens`. The dispatch clamps the request's
3137
- * maxOutputTokens to it and denies the turn entirely when not even one
3138
- * output token fits. Undefined = unbounded (no ceiling, no price row,
3139
- * or free output).
3123
+ * Audit fields (M5-T05): the chain verdict,
3124
+ * the deciding layer, the matched rule, and advisory domain-rule
3125
+ * matches. Telemetry, never identity; ask verdicts additionally
3126
+ * journal as suspended approvals.
3140
3127
  */
3141
- maxAffordableOutputTokens?: (servedBy: ModelRef, estimatedInputTokens: number) => number | undefined;
3142
- /** Live usage accounting; layer 3 may respond by aborting `signal`. */
3143
- onUsage(usage: Usage, servedBy: ModelRef): void;
3144
- /** Layer 3: the ceiling AbortSignal. */
3145
- signal?: AbortSignal;
3146
- }
3147
- /** Reason marker distinguishing a budget-ceiling abort from host cancellation. */
3148
- declare const BUDGET_ABORT_REASON = "rulvar:budget-ceiling";
3149
- /** One model-issued tool call as the loop dispatches it. */
3150
- interface ToolCallRequest {
3151
- id: string;
3152
- name: string;
3153
- args: unknown;
3154
- }
3155
- /**
3156
- * The ctx-side verdict for one dispatch, produced by the permission
3157
- * chain (M3-T03). For 'ask' the loop writes the turn checkpoint with the
3158
- * pending state FIRST, then suspend() journals the approval entry (or
3159
- * re-matches an existing one) and parks until a resolution closes it.
3160
- */
3161
- interface GateAudit {
3162
- verdict: "allow" | "deny" | "ask";
3163
- decidedBy: string;
3128
+ verdict?: "allow" | "deny" | "ask";
3129
+ decidedBy?: string;
3164
3130
  rule?: Json;
3165
3131
  advisory?: Json;
3166
- }
3167
- type PermissionGate = ({
3168
- kind: "allow";
3169
- input: unknown;
3170
- } | {
3171
- kind: "deny";
3172
- reason: string;
3173
- } | {
3174
- kind: "ask";
3175
- input: unknown;
3176
- suspend: () => Promise<{
3177
- decision: "allow" | "deny";
3178
- reason?: string;
3179
- }>;
3180
- }) & {
3181
- /** Chain audit payload ridden into tool:end telemetry. */audit?: GateAudit;
3132
+ /**
3133
+ * Present when an exploration guard (RV-210), not the permission
3134
+ * chain, denied the call: the outcome is 'denied' and the call was
3135
+ * never dispatched.
3136
+ */
3137
+ guard?: "repeated-signature";
3182
3138
  };
3183
3139
  /**
3184
- * The spawn's frozen toolset plus the per-call context factory, prepared
3185
- * by the ctx layer (M3-T01). The contracts are the canonical identity
3186
- * projection already hashed into the spawn's content key; the loop sends
3187
- * exactly them to the model.
3140
+ * Bare-nondeterminism detection (RV-209). Emitted LIVE by the segment
3141
+ * that observed the call, at most once per (category, provenance) per
3142
+ * execution segment; never journaled and never re-emitted with the
3143
+ * `replayed` flag. Because replay re-executes the workflow body, a
3144
+ * violation that survives in the code fires again on every replay of
3145
+ * the run, so the event appears organically in both live and replayed
3146
+ * streams. Exempt provenances (installed dependencies under
3147
+ * node_modules and Node runtime frames) never emit: they are
3148
+ * classified and silenced, which is what keeps an SDK's internal
3149
+ * `Math.random()` from branding the run nondeterministic.
3188
3150
  */
3189
- interface ToolRuntime {
3190
- defs: ToolDef[];
3191
- contracts: ToolContract[];
3192
- /** Mints a per-call ToolContext (fresh tool span under the agent span). */
3193
- contextFor(toolName: string): ToolContext;
3194
- /** Permission chain evaluation (M3-T03); absent = every call allowed. */
3195
- permission?: (call: ToolCallRequest) => Promise<PermissionGate>;
3196
- }
3197
- /** One serving target of a phase: the primary or a failover fallback. */
3198
- interface PhaseTarget {
3199
- adapter: ProviderAdapter;
3200
- resolved: ResolvedInvocation;
3201
- }
3202
- interface RunAgentOptions<S extends SchemaSpec = JsonSchema> {
3203
- prompt: string;
3204
- schema?: S;
3205
- /** Canonicalized JSON Schema projection of `schema` (precomputed for identity). */
3206
- canonicalSchema?: JsonSchema;
3207
- adapter: ProviderAdapter;
3208
- resolved: ResolvedInvocation;
3151
+ type DeterminismEvents = {
3152
+ type: "determinism:warning"; /** Which patched global fired. */
3153
+ category: "bare-date-now" | "bare-math-random";
3209
3154
  /**
3210
- * Transport failover chain for the loop phase (M4-T04):
3211
- * resolved fallback targets tried in order on
3212
- * transport or rate-limit failures after retries exhaust. Failover is
3213
- * sticky and changes only servedBy, never the content key.
3155
+ * 'workflow': the caller is workflow-origin code (the violation the
3156
+ * guard exists for; rejects the run under `determinism.mode:
3157
+ * 'error'`). 'allowlisted': the caller matched a configured
3158
+ * `determinism.allowlist` pattern and is exempt by explicit host
3159
+ * decision; emitted for visibility, never rejects.
3214
3160
  */
3215
- fallbacks?: PhaseTarget[];
3161
+ provenance: "workflow" | "allowlisted"; /** The calling stack frame, after the configured redaction hook. */
3162
+ frame: string; /** Parsed location when the frame carries one, after redaction. */
3163
+ file?: string;
3164
+ line?: number;
3165
+ column?: number;
3166
+ };
3167
+ /**
3168
+ * Adaptive orchestration, resolutions, and
3169
+ * accounting: emitted only by runs where the corresponding machinery is
3170
+ * active (applicability per mode:
3171
+ * https://docs.rulvar.com/guide/adaptive-orchestration). The types land as
3172
+ * one closed catalog with M7-T03; emitters arrive with their tasks.
3173
+ */
3174
+ type AdaptiveEvents = {
3175
+ type: "plan:revised";
3176
+ entryRef: number;
3177
+ planHash: string;
3178
+ applied: number;
3179
+ dropped: number;
3180
+ revisionUnitsRemaining: number;
3181
+ } | {
3182
+ type: "node:parked";
3183
+ nodeId: string;
3184
+ logicalTaskId: string;
3185
+ } | {
3186
+ type: "node:cancelled";
3187
+ nodeId: string;
3188
+ logicalTaskId: string;
3189
+ } | {
3190
+ type: "node:linked";
3191
+ nodeId: string;
3192
+ logicalTaskId: string;
3193
+ donorRef: number;
3194
+ reclaimedUsd: number;
3195
+ } | {
3196
+ type: "orchestrator:woke";
3197
+ digestSeq: number;
3198
+ planHash: string;
3199
+ coversToOrdinal: number;
3200
+ renderSize: number;
3201
+ } | {
3216
3202
  /**
3217
- * Transport RetryPolicy (M4-T05): lives UNDER
3218
- * the journal, wired around every adapter.stream dispatch. sleep and
3219
- * random are injectable for tests; the core owns wall-clock.
3203
+ * Two emitted shapes share the discriminant: the cap-freeze form
3204
+ * carries { atCap: true, spentUsd, capUsd, finalizeReserveUsd },
3205
+ * and the per-wake digest form carries atCap plus the passive
3206
+ * WakeBudgetBlock fields (runSpentUsd .. softWarning).
3220
3207
  */
3221
- retry?: {
3222
- policy?: RetryPolicy;
3223
- sleep?: (ms: number) => Promise<void>;
3224
- random?: () => number;
3225
- };
3208
+ type: "orchestrator:budget";
3209
+ atCap: boolean;
3210
+ spentUsd?: number;
3211
+ capUsd?: number;
3212
+ finalizeReserveUsd?: number;
3213
+ runSpentUsd?: number;
3214
+ runCeilingUsd?: number;
3215
+ orchestratorSpentUsd?: number;
3216
+ orchestratorCapUsd?: number;
3217
+ orchestratorShare?: number;
3218
+ softWarning?: boolean;
3219
+ } | {
3220
+ type: "escalation:raised";
3221
+ entryRef: number;
3222
+ kind: "scope_bigger" | "scope_different" | "blocked_with_evidence";
3223
+ logicalTaskId: string;
3224
+ costToDateUsd: number;
3225
+ } | {
3226
+ type: "escalation:decided";
3227
+ entryRef: number;
3228
+ decision: "retry" | "decompose" | "cancel" | "accept";
3229
+ by: ResolutionBy;
3230
+ countsAgainstLimit: boolean;
3231
+ } | {
3232
+ type: "spawn:admitted";
3233
+ entryRef: number; /** The admitting arms of the unified AdmitVerdict union. */
3234
+ verdict: "admit" | "reuse_full" | "admit_graft";
3235
+ agentType: string;
3236
+ logicalTaskId: string;
3226
3237
  /**
3227
- * Per-provider keyed limiter hook (M4-T07): wraps every wire dispatch
3228
- * under the serving adapter's key; absent = unlimited (Appendix A).
3229
- * `signal` is the agent-level abort: an aborted caller leaves the
3230
- * key's queue without a slot (v1.34.0 review P2-4).
3238
+ * Spawn-unit balance after the budget-layer debit. Present on
3239
+ * budget-layer admissions (the orchestrator spawn tools and
3240
+ * ctx.workflow children); absent on lineage-layer admissions
3241
+ * (ctx.agent roots), whose spawn-unit debit rides the dispatch
3242
+ * itself (v1.22.0 review P2-5).
3231
3243
  */
3232
- providerSlot?: <T>(key: string, fn: () => Promise<T>, signal?: AbortSignal) => Promise<T>;
3233
- /** The resolved toolset; absent = no tools declared. */
3234
- tools?: ToolRuntime;
3235
- /**
3236
- * Separate final extract invocation, present only when the role trigger
3237
- * protocol demands one: schema set AND (routing directs extract to a
3238
- * different model OR the loop model's caps cannot serve the required
3239
- * tier OR finalize is routed). Otherwise the schema rides the last loop
3240
- * turn (the necessity rule is
3241
- * decided by the ctx layer via model/roles.ts).
3244
+ spawnUnitsAfter?: number;
3245
+ } | {
3246
+ type: "spawn:rejected";
3247
+ /**
3248
+ * The journaled admission decision entry; absent for the
3249
+ * pre-admission config gates (orchestrate maxSpawns), which
3250
+ * reject before anything is journaled.
3242
3251
  */
3243
- extract?: PhaseTarget & {
3244
- fallbacks?: PhaseTarget[];
3245
- };
3252
+ entryRef?: number;
3253
+ code: string;
3254
+ agentType: string;
3255
+ logicalTaskId?: string;
3256
+ } | {
3257
+ type: "verify:failed";
3258
+ entryRef: number;
3259
+ logicalTaskId: string;
3260
+ rung: number;
3261
+ gate: "mechanical" | "judge" | "spot-check";
3262
+ } | {
3263
+ type: "ledger:op";
3264
+ entryRef: number;
3265
+ op: "brief_set" | "fact_add" | "fact_supersede" | "lesson_add" | "observation_add";
3266
+ } | {
3267
+ type: "stall:detected";
3268
+ logicalTaskId: string;
3269
+ stallStreak: number;
3270
+ } | {
3271
+ type: "guard:oscillation";
3272
+ spawnKeyHash: string;
3273
+ oscillationCount: number;
3274
+ limit: number;
3275
+ } | {
3276
+ type: "resolution:applied";
3277
+ targetRef: number;
3278
+ entryRef: number;
3279
+ by: ResolutionBy;
3280
+ } | {
3281
+ type: "resolution:superseded";
3282
+ targetRef: number;
3283
+ entryRef: number;
3284
+ supersededBy: number;
3285
+ reason: "already_resolved" | "target_abandoned";
3286
+ } | {
3287
+ type: "termination:debit";
3288
+ entryRef: number;
3289
+ counter: string;
3290
+ remaining: number;
3291
+ phi: number;
3292
+ } | {
3293
+ type: "termination:denied";
3294
+ entryRef: number;
3295
+ counter: string;
3296
+ code: string;
3297
+ } | {
3298
+ type: "termination:config-drift";
3299
+ field: string;
3300
+ frozenValue: Json;
3301
+ liveValue: Json;
3302
+ } | {
3246
3303
  /**
3247
- * Finalize synthesis invocation (M4-T01), present only when the role
3248
- * trigger protocol fires it: configured in routing AND the toolset is
3249
- * non-empty. Runs after tools stop with toolChoice 'none' over the
3250
- * full transcript plus a deterministic synthesis instruction appended
3251
- * to the REQUEST only (the durable transcript keeps the raw history);
3252
- * its text becomes the output for schema-less calls, a non-truncated
3253
- * empty synthesis falls back to the loop turn's text, and a
3254
- * schema-bearing call always pairs it with a separate extract
3255
- * (the ctx layer guarantees `extract` is present in that case). Like
3256
- * extract, the finalize invocation is not checkpointed in v1.
3304
+ * Declared for hosts; not emitted today. The compatibility scan
3305
+ * runs strictly before a run's event stream exists, so the
3306
+ * refusal travels only as the typed JournalCompatibilityError
3307
+ * (which carries the same fields).
3257
3308
  */
3258
- finalize?: PhaseTarget & {
3259
- fallbacks?: PhaseTarget[];
3260
- };
3309
+ type: "journal:compat";
3310
+ code: "HASH_VERSION_TOO_OLD" | "HASH_VERSION_TOO_NEW";
3311
+ found: number;
3312
+ window: [number, number];
3313
+ };
3314
+ type WorkflowEventBody = CoreEvents | AgentEvents | ToolEvents | DeterminismEvents | AdaptiveEvents;
3315
+ /**
3316
+ * The envelope: seq is an independent per-run
3317
+ * telemetry counter, strictly increasing in emission order and DISTINCT
3318
+ * from JournalEntry.seq (never compare or join the two; entryRef fields
3319
+ * carry journal seqs explicitly). ts is wall clock, telemetry only.
3320
+ * replayed is true only on re-emitted journal-backed lifecycle events;
3321
+ * stream deltas are never re-emitted.
3322
+ */
3323
+ type WorkflowEvent = {
3324
+ runId: string;
3325
+ seq: number;
3326
+ ts: string;
3327
+ spanId: string;
3328
+ parentSpanId?: string;
3329
+ replayed?: boolean;
3330
+ } & WorkflowEventBody;
3331
+ //#endregion
3332
+ //#region src/runtime/no-progress.d.ts
3333
+ /**
3334
+ * The no-progress abort class (M3-T08): an engine-defined detector
3335
+ * journaled as a first-class terminal abort distinct from user
3336
+ * cancellation (a cancelled entry always reruns; a no-progress abort
3337
+ * must replay, or every resume would re-pay the stuck turns). The
3338
+ * interim heuristic is committed: N consecutive
3339
+ * turns without tool calls or artifact deltas, N = 3; the broader
3340
+ * heuristic stays OQ-15, revisited on dogfood traces.
3341
+ *
3342
+ * Encoding: the abort is the agent's
3343
+ * terminal entry with status 'limit', an error payload carrying
3344
+ * abortClass 'no-progress', and memoizeOutcome stamped by the ENGINE on
3345
+ * the terminal entry, so the frozen memoize-limit rule replays it on
3346
+ * every subsequent resume without a live rerun. In M3 the runtime has no
3347
+ * per-turn artifact channel, so the tool-call test subsumes artifact
3348
+ * deltas; per-turn artifact producers arrive with M4 compaction.
3349
+ */
3350
+ /** The committed no-progress detector N. */
3351
+ declare const DEFAULT_NO_PROGRESS_TURNS = 3;
3352
+ /**
3353
+ * The consumer-visible engine-decided abort classes (FR-424).
3354
+ * 'no-progress' is the detector below; 'output-truncated' is a
3355
+ * schema-less turn that ended at its output token allowance
3356
+ * (finish reason 'max-tokens') without visible output (v1.9.0
3357
+ * follow-up review); 'exploration' is the tripped no-new-evidence
3358
+ * exploration guard (RV-210), carrying its structured summary in the
3359
+ * terminal error payload. All stamp memoizeOutcome on the terminal:
3360
+ * the work is paid, so every resume replays the abort instead of
3361
+ * re-paying the same bounded failure.
3362
+ */
3363
+ type AbortClass = "no-progress" | "output-truncated" | "exploration";
3364
+ /**
3365
+ * Counts consecutive progress-free turns. A turn with at least one tool
3366
+ * call (or, later, an artifact delta) resets the streak; a turn with
3367
+ * neither lengthens it; the detector trips when the streak reaches the
3368
+ * threshold AND the loop would otherwise continue.
3369
+ */
3370
+ declare class NoProgressDetector {
3371
+ private streakInternal;
3372
+ private readonly threshold;
3373
+ constructor(threshold?: number);
3374
+ get streak(): number;
3375
+ /** Records one completed model turn. */
3376
+ recordTurn(progress: {
3377
+ toolCalls: number;
3378
+ artifactDeltas?: number;
3379
+ }): void;
3380
+ get tripped(): boolean;
3381
+ describe(): string;
3382
+ }
3383
+ //#endregion
3384
+ //#region src/runtime/usage-limits.d.ts
3385
+ interface UsageLimits {
3386
+ /** Default 32. */
3387
+ maxTurns?: number;
3388
+ /** Unlimited by default. */
3389
+ maxToolCalls?: number;
3390
+ /** Unlimited by default (model caps still apply). */
3391
+ maxOutputTokensPerTurn?: number;
3392
+ /** Per-agent wall clock; unlimited by default. */
3393
+ timeoutMs?: number;
3394
+ /** Gap between stream events; default 120000. */
3395
+ streamIdleTimeoutMs?: number;
3261
3396
  /**
3262
- * Summarize invocation target for compaction (M4-T03): resolved
3263
- * through the chain with role 'summarize', falling back to the loop
3264
- * model when routing resolves nothing. Compaction
3265
- * is ON by default; absence of this option disables it (direct
3266
- * runAgent callers).
3397
+ * The no-progress detector N (committed at 3):
3398
+ * consecutive turns without tool calls or artifact deltas before the
3399
+ * engine aborts with the dedicated class (M3-T08).
3267
3400
  */
3268
- summarize?: PhaseTarget & {
3269
- fallbacks?: PhaseTarget[];
3270
- };
3271
- /** Per-profile compaction config; threshold default 0.8 (Appendix A). */
3272
- compaction?: {
3273
- threshold?: number;
3274
- };
3401
+ noProgressTurns?: number;
3275
3402
  /**
3276
- * Turn-boundary checkpointing (M3-T02).
3277
- * load() restores the last boundary on a dangling-dispatch resume;
3278
- * save() persists each boundary where the loop continues. The separate
3279
- * extract invocation is not checkpointed in v1: an extract-phase crash
3280
- * re-pays from the last loop boundary.
3403
+ * Soft 50%/80% thresholds over maxToolCalls (RV-210), surfaced to the
3404
+ * model as a plain user message carrying the exact remaining count.
3405
+ * Inert (with a loud log warning) when maxToolCalls is not set. Off by
3406
+ * default: the notice enters the conversation, so enabling it changes
3407
+ * recorded model requests.
3281
3408
  */
3282
- checkpoint?: {
3283
- load(): Promise<CheckpointState | undefined>;
3284
- save(state: CheckpointState): Promise<void>;
3285
- };
3286
- limits: EffectiveUsageLimits;
3287
- /** Emits agent:stream deltas when true (telemetry only). */
3288
- stream?: boolean;
3289
- /** Host or sibling cancellation. */
3290
- signal?: AbortSignal;
3291
- budget?: BudgetHooks;
3292
- events?: RuntimeEventSink;
3293
- transcript?: {
3294
- mintRef(): string;
3295
- put(ref: string, blob: Uint8Array): Promise<void>;
3296
- };
3297
- priceUsd?: (servedBy: ModelRef, usage: Usage) => number | undefined;
3298
- /** Bounded schema re-prompt attempts; default 2 (Appendix A). */
3299
- schemaRetryAttempts?: number;
3300
- /** Bounded ModelRetry conversions per tool call chain; default 2 (Appendix A). */
3301
- modelRetryAttempts?: number;
3409
+ toolBudgetNotices?: boolean;
3302
3410
  /**
3303
- * Escalation opt-in (M3-T07): the loop intercepts accepted calls to
3304
- * the escalate tool and terminates with status 'escalated'; the
3305
- * in-run minSpend gate rejects early scope_bigger escalations with a
3306
- * "keep working" error tool result (M3-T09).
3411
+ * How many times the SAME tool signature (name + canonical JCS args)
3412
+ * may execute per invocation (RV-210). The call that would exceed it
3413
+ * is denied with a typed error tool result instead of dispatched; the
3414
+ * denial is visible to the model and does not consume maxToolCalls.
3415
+ * Unlimited by default.
3307
3416
  */
3308
- escalation?: {
3309
- minSpendUsd: number;
3310
- };
3417
+ maxRepeatedToolSignature?: number;
3311
3418
  /**
3312
- * Terminal-tool interception (M6-T07): an accepted call to the named
3313
- * tool ends the loop with status ok; the call's validated `result`
3314
- * argument becomes the agent output (the orchestrator finish
3315
- * tool). The tool's execute never runs, mirroring escalate.
3316
- * `validate` is the optional host judgment over a schema valid call
3317
- * (the RV-204 finish validators): ok finishes as before; a rejection
3318
- * becomes the call's error tool result and the turn continues, so the
3319
- * model can repair and call the terminal tool again. The hook owns
3320
- * bounding and journaling; the loop stays policy only and never
3321
- * throws.
3419
+ * How many consecutive successful tool executions may return only
3420
+ * already-seen result digests before the engine aborts the invocation
3421
+ * as status 'limit' with abortClass 'exploration' (RV-210). The
3422
+ * executed work is kept and the terminal memoizes. Unlimited by
3423
+ * default.
3322
3424
  */
3323
- terminalTool?: {
3324
- name: string;
3325
- validate?: (call: {
3326
- id: string;
3327
- result: unknown;
3328
- }) => Promise<{
3329
- ok: true;
3330
- } | {
3331
- ok: false;
3332
- feedback: Record<string, unknown>;
3333
- }>;
3334
- };
3335
- agentType?: string;
3336
- /** The primary invocation role of the tool loop; default 'loop' (M6-T05). */
3337
- role?: "loop" | "plan" | "orchestrate";
3338
- label?: string;
3339
- now?: () => number;
3425
+ maxNoNewEvidenceCalls?: number;
3426
+ }
3427
+ declare const DEFAULT_MAX_TURNS = 32;
3428
+ declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 12e4;
3429
+ interface EffectiveUsageLimits {
3430
+ maxTurns: number;
3431
+ maxToolCalls?: number;
3432
+ maxOutputTokensPerTurn?: number;
3433
+ timeoutMs?: number;
3434
+ streamIdleTimeoutMs: number;
3435
+ /** Default DEFAULT_NO_PROGRESS_TURNS. */
3436
+ noProgressTurns?: number;
3437
+ /** RV-210 exploration guards; absent = off. */
3438
+ toolBudgetNotices?: boolean;
3439
+ maxRepeatedToolSignature?: number;
3440
+ maxNoNewEvidenceCalls?: number;
3340
3441
  }
3341
3442
  /**
3342
- * The output-truncation abort message (v1.9.0 follow-up review). The
3343
- * constraint is named neutrally as the turn's output token allowance:
3344
- * the effective request cap can come from limits.maxOutputTokensPerTurn,
3345
- * the budget clamp above, or the adapter's own default, and the provider
3346
- * can also cut at its model maximum with no request cap at all.
3347
- */
3348
- /**
3349
- * The deterministic synthesis instruction appended (as a user message)
3350
- * to the finalize REQUEST only, never to the durable transcript. A
3351
- * transcript that simply ends at an assistant message reads to a real
3352
- * model as a fresh conversation opening, so an uninstructed synthesis
3353
- * call can replace the loop's correct answer with a greeting (v1.18.0
3354
- * review P1-1); the extract arm has carried its own instruction since
3355
- * M4, and this is its finalize twin. The wording is part of the wire
3356
- * request: keep it stable.
3443
+ * Limits merge per spawn: AgentOpts.limits over profile limits over engine
3444
+ * defaults.limits.
3357
3445
  */
3358
- declare const FINALIZE_SYNTHESIS_INSTRUCTION: string;
3446
+ declare function mergeUsageLimits(call?: UsageLimits, profile?: UsageLimits, engine?: UsageLimits): EffectiveUsageLimits;
3359
3447
  /**
3360
- * Runs one agent to a typed AgentResult. Never throws past policy: every
3361
- * failure mode becomes a typed status on the result.
3448
+ * Validates one UsageLimits layer at its intake boundary (v1.34.0
3449
+ * review P2-3): a malformed field (NaN, Infinity, a negative, a
3450
+ * fraction) is a typed ConfigError before the merge, before any journal
3451
+ * entry, and before any provider dispatch. `site` names the layer in the
3452
+ * error text (e.g. `RunOptions.limits`). Counts are positive integers
3453
+ * (maxToolCalls may be 0: a spawn that must not call tools).
3454
+ * streamIdleTimeoutMs is handed to setTimeout as-is, so it is bounded by
3455
+ * the Node timer maximum like RetryPolicy delays; timeoutMs is a
3456
+ * wall-clock comparison, so it has no upper bound. Every present field
3457
+ * is checked; absent fields keep their defaults.
3362
3458
  */
3363
- declare function runAgent<S extends SchemaSpec>(options: RunAgentOptions<S>): Promise<AgentResult<Out<S>>>;
3459
+ declare function validateUsageLimits(limits: UsageLimits, site: string): void;
3364
3460
  //#endregion
3365
- //#region src/runtime/permission-chain.d.ts
3366
- type HookVerdict = "allow" | "deny" | "ask" | {
3367
- modifiedInput: unknown;
3368
- } | undefined;
3369
- type PermissionHook = (toolName: string, input: unknown, ctx: ToolContext) => HookVerdict | Promise<HookVerdict>;
3461
+ //#region src/runtime/agent-loop.d.ts
3462
+ type AgentStatus = "ok" | "error" | "limit" | "cancelled" | "skipped" | "escalated";
3463
+ /** Artifact: the normative shape of AgentResult.artifacts entries. */
3464
+ interface Artifact {
3465
+ /** Stable within the result. */
3466
+ id: string;
3467
+ /** Closed in v1. */
3468
+ kind: "file" | "patch" | "json" | "text";
3469
+ /** Telemetry only. */
3470
+ label?: string;
3471
+ /** Changed-file list (kind 'patch': worktree collect()). */
3472
+ files?: string[];
3473
+ /** TranscriptStore blob ref for offloaded content. */
3474
+ ref?: string;
3475
+ /** Inline JSON content for small values. */
3476
+ data?: Json;
3477
+ }
3478
+ /** The verdict of one mechanical acceptance gate evaluation. */
3479
+ interface MechanicalGateVerdict {
3480
+ pass: boolean;
3481
+ detail?: string;
3482
+ }
3370
3483
  /**
3371
- * Declarative rule tables (no closures). `'undeclared'` in risk
3372
- * position matches every tool WITHOUT declared risk: presets treat the
3373
- * undeclared state conservatively. Argv rules
3374
- * match through the real shell matcher; domain rules are
3375
- * ADVISORY for every tool in the current release: they never
3376
- * change a verdict, and matches surface in the tool:end audit
3377
- * fields (enforcement will live in a first-party fetch tool
3378
- * when one ships).
3484
+ * A mechanical acceptance gate: an engine-registered NAMED pure function
3485
+ * over AgentResult.artifacts.
3486
+ * The registry is per engine like every other registry; the
3487
+ * ladder driver journals each evaluation as a decision entry, so the
3488
+ * ladder fold consumes only journaled verdicts, never live re-evaluation.
3379
3489
  */
3380
- type RiskRuleValue = ToolRisk | "undeclared";
3381
- type PermissionRule = {
3382
- tool: string | string[];
3383
- } | {
3384
- risk: RiskRuleValue | RiskRuleValue[];
3385
- } | {
3386
- tool: string;
3387
- argv: string | string[];
3388
- } | {
3389
- tool: string;
3390
- domains: string[];
3490
+ type MechanicalGateProfile = (artifacts: readonly Artifact[]) => MechanicalGateVerdict;
3491
+ interface AgentResult<T> {
3492
+ status: AgentStatus;
3493
+ output: T | null;
3494
+ usage: Usage;
3495
+ costUsd: number;
3496
+ turns: number;
3497
+ /**
3498
+ * The model that actually served the loop phase at the end (M4-T04):
3499
+ * differs from the requested spec only under transport failover.
3500
+ */
3501
+ servedBy: ModelRef;
3502
+ /**
3503
+ * Present only when the call spanned MORE THAN ONE (invocation role,
3504
+ * serving model) pair (the loop, extract, finalize, and summarize
3505
+ * roles resolve independently): usage split per (role, model), so
3506
+ * `costUsd` and every cost bucket price each slice at its own rate
3507
+ * and `CostReport.byRole` attributes each phase to its own bucket
3508
+ * (v1.19.0 review P1-2). Absent for a single-phase single-model call,
3509
+ * which (usage, servedBy) already describes exactly.
3510
+ */
3511
+ usageByModel?: UsageSlice[];
3512
+ transcriptRef: string;
3513
+ artifacts?: Artifact[];
3514
+ error?: AgentError;
3515
+ /**
3516
+ * Human-readable detail behind `error` (provider message, first schema
3517
+ * issue): feeds the journaled WireError message. An additive
3518
+ * field; never part of identity.
3519
+ */
3520
+ errorMessage?: string;
3521
+ /** Present if and only if status === 'escalated'. */
3522
+ escalation?: EscalationReport;
3523
+ /**
3524
+ * Engine-internal: the accepted escalate request before the runtime
3525
+ * fills costToDate and salvage into the full report. The ctx layer
3526
+ * consumes and removes it; consumers read `escalation`.
3527
+ */
3528
+ escalationRequest?: EscalationRequest;
3529
+ /**
3530
+ * The dedicated first-class abort class (M3-T08): present on the
3531
+ * engine-decided no-progress abort (status 'limit'), never on user
3532
+ * cancellation or ordinary cap hits.
3533
+ */
3534
+ abortClass?: AbortClass;
3535
+ /**
3536
+ * Transport retries across the span's phase activations, present only
3537
+ * when greater than zero. Live telemetry only: the ctx layer surfaces
3538
+ * it as `agent:end` retryCount; it is never journaled, so a replayed
3539
+ * result omits it (absent means "zero or unknown").
3540
+ */
3541
+ transportRetries?: number;
3542
+ /**
3543
+ * The exploration guard counters (RV-210): present whenever any of
3544
+ * the exploration limits (toolBudgetNotices, maxRepeatedToolSignature,
3545
+ * maxNoNewEvidenceCalls) was configured. Journaled inside the terminal
3546
+ * error payload (and restored on replay) only for the guard's own
3547
+ * abort (abortClass 'exploration'); otherwise live telemetry like
3548
+ * transportRetries.
3549
+ */
3550
+ exploration?: ExplorationSummary;
3551
+ }
3552
+ type EscalatedResult<T> = AgentResult<T> & {
3553
+ status: "escalated";
3554
+ escalation: EscalationReport;
3391
3555
  };
3392
- type CanUseTool = (toolName: string, input: unknown, ctx: ToolContext) => "allow" | "deny" | {
3393
- modifiedInput: unknown;
3394
- } | Promise<"allow" | "deny" | {
3395
- modifiedInput: unknown;
3396
- }>;
3397
- /** Host-side permission configuration (engine defaults.permissions). */
3398
- interface PermissionConfig {
3399
- hooks?: PermissionHook[];
3400
- deny?: PermissionRule[];
3401
- ask?: PermissionRule[];
3402
- canUseTool?: CanUseTool;
3556
+ declare function isEscalated<T>(r: AgentResult<T>): r is EscalatedResult<T>;
3557
+ /** Minimal internal event sink; the typed WorkflowEvent envelope wraps it in M1-T10. */
3558
+ interface RuntimeEventSink {
3559
+ emit(body: {
3560
+ type: string;
3561
+ } & Record<string, unknown>): void;
3562
+ }
3563
+ /** Budget hooks bound by the three-layer budget. */
3564
+ interface BudgetHooks {
3565
+ /** Layer 2: before every turn; throws BudgetExhaustedError to block dispatch. */
3566
+ beforeTurn(): void;
3567
+ /**
3568
+ * Layer 2b, the pre-dispatch output bound: the output tokens the
3569
+ * remaining budget still affords from `servedBy` for a prompt of
3570
+ * `estimatedInputTokens`. The dispatch clamps the request's
3571
+ * maxOutputTokens to it and denies the turn entirely when not even one
3572
+ * output token fits. Undefined = unbounded (no ceiling, no price row,
3573
+ * or free output).
3574
+ */
3575
+ maxAffordableOutputTokens?: (servedBy: ModelRef, estimatedInputTokens: number) => number | undefined;
3576
+ /** Live usage accounting; layer 3 may respond by aborting `signal`. */
3577
+ onUsage(usage: Usage, servedBy: ModelRef): void;
3578
+ /** Layer 3: the ceiling AbortSignal. */
3579
+ signal?: AbortSignal;
3580
+ }
3581
+ /** Reason marker distinguishing a budget-ceiling abort from host cancellation. */
3582
+ declare const BUDGET_ABORT_REASON = "rulvar:budget-ceiling";
3583
+ /** One model-issued tool call as the loop dispatches it. */
3584
+ interface ToolCallRequest {
3585
+ id: string;
3586
+ name: string;
3587
+ args: unknown;
3403
3588
  }
3404
3589
  /**
3405
- * Profile-level permissions.
3406
- * inheritPermissions governs SUBAGENT inheritance (mode c orchestrators,
3407
- * M6+): children get their own config only unless explicitly opted in.
3408
- * It is carried as data here and consumed by the spawning layers.
3590
+ * The ctx-side verdict for one dispatch, produced by the permission
3591
+ * chain (M3-T03). For 'ask' the loop writes the turn checkpoint with the
3592
+ * pending state FIRST, then suspend() journals the approval entry (or
3593
+ * re-matches an existing one) and parks until a resolution closes it.
3409
3594
  */
3410
- interface AgentProfilePermissions extends PermissionConfig {
3411
- /** Compiles into deny/ask rules; ships in M5. */
3412
- preset?: "strict" | "standard" | "open";
3413
- /** Default false. */
3414
- inheritPermissions?: boolean;
3415
- }
3416
- interface CompiledPermissionChain {
3417
- hooks: PermissionHook[];
3418
- deny: PermissionRule[];
3419
- ask: PermissionRule[];
3420
- canUseTool?: CanUseTool;
3595
+ interface GateAudit {
3596
+ verdict: "allow" | "deny" | "ask";
3597
+ decidedBy: string;
3598
+ rule?: Json;
3599
+ advisory?: Json;
3421
3600
  }
3422
- type PermissionVerdict = ({
3423
- verdict: "allow";
3424
- decidedBy: "hook" | "canUseTool" | "default";
3601
+ type PermissionGate = ({
3602
+ kind: "allow";
3425
3603
  input: unknown;
3426
3604
  } | {
3427
- verdict: "deny";
3428
- decidedBy: "hook" | "deny-rule" | "canUseTool";
3429
- rule?: PermissionRule;
3430
- input: unknown;
3605
+ kind: "deny";
3606
+ reason: string;
3431
3607
  } | {
3432
- verdict: "ask";
3433
- decidedBy: "hook" | "ask-rule" | "default";
3434
- rule?: PermissionRule;
3608
+ kind: "ask";
3435
3609
  input: unknown;
3610
+ suspend: () => Promise<{
3611
+ decision: "allow" | "deny";
3612
+ reason?: string;
3613
+ }>;
3436
3614
  }) & {
3437
- /**
3438
- * Advisory domain-rule matches: reported in the tool:end
3439
- * audit fields, never enforced in the current release.
3440
- */
3441
- advisory?: PermissionRule[];
3615
+ /** Chain audit payload ridden into tool:end telemetry. */audit?: GateAudit;
3442
3616
  };
3443
3617
  /**
3444
- * Merges the engine-wide config and the profile config into one chain.
3445
- * Layers concatenate engine-first; since rules only deny or ask, ordering
3446
- * within a layer cannot change the verdict. The
3447
- * profile's canUseTool wins over the engine's (a single slot by
3448
- * construction). A declared preset compiles INTO the same layers, after
3449
- * the host-authored rules, never as a fifth layer (M5-T05).
3450
- */
3451
- declare function compilePermissionChain(engine?: PermissionConfig, profile?: AgentProfilePermissions): CompiledPermissionChain;
3452
- /**
3453
- * Evaluates the chain for one dispatch, or OFFLINE against a
3454
- * hypothetical call by tool name (the dry-run API: nothing executes;
3455
- * shells and tests read the verdict, the
3456
- * deciding layer, and the matched rule). Hooks run in deterministic
3457
- * registration order; { modifiedInput } substitutes the input and
3458
- * continues; the first decisive verdict wins. The returned input is what
3459
- * execute receives and what the approval identity hashes (post hook
3460
- * modification). Advisory domain-rule matches
3461
- * ride every verdict for the audit payload.
3618
+ * The spawn's frozen toolset plus the per-call context factory, prepared
3619
+ * by the ctx layer (M3-T01). The contracts are the canonical identity
3620
+ * projection already hashed into the spawn's content key; the loop sends
3621
+ * exactly them to the model.
3462
3622
  */
3463
- declare function evaluatePermission(chain: CompiledPermissionChain, tool: string | Pick<ToolDef, "name" | "needsApproval" | "risk">, input: unknown, ctx?: ToolContext): Promise<PermissionVerdict>;
3464
- //#endregion
3465
- //#region src/tools/toolset-hash.d.ts
3466
- /** The per-spawn tools option value domain. */
3467
- type ToolsOption = ReadonlyArray<ToolDef | ToolSource | string>;
3468
- /** The spawn's frozen toolset snapshot plus its identity hash. */
3469
- interface ResolvedToolset {
3470
- tools: ToolDef[];
3623
+ interface ToolRuntime {
3624
+ defs: ToolDef[];
3471
3625
  contracts: ToolContract[];
3472
- hash: string;
3473
- }
3474
- /** The empty toolset (no tools declared anywhere). */
3475
- declare function emptyToolset(): ResolvedToolset;
3476
- /**
3477
- * Expands registered names and sources, validates every tool name and
3478
- * duplicate names across the whole toolset (ConfigError at spawn time),
3479
- * and computes the toolsetHash over contracts sorted by name. The
3480
- * `toolsets` registry is the engine's `defaults.toolsets` snapshot;
3481
- * without one, string entries fail with the same unknown-name error as
3482
- * a miss, so nothing outside the declared registry is ever reachable.
3483
- */
3484
- declare function resolveToolset(specs: ToolsOption | undefined, session: ToolSourceSession, toolsets?: Record<string, ToolsOption>): Promise<ResolvedToolset>;
3485
- //#endregion
3486
- //#region src/journal/termination.d.ts
3487
- /** The frozen limits vector written into termination.init. */
3488
- interface TerminationLimits {
3489
- /** V0, default 32; absolute and non-replenishable. */
3490
- maxRevisionsPerRun: number;
3491
- /** S0, default 128; debited on every admitted spawn of any origin. */
3492
- maxTotalSpawns: number;
3493
- /** E0, default 2, per lineage; the old name is rejected (XF-10). */
3494
- maxEscalationsPerLogicalTask: number;
3495
- /** D0, default 1, ceiling 4; static per-branch limit. */
3496
- maxDepth: number;
3497
- /** Maximum declared ladder length per the profile-registry snapshot. */
3498
- kMax: number;
3499
- /** B0; immutable after start, no API including HITL can top up. */
3500
- runBudgetUsdCeiling: number;
3501
- /**
3502
- * The resolved orchestrator cap in absolute USD (DEF-7; XF-09),
3503
- * frozen with the counters. Journals recorded before v1.8 store 0
3504
- * ("not yet resolved"); for them the orchestrator_budget_reserve
3505
- * decision is the authority and is recovered on resume.
3506
- */
3507
- orchestratorCapUsd: number;
3508
- /** The finalize reserve carved out of the cap; 0 in pre-v1.8 journals. */
3509
- finalizeReserveUsd: number;
3510
- }
3511
- /** Appendix A committed defaults for the countable resources. */
3512
- declare const DEFAULT_MAX_REVISIONS_PER_RUN = 32;
3513
- declare const DEFAULT_MAX_TOTAL_SPAWNS = 128;
3514
- /** The countable resource vocabulary. */
3515
- type TerminationResource = "revisionUnits" | "spawnUnits" | "escalationUnits" | "rungs" | "depth";
3516
- interface LineageCounters {
3517
- escalationUnitsRemaining: number;
3518
- rungsRemaining: number;
3519
- }
3520
- interface TerminationAccountSnapshot {
3521
- revisionUnitsRemaining: number;
3522
- spawnUnitsRemaining: number;
3523
- perLineage: Record<LogicalTaskId, LineageCounters>;
3524
- /** The variant function, a pure fold over the journal. */
3525
- phi: number;
3526
- }
3527
- type DebitResult = {
3528
- ok: true;
3529
- balanceAfter: number;
3530
- } | {
3531
- ok: false;
3532
- deniedEntryRef: EntryRef;
3533
- resource: TerminationResource;
3534
- };
3535
- /** The value payload of a termination.init entry. */
3536
- interface TerminationInitValue {
3537
- limits: TerminationLimits;
3538
- profileRegistrySnapshotHash: string;
3539
- phiInitial: number;
3626
+ /** Mints a per-call ToolContext (fresh tool span under the agent span). */
3627
+ contextFor(toolName: string): ToolContext;
3628
+ /** Permission chain evaluation (M3-T03); absent = every call allowed. */
3629
+ permission?: (call: ToolCallRequest) => Promise<PermissionGate>;
3540
3630
  }
3541
- /** The value payload of a termination.denied entry. */
3542
- interface TerminationDeniedValue {
3543
- resource: TerminationResource;
3544
- logicalTaskId?: LogicalTaskId;
3545
- /** Seq of the calling tool-call or EscalationReport entry. */
3546
- requestedByRef?: EntryRef;
3547
- reasonCode: string;
3548
- snapshotAfter: TerminationAccountSnapshot;
3631
+ /** One serving target of a phase: the primary or a failover fallback. */
3632
+ interface PhaseTarget {
3633
+ adapter: ProviderAdapter;
3634
+ resolved: ResolvedInvocation;
3549
3635
  }
3550
- /**
3551
- * Reads the declared ladder length of one agent profile. Ladders are
3552
- * declared through the profile's ModelSpec (`model: { ladder }`, or the
3553
- * loop-role routing entry). The reader is defensive
3554
- * so the snapshot is total over every registry shape (an undeclared
3555
- * ladder has length 1: the single implicit rung).
3556
- */
3557
- declare function ladderLengthOf(profile: unknown): number;
3558
- /** kMax: the maximum declared ladder length across the registry snapshot. */
3559
- declare function kMaxOf(profiles: Record<string, unknown> | undefined): number;
3560
- /**
3561
- * The deterministic profile-registry snapshot hash frozen inside
3562
- * termination.init: profile names mapped to their declared ladder
3563
- * lengths, canonical JSON, sha256.
3564
- */
3565
- declare function profileRegistrySnapshotHash(profiles: Record<string, unknown> | undefined): string;
3566
- /**
3567
- * Validates a raw limits record into the frozen vector. The pre-rename
3568
- * escalation knob is rejected with a migration hint (XF-10); counters
3569
- * must be non-negative integers; kMax at least 1.
3570
- */
3571
- declare function validateTerminationLimits(raw: Partial<TerminationLimits> | Record<string, unknown>): TerminationLimits;
3572
- /** C = E0 + kMax: the per-spawn weight of the variant function. */
3573
- declare function lineageWeightOf(limits: TerminationLimits): number;
3574
- /** Phi0 = V0 + C * S0, finite and fixed in termination.init. */
3575
- declare function phiInitialOf(limits: TerminationLimits): number;
3576
- /** Builds the termination.init value payload. */
3577
- declare function buildTerminationInitValue(limits: TerminationLimits, registrySnapshotHash: string): TerminationInitValue;
3578
- /** Reads a termination.init entry's payload; undefined when malformed. */
3579
- declare function readTerminationInit(entry: JournalEntry): TerminationInitValue | undefined;
3580
- /**
3581
- * Config-drift detection at resume: the journaled vector
3582
- * always wins; every differing field is reported for the
3583
- * `termination:config-drift` event. Dynamic budget top-up via restart is
3584
- * excluded by construction.
3585
- */
3586
- declare function terminationConfigDrift(frozen: TerminationLimits, live: Partial<TerminationLimits>): Array<{
3587
- field: keyof TerminationLimits;
3588
- frozenValue: Json;
3589
- liveValue: Json;
3590
- }>;
3591
- /** Injected appender for termination.denied entries (engine-owned I/O). */
3592
- type TerminationDeniedWriter = (denied: TerminationDeniedValue) => Promise<EntryRef>;
3593
- /**
3594
- * The single per-run TerminationAccount: debit ONLY. No
3595
- * credit operation exists by construction; reclaim never replenishes
3596
- * anything (DEF-5 interaction). Live: the engine debits the
3597
- * in-memory account, writes the carrying entry with the balance-after,
3598
- * then applies effects. Resume state is rebuilt by TerminationFold from
3599
- * the journal, never from live config.
3600
- */
3601
- declare class TerminationAccount {
3602
- readonly limits: TerminationLimits;
3603
- private revisionUnits;
3604
- private spawnUnits;
3605
- private readonly lineages;
3606
- private deniedWriter?;
3607
- constructor(options: {
3608
- limits: TerminationLimits;
3609
- deniedWriter?: TerminationDeniedWriter;
3610
- });
3636
+ interface RunAgentOptions<S extends SchemaSpec = JsonSchema> {
3637
+ prompt: string;
3638
+ schema?: S;
3639
+ /** Canonicalized JSON Schema projection of `schema` (precomputed for identity). */
3640
+ canonicalSchema?: JsonSchema;
3641
+ adapter: ProviderAdapter;
3642
+ resolved: ResolvedInvocation;
3611
3643
  /**
3612
- * Binds the denied-entry appender onto an account rebuilt by the fold
3613
- * (resume path): the fold is pure and cannot own I/O. Never rebinds an
3614
- * existing writer.
3644
+ * Transport failover chain for the loop phase (M4-T04):
3645
+ * resolved fallback targets tried in order on
3646
+ * transport or rate-limit failures after retries exhaust. Failover is
3647
+ * sticky and changes only servedBy, never the content key.
3615
3648
  */
3616
- bindDeniedWriter(writer: TerminationDeniedWriter): void;
3617
- snapshot(): TerminationAccountSnapshot;
3618
- /** Phi = V + C * S + sum over live lineages (E + R). */
3619
- phi(): number;
3620
- /** The current rung index of a lineage (0 before any raise). */
3621
- rungIndexOf(logicalTaskId: LogicalTaskId): number;
3622
- /** True when a spawn-unit debit would underflow (pre-reserve check). */
3623
- get spawnUnitsExhausted(): boolean;
3624
- get revisionUnitsRemaining(): number;
3649
+ fallbacks?: PhaseTarget[];
3625
3650
  /**
3626
- * The spawn-admission debit: minus one spawnUnit for
3627
- * an admitted spawn of ANY origin; a NEW lineage receives E0 escalation
3628
- * units and (K_l - 1) rung transitions in the same atomic step, so the
3629
- * lemma's per-spawn decrease is C - (E0 + K_l - 1) = kMax - K_l + 1,
3630
- * at least 1. Synchronous: the caller embeds spawnUnitsAfter in the
3631
- * decision entry it appends next.
3651
+ * Transport RetryPolicy (M4-T05): lives UNDER
3652
+ * the journal, wired around every adapter.stream dispatch. sleep and
3653
+ * random are injectable for tests; the core owns wall-clock.
3632
3654
  */
3633
- debitSpawn(lineage?: {
3634
- logicalTaskId: LogicalTaskId;
3635
- isNew: boolean;
3636
- ladderLength?: number;
3637
- }): {
3638
- ok: true;
3639
- spawnUnitsAfter: number;
3640
- } | {
3641
- ok: false;
3642
- resource: "spawnUnits";
3655
+ retry?: {
3656
+ policy?: RetryPolicy;
3657
+ sleep?: (ms: number) => Promise<void>;
3658
+ random?: () => number;
3643
3659
  };
3644
3660
  /**
3645
- * The plan_revise debit: minus one
3646
- * revisionUnit on EVERY journaled plan.revision, regardless of the op
3647
- * count, guard verdicts, or the auto-rebase outcome; conflict spam is
3648
- * never a free retry.
3661
+ * Per-provider keyed limiter hook (M4-T07): wraps every wire dispatch
3662
+ * under the serving adapter's key; absent = unlimited (Appendix A).
3663
+ * `signal` is the agent-level abort: an aborted caller leaves the
3664
+ * key's queue without a slot (v1.34.0 review P2-4).
3649
3665
  */
3650
- debitRevision(): {
3651
- ok: true;
3652
- revisionUnitsAfter: number;
3653
- } | {
3654
- ok: false;
3655
- resource: "revisionUnits";
3656
- };
3666
+ providerSlot?: <T>(key: string, fn: () => Promise<T>, signal?: AbortSignal) => Promise<T>;
3667
+ /** The resolved toolset; absent = no tools declared. */
3668
+ tools?: ToolRuntime;
3657
3669
  /**
3658
- * The escalation debit: minus one escalationUnit of
3659
- * the affected lineage, including EACH lineage of a class-level
3660
- * decision and timeout defaultDecisions. Conditioned on the
3661
- * countsAgainstLimit flag embedded in the decision entry by the caller.
3670
+ * Separate final extract invocation, present only when the role trigger
3671
+ * protocol demands one: schema set AND (routing directs extract to a
3672
+ * different model OR the loop model's caps cannot serve the required
3673
+ * tier OR finalize is routed). Otherwise the schema rides the last loop
3674
+ * turn (the necessity rule is
3675
+ * decided by the ctx layer via model/roles.ts).
3662
3676
  */
3663
- debitEscalation(logicalTaskId: LogicalTaskId): {
3664
- ok: true;
3665
- escalationUnitsAfter: number;
3666
- } | {
3667
- ok: false;
3668
- resource: "escalationUnits";
3677
+ extract?: PhaseTarget & {
3678
+ fallbacks?: PhaseTarget[];
3669
3679
  };
3670
3680
  /**
3671
- * The ladder-raise debit: minus one rung of the
3672
- * lineage; rungIndex is strictly monotone, there are no demotions and
3673
- * no runtime startTier promotion in v1.
3681
+ * Finalize synthesis invocation (M4-T01), present only when the role
3682
+ * trigger protocol fires it: configured in routing AND the toolset is
3683
+ * non-empty. Runs after tools stop with toolChoice 'none' over the
3684
+ * full transcript plus a deterministic synthesis instruction appended
3685
+ * to the REQUEST only (the durable transcript keeps the raw history);
3686
+ * its text becomes the output for schema-less calls, a non-truncated
3687
+ * empty synthesis falls back to the loop turn's text, and a
3688
+ * schema-bearing call always pairs it with a separate extract
3689
+ * (the ctx layer guarantees `extract` is present in that case). Like
3690
+ * extract, the finalize invocation is not checkpointed in v1.
3674
3691
  */
3675
- debitRung(logicalTaskId: LogicalTaskId): {
3676
- ok: true;
3677
- rungIndexAfter: number;
3678
- rungsRemainingAfter: number;
3679
- } | {
3680
- ok: false;
3681
- resource: "rungs";
3692
+ finalize?: PhaseTarget & {
3693
+ fallbacks?: PhaseTarget[];
3682
3694
  };
3683
3695
  /**
3684
- * The unified debit surface: attempts the named resource and, on
3685
- * underflow, writes `termination.denied` strictly BEFORE resolving with
3686
- * the typed failure (the caller surfaces the error only after this
3687
- * settles). Requires a deniedWriter; pure-fold contexts use the
3688
- * synchronous per-resource methods instead.
3696
+ * Summarize invocation target for compaction (M4-T03): resolved
3697
+ * through the chain with role 'summarize', falling back to the loop
3698
+ * model when routing resolves nothing. Compaction
3699
+ * is ON by default; absence of this option disables it (direct
3700
+ * runAgent callers).
3689
3701
  */
3690
- debit(resource: Exclude<TerminationResource, "depth">, lineage?: LogicalTaskId, context?: {
3691
- requestedByRef?: EntryRef;
3692
- reasonCode?: string;
3693
- }): Promise<DebitResult>;
3694
- private tryDebit;
3702
+ summarize?: PhaseTarget & {
3703
+ fallbacks?: PhaseTarget[];
3704
+ };
3705
+ /** Per-profile compaction config; threshold default 0.8 (Appendix A). */
3706
+ compaction?: {
3707
+ threshold?: number;
3708
+ };
3695
3709
  /**
3696
- * Restores one lineage's counters from journaled balances (fold use
3697
- * only): never a credit path, the fold consumes recorded balances.
3710
+ * Turn-boundary checkpointing (M3-T02).
3711
+ * load() restores the last boundary on a dangling-dispatch resume;
3712
+ * save() persists each boundary where the loop continues. The separate
3713
+ * extract invocation is not checkpointed in v1: an extract-phase crash
3714
+ * re-pays from the last loop boundary.
3698
3715
  */
3699
- restoreLineage(logicalTaskId: LogicalTaskId, state: LineageCounters & {
3700
- rungIndex?: number;
3701
- }): void;
3702
- /** Fold use only: restores the run counters from journaled balances. */
3703
- restoreCounters(state: {
3704
- revisionUnitsRemaining?: number;
3705
- spawnUnitsRemaining?: number;
3706
- }): void;
3707
- private requireLineage;
3708
- private requireLineageId;
3716
+ checkpoint?: {
3717
+ load(): Promise<CheckpointState | undefined>;
3718
+ save(state: CheckpointState): Promise<void>;
3719
+ };
3720
+ limits: EffectiveUsageLimits;
3721
+ /** Emits agent:stream deltas when true (telemetry only). */
3722
+ stream?: boolean;
3723
+ /** Host or sibling cancellation. */
3724
+ signal?: AbortSignal;
3725
+ budget?: BudgetHooks;
3726
+ events?: RuntimeEventSink;
3727
+ transcript?: {
3728
+ mintRef(): string;
3729
+ put(ref: string, blob: Uint8Array): Promise<void>;
3730
+ };
3731
+ priceUsd?: (servedBy: ModelRef, usage: Usage) => number | undefined;
3732
+ /** Bounded schema re-prompt attempts; default 2 (Appendix A). */
3733
+ schemaRetryAttempts?: number;
3734
+ /** Bounded ModelRetry conversions per tool call chain; default 2 (Appendix A). */
3735
+ modelRetryAttempts?: number;
3736
+ /**
3737
+ * Escalation opt-in (M3-T07): the loop intercepts accepted calls to
3738
+ * the escalate tool and terminates with status 'escalated'; the
3739
+ * in-run minSpend gate rejects early scope_bigger escalations with a
3740
+ * "keep working" error tool result (M3-T09).
3741
+ */
3742
+ escalation?: {
3743
+ minSpendUsd: number;
3744
+ };
3745
+ /**
3746
+ * Terminal-tool interception (M6-T07): an accepted call to the named
3747
+ * tool ends the loop with status ok; the call's validated `result`
3748
+ * argument becomes the agent output (the orchestrator finish
3749
+ * tool). The tool's execute never runs, mirroring escalate.
3750
+ * `validate` is the optional host judgment over a schema valid call
3751
+ * (the RV-204 finish validators): ok finishes as before; a rejection
3752
+ * becomes the call's error tool result and the turn continues, so the
3753
+ * model can repair and call the terminal tool again. The hook owns
3754
+ * bounding and journaling; the loop stays policy only and never
3755
+ * throws.
3756
+ */
3757
+ terminalTool?: {
3758
+ name: string;
3759
+ validate?: (call: {
3760
+ id: string;
3761
+ result: unknown;
3762
+ }) => Promise<{
3763
+ ok: true;
3764
+ } | {
3765
+ ok: false;
3766
+ feedback: Record<string, unknown>;
3767
+ }>;
3768
+ };
3769
+ agentType?: string;
3770
+ /** The primary invocation role of the tool loop; default 'loop' (M6-T05). */
3771
+ role?: "loop" | "plan" | "orchestrate";
3772
+ label?: string;
3773
+ now?: () => number;
3709
3774
  }
3710
- /** The typed error code surfaced after a denied debit. */
3711
- declare function exhaustionCodeOf(resource: TerminationResource): string;
3712
3775
  /**
3713
- * The replay fold: rebuilds the account from
3714
- * termination.init and the debiting decision entries, asserting every
3715
- * embedded balance-after against the recomputation. A divergence raises
3716
- * the typed journal-integrity error at exactly the diverging entry;
3717
- * denials are re-issued from termination.denied with zero live calls.
3776
+ * The output-truncation abort message (v1.9.0 follow-up review). The
3777
+ * constraint is named neutrally as the turn's output token allowance:
3778
+ * the effective request cap can come from limits.maxOutputTokensPerTurn,
3779
+ * the budget clamp above, or the adapter's own default, and the provider
3780
+ * can also cut at its model maximum with no request cap at all.
3718
3781
  */
3719
- declare function foldTermination(entries: readonly JournalEntry[]): {
3720
- account: TerminationAccount;
3721
- initRef: EntryRef;
3722
- init: TerminationInitValue;
3723
- denials: Array<{
3724
- seq: EntryRef;
3725
- value: TerminationDeniedValue;
3726
- }>;
3727
- } | undefined;
3782
+ /**
3783
+ * The deterministic synthesis instruction appended (as a user message)
3784
+ * to the finalize REQUEST only, never to the durable transcript. A
3785
+ * transcript that simply ends at an assistant message reads to a real
3786
+ * model as a fresh conversation opening, so an uninstructed synthesis
3787
+ * call can replace the loop's correct answer with a greeting (v1.18.0
3788
+ * review P1-1); the extract arm has carried its own instruction since
3789
+ * M4, and this is its finalize twin. The wording is part of the wire
3790
+ * request: keep it stable.
3791
+ */
3792
+ declare const FINALIZE_SYNTHESIS_INSTRUCTION: string;
3793
+ /**
3794
+ * Runs one agent to a typed AgentResult. Never throws past policy: every
3795
+ * failure mode becomes a typed status on the result.
3796
+ */
3797
+ declare function runAgent<S extends SchemaSpec>(options: RunAgentOptions<S>): Promise<AgentResult<Out<S>>>;
3728
3798
  //#endregion
3729
- //#region src/engine/budget.d.ts
3730
- type Spend = {
3731
- usd: number;
3732
- usage: Usage;
3733
- agentsSpawned: number;
3734
- };
3735
- /** Last resort of the admission reserve formula. */
3736
- declare const DEFAULT_FLAT_RESERVE_USD = .5;
3737
- /** The run-root account scope. */
3738
- declare const ROOT_ACCOUNT = "run";
3799
+ //#region src/runtime/permission-chain.d.ts
3800
+ type HookVerdict = "allow" | "deny" | "ask" | {
3801
+ modifiedInput: unknown;
3802
+ } | undefined;
3803
+ type PermissionHook = (toolName: string, input: unknown, ctx: ToolContext) => HookVerdict | Promise<HookVerdict>;
3739
3804
  /**
3740
- * The admission reserve for a spawn: opts.estCost, else profile.estCost,
3741
- * else price(countTokens(input) + one turn's worth of output), else the
3742
- * engine flat default. The output term is caps.maxOutputTokens clamped to
3743
- * limits.maxOutputTokensPerTurn when the spawn carries one, so a host can
3744
- * bound reserves without hand-written estimates. The priced path uses the
3745
- * SAME price function as settlement (priceUsdOf), so long-context tiers
3746
- * apply to estimates too.
3805
+ * Declarative rule tables (no closures). `'undeclared'` in risk
3806
+ * position matches every tool WITHOUT declared risk: presets treat the
3807
+ * undeclared state conservatively. Argv rules
3808
+ * match through the real shell matcher; domain rules are
3809
+ * ADVISORY for every tool in the current release: they never
3810
+ * change a verdict, and matches surface in the tool:end audit
3811
+ * fields (enforcement will live in a first-party fetch tool
3812
+ * when one ships).
3747
3813
  */
3748
- declare function admissionReserveUsd(options: {
3749
- estCost?: number;
3750
- profileEstCost?: number;
3751
- inputTokens?: number;
3752
- caps?: ModelCaps;
3753
- maxOutputTokensPerTurn?: number;
3754
- flatReserveUsd?: number;
3755
- }): number;
3756
- /** Read-only projection of one account. */
3757
- interface BudgetAccountView {
3758
- scope: string;
3759
- ceilingUsd?: number;
3760
- spentUsd: number;
3761
- committedReserveUsd: number;
3762
- finalizeReserveUsd: number;
3763
- parentScope?: string;
3814
+ type RiskRuleValue = ToolRisk | "undeclared";
3815
+ type PermissionRule = {
3816
+ tool: string | string[];
3817
+ } | {
3818
+ risk: RiskRuleValue | RiskRuleValue[];
3819
+ } | {
3820
+ tool: string;
3821
+ argv: string | string[];
3822
+ } | {
3823
+ tool: string;
3824
+ domains: string[];
3825
+ };
3826
+ type CanUseTool = (toolName: string, input: unknown, ctx: ToolContext) => "allow" | "deny" | {
3827
+ modifiedInput: unknown;
3828
+ } | Promise<"allow" | "deny" | {
3829
+ modifiedInput: unknown;
3830
+ }>;
3831
+ /** Host-side permission configuration (engine defaults.permissions). */
3832
+ interface PermissionConfig {
3833
+ hooks?: PermissionHook[];
3834
+ deny?: PermissionRule[];
3835
+ ask?: PermissionRule[];
3836
+ canUseTool?: CanUseTool;
3764
3837
  }
3765
3838
  /**
3766
- * Why a ceiling error ended the work: the first closed account walking
3767
- * from the debited scope toward the root, plus the root state, so the
3768
- * outward message can name WHICH ceiling actually crossed instead of
3769
- * blaming the run ceiling for every crossing.
3839
+ * Profile-level permissions.
3840
+ * inheritPermissions governs SUBAGENT inheritance (mode c orchestrators,
3841
+ * M6+): children get their own config only unless explicitly opted in.
3842
+ * It is carried as data here and consumed by the spawning layers.
3770
3843
  */
3771
- interface BudgetExhaustionDiagnostics {
3772
- crossed?: {
3773
- scope: string;
3774
- source: "root" | "orchestrator-cap" | "child-account";
3775
- ceilingUsd: number;
3776
- spentUsd: number;
3777
- committedReserveUsd: number;
3778
- finalizeReserveUsd: number;
3779
- };
3780
- root: {
3781
- ceilingUsd?: number;
3782
- spentUsd: number;
3783
- };
3844
+ interface AgentProfilePermissions extends PermissionConfig {
3845
+ /** Compiles into deny/ask rules; ships in M5. */
3846
+ preset?: "strict" | "standard" | "open";
3847
+ /** Default false. */
3848
+ inheritPermissions?: boolean;
3849
+ }
3850
+ interface CompiledPermissionChain {
3851
+ hooks: PermissionHook[];
3852
+ deny: PermissionRule[];
3853
+ ask: PermissionRule[];
3854
+ canUseTool?: CanUseTool;
3855
+ }
3856
+ type PermissionVerdict = ({
3857
+ verdict: "allow";
3858
+ decidedBy: "hook" | "canUseTool" | "default";
3859
+ input: unknown;
3860
+ } | {
3861
+ verdict: "deny";
3862
+ decidedBy: "hook" | "deny-rule" | "canUseTool";
3863
+ rule?: PermissionRule;
3864
+ input: unknown;
3865
+ } | {
3866
+ verdict: "ask";
3867
+ decidedBy: "hook" | "ask-rule" | "default";
3868
+ rule?: PermissionRule;
3869
+ input: unknown;
3870
+ }) & {
3871
+ /**
3872
+ * Advisory domain-rule matches: reported in the tool:end
3873
+ * audit fields, never enforced in the current release.
3874
+ */
3875
+ advisory?: PermissionRule[];
3876
+ };
3877
+ /**
3878
+ * Merges the engine-wide config and the profile config into one chain.
3879
+ * Layers concatenate engine-first; since rules only deny or ask, ordering
3880
+ * within a layer cannot change the verdict. The
3881
+ * profile's canUseTool wins over the engine's (a single slot by
3882
+ * construction). A declared preset compiles INTO the same layers, after
3883
+ * the host-authored rules, never as a fifth layer (M5-T05).
3884
+ */
3885
+ declare function compilePermissionChain(engine?: PermissionConfig, profile?: AgentProfilePermissions): CompiledPermissionChain;
3886
+ /**
3887
+ * Evaluates the chain for one dispatch, or OFFLINE against a
3888
+ * hypothetical call by tool name (the dry-run API: nothing executes;
3889
+ * shells and tests read the verdict, the
3890
+ * deciding layer, and the matched rule). Hooks run in deterministic
3891
+ * registration order; { modifiedInput } substitutes the input and
3892
+ * continues; the first decisive verdict wins. The returned input is what
3893
+ * execute receives and what the approval identity hashes (post hook
3894
+ * modification). Advisory domain-rule matches
3895
+ * ride every verdict for the audit payload.
3896
+ */
3897
+ declare function evaluatePermission(chain: CompiledPermissionChain, tool: string | Pick<ToolDef, "name" | "needsApproval" | "risk">, input: unknown, ctx?: ToolContext): Promise<PermissionVerdict>;
3898
+ //#endregion
3899
+ //#region src/tools/toolset-hash.d.ts
3900
+ /** The per-spawn tools option value domain. */
3901
+ type ToolsOption = ReadonlyArray<ToolDef | ToolSource | string>;
3902
+ /** The spawn's frozen toolset snapshot plus its identity hash. */
3903
+ interface ResolvedToolset {
3904
+ tools: ToolDef[];
3905
+ contracts: ToolContract[];
3906
+ hash: string;
3907
+ }
3908
+ /** The empty toolset (no tools declared anywhere). */
3909
+ declare function emptyToolset(): ResolvedToolset;
3910
+ /**
3911
+ * Expands registered names and sources, validates every tool name and
3912
+ * duplicate names across the whole toolset (ConfigError at spawn time),
3913
+ * and computes the toolsetHash over contracts sorted by name. The
3914
+ * `toolsets` registry is the engine's `defaults.toolsets` snapshot;
3915
+ * without one, string entries fail with the same unknown-name error as
3916
+ * a miss, so nothing outside the declared registry is ever reachable.
3917
+ */
3918
+ declare function resolveToolset(specs: ToolsOption | undefined, session: ToolSourceSession, toolsets?: Record<string, ToolsOption>): Promise<ResolvedToolset>;
3919
+ //#endregion
3920
+ //#region src/journal/termination.d.ts
3921
+ /** The frozen limits vector written into termination.init. */
3922
+ interface TerminationLimits {
3923
+ /** V0, default 32; absolute and non-replenishable. */
3924
+ maxRevisionsPerRun: number;
3925
+ /** S0, default 128; debited on every admitted spawn of any origin. */
3926
+ maxTotalSpawns: number;
3927
+ /** E0, default 2, per lineage; the old name is rejected (XF-10). */
3928
+ maxEscalationsPerLogicalTask: number;
3929
+ /** D0, default 1, ceiling 4; static per-branch limit. */
3930
+ maxDepth: number;
3931
+ /** Maximum declared ladder length per the profile-registry snapshot. */
3932
+ kMax: number;
3933
+ /** B0; immutable after start, no API including HITL can top up. */
3934
+ runBudgetUsdCeiling: number;
3935
+ /**
3936
+ * The resolved orchestrator cap in absolute USD (DEF-7; XF-09),
3937
+ * frozen with the counters. Journals recorded before v1.8 store 0
3938
+ * ("not yet resolved"); for them the orchestrator_budget_reserve
3939
+ * decision is the authority and is recovered on resume.
3940
+ */
3941
+ orchestratorCapUsd: number;
3942
+ /** The finalize reserve carved out of the cap; 0 in pre-v1.8 journals. */
3943
+ finalizeReserveUsd: number;
3944
+ }
3945
+ /** Appendix A committed defaults for the countable resources. */
3946
+ declare const DEFAULT_MAX_REVISIONS_PER_RUN = 32;
3947
+ declare const DEFAULT_MAX_TOTAL_SPAWNS = 128;
3948
+ /** The countable resource vocabulary. */
3949
+ type TerminationResource = "revisionUnits" | "spawnUnits" | "escalationUnits" | "rungs" | "depth";
3950
+ interface LineageCounters {
3951
+ escalationUnitsRemaining: number;
3952
+ rungsRemaining: number;
3953
+ }
3954
+ interface TerminationAccountSnapshot {
3955
+ revisionUnitsRemaining: number;
3956
+ spawnUnitsRemaining: number;
3957
+ perLineage: Record<LogicalTaskId, LineageCounters>;
3958
+ /** The variant function, a pure fold over the journal. */
3959
+ phi: number;
3960
+ }
3961
+ type DebitResult = {
3962
+ ok: true;
3963
+ balanceAfter: number;
3964
+ } | {
3965
+ ok: false;
3966
+ deniedEntryRef: EntryRef;
3967
+ resource: TerminationResource;
3968
+ };
3969
+ /** The value payload of a termination.init entry. */
3970
+ interface TerminationInitValue {
3971
+ limits: TerminationLimits;
3972
+ profileRegistrySnapshotHash: string;
3973
+ phiInitial: number;
3974
+ }
3975
+ /** The value payload of a termination.denied entry. */
3976
+ interface TerminationDeniedValue {
3977
+ resource: TerminationResource;
3978
+ logicalTaskId?: LogicalTaskId;
3979
+ /** Seq of the calling tool-call or EscalationReport entry. */
3980
+ requestedByRef?: EntryRef;
3981
+ reasonCode: string;
3982
+ snapshotAfter: TerminationAccountSnapshot;
3983
+ }
3984
+ /**
3985
+ * Reads the declared ladder length of one agent profile. Ladders are
3986
+ * declared through the profile's ModelSpec (`model: { ladder }`, or the
3987
+ * loop-role routing entry). The reader is defensive
3988
+ * so the snapshot is total over every registry shape (an undeclared
3989
+ * ladder has length 1: the single implicit rung).
3990
+ */
3991
+ declare function ladderLengthOf(profile: unknown): number;
3992
+ /** kMax: the maximum declared ladder length across the registry snapshot. */
3993
+ declare function kMaxOf(profiles: Record<string, unknown> | undefined): number;
3994
+ /**
3995
+ * The deterministic profile-registry snapshot hash frozen inside
3996
+ * termination.init: profile names mapped to their declared ladder
3997
+ * lengths, canonical JSON, sha256.
3998
+ */
3999
+ declare function profileRegistrySnapshotHash(profiles: Record<string, unknown> | undefined): string;
4000
+ /**
4001
+ * Validates a raw limits record into the frozen vector. The pre-rename
4002
+ * escalation knob is rejected with a migration hint (XF-10); counters
4003
+ * must be non-negative integers; kMax at least 1.
4004
+ */
4005
+ declare function validateTerminationLimits(raw: Partial<TerminationLimits> | Record<string, unknown>): TerminationLimits;
4006
+ /** C = E0 + kMax: the per-spawn weight of the variant function. */
4007
+ declare function lineageWeightOf(limits: TerminationLimits): number;
4008
+ /** Phi0 = V0 + C * S0, finite and fixed in termination.init. */
4009
+ declare function phiInitialOf(limits: TerminationLimits): number;
4010
+ /** Builds the termination.init value payload. */
4011
+ declare function buildTerminationInitValue(limits: TerminationLimits, registrySnapshotHash: string): TerminationInitValue;
4012
+ /** Reads a termination.init entry's payload; undefined when malformed. */
4013
+ declare function readTerminationInit(entry: JournalEntry): TerminationInitValue | undefined;
4014
+ /**
4015
+ * Config-drift detection at resume: the journaled vector
4016
+ * always wins; every differing field is reported for the
4017
+ * `termination:config-drift` event. Dynamic budget top-up via restart is
4018
+ * excluded by construction.
4019
+ */
4020
+ declare function terminationConfigDrift(frozen: TerminationLimits, live: Partial<TerminationLimits>): Array<{
4021
+ field: keyof TerminationLimits;
4022
+ frozenValue: Json;
4023
+ liveValue: Json;
4024
+ }>;
4025
+ /** Injected appender for termination.denied entries (engine-owned I/O). */
4026
+ type TerminationDeniedWriter = (denied: TerminationDeniedValue) => Promise<EntryRef>;
4027
+ /**
4028
+ * The single per-run TerminationAccount: debit ONLY. No
4029
+ * credit operation exists by construction; reclaim never replenishes
4030
+ * anything (DEF-5 interaction). Live: the engine debits the
4031
+ * in-memory account, writes the carrying entry with the balance-after,
4032
+ * then applies effects. Resume state is rebuilt by TerminationFold from
4033
+ * the journal, never from live config.
4034
+ */
4035
+ declare class TerminationAccount {
4036
+ readonly limits: TerminationLimits;
4037
+ private revisionUnits;
4038
+ private spawnUnits;
4039
+ private readonly lineages;
4040
+ private deniedWriter?;
4041
+ constructor(options: {
4042
+ limits: TerminationLimits;
4043
+ deniedWriter?: TerminationDeniedWriter;
4044
+ });
4045
+ /**
4046
+ * Binds the denied-entry appender onto an account rebuilt by the fold
4047
+ * (resume path): the fold is pure and cannot own I/O. Never rebinds an
4048
+ * existing writer.
4049
+ */
4050
+ bindDeniedWriter(writer: TerminationDeniedWriter): void;
4051
+ snapshot(): TerminationAccountSnapshot;
4052
+ /** Phi = V + C * S + sum over live lineages (E + R). */
4053
+ phi(): number;
4054
+ /** The current rung index of a lineage (0 before any raise). */
4055
+ rungIndexOf(logicalTaskId: LogicalTaskId): number;
4056
+ /** True when a spawn-unit debit would underflow (pre-reserve check). */
4057
+ get spawnUnitsExhausted(): boolean;
4058
+ get revisionUnitsRemaining(): number;
4059
+ /**
4060
+ * The spawn-admission debit: minus one spawnUnit for
4061
+ * an admitted spawn of ANY origin; a NEW lineage receives E0 escalation
4062
+ * units and (K_l - 1) rung transitions in the same atomic step, so the
4063
+ * lemma's per-spawn decrease is C - (E0 + K_l - 1) = kMax - K_l + 1,
4064
+ * at least 1. Synchronous: the caller embeds spawnUnitsAfter in the
4065
+ * decision entry it appends next.
4066
+ */
4067
+ debitSpawn(lineage?: {
4068
+ logicalTaskId: LogicalTaskId;
4069
+ isNew: boolean;
4070
+ ladderLength?: number;
4071
+ }): {
4072
+ ok: true;
4073
+ spawnUnitsAfter: number;
4074
+ } | {
4075
+ ok: false;
4076
+ resource: "spawnUnits";
4077
+ };
4078
+ /**
4079
+ * The plan_revise debit: minus one
4080
+ * revisionUnit on EVERY journaled plan.revision, regardless of the op
4081
+ * count, guard verdicts, or the auto-rebase outcome; conflict spam is
4082
+ * never a free retry.
4083
+ */
4084
+ debitRevision(): {
4085
+ ok: true;
4086
+ revisionUnitsAfter: number;
4087
+ } | {
4088
+ ok: false;
4089
+ resource: "revisionUnits";
4090
+ };
4091
+ /**
4092
+ * The escalation debit: minus one escalationUnit of
4093
+ * the affected lineage, including EACH lineage of a class-level
4094
+ * decision and timeout defaultDecisions. Conditioned on the
4095
+ * countsAgainstLimit flag embedded in the decision entry by the caller.
4096
+ */
4097
+ debitEscalation(logicalTaskId: LogicalTaskId): {
4098
+ ok: true;
4099
+ escalationUnitsAfter: number;
4100
+ } | {
4101
+ ok: false;
4102
+ resource: "escalationUnits";
4103
+ };
4104
+ /**
4105
+ * The ladder-raise debit: minus one rung of the
4106
+ * lineage; rungIndex is strictly monotone, there are no demotions and
4107
+ * no runtime startTier promotion in v1.
4108
+ */
4109
+ debitRung(logicalTaskId: LogicalTaskId): {
4110
+ ok: true;
4111
+ rungIndexAfter: number;
4112
+ rungsRemainingAfter: number;
4113
+ } | {
4114
+ ok: false;
4115
+ resource: "rungs";
4116
+ };
4117
+ /**
4118
+ * The unified debit surface: attempts the named resource and, on
4119
+ * underflow, writes `termination.denied` strictly BEFORE resolving with
4120
+ * the typed failure (the caller surfaces the error only after this
4121
+ * settles). Requires a deniedWriter; pure-fold contexts use the
4122
+ * synchronous per-resource methods instead.
4123
+ */
4124
+ debit(resource: Exclude<TerminationResource, "depth">, lineage?: LogicalTaskId, context?: {
4125
+ requestedByRef?: EntryRef;
4126
+ reasonCode?: string;
4127
+ }): Promise<DebitResult>;
4128
+ private tryDebit;
4129
+ /**
4130
+ * Restores one lineage's counters from journaled balances (fold use
4131
+ * only): never a credit path, the fold consumes recorded balances.
4132
+ */
4133
+ restoreLineage(logicalTaskId: LogicalTaskId, state: LineageCounters & {
4134
+ rungIndex?: number;
4135
+ }): void;
4136
+ /** Fold use only: restores the run counters from journaled balances. */
4137
+ restoreCounters(state: {
4138
+ revisionUnitsRemaining?: number;
4139
+ spawnUnitsRemaining?: number;
4140
+ }): void;
4141
+ private requireLineage;
4142
+ private requireLineageId;
4143
+ }
4144
+ /** The typed error code surfaced after a denied debit. */
4145
+ declare function exhaustionCodeOf(resource: TerminationResource): string;
4146
+ /**
4147
+ * The replay fold: rebuilds the account from
4148
+ * termination.init and the debiting decision entries, asserting every
4149
+ * embedded balance-after against the recomputation. A divergence raises
4150
+ * the typed journal-integrity error at exactly the diverging entry;
4151
+ * denials are re-issued from termination.denied with zero live calls.
4152
+ */
4153
+ declare function foldTermination(entries: readonly JournalEntry[]): {
4154
+ account: TerminationAccount;
4155
+ initRef: EntryRef;
4156
+ init: TerminationInitValue;
4157
+ denials: Array<{
4158
+ seq: EntryRef;
4159
+ value: TerminationDeniedValue;
4160
+ }>;
4161
+ } | undefined;
4162
+ //#endregion
4163
+ //#region src/engine/budget.d.ts
4164
+ type Spend = {
4165
+ usd: number;
4166
+ usage: Usage;
4167
+ agentsSpawned: number;
4168
+ };
4169
+ /** Last resort of the admission reserve formula. */
4170
+ declare const DEFAULT_FLAT_RESERVE_USD = .5;
4171
+ /** The run-root account scope. */
4172
+ declare const ROOT_ACCOUNT = "run";
4173
+ /**
4174
+ * The admission reserve for a spawn: opts.estCost, else profile.estCost,
4175
+ * else price(countTokens(input) + one turn's worth of output), else the
4176
+ * engine flat default. The output term is caps.maxOutputTokens clamped to
4177
+ * limits.maxOutputTokensPerTurn when the spawn carries one, so a host can
4178
+ * bound reserves without hand-written estimates. The priced path uses the
4179
+ * SAME price function as settlement (priceUsdOf), so long-context tiers
4180
+ * apply to estimates too.
4181
+ */
4182
+ declare function admissionReserveUsd(options: {
4183
+ estCost?: number;
4184
+ profileEstCost?: number;
4185
+ inputTokens?: number;
4186
+ caps?: ModelCaps;
4187
+ maxOutputTokensPerTurn?: number;
4188
+ flatReserveUsd?: number;
4189
+ }): number;
4190
+ /** Read-only projection of one account. */
4191
+ interface BudgetAccountView {
4192
+ scope: string;
4193
+ ceilingUsd?: number;
4194
+ spentUsd: number;
4195
+ committedReserveUsd: number;
4196
+ finalizeReserveUsd: number;
4197
+ parentScope?: string;
4198
+ }
4199
+ /**
4200
+ * Why a ceiling error ended the work: the first closed account walking
4201
+ * from the debited scope toward the root, plus the root state, so the
4202
+ * outward message can name WHICH ceiling actually crossed instead of
4203
+ * blaming the run ceiling for every crossing.
4204
+ */
4205
+ interface BudgetExhaustionDiagnostics {
4206
+ crossed?: {
4207
+ scope: string;
4208
+ source: "root" | "orchestrator-cap" | "child-account";
4209
+ ceilingUsd: number;
4210
+ spentUsd: number;
4211
+ committedReserveUsd: number;
4212
+ finalizeReserveUsd: number;
4213
+ };
4214
+ root: {
4215
+ ceilingUsd?: number;
4216
+ spentUsd: number;
4217
+ };
3784
4218
  }
3785
4219
  /**
3786
4220
  * The per-run budget account tree. All spend accounting is per instance;
@@ -4304,443 +4738,83 @@ declare class AdmissionController {
4304
4738
  /** The bound account, when this is a PlanRunner run (DEF-2). */
4305
4739
  get termination(): TerminationAccount | undefined;
4306
4740
  /**
4307
- * The lineage half of admission (DEF-3): folds are
4308
- * computed live STRICTLY BEFORE the carrying decision entry is appended;
4309
- * the caller embeds the returned block in the entry and replay reads it
4310
- * back byte-exact. Enforces the single-live-attempt invariant
4311
- * (`lineage_busy`) and monotonic attempt consumption
4312
- * (`lineage_exhausted`); never touches budget or structural limits.
4313
- */
4314
- evaluateLineage(spec: {
4315
- name: string;
4316
- lineage?: SpawnLineageOpt;
4317
- approach?: string;
4318
- ancestry?: LogicalTaskId[];
4319
- signature?: Partial<ApproachSignatureInputs>;
4320
- }): {
4321
- decision: {
4322
- kind: "ok";
4323
- lineage: SpawnLineage;
4324
- } | {
4325
- kind: "reject";
4326
- reason: {
4327
- code: "lineage_busy" | "lineage_exhausted";
4328
- };
4329
- };
4330
- statsBefore?: LineageStats;
4331
- };
4332
- /**
4333
- * Registers a live lineage admit the moment its caller commits to
4334
- * appending the decision entry, closing the single-live-attempt window
4335
- * until the journal absorbs the entry (DEF-3).
4336
- */
4337
- registerLineageAdmit(logicalTaskId: LogicalTaskId): void;
4338
- /**
4339
- * Evaluates one spawn live, strictly BEFORE its decision entry is
4340
- * appended. On admit the reserve is committed on the whole ancestor
4341
- * account chain atomically with the evaluation; the caller journals the
4342
- * returned decision and only then produces effects (child account,
4343
- * dispatch). On reject nothing is committed and the reject verdict is
4344
- * journaled by the caller so replay re-delivers it without
4345
- * re-evaluation.
4346
- */
4347
- /**
4348
- * The reserve the DISPATCH layer will actually commit for this spec:
4349
- * the estimate (or the flat default) clamped by the explicit child
4350
- * budget when one exists, because only an explicit budget opens a
4351
- * child-allowance account at dispatch; the childBudgetFraction cap
4352
- * never materializes as an account and must not shrink the
4353
- * projection. The token-count-priced estimate of ctx.agent is
4354
- * unreachable here (async); a divergence there lands as a journaled
4355
- * dispatch rejection instead of a strand.
4356
- */
4357
- projectedDispatchReserveUsd(spec: Pick<AdmitSpec, "estCostUsd" | "budgetUsd">): number;
4358
- admit(spec: AdmitSpec, options?: {
4359
- commitReserve?: boolean;
4360
- }): AdmissionDecision;
4361
- /**
4362
- * Resume roll-forward for an orchestrator child (M6-T07): restores the
4363
- * children-quota counter only. The budget seed already counts settled
4364
- * agent dispatches, and an in-flight child re-commits its reserve
4365
- * through the ctx.agent dispatch path.
4366
- */
4367
- recoverChild(nodeKey: string): void;
4368
- /**
4369
- * Resume roll-forward for a child that already SETTLED before the
4370
- * resume: re-registers the counters (maxChildrenPerNode, the lifetime
4371
- * cap, statsBefore fidelity) without committing any reserve; the spend
4372
- * itself sits in the root ledger seed.
4373
- */
4374
- recoverSettled(parentAccountScope: string): void;
4375
- /**
4376
- * Resume roll-forward for an admission whose decision entry exists but
4377
- * whose child has NOT settled: re-applies the recorded reserve and
4378
- * counters without re-evaluating any limit (replay never
4379
- * re-evaluates admission; reserves are recovered, never
4380
- * re-estimated).
4381
- */
4382
- recoverInFlight(parentAccountScope: string, verdict: AdmitVerdict): void;
4383
- }
4384
- //#endregion
4385
- //#region src/l0/events.d.ts
4386
- /** Run lifecycle and core telemetry (M1 subset). */
4387
- type CoreEvents = {
4388
- type: "run:start";
4389
- workflow: string;
4390
- resumed: boolean;
4391
- } | {
4392
- type: "run:end";
4393
- status: "ok" | "error" | "cancelled" | "exhausted" | "suspended";
4394
- totalUsd: number;
4395
- /**
4396
- * Present and true when any priced usage folded into totalUsd is
4397
- * approximate (a transport cut, a stream the ceiling severed, or an
4398
- * abort left a turn's usage estimated rather than reported by the
4399
- * provider), so totalUsd is a lower bound estimate, never an exact
4400
- * charge. Absent means every contributing turn reported exact usage.
4401
- */
4402
- usageApprox?: boolean;
4403
- } | {
4404
- type: "phase:start";
4405
- phase: string;
4406
- } | {
4407
- type: "log";
4408
- level: "debug" | "info" | "warn" | "error";
4409
- msg: string;
4410
- data?: Json;
4411
- } | {
4412
- type: "budget:update";
4413
- spentUsd: number;
4414
- remainingUsd: number | null;
4415
- committedReserveUsd: number;
4416
- } | {
4417
- type: "external:waiting";
4418
- key: string;
4419
- entryRef: number;
4420
- prompt?: string;
4421
- deadlineAt?: string;
4422
- } | {
4423
- type: "approval:pending";
4424
- toolName: string;
4425
- entryRef: number;
4426
- deadlineAt?: string;
4427
- } | {
4428
- type: "child:start";
4429
- workflow: string;
4430
- scope: string;
4431
- } | {
4432
- type: "child:end";
4433
- workflow: string;
4434
- scope: string;
4435
- status: string;
4436
- };
4437
- /**
4438
- * Agent lifecycle. One logical agent dispatch emits EXACTLY ONE
4439
- * `agent:start`/`agent:end` pair on its span (the start carries the
4440
- * primary role), and each model invocation phase inside the span
4441
- * (`loop`, then possibly `summarize` activations, `finalize`,
4442
- * `extract`) emits its own `agent:phase:start`/`agent:phase:end` pair,
4443
- * so durations, per-phase usage, and attempts are derivable without
4444
- * heuristics (the RV-207 event-model contract; before it, every phase
4445
- * emitted an unpaired extra `agent:start` and consumers pairing starts
4446
- * with the single end computed the LAST phase's duration as the
4447
- * agent's). `reduceInvocationTable` is the official reducer over this
4448
- * vocabulary.
4449
- */
4450
- type AgentEvents = {
4451
- type: "agent:queued";
4452
- agentType: string;
4453
- label?: string;
4454
- } | {
4455
- type: "agent:start";
4456
- agentType: string;
4457
- label?: string;
4458
- model: string;
4459
- role: string;
4460
- } | {
4461
- type: "agent:phase:start";
4462
- agentType: string;
4463
- label?: string; /** The invocation role this phase activation runs as. */
4464
- role: string; /** The model the activation resolved to (fallbacks may serve another; the end event reports the server). */
4465
- model: string;
4466
- /**
4467
- * 1-based activation ordinal within the span, unique per
4468
- * activation (a summarize that fires three times gets three
4469
- * pairs). Key phases by (spanId, invocation).
4470
- */
4471
- invocation: number;
4472
- } | {
4473
- type: "agent:phase:end";
4474
- agentType: string;
4475
- label?: string;
4476
- role: string; /** The model that actually served the activation's last attempt. */
4477
- model: string;
4478
- invocation: number;
4479
- /**
4480
- * Wall-clock activation duration. Live telemetry only: replayed
4481
- * phase pairs (reconstructed from the terminal entry's usage
4482
- * slices) carry 0.
4483
- */
4484
- durationMs: number; /** The usage this activation added to its (role, model) slices. */
4485
- usage: Usage; /** That usage priced at each serving model's own rate. */
4486
- costUsd: number;
4487
- outcome: "ok" | "error";
4488
- /**
4489
- * Transport retries inside this activation. Present only when
4490
- * greater than zero; live telemetry only (absent on replay).
4491
- */
4492
- retries?: number;
4493
- } | {
4494
- type: "agent:end";
4495
- agentType: string;
4496
- label?: string;
4497
- status: string;
4498
- usage: Usage;
4499
- costUsd: number;
4500
- entryRef: number;
4501
- /**
4502
- * Present and true when this agent's usage is approximate rather
4503
- * than reported by the provider (the turn was cut by a transport
4504
- * failure, a ceiling that severed the stream, or an abort). Absent
4505
- * means the provider reported the usage exactly. Mirrors the
4506
- * terminal journal entry's usageApprox.
4507
- */
4508
- usageApprox?: boolean;
4509
- /**
4510
- * Total transport retries across the span's activations. Present
4511
- * only when greater than zero; live telemetry only, never
4512
- * journaled, so a replayed agent:end omits it (absent means "zero
4513
- * or unknown").
4514
- */
4515
- retryCount?: number;
4516
- } | {
4517
- type: "agent:error";
4518
- agentType: string;
4519
- label?: string;
4520
- error: WireError;
4521
- willRetry: boolean;
4522
- } | {
4523
- type: "agent:schema-retry";
4524
- agentType: string;
4525
- attempt: number;
4526
- maxAttempts: number;
4527
- } | {
4528
- type: "agent:stream";
4529
- delta: string;
4530
- };
4531
- /** Tool lifecycle (emitters arrive with the tool system, M3). */
4532
- type ToolEvents = {
4533
- type: "tool:start";
4534
- toolName: string;
4535
- risk?: Json;
4536
- } | {
4537
- type: "tool:end";
4538
- toolName: string;
4539
- outcome: "ok" | "error" | "denied";
4540
- durationMs: number;
4741
+ * The lineage half of admission (DEF-3): folds are
4742
+ * computed live STRICTLY BEFORE the carrying decision entry is appended;
4743
+ * the caller embeds the returned block in the entry and replay reads it
4744
+ * back byte-exact. Enforces the single-live-attempt invariant
4745
+ * (`lineage_busy`) and monotonic attempt consumption
4746
+ * (`lineage_exhausted`); never touches budget or structural limits.
4747
+ */
4748
+ evaluateLineage(spec: {
4749
+ name: string;
4750
+ lineage?: SpawnLineageOpt;
4751
+ approach?: string;
4752
+ ancestry?: LogicalTaskId[];
4753
+ signature?: Partial<ApproachSignatureInputs>;
4754
+ }): {
4755
+ decision: {
4756
+ kind: "ok";
4757
+ lineage: SpawnLineage;
4758
+ } | {
4759
+ kind: "reject";
4760
+ reason: {
4761
+ code: "lineage_busy" | "lineage_exhausted";
4762
+ };
4763
+ };
4764
+ statsBefore?: LineageStats;
4765
+ };
4541
4766
  /**
4542
- * Audit fields (M5-T05): the chain verdict,
4543
- * the deciding layer, the matched rule, and advisory domain-rule
4544
- * matches. Telemetry, never identity; ask verdicts additionally
4545
- * journal as suspended approvals.
4767
+ * Registers a live lineage admit the moment its caller commits to
4768
+ * appending the decision entry, closing the single-live-attempt window
4769
+ * until the journal absorbs the entry (DEF-3).
4546
4770
  */
4547
- verdict?: "allow" | "deny" | "ask";
4548
- decidedBy?: string;
4549
- rule?: Json;
4550
- advisory?: Json;
4551
- };
4552
- /**
4553
- * Bare-nondeterminism detection (RV-209). Emitted LIVE by the segment
4554
- * that observed the call, at most once per (category, provenance) per
4555
- * execution segment; never journaled and never re-emitted with the
4556
- * `replayed` flag. Because replay re-executes the workflow body, a
4557
- * violation that survives in the code fires again on every replay of
4558
- * the run, so the event appears organically in both live and replayed
4559
- * streams. Exempt provenances (installed dependencies under
4560
- * node_modules and Node runtime frames) never emit: they are
4561
- * classified and silenced, which is what keeps an SDK's internal
4562
- * `Math.random()` from branding the run nondeterministic.
4563
- */
4564
- type DeterminismEvents = {
4565
- type: "determinism:warning"; /** Which patched global fired. */
4566
- category: "bare-date-now" | "bare-math-random";
4771
+ registerLineageAdmit(logicalTaskId: LogicalTaskId): void;
4567
4772
  /**
4568
- * 'workflow': the caller is workflow-origin code (the violation the
4569
- * guard exists for; rejects the run under `determinism.mode:
4570
- * 'error'`). 'allowlisted': the caller matched a configured
4571
- * `determinism.allowlist` pattern and is exempt by explicit host
4572
- * decision; emitted for visibility, never rejects.
4773
+ * Evaluates one spawn live, strictly BEFORE its decision entry is
4774
+ * appended. On admit the reserve is committed on the whole ancestor
4775
+ * account chain atomically with the evaluation; the caller journals the
4776
+ * returned decision and only then produces effects (child account,
4777
+ * dispatch). On reject nothing is committed and the reject verdict is
4778
+ * journaled by the caller so replay re-delivers it without
4779
+ * re-evaluation.
4573
4780
  */
4574
- provenance: "workflow" | "allowlisted"; /** The calling stack frame, after the configured redaction hook. */
4575
- frame: string; /** Parsed location when the frame carries one, after redaction. */
4576
- file?: string;
4577
- line?: number;
4578
- column?: number;
4579
- };
4580
- /**
4581
- * Adaptive orchestration, resolutions, and
4582
- * accounting: emitted only by runs where the corresponding machinery is
4583
- * active (applicability per mode:
4584
- * https://docs.rulvar.com/guide/adaptive-orchestration). The types land as
4585
- * one closed catalog with M7-T03; emitters arrive with their tasks.
4586
- */
4587
- type AdaptiveEvents = {
4588
- type: "plan:revised";
4589
- entryRef: number;
4590
- planHash: string;
4591
- applied: number;
4592
- dropped: number;
4593
- revisionUnitsRemaining: number;
4594
- } | {
4595
- type: "node:parked";
4596
- nodeId: string;
4597
- logicalTaskId: string;
4598
- } | {
4599
- type: "node:cancelled";
4600
- nodeId: string;
4601
- logicalTaskId: string;
4602
- } | {
4603
- type: "node:linked";
4604
- nodeId: string;
4605
- logicalTaskId: string;
4606
- donorRef: number;
4607
- reclaimedUsd: number;
4608
- } | {
4609
- type: "orchestrator:woke";
4610
- digestSeq: number;
4611
- planHash: string;
4612
- coversToOrdinal: number;
4613
- renderSize: number;
4614
- } | {
4615
4781
  /**
4616
- * Two emitted shapes share the discriminant: the cap-freeze form
4617
- * carries { atCap: true, spentUsd, capUsd, finalizeReserveUsd },
4618
- * and the per-wake digest form carries atCap plus the passive
4619
- * WakeBudgetBlock fields (runSpentUsd .. softWarning).
4782
+ * The reserve the DISPATCH layer will actually commit for this spec:
4783
+ * the estimate (or the flat default) clamped by the explicit child
4784
+ * budget when one exists, because only an explicit budget opens a
4785
+ * child-allowance account at dispatch; the childBudgetFraction cap
4786
+ * never materializes as an account and must not shrink the
4787
+ * projection. The token-count-priced estimate of ctx.agent is
4788
+ * unreachable here (async); a divergence there lands as a journaled
4789
+ * dispatch rejection instead of a strand.
4620
4790
  */
4621
- type: "orchestrator:budget";
4622
- atCap: boolean;
4623
- spentUsd?: number;
4624
- capUsd?: number;
4625
- finalizeReserveUsd?: number;
4626
- runSpentUsd?: number;
4627
- runCeilingUsd?: number;
4628
- orchestratorSpentUsd?: number;
4629
- orchestratorCapUsd?: number;
4630
- orchestratorShare?: number;
4631
- softWarning?: boolean;
4632
- } | {
4633
- type: "escalation:raised";
4634
- entryRef: number;
4635
- kind: "scope_bigger" | "scope_different" | "blocked_with_evidence";
4636
- logicalTaskId: string;
4637
- costToDateUsd: number;
4638
- } | {
4639
- type: "escalation:decided";
4640
- entryRef: number;
4641
- decision: "retry" | "decompose" | "cancel" | "accept";
4642
- by: ResolutionBy;
4643
- countsAgainstLimit: boolean;
4644
- } | {
4645
- type: "spawn:admitted";
4646
- entryRef: number; /** The admitting arms of the unified AdmitVerdict union. */
4647
- verdict: "admit" | "reuse_full" | "admit_graft";
4648
- agentType: string;
4649
- logicalTaskId: string;
4791
+ projectedDispatchReserveUsd(spec: Pick<AdmitSpec, "estCostUsd" | "budgetUsd">): number;
4792
+ admit(spec: AdmitSpec, options?: {
4793
+ commitReserve?: boolean;
4794
+ }): AdmissionDecision;
4650
4795
  /**
4651
- * Spawn-unit balance after the budget-layer debit. Present on
4652
- * budget-layer admissions (the orchestrator spawn tools and
4653
- * ctx.workflow children); absent on lineage-layer admissions
4654
- * (ctx.agent roots), whose spawn-unit debit rides the dispatch
4655
- * itself (v1.22.0 review P2-5).
4796
+ * Resume roll-forward for an orchestrator child (M6-T07): restores the
4797
+ * children-quota counter only. The budget seed already counts settled
4798
+ * agent dispatches, and an in-flight child re-commits its reserve
4799
+ * through the ctx.agent dispatch path.
4656
4800
  */
4657
- spawnUnitsAfter?: number;
4658
- } | {
4659
- type: "spawn:rejected";
4801
+ recoverChild(nodeKey: string): void;
4660
4802
  /**
4661
- * The journaled admission decision entry; absent for the
4662
- * pre-admission config gates (orchestrate maxSpawns), which
4663
- * reject before anything is journaled.
4803
+ * Resume roll-forward for a child that already SETTLED before the
4804
+ * resume: re-registers the counters (maxChildrenPerNode, the lifetime
4805
+ * cap, statsBefore fidelity) without committing any reserve; the spend
4806
+ * itself sits in the root ledger seed.
4664
4807
  */
4665
- entryRef?: number;
4666
- code: string;
4667
- agentType: string;
4668
- logicalTaskId?: string;
4669
- } | {
4670
- type: "verify:failed";
4671
- entryRef: number;
4672
- logicalTaskId: string;
4673
- rung: number;
4674
- gate: "mechanical" | "judge" | "spot-check";
4675
- } | {
4676
- type: "ledger:op";
4677
- entryRef: number;
4678
- op: "brief_set" | "fact_add" | "fact_supersede" | "lesson_add" | "observation_add";
4679
- } | {
4680
- type: "stall:detected";
4681
- logicalTaskId: string;
4682
- stallStreak: number;
4683
- } | {
4684
- type: "guard:oscillation";
4685
- spawnKeyHash: string;
4686
- oscillationCount: number;
4687
- limit: number;
4688
- } | {
4689
- type: "resolution:applied";
4690
- targetRef: number;
4691
- entryRef: number;
4692
- by: ResolutionBy;
4693
- } | {
4694
- type: "resolution:superseded";
4695
- targetRef: number;
4696
- entryRef: number;
4697
- supersededBy: number;
4698
- reason: "already_resolved" | "target_abandoned";
4699
- } | {
4700
- type: "termination:debit";
4701
- entryRef: number;
4702
- counter: string;
4703
- remaining: number;
4704
- phi: number;
4705
- } | {
4706
- type: "termination:denied";
4707
- entryRef: number;
4708
- counter: string;
4709
- code: string;
4710
- } | {
4711
- type: "termination:config-drift";
4712
- field: string;
4713
- frozenValue: Json;
4714
- liveValue: Json;
4715
- } | {
4808
+ recoverSettled(parentAccountScope: string): void;
4716
4809
  /**
4717
- * Declared for hosts; not emitted today. The compatibility scan
4718
- * runs strictly before a run's event stream exists, so the
4719
- * refusal travels only as the typed JournalCompatibilityError
4720
- * (which carries the same fields).
4810
+ * Resume roll-forward for an admission whose decision entry exists but
4811
+ * whose child has NOT settled: re-applies the recorded reserve and
4812
+ * counters without re-evaluating any limit (replay never
4813
+ * re-evaluates admission; reserves are recovered, never
4814
+ * re-estimated).
4721
4815
  */
4722
- type: "journal:compat";
4723
- code: "HASH_VERSION_TOO_OLD" | "HASH_VERSION_TOO_NEW";
4724
- found: number;
4725
- window: [number, number];
4726
- };
4727
- type WorkflowEventBody = CoreEvents | AgentEvents | ToolEvents | DeterminismEvents | AdaptiveEvents;
4728
- /**
4729
- * The envelope: seq is an independent per-run
4730
- * telemetry counter, strictly increasing in emission order and DISTINCT
4731
- * from JournalEntry.seq (never compare or join the two; entryRef fields
4732
- * carry journal seqs explicitly). ts is wall clock, telemetry only.
4733
- * replayed is true only on re-emitted journal-backed lifecycle events;
4734
- * stream deltas are never re-emitted.
4735
- */
4736
- type WorkflowEvent = {
4737
- runId: string;
4738
- seq: number;
4739
- ts: string;
4740
- spanId: string;
4741
- parentSpanId?: string;
4742
- replayed?: boolean;
4743
- } & WorkflowEventBody;
4816
+ recoverInFlight(parentAccountScope: string, verdict: AdmitVerdict): void;
4817
+ }
4744
4818
  //#endregion
4745
4819
  //#region src/engine/cost-report.d.ts
4746
4820
  /** Folds the per-run attribution buckets into the normative CostReport. */
@@ -7596,4 +7670,4 @@ interface SandboxBridge {
7596
7670
  declare const SANDBOX_AGENT_OPT_KEYS: readonly string[];
7597
7671
  declare function createSandboxBridge(ctx: Ctx<never>, options: SandboxBridgeOptions): SandboxBridge;
7598
7672
  //#endregion
7599
- export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentResult, AgentResultMeta, AgentStatus, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, CostReport, CreateEngineOptions, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, InvocationRole, type InvocationTable, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, type PhaseRow, PhaseTarget, PipelineCollected, PipelineOpts, PlanInvariantError, PriceTable, PricedUsage, type Pricing, type PricingTier, type ProviderAdapter, QualityFloors, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, Semaphore, SerializationHook, Settled, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
7673
+ export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentResult, AgentResultMeta, AgentStatus, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, CostReport, CreateEngineOptions, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, type ExplorationSummary, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, InvocationRole, type InvocationTable, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, type PhaseRow, PhaseTarget, PipelineCollected, PipelineOpts, PlanInvariantError, PriceTable, PricedUsage, type Pricing, type PricingTier, type ProviderAdapter, QualityFloors, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, Semaphore, SerializationHook, Settled, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };