/**
 * # session/agent — the Agent seam (the frozen-frame → Actions boundary of Simulate)
 *
 * Simulate is a **wake-driven, agent-in-loop** run: between wakes standing Plans fire
 * autonomously (fire-then-inform); at a Wake the runtime hands the agent a **frozen,
 * date-blind {@link ActingFrame}** and consumes the {@link AgentTurn} it returns. This module
 * defines the ONE narrow boundary the runtime invokes the author through — `open(briefing) /
 * decide(frame) / close(final)` — and the four adapters that satisfy it. The driver that walks
 * a bus, freezes the vantage, and serializes each Action onto the graded bus
 * (`runSimulateSession`) is the companion module `./simulate.ts` (next phase); it drives the
 * SAME {@link import("./sim.ts").SessionCore} the stepped day already drives, so the two share
 * one event loop and one determinism hash.
 *
 * ## Where the determinism boundary sits (the whole point)
 * The live loop is *deliberately non-deterministic* — judgment is the variable Simulate
 * measures. Everything ABOVE the boundary (Rendering the Frame, the model call, sampling) sits
 * OFF the runtime path. The boundary is the **returned {@link AgentTurn}**: exactly one value
 * crosses, and below it everything is a pure function of Bus bytes (ADR-0011). The driver stamps
 * every Action at the **injected wake ts** (no wall clock, no unseeded RNG on the record path),
 * so `project(gradedBus)` re-derives a byte-identical Blotter, and a captured run re-runs as a
 * Backtest.
 *
 * ## Four adapters, one seam, one driver
 * - {@link liveAgent}          — the model; the sole non-deterministic point, above the line.
 *                                Declared-only here — its concrete body (provider SDK, credential
 *                                injection, Rendering, token/reasoning capture) is the Agent
 *                                Harness epic's, and imports no part of the deterministic core.
 * - {@link recordedAgent}      — replays a prior run's captured turns keyed by stable wake identity
 *                                ({@link wakeKeyOf}): byte-identity replay, no model call, no Rendering.
 * - {@link fixedPlanAgent}     — arm one document at open, pass forever = a Backtest expressed
 *                                through the seam (the case where discretionary and static coincide).
 * - `fileHandshakeAgent`        — the file-handshake protocol (frames/turns as JSON files), now ONE
 *                                adapter rather than the boundary. Promoted to a versioned,
 *                                identity-stamped seam in `./harness/file-handshake.ts` (kestrel-m9i.7).
 *
 * ## Non-negotiables the seam encodes (enforced by the driver next phase)
 * - **Fail closed.** A parse escape on an authored `supersede` document, or an unparseable whole
 *   turn, → a {@link StandDownAction} turn (de-arm clean, inventory rides its TP/EXIT, logged
 *   reason); the agent can never crash the Session. A single unresolvable/past
 *   {@link ScheduleWakeAction} is the *proportionate* refuse-that-action-and-continue (the book
 *   stays armed on the staleness backstop) — NOT a book-wide stand-down. An empty `actions[]` is a
 *   legitimate pass (standing Plans keep managing). A missing {@link AgentConfig} refuses to grade,
 *   never a silent default.
 * - **Bounded risk / never naked.** {@link PlaceOrderAction} / {@link CancelOrderAction} route the
 *   SAME Gate as a fired Plan (SELL floored at intrinsic, budget clamp, never naked); price is a
 *   Kestrel expression the engine resolves, never a bare mid; `standDown` never liquidates.
 * - **Round-trip.** Two substrates, kept apart: the authored `supersede` document round-trips
 *   through Kestrel `parse`/`print` (the `tests/golden/` contract), while the non-surface actions
 *   (`standDown`/`scheduleWake`/`placeOrder`/`cancelOrder`) serialize through the SAME sorted-key /
 *   drop-undefined canonicalizer the Blotter and receipts already use — never Kestrel `print()`.
 *
 * This module is an **extraction** from `./day.ts`, not a greenfield: the frozen-at-wake
 * checkpoint (`events[idx].ts < w.ts`), the date-blind author projection (`projectAuthorFrame`),
 * and supersede+arm already exist there. Simulate's one behavioral change is that the wake set
 * stops being a precomputed static list and becomes agent-driven via {@link ScheduleWakeAction},
 * still floored by the staleness backstop and coalesced/downgraded past the attention budget.
 */
import type { WakeDeltaInput, BriefingInput } from "../frame/types.ts";
import type { ViewSelection } from "../frame/pane-catalog.ts";
import type { SeatViewsPolicy } from "../frame/seat.ts";
import type { CorpusTier, Face, TokenAccounting } from "../bus/types.ts";
/**
 * The agent **config** — the comparison axis of Simulate (same input bus, many configs),
 * stamped onto the graded bus META as a judge self-description (alongside `fill_model`), so a
 * cell coordinate is a pure read of the record.
 *
 * This IS the a57.14 experimental envelope's **input half** — a single definition, never a second one
 * (the agent-harness ADR (d)). {@link import("./config.ts").canonicalizeConfig} folds it to the canonical descriptor
 * (`ModelIdentity` ⊕ `SamplingConfig` ⊕ `RenderingIdentity` ⊕ `AuthorPolicy` → `ConfigId =
 * sha256(canonical)`, the grid column key), and {@link import("./config.ts").envelopeForConfig} maps it to
 * the {@link import("../bus/types.ts").ExperimentalEnvelope} the Simulate driver stamps — the same value in
 * two shapes, never two truths (ADR-0011).
 *
 * The first six fields are the mechanical core every run carries (a NO-LLM Backtest carries only these —
 * {@link BACKTEST_CONFIG}). The envelope-identity fields below are OPTIONAL: a config that declares any of
 * them is an authoring run whose envelope is stamped; a Backtest declares none, so no envelope is stamped and
 * the Blotter stays `certified` (fail-closed by omission — never a fabricated identity, a57.14).
 */
export interface AgentConfig {
    /** The pinned model identity (family/snapshot). Credentials are NEVER part of the config. */
    readonly model: string;
    /** The Rendering tokenizer identity — the tokenizer token costs are measured under. */
    readonly tokenizer: string;
    /** The Rendering format (the Frame is rendered to tokens INSIDE the live adapter). */
    readonly format: "ascii" | "unicode" | "md" | "json" | "html";
    readonly temperature: number;
    readonly thinkingLevel: "none" | "low" | "medium" | "high" | "max";
    /** The leaderboard / `BY` key (names are data, ADR-0006). */
    readonly label: string;
    /** SamplingConfig — the **fill-realization seed** for the sampled (seeded-Bernoulli) fill channel
     * (ADR-0016 / kestrel-9gu.8.1). Present ⇒ the SimFillEngine draws causal fills off a `runSeed`-keyed
     * mulberry32 substream (`hash(runSeed, model.version, order.ref, episodeIndex)`); **absent ⇒ the sampled
     * channel is OFF** (fail-closed — the run grades floor+expected only, no realized draws). It folds into
     * the {@link import("./config.ts").deriveConfigId ConfigId} (a sampling knob, like `temperature`) but is
     * NOT an envelope-identity field, so two runs differing only in `fillSeed` are REPLICATES under one
     * {@link import("./run-identity.ts").CellKey CellKey} (same tape × fill_model × envelope) yet each yields a
     * distinct {@link import("./run-identity.ts").SimRunId SimRunId} — the ensemble (`baseSeed + i`). */
    readonly fillSeed?: number;
    /** ModelIdentity — the model provider/family (a generic vendor label; NEVER a credential). */
    readonly provider?: string;
    /** ModelIdentity — the model version/snapshot token. */
    readonly version?: string;
    /** ModelIdentity — the model's training cutoff (the basis for model-relative holdback gating). */
    readonly trainingCutoff?: string;
    /** RenderingIdentity — how the Frame was rendered to tokens (distinct from `format`, which rides the ConfigId). */
    readonly renderingIdentity?: string;
    /** AuthorPolicy — the sha256 HASH of the author prompt/profile (a HASH, NEVER the prompt content). */
    readonly promptHash?: string;
    /** AuthorPolicy — the sha256 HASH of the author's BRIEF (ADR-0026 — the soft, directional English
     * persona/goal). A HASH, sibling to {@link promptHash}, NEVER the brief text: it binds "this
     * performance came from this thesis" into the run/grade provenance (folds into the ConfigId /
     * grid column, so a rebrief mints a new column). The Brief itself is rendered into the frame from
     * the cell/kernel and can NEVER enter admission — only the mandate/envelope do (the hard guard). */
    readonly briefHash?: string;
    /** AuthorPolicy — the tool policy the author ran under (e.g. `no-tools`). */
    readonly toolPolicy?: string;
    /** AuthorPolicy — what woke the author (e.g. `structural-cadence`). */
    readonly wakeSource?: string;
    /** AuthorPolicy — the corpus tier the author draws on — the CLOSED {@link CorpusTier} vocabulary
     * (`public`|`semi-private`|`private`, ADR-0018 three tiers), the practice-vs-holdback wall (kestrel-m9i.26).
     * Closed at capture (mirror {@link face}); the projector re-checks the injected bytes fail-closed. */
    readonly corpusTier?: CorpusTier;
    /** The interface {@link Face} the author reaches the model through (`http`|`sdk`|`cli`|`mcp`) — the
     * m9i.7 tournament axis (m9i.2 owner tweak). Declared by the CALLER (who knows the transport); a
     * harness never fabricates it — an undeclared face fails the envelope closed to PROVISIONAL. */
    readonly face?: Face;
    /** The adapter/harness identity that drives the author (m9i.2 owner tweak — mandatory-for-certified
     * BEFORE the m9i.7 harness tournament). `liveAgent` stamps its own identity when the caller leaves it
     * unset (the harness KNOWS itself — never a fabricated third-party identity). */
    readonly adapter?: string;
    /** The adapter/harness version/revision token (paired with `adapter`). */
    readonly adapterVersion?: string;
    /** The EXTERNALLY-DECLARED brain identity the shared `adapter` (e.g. `file-handshake`) drives — the
     * m9i.7 harness-tournament pivot: `claude-code/2.x` | `codex/x` | `opencode/x` | `first-party-liveagent`
     * (kestrel-m9i.7 stage-0). CFG-only, NOT an a57.14 envelope field (the certified envelope stays exactly
     * 14 fields), yet it folds into {@link import("./config.ts").deriveConfigId ConfigId} — which the grid
     * CellKey keys on — so two runs differing only in `harness` are DISTINCT grid columns. Declared by the
     * CALLER (the harness names ITSELF); a shared adapter never fabricates it. */
    readonly harness?: string;
    /** The `harness` version/revision token (paired with `harness`) — folds into the ConfigId alongside it. */
    readonly harnessVersion?: string;
    /** The prompt-cache / conversation-reuse policy the live harness ran under (kestrel-rul; System Profile
     * v1.1 `cache policy` slot). A **ConfigId axis only** (like `format`/`temperature`), NOT an envelope-identity
     * field: caching is transport-side and OFF the graded path, so two runs differing only in `cachePolicy`
     * grade byte-identically yet land in DISTINCT grid columns — exactly the A/B m9i.5 sweeps (append-only KV
     * reuse vs stateless redraw, cache on/off). `liveAgent` stamps the policy it actually ran under when the
     * caller pins none (the harness knows its own transport). See {@link CachePolicy}. */
    readonly cachePolicy?: CachePolicy;
    /** The provider prompt-cache TTL the `conversation-cached` policy requests on its breakpoints (kestrel-wa0j.1).
     * ABSENT ⇒ the provider default (Anthropic 5-minute ephemeral / Bedrock default cachePoint) — the request
     * bytes and ConfigId are byte-identical to before this axis existed. `"1h"` opts a live-paced session (wakes
     * > 5 min apart) into the 1-hour TTL, so the stable prefix survives between wakes instead of expiring and
     * re-writing at the cache-write premium every wake. Like {@link cachePolicy}, a **ConfigId axis only** —
     * never an envelope field — so a changed TTL mints a distinct grid column. Fail-closed: a `cacheTtl` on a
     * config whose policy requests no cache breakpoints (anything but `conversation-cached`), or on a provider
     * lane with no explicit breakpoint primitive, throws rather than riding silently inert. */
    readonly cacheTtl?: CacheTtl;
    /** The INJECTED token accounting (off the deterministic record path — the owner-away default). */
    readonly tokenAccounting?: TokenAccounting;
    /** The **clock-honest session-semantics switch** (ADR-0040 / kestrel-w7la.1, clock-honest wakes §4):
     * `true` ⇒ deliberation consumes tape time — a Seat's turn is measured at the driver's injectable
     * `now` seam, buffered by {@link latencyBufferMs}, recorded on the Bus as a `deliberation` record,
     * and its control lands at `returnTs = vantageTs + measured + buffer`. Absent ⇒ latency-blind,
     * byte-identical driver behavior to today. A ConfigId axis (it folds into `deriveConfigId`
     * automatically), never an envelope-identity field — a clocked run can NEVER share a grid column
     * with an unclocked one. When the ADR-0032 cascade lands this stays session-scoped (all seats or
     * none); {@link latencyBufferMs} becomes per-seat. */
    readonly clockHonest?: true;
    /** The configured network/infra latency allowance added to EVERY measured Seat turn under
     * {@link clockHonest} (clock-honest wakes §4). Integer milliseconds. **No default (decided)**: a
     * clock-honest session with this absent (or non-integer, or negative) is REFUSED loudly at open —
     * "never a silent default", and any designed default would be a judge-designed weighting (ADR-0030
     * spirit: the clock is measured, not designed). `0` is legal and visible: it declares a colocated
     * seat in the column identity. Governed seasons pin the production value platform-side
     * (PLAT-ADR-0033). A ConfigId axis like {@link clockHonest}. */
    readonly latencyBufferMs?: number;
    /** The **founder-View opt-in** (ADR-0041 §2 / A1, kestrel-wa0j.26). `"founder"` ⇒ the driver passes
     * the acting tier's pod SEAT into the render's `resolveView` (strategist at OPEN, watcher at wakes),
     * so a seat with a founder seed reads its GRADED founder View when it authored none — a distinct
     * experimental subject. Founder Views are SEEDS, never blessed defaults, so this is OFF by default:
     * absent (or `"phase-default"`) ⇒ no seat is consulted ⇒ the frame-kind default panes, byte-identical
     * to before this axis existed. A ConfigId axis (it folds into {@link import("./config.ts").deriveConfigId
     * deriveConfigId} automatically, like {@link clockHonest}/`cachePolicy`), NEVER an a57.14 envelope
     * field — so a founder-View run mints a DISTINCT grid column while the certified envelope stays exactly
     * 14 fields. Absent ⇒ every existing ConfigId is byte-identical (drop-undefined canonicalizer). */
    readonly seatViews?: SeatViewsPolicy;
}
/**
 * How the live harness reuses a session's conversation across wakes — the prompt-cache economics lever
 * (kestrel-rul, the CONTEXT "Streaming Rendering (cache-monotone)" doctrine). A pure {@link AgentConfig}
 * axis: it selects transport behaviour ABOVE the determinism line and never changes the returned
 * {@link AgentTurn}, so a recorded run replays byte-identically regardless of the policy it ran under.
 *
 * - `stateless-redraw` — v0: each wake re-renders its frame as ONE fresh user message with no prior turns
 *   in context and no cache markers (the model has no memory of earlier wakes). The redraw arm for m9i.5.
 * - `conversation` — the session is a GROWING message list (byte-stable system + briefing + each wake's
 *   appended delta frame + the model's prior replies), so the model sees the whole session, but no provider
 *   prompt-cache control is requested.
 * - `conversation-cached` — `conversation` PLUS a provider prompt-cache breakpoint on the byte-stable
 *   prefix (Anthropic `cache_control` / Bedrock cache-point via the AI SDK), so the stable prefix is billed
 *   as a cache-read (~0.1×) instead of full-price on every wake. The default the live harness runs under.
 */
export type CachePolicy = "stateless-redraw" | "conversation" | "conversation-cached";
/**
 * The provider prompt-cache TTL requested on every breakpoint the `conversation-cached` policy marks
 * (kestrel-wa0j.1). The values are the two TTLs the Anthropic-family cache actually serves (`cache_control
 * ttl` on the direct API, `cachePoint.ttl` on Bedrock — verified against the installed AI-SDK providers).
 * The economics: a 5-minute entry costs 1.25× to write; a 1-hour entry costs 2× to write but survives a
 * live-paced session's inter-wake gaps — under the default 5m TTL, wakes > 5 min apart MISS the expired
 * cache and re-write the whole prefix at 1.25× every wake, making `conversation-cached` the most expensive
 * policy exactly where it should be the cheapest. Absent ({@link AgentConfig.cacheTtl} undefined) ⇒ the
 * provider default rides the wire — byte-identical to before this axis existed.
 */
export type CacheTtl = "5m" | "1h";
/**
 * The ONE shared refusal text for a configured {@link CacheTtl} that cannot reach the wire
 * (kestrel-wa0j.1). THREE independent guards refuse for three different reasons — the live-agent
 * policy gate (a {@link CachePolicy} that marks no breakpoints), the AI-SDK breakpoint builder (a
 * provider lane with no breakpoint primitive), and the codex-cli lane (no cache-control flag at
 * all) — but the doctrine is one: a ConfigId column must never claim a cache TTL the provider
 * never saw (a configured knob silently inert is exactly what fail-closed forbids). Each guard
 * supplies its own `blocker` (why THIS layer cannot carry the TTL) and, optionally, a `remedy`.
 */
export declare function cacheTtlNeverReachesWire(ttl: CacheTtl, blocker: string, remedy?: string): string;
/**
 * Does `provider` expose an explicit per-request prompt-cache breakpoint primitive a {@link CacheTtl}
 * can ride (kestrel-wa0j.19 §4)? TRUE only for the Anthropic-family lanes — `anthropic` (`cacheControl`)
 * and `bedrock` (`cachePoint`) — the two the AI-SDK wire guard ({@link import("./harness/ai-sdk-client.ts").cacheBreakpoint})
 * can attach a `ttl` to. Every other lane (Gemini/OpenAI-compatible/gateway/local/codex-cli/…) caches
 * IMPLICITLY with no breakpoint to carry a TTL, so a configured `cacheTtl` there would never reach the
 * wire. PROVIDER-FREE (a pure string check, imports no provider SDK), so the deterministic core — and
 * {@link import("./harness/live-agent.ts").liveAgent}'s CONSTRUCTION gate — can refuse a misconfigured
 * `cacheTtl × provider` column BEFORE a session of provider-error passes burns, while the wire guard
 * stays as defense in depth. A blank/unknown provider is NOT positively refused here (the caller may
 * pin none — a mock/test); the wire guard is the backstop for what reaches an actual provider.
 */
export declare function providerSupportsCacheTtl(provider: string): boolean;
/** How urgent this wake is (authored PRIORITY for author wakes; a platform default otherwise). */
export type WakeSeverity = "routine" | "elevated" | "urgent";
/** WHICH frontier raised a wake — the driver's own provenance for a delivery, and the stable half of the
 * {@link WakeKey} replay identity. Lives on the seam (not in the driver) because it crosses to the agent
 * on every {@link ActingFrame}: `agent` (the author's own {@link ScheduleWakeAction}), `seed` (an authored
 * fixture vantage), `own-fill` (the seeded run's fire-then-inform management wake, ADR-0016), `structural`
 * (the cadence), `staleness` (the platform backstop), `latency-fold` (the clock-honest catch-up delivery —
 * ONE vantage at the Seat's return time carrying every wake that fell inside its open deliberation window,
 * ADR-0040 / clock-honest wakes §2.3; CONTEXT "Latency-fold"). */
export type WakeSource = "agent" | "seed" | "own-fill" | "structural" | "staleness" | "latency-fold";
/** Per-signal data health at the wake vantage — date-blind (a clock, never a date). `stale` /
 * `unavailable` name the instruments/capabilities the runtime could not resolve, so the agent
 * always sees what is UNKNOWN rather than a guessed default (fail-closed). */
export interface DataHealth {
    /** The `HHMM` ET clock this health snapshot was taken at (dateless). */
    readonly asOfClockET: string;
    /** Instruments whose canonical series is stale this vantage. */
    readonly stale: readonly string[];
    /** Capabilities currently UNKNOWN (a de-armed pane / series), each with its reason upstream. */
    readonly unavailable: readonly string[];
}
/** The sim-time horizon around the wake — NOT a think budget (phase 1 is frozen-at-wake, so
 * fast and slow models decide on byte-identical Frames). Any horizon may be `null` ⇒ `—`. */
export interface WakeDeadline {
    readonly minutesToClose: number | null;
    readonly minutesToNextWake: number | null;
}
/**
 * The acting Frame handed to the agent at a Wake — **identical bytes for every Agent** (frozen-
 * at-wake isolates judgment). A superset of the existing {@link WakeDeltaInput} (tape/levels/
 * kernel since the last vantage) plus the acting-kernel strip. All fields are date-blind: relative
 * time and the `HHMM` ET clock only (the contamination fence).
 */
export interface ActingFrame extends WakeDeltaInput {
    /** The 0-based GLOBAL wake ordinal — this delivery's position in the session's wake sequence (distinct
     * from the inherited `wakeIndex` display field). A display/log coordinate, NOT the replay key: it is
     * unstable under vantage insertion (see {@link wakeKeyOf}). */
    readonly wakeOrdinal: number;
    /** WHICH frontier raised this delivery — the stable half of the {@link WakeKey} replay identity
     * (kestrel-5zl.19). */
    readonly wakeSource: WakeSource;
    /** The 0-based MONOTONE PER-SOURCE ordinal — this wake's position among the wakes THIS source RAISED,
     * minted at the raise (kestrel-5zl.20). Unlike {@link wakeOrdinal} it does not move when a *different*
     * source inserts a vantage, NOR when an earlier delivery is folded (spacing/budget/own-fill/probe). */
    readonly wakeSourceOrdinal: number;
    /** The relative-day coordinate `d{k}` (kestrel-5zl.16.4): this session's ordinal in its Instance,
     * pinning no calendar date. Present ONLY for a multi-session run; absent (and unserialized) for a
     * standalone session — so existing single-session acting-frame goldens are byte-identical. Paired with
     * the per-session `sinceOpenMs`/`clockET` (both reset at each session's open), it is how the agent tells
     * the days of a horizon apart without any calendar identity reaching the frame. */
    readonly sessionOrdinal?: number;
    readonly severity: WakeSeverity;
    readonly deadline: WakeDeadline;
    readonly dataHealth: DataHealth;
    /** The View delivered WITH this wake (kestrel-wa0j.4): the scheduled wake's stored View
     * ({@link ScheduleWakeAction.view}), resolved fail-closed at schedule time — the wake decides
     * *when*, the View decides *what* (CONTEXT "Wake delivery"). Absent ⇒ the frame-kind default
     * WAKE panes, byte-identical to a view-less delivery. The kernel stays OUTSIDE this selection,
     * and the View budget guard applies at materialization exactly as on OPEN. */
    readonly view?: ViewSelection;
    /** Attention accounting — the squelch stays visible, never silently dropped. */
    readonly attention: {
        /** Wakes remaining under the attention budget; `null` ⇒ unbounded/unknown. */
        readonly wakesRemaining: number | null;
        /** Same-key wakes folded into this delivery (coalesced past the budget). */
        readonly coalesced: number;
    };
}
/** A dateless sim-time instant the agent schedules its next Wake for. An unresolvable/past value
 * is refused-and-logged (the book rides the staleness backstop), never a book-wide stand-down. */
export type WakeAt = {
    readonly kind: "inMinutes";
    readonly minutes: number;
} | {
    readonly kind: "atClockET";
    readonly clockET: string;
};
/** A single-leg order intent. `price` is a **Kestrel expression** the engine resolves and gates
 * exactly like a fired Plan's price (never a bare mid; SELL floored at intrinsic).
 *
 * `strike`+`right` follow the ADR-0017 leg convention: BOTH present ⇒ an OPTION order (option-chain
 * fill path); BOTH absent ⇒ an EQUITY/SPOT order (spot-fill path). Exactly one present is a defect the
 * parser fails closed on — never a silent equity fallback. `qty` is contracts for an option, shares for
 * equity. */
export interface OrderIntent {
    readonly side: "buy" | "sell";
    readonly instrument: string;
    /** Present TOGETHER with `right` for an option; BOTH absent for an equity/spot order (ADR-0017). */
    readonly strike?: number;
    readonly right?: "C" | "P";
    readonly qty: number;
    /** A Kestrel price expression (e.g. `@fair`, `cap fair,0.80`) — resolved + gated, never a raw mid. */
    readonly price: string;
}
/** Author or revise the standing document. The first turn's supersede is the initial arm. A parse
 * escape on `document` → a {@link StandDownAction} turn (fail-closed). Only the embedded `document`
 * is a Kestrel surface statement (`print(parse(document))` round-trips). */
export interface SupersedeAction {
    readonly kind: "supersede";
    /** Kestrel source (a View/Wake/Plan document — decision, record, and executable in one object). */
    readonly document: string;
    readonly note?: string;
}
/** Self-defined cadence atop the platform staleness backstop + optional structural cadence. */
export interface ScheduleWakeAction {
    readonly kind: "scheduleWake";
    readonly at: WakeAt;
    readonly reason: string;
    /** An optional View selection to deliver at the scheduled wake. */
    readonly view?: string;
}
/** Place a single-leg order — routed through the SAME Gate as a fired Plan (never naked). */
export interface PlaceOrderAction {
    readonly kind: "placeOrder";
    readonly order: OrderIntent;
    readonly note?: string;
}
/** Cancel a resting order by `ref` (from the Frame kernel's resting list). An unknown ref is
 * refused-and-logged (fail-closed), not a stand-down. */
export interface CancelOrderAction {
    readonly kind: "cancelOrder";
    readonly ref: string;
    readonly note?: string;
}
/** De-arm clean — inventory rides its TP/EXIT. The fail-closed default (never liquidates). */
export interface StandDownAction {
    readonly kind: "standDown";
    readonly reason: string;
}
/** FLATTEN a held position (bd if0 / 75n): the first-class "get me out now". For every managing plan
 * holding `instrument`, the engine cancels its resting orders (neutralizing the rolling TP re-post that
 * defeats a bare `cancelOrder`) AND crosses a COVERED close through the SAME admission Gate a fired Plan
 * uses — so never-naked still holds (a flatten of a HELD long is a covered sell; SELL floored at
 * intrinsic) and it can NEVER create a naked position. After a flatten the position is flat and its R is
 * freed (bd 1a8). A flatten of a flat book is a clean no-op. Unlike `standDown` (de-arm, inventory RIDES),
 * `flatten` actually LIQUIDATES the named position. */
export interface FlattenAction {
    readonly kind: "flatten";
    readonly instrument: string;
    readonly note?: string;
}
/** What the agent may DO at a wake. Each serializes to a CONTROL/ORDER/JOURNAL bus event; the
 * order actions route via the Gate and land as ORDER events (bounded-risk enforced there). */
export type Action = SupersedeAction | ScheduleWakeAction | PlaceOrderAction | CancelOrderAction | FlattenAction | StandDownAction;
/** One turn = everything decided at one wake. `journal`, when present, becomes a **pre-hoc**
 * JOURNAL `author` event (provably pre-hoc by `seq` — written BEFORE arming). An empty `actions[]`
 * is a legitimate pass (standing Plans keep managing). */
export interface AgentTurn {
    readonly actions: readonly Action[];
    readonly journal?: string;
}
/**
 * The **view-request outcome** (ADR-0029 §1, Option C) — a DISTINCT top-level authoring reply, NOT
 * an {@link Action}: it is the only agent output that lives ABOVE the determinism line and NEVER
 * becomes a Bus event (folding it into the {@link Action} union would break "every Action is a Bus
 * event"). Its `view` payload is a Kestrel VIEW document (validated to a SINGLE `View` statement, so
 * `print(parse(view))` round-trips and the panes come from the one catalog), and `reason` is the
 * agent's stated why — the emergence-log signal (§5). Honored ONLY under a viewshop-enabled config;
 * under the baseline an emitted `requestView` is an unknown/illegal outcome (fail-closed).
 */
export interface RequestView {
    /** A Kestrel VIEW document — exactly one `VIEW` statement selecting panes from the one catalog. */
    readonly view: string;
    /** Why this lens, now (against the Brief) — logged as evidence, never a graded input. */
    readonly reason: string;
}
/**
 * The classified result of ONE authoring-window model call (ADR-0029 §1/§2). The bounded OPEN loop
 * branches on the three variants; two of them are NON-terminal (they consume the shared dual budget
 * and the driver re-asks):
 *  - `turn`        — a valid TERMINAL {@link AgentTurn} (`supersede`/`standDown`/empty pass);
 *  - `requestView` — a well-formed, non-terminal lens request; the driver materializes it at the SAME
 *                    frozen cutoff and re-asks (the shopping half of the loop);
 *  - `invalid`     — a repairable defect; the driver surfaces `reason` (the repair-guiding error) and
 *                    re-asks the model to fix and resubmit (the repair half — ADR-0029's approved
 *                    sibling, unified here). `reason` becomes the terminal fail-closed pass ONLY once
 *                    the budget is spent.
 */
export type AuthoringReply = {
    readonly kind: "turn";
    readonly turn: AgentTurn;
} | {
    readonly kind: "requestView";
    readonly request: RequestView;
} | {
    readonly kind: "invalid";
    readonly reason: string;
};
/** How the driver drives one in-window authoring re-entry ({@link Agent.authoringOpen}). Exactly one
 * of these framings applies per call: materialize the briefing under `view` (a lens), OR — when
 * `repairError` is set — re-ask the model to fix its last invalid author (a repair). The very first
 * call carries neither (the incumbent default View, the baseline ask). */
export interface AuthoringOpenOptions {
    /** Materialize the OPEN briefing under this lens (a requested View); absent ⇒ the incumbent default
     * View. The SAME frozen briefing snapshot / cutoff — a lens, never a look-ahead (ADR-0029 §3). */
    readonly view?: ViewSelection;
    /** A repair re-ask: surface this repair-guiding error to the model (do NOT re-render a frame) and
     * ask it to fix and resubmit. Mutually exclusive with a fresh `view` materialization in practice. */
    readonly repairError?: string;
}
/** One in-window authoring call's result: the classified {@link AuthoringReply} plus the model spend.
 * `usage` (input + output + thinking, incl. cache splits) is summed by the driver into the
 * `authoringTokenBudget` AND folds into cumulative session spend — so a model that needs many
 * iterations scores lower on the `ev_per_ktoken` attention axis (ADR-0029 §7). `latencyMs` is audit
 * evidence only, off the graded path. */
export interface AuthoringStep {
    readonly reply: AuthoringReply;
    readonly usage: LlmUsage;
    readonly latencyMs?: number;
}
/**
 * THE WAKEHANDLER SEAM (CONTEXT.md "WakeHandler"). The adapter boundary between the ONE session
 * driver ({@link import("./simulate.ts").runSimulateSession}) and its author: at each wake the driver
 * hands the adapter the delivered Frame ({@link BriefingInput} at OPEN, {@link ActingFrame} at every
 * wake) and the adapter returns the author's response — new/superseding statements (an
 * {@link AgentTurn}), or nothing (an empty pass). Stateful across ONE Session (the live adapter owns
 * its conversation / KV cache; delta Frames arrive append-only, ADR-0008) but it never touches the
 * clock, the bus, or the market.
 *
 * **The adapter is the ONLY place wall time may exist** (an external author deliberating); **the
 * driver owns tape-time accounting** (the Deliberation record, the Latency-fold — ADR-0040)
 * UNIFORMLY, ABOVE this seam. That accounting must NOT live per-adapter: it is minted once at the
 * driver's single `now` seam ({@link import("./simulate.ts").runSimulateSession}'s `clockedTurn`),
 * so day-compat and in-process and (later) the platform DO adapter can never drift a second clock.
 * A response that tries to carry driver-owned tape-time back through this seam is REFUSED fail-closed
 * ({@link assertHandlerResponseTimeless}) — the response channel is authored statements only.
 *
 * **The wake boundary is CHECKPOINT-CAPABLE.** Driver state is serializable while a response is
 * pending, so the platform `SimulationSessionDO` can become a fourth WakeHandler adapter in a later,
 * separate slice (kestrel-3wik notes this; it is deliberately NOT implemented here). The
 * checkpointable driver state at the seam is exactly: the pending wake frontier + its cursor
 * (`frontier`, `idx`, `prevVantageTs`, `prevWakeSeq`), the delivery accounting (`delivered`,
 * `coalesced`, `sourceOrdinals`, `pendingCatchUp`, `fillWatermark`, `deliveredWakeTs`), the armed
 * standing state (`armed`, `authoredWakesPerDay`), and the {@link SessionCore} — every one a pure
 * value/offset off the injected `firstTs`/`session_date` (no wall clock, no RNG), so a resumed
 * driver re-projects byte-identically.
 *
 * The four adapters that satisfy this seam today — {@link liveAgent} (in-process), {@link recordedAgent}
 * (replay), {@link fixedPlanAgent} (autonomous no-op / backtest), and the day file-handshake adapter —
 * are the three WakeHandler modes of the decided design (arch-review B5): the autonomous no-op, the
 * file-handshake external author, and the in-process Agent, over the ONE shared driver.
 *
 * `decide` is `async` because the live loop is deliberately non-deterministic; the recorded and
 * fixed adapters resolve synchronously.
 */
export interface WakeHandler {
    readonly config: AgentConfig;
    /** Open the Session on the OPEN keyframe: arm the initial document, or stand down. */
    open(briefing: BriefingInput): Promise<AgentTurn> | AgentTurn;
    /** Decide at one Wake on the frozen {@link ActingFrame}. */
    decide(frame: ActingFrame): Promise<AgentTurn> | AgentTurn;
    /** Optional end-of-horizon debrief at settle — a post-hoc JOURNAL `debrief`. (Exercising a
     * close *decision* turn that routes end-of-horizon actions through the Gate is a next-phase
     * refinement; this seam keeps close to the debrief note for now.) */
    close?(final: ActingFrame): Promise<string | void> | string | void;
    /**
     * The bounded OPEN authoring loop's in-window re-entry (ADR-0029 §2/§6). Present ONLY on a
     * **viewshop-enabled** adapter — its presence IS the config gate: when the driver sees it, it runs
     * the bounded loop through this instead of {@link open}; when it is absent (baseline, recorded,
     * fixed-plan) the driver runs the single-shot {@link open} and the view-request move does not exist.
     *
     * Each call is ONE model call at the SAME frozen vantage: it materializes the briefing under
     * `opts.view` (or the incumbent default View), or — when `opts.repairError` is set — re-asks the
     * model to fix its last invalid author, and returns the classified {@link AuthoringStep}. The adapter
     * reuses its growing conversation across calls, so the model shops/repairs WITH memory. Only the
     * driver-selected TERMINAL turn ever enters {@link CapturedTurns}, so {@link recordedAgent} (which
     * never implements this) replays byte-identically with zero new graded-path machinery (§5).
     */
    authoringOpen?(briefing: BriefingInput, opts: AuthoringOpenOptions): Promise<AuthoringStep>;
    /**
     * The REPLAY-mode deliberation-cost source (ADR-0040 / clock-honest wakes §7). Present ONLY on a
     * replay adapter ({@link recordedAgent}); its very presence tells the driver this run's cost source
     * is the capture, so the driver NEVER touches its injectable clock (replay never re-times — the
     * poisoned-clock fixture proves it). Three answers, each pinned:
     *  - a number — the recorded `measuredMs` of the Seat-answered turn at `key` (buffered + recorded
     *    exactly like a live measurement);
     *  - `null`   — the capture holds NO turn at `key`: the replay machinery SYNTHESIZED one (a
     *    divergence stand-down / inserted-vantage pass). Engine-minted, not Seat deliberation — it
     *    costs 0, takes no buffer, and records nothing (charging tape for a turn no Seat took would
     *    fabricate cost);
     *  - `undefined` — the capture holds a turn at `key` but no cost: a COSTLESS (latency-blind /
     *    legacy) capture. Under `clockHonest: true` the driver refuses loudly at open — a costless
     *    capture replays only latency-blind (never a silent downgrade).
     */
    recordedCostMs?(key: WakeKey): number | null | undefined;
}
/**
 * The historical name for the {@link WakeHandler} seam — retained as an alias so every existing
 * adapter (`recordedAgent`/`fixedPlanAgent`/`liveAgent`/the day file agent) and their consumers keep
 * their `Agent` type annotations while the canonical CONTEXT.md vocabulary (`WakeHandler`) lands
 * (kestrel-3wik). A follow-up bead does the flat call-site rename; nothing behavioural rides on the
 * name, so the alias keeps this slice byte-identical.
 */
export type Agent = WakeHandler;
/**
 * Fail-closed fence over a {@link WakeHandler} response at the driver's consult seam (kestrel-3wik) —
 * the belt that mechanically enforces "the driver owns tape-time accounting UNIFORMLY, above the
 * seam; it must not live per-adapter" (CONTEXT.md "WakeHandler"). Mirrors {@link assertFrameDateBlind}
 * (the date-blind fence at the acting-Frame boundary): a pure inspection that is a NO-OP on a
 * conformant turn (`{ actions, journal? }`) and THROWS on any response smuggling a driver-owned
 * tape-time field back through the seam. Wired through the REAL driver at every consult site (OPEN +
 * every wake, latency-blind AND clocked), so the guard is proven WIRED by a fixture that goes red
 * without it — never a green unit test of an inert function (AGENTS.md non-negotiable).
 */
export declare function assertHandlerResponseTimeless(turn: AgentTurn): AgentTurn;
/**
 * The **stable wake identity** one captured turn is keyed by (kestrel-5zl.19) — `<source>#<k>#<trigger>`:
 * the wake's {@link WakeSource}, its MONOTONE PER-SOURCE ordinal, and its trigger (the semantic
 * `wakeReason`). Never the global wake ordinal: the ordinal is a function of the WHOLE frontier, so any
 * source that inserts a vantage the recording never held (the seeded run's `own-fill` management wake,
 * ADR-0016 / kestrel-9gu.8.3) shifts every later ordinal and silently re-joins the recorded stream one
 * wake off. A per-source ordinal is NARROWER: another source raising a vantage does not, by itself, move
 * it. Carrying the trigger too makes a genuine divergence MISS (fail closed) rather than misattribute a
 * decision the agent made at some other vantage.
 *
 * `k` is minted where the wake is RAISED (kestrel-5zl.20) — on the `FrontierWake` at `pushFrontier` in
 * `./simulate.ts` — and carried through to the {@link ActingFrame}, so it counts RAISES of a source, NOT
 * deliveries. This closes the residual 5zl.19 only narrowed: delivery is a decision of the WHOLE frontier
 * (an inserted `own-fill` delivery advances `prevVantageTs` and the global delivered-budget counter, so it
 * can FOLD — by `minWakeSpacingMin` / `effectiveMaxWakes` — a wake the recording DID deliver), but the
 * folded wake already consumed its `k` at the raise, so the next same-source wake keeps its OWN raise
 * ordinal instead of inheriting the folded wake's. The key therefore no longer depends on whether a
 * delivery survived folding: a survivor never collides with a folded wake's recorded key, and the silent
 * misjoin that class produced is eliminated (not merely narrowed).
 */
export type WakeKey = string;
/**
 * One captured turn PLUS its deliberation cost (ADR-0040 / kestrel-w7la.1, clock-honest wakes §7):
 * ADR-0012 §4's "one value crosses the determinism line: the {@link AgentTurn}" becomes "the
 * `AgentTurn` plus its deliberation cost". `measuredMs` is minted ONCE, live-side, at the driver's
 * injectable `now` seam — integer ms of the Seat's WHOLE awaited turn (bounded authoring loop and
 * repair retries included); a synchronous adapter legitimately measures 0.
 *
 * `measuredMs` is ABSENT exactly when the run never measured — a latency-blind session, or a legacy /
 * externally-captured (run-dir) recording. Such a **costless** capture replays ONLY under
 * latency-blind semantics: replaying it with `clockHonest: true` is REFUSED loudly at open (a silent
 * cost-0 stand-in would let a latency-blind record claim a clock-honest result — the exact silent
 * downgrade §7 forbids). Absent-vs-0 is load-bearing: `0` is a measured colocated turn; absent is
 * "never measured".
 */
export interface CapturedTurn {
    readonly turn: AgentTurn;
    /** Measured wall ms of the Seat's whole turn at this vantage (integer ≥ 0). Absent ⇒ a costless
     * (latency-blind / legacy) capture — see above. */
    readonly measuredMs?: number;
}
/**
 * Captured turns keyed by stable {@link WakeKey} — the deterministic replay input. NOT stored as Kestrel
 * `print()` text: only an embedded `supersede` document is a Kestrel surface statement, so the
 * replay substrate serializes each Action's control/order envelope through the SAME sorted-key /
 * drop-undefined canonicalizer the Blotter and receipts use, while the embedded document keeps its
 * Kestrel `parse`/`print` round-trip. Replaying these re-emits identical Bus events at identical
 * wake ts (byte-identity, not re-computation). Each entry carries the turn AND — on a clocked run —
 * its recorded deliberation cost ({@link CapturedTurn}), so a clock-honest replay re-projects from
 * recorded time and never re-times (ADR-0040 §7).
 */
export type CapturedTurns = ReadonlyMap<WakeKey, CapturedTurn>;
/** The {@link CapturedTurns} replay key for the OPEN turn (`agent.open`) — the one delivery that is not a
 * wake, so it carries no {@link WakeSource} and can never collide with a {@link wakeKeyOf} key. */
export declare const OPEN_WAKE_KEY: WakeKey;
/** The OPEN keyframe's wake ordinal (`n = -1`, the stepped runner's convention) — a LOG/trace coordinate
 * (the authoring trace's `ordinal`), no longer a {@link CapturedTurns} key. Replay keys on
 * {@link OPEN_WAKE_KEY} / {@link wakeKeyOf}. */
export declare const OPEN_ORDINAL = -1;
/** Derive a delivery's stable {@link WakeKey} — the ONE join both the Simulate driver (capture) and
 * {@link recordedAgent} (replay) key on, so a recorded turn and its wake can never drift apart. */
export declare function wakeKeyOf(frame: ActingFrame): WakeKey;
/** The {@link AgentConfig} a NO-LLM deterministic adapter (recorded / fixed-plan) advertises: a Backtest,
 * not a model call. Names are data (ADR-0006) — `label` is the leaderboard key. Credentials are NEVER
 * config; a fixed-plan run pins no tokenizer/format because it renders nothing (frozen-at-wake). */
export declare const BACKTEST_CONFIG: AgentConfig;
/** Token usage observed at the provider call — the on-record source of the attention-efficiency
 * axis (output + thinking spend, kept distinct from any offline estimate). `inputTokens` is the TOTAL
 * input the provider billed for (fresh + cache-read + cache-write); the two optional cache counters split
 * out the prompt-cache economics (kestrel-rul, consumed by m9i.5). All are provider-reported, off the graded
 * path — a mock/deterministic client omits the cache fields. */
export interface LlmUsage {
    readonly inputTokens: number;
    readonly outputTokens: number;
    readonly thinkingTokens: number;
    /** Input tokens served from the provider prompt cache (a cache HIT on the stable prefix) — the cheap
     * (~0.1×) tokens the `conversation-cached` policy trades full-price re-reads for. Absent ⇒ not reported. */
    readonly cacheReadTokens?: number;
    /** Input tokens WRITTEN into the provider prompt cache this call (the one-time cost of caching a newly
     * stable prefix segment, ~1.25× on Anthropic). Absent ⇒ not reported. */
    readonly cacheWriteTokens?: number;
}
/** One completion: the reply text, an optional raw reasoning trace (free evidence, never
 * re-summarized), and the provider-native usage. `wire` is the OPTIONAL scrubbed wire evidence
 * the concrete (AI-SDK) client captured — redacted of all credential material AT capture time
 * (ADR-0013 (e)); it rides ABOVE the determinism line as free audit evidence and never enters the
 * graded bus. A deterministic/mock client omits it. */
export interface LlmCompletion {
    readonly text: string;
    readonly reasoning?: string;
    readonly usage: LlmUsage;
    readonly wire?: string;
}
/** One turn in a session conversation: a `user` delta frame the harness rendered, or an `assistant`
 * reply the model authored on an earlier wake. The growing list of these is how a session's conversation
 * (KV) is reused across wakes — a byte-stable prefix a provider can prompt-cache (kestrel-rul). `cache`
 * marks a provider prompt-cache BREAKPOINT at (and including) this message: the AI-SDK client translates
 * it to the provider-native control (Anthropic `cache_control` ephemeral / Bedrock cache-point); a client
 * without cache support IGNORES it (conversation reuse alone still wins). Off the graded path. */
export interface LlmMessage {
    readonly role: "user" | "assistant";
    readonly content: string;
    readonly cache?: boolean;
}
/**
 * The narrow provider seam {@link liveAgent} calls. The concrete implementations (the multi-provider
 * AI-SDK client, bring-your-own-key credential injection, wire-evidence redaction, provider prompt-cache
 * control) are the Agent Harness epic's and sit strictly ABOVE the determinism line — the deterministic
 * core imports none of that.
 *
 * A `complete` call is stateless per-call; SESSION state lives in {@link liveAgent}, which passes the
 * growing conversation ({@link LlmMessage}[]) each wake so the provider can prompt-cache the byte-stable
 * prefix. `cacheSystem` asks the client to mark the (byte-stable) `system` prefix cacheable too; a client
 * without cache support ignores both cache signals (the conversation is still reused).
 */
export interface LlmClient {
    complete(req: {
        readonly system: string;
        /** Mark the byte-stable `system` prefix as a provider prompt-cache breakpoint (ignored by a client
         * without cache support). Set by the `conversation-cached` policy. */
        readonly cacheSystem?: boolean;
        /** The prompt-cache TTL every breakpoint this request marks should carry ({@link CacheTtl},
         * kestrel-wa0j.1). ABSENT ⇒ the provider default (byte-identical to before this knob existed).
         * UNLIKE the two boolean cache signals — which a cache-less client may ignore (reuse alone still
         * wins) — a client that cannot put this TTL on the wire MUST throw (fail-closed): the ConfigId
         * claims a TTL, and a silently-dropped one would be a config axis that lies (kestrel-gvx). */
        readonly cacheTtl?: CacheTtl;
        readonly messages: readonly LlmMessage[];
        readonly sampling: {
            readonly temperature: number;
            readonly thinkingLevel: AgentConfig["thinkingLevel"];
        };
    }): Promise<LlmCompletion>;
}
/**
 * Replay a prior run's captured turns byte-identically (no model call, no Rendering). Its contract
 * is a byte-identity claim: re-projecting the recorded run's graded Bus is byte-identical to the
 * original. This is what "re-runnable as a Backtest" concretely means.
 *
 * Deterministic substrate: the replay is keyed ONLY by the stable {@link WakeKey} ({@link OPEN_WAKE_KEY}
 * for `open`, {@link wakeKeyOf} for `decide`) — the rest of the delivered {@link ActingFrame} is IGNORED
 * (rendering is above the determinism line, RUNTIME §0). Synchronous — no model call.
 *
 * Two misses, two proportionate answers (kestrel-5zl.19 — the shakedown-2 finding). A replay may be driven
 * by an engine the recording never ran under (the canonical case: an UNSEEDED recording regraded under a
 * SEEDED engine, which raises `own-fill` management wakes the original session never delivered), so a
 * missing key is not one failure but two:
 *  - **An INSERTED vantage** — the wake's {@link WakeSource} is one of {@link INSERTED_VANTAGE_SOURCES} AND
 *    the recording holds no wake from it at all: that frontier did not exist when the agent decided. The
 *    agent made no decision here and cannot be made to have made one, so replay a LOGGED empty pass (a
 *    legitimate pass — the standing Plans keep managing, exactly as they did between the recorded
 *    vantages). Standing down instead would inject a de-arm the agent never authored and collapse the rest
 *    of the replay — the same trap `frozenStrategist` already holds armed for in `./harness/plan-fixture.ts`.
 *  - **EVERY other miss** — a source OUTSIDE the allowlist (`agent`/`seed`/`structural`/`staleness`), or an
 *    allowlisted source that IS in the recording but not at this wake: the recorded stream genuinely
 *    diverged. That fails closed to a {@link standDownTurn} (never a crash, never a silent pass). A
 *    faithful replay of a driver-captured run never hits it, because the driver captures every turn it
 *    consumed (incl. empty passes) under this same key.
 *
 * The leniency is an ALLOWLIST, never a set-membership miss ({@link INSERTED_VANTAGE_SOURCES}), so a
 * WakeSource added later cannot silently inherit it — most of all `staleness`, whose backstop is the
 * platform's fail-closed safety floor (no Action removes it; the agent-path stand-down is the only de-arm).
 * An unrecorded `staleness` wake is a DIVERGENCE and stands down, never an empty pass.
 *
 * The discriminator needs EVIDENCE, so an OPEN-only recording (no wake turns at all — the frozen-plan
 * fixture of `./harness/plan-fixture.ts`) cannot tell the two apart for any wake, and every wake fails
 * closed to a stand-down exactly as before: ambiguity resolves to the fail-closed branch, never the
 * lenient one.
 */
export declare function recordedAgent(config: AgentConfig, turns: CapturedTurns): Agent;
/**
 * Arm one document at `open` and pass forever = a Backtest expressed through the seam (the
 * degenerate case where discretionary and static coincide). Synchronous and deterministic — the
 * tracer-bullet stub agent.
 *
 * The `open` turn is a single {@link SupersedeAction} carrying `document` (the driver's initial arm);
 * every subsequent `decide` returns an empty `actions[]` (a legitimate pass — the standing Plans keep
 * managing autonomously between wakes). Fail-closed (RUNTIME §8): the document parse is pre-validated
 * ONCE at construction, and a parse escape turns the `open` turn into a {@link StandDownAction} — the
 * agent can never hand the driver an unparseable document, and can never crash the Session.
 */
export declare function fixedPlanAgent(document: string, config?: AgentConfig): Agent;
//# sourceMappingURL=agent.d.ts.map