/**
 * # session/simulate — the frozen-at-wake Simulate driver (the Agent seam's companion to `./day.ts`)
 *
 * The **wake-driven, agent-in-loop** driver (RUNTIME §7). Where {@link import("./day.ts").runDaySession}
 * pauses at each wake and hands an external author a Frame through a FILE handshake, this drives the SAME
 * {@link SessionCore} — the same bus-stepping, the same {@link import("../engine").Gate}, the same
 * fills-before-sweep ordering — but hands the frozen vantage to the {@link Agent} seam IN-PROCESS and
 * consumes the {@link AgentTurn} it returns. Between wakes the standing Plans fire autonomously
 * (fire-then-inform); at a wake the driver freezes market time, assembles a date-blind {@link ActingFrame},
 * `await`s `agent.decide(frame)`, and serializes every returned {@link Action} onto the graded Bus.
 *
 * ## Where the determinism boundary sits (RUNTIME §0, the whole point)
 * The single value that crosses the boundary is the returned {@link AgentTurn}; BELOW it everything is a
 * pure function of Bus bytes (ADR-0011). Every Action is stamped 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 through {@link recordedAgent}. The delivered {@link ActingFrame}
 * (Rendering, model call, sampling) sits ABOVE the line — the recorded/fixed adapters ignore it entirely.
 *
 * ## Action → Bus routing (fail-closed, bounded-risk)
 * - `supersede`  → parse the Kestrel document; the FIRST is the initial arm (no CONTROL, `day.ts` plans-0
 *                  parity), a later one emits a CONTROL `supersede` + de-arm + arm. A parse escape de-arms
 *                  clean with a logged reason (never a crash — RUNTIME §8).
 * - `standDown`  → a CONTROL `disarm` + de-arm clean (inventory rides its TP/EXIT — never liquidates).
 * - `journal`    → a **pre-hoc** JOURNAL `author` record, emitted BEFORE the turn's other actions (provably
 *                  pre-hoc by `seq`).
 * - `scheduleWake` → recorded as a WAKE `scheduled` record AND unioned onto the agent-driven wake
 *                  frontier (kestrel-5zl.4): the agent's own cadence drives, floored (never replaced) by
 *                  the staleness backstop + optional structural cadence, coalesced/downgraded past the
 *                  attention budget (the squelch stays visible — never a silent drop).
 * - `placeOrder` / `cancelOrder` → routed through the **SAME Gate** a fired Plan uses (`core.gate`): an
 *                  order is expressed as a one-shot Plan and armed, so it crosses the identical
 *                  engine→Gate→fill path — SELL≥intrinsic, the budget clamp, and never-naked are enforced by
 *                  the engine, never re-implemented here (bounded risk by construction).
 *
 * Scope: this is the tracer-bullet slice — the thinnest deterministic Simulate path exercised by
 * {@link fixedPlanAgent} + {@link recordedAgent}. The live adapter body, the config matrix, and
 * wire-capture are later slices; the full Wake-grammar authoring (subscriptions/Views, the budget
 * algebra, per-session structural re-anchoring) is the b3l Wake-router epic — see `armStaleness`/
 * `resolveWakeAt` for the conservative defaults taken here.
 */

import type { BusEvent, MetaEvent } from "../bus/index.ts";
import { readBus } from "../bus/index.ts";
import type { Right } from "../bus/types.ts";
import { intrinsic } from "../fair/index.ts";
import { assertNever, parse, print, type KestrelNode, type Module, type PlanStatement } from "../lang/index.ts";
import { armedPlanTermsOf, ENFORCED_PLAN_STATES } from "./armed-plan-terms.ts";
import { decisionControlFields, driverMeasurementVersions, type DecisionEmit } from "../grade/index.ts";
import type { InstrumentSpec } from "../engine/index.ts";
import type { EpisodeSigmoidParams } from "../fill/index.ts";
import { heldPositionAsOfGradedBus } from "../fill/index.ts";
import type { Blotter } from "../blotter/index.ts";
import { project } from "../blotter/index.ts";
import type {
  BriefingInput,
  EngineAction,
  FillRecord,
  FramePhase,
  FrameRight,
  InstrumentSpec as FrameInstrumentSpec,
  Kernel,
  Mandate,
  Brief,
  PlanStateEntry,
  Position,
  PriorSessionTape,
  PriorVantage,
  SizingHeadroom,
  RestingOrder,
  VehicleHealth,
  WakeRef,
} from "../frame/types.ts";
import { expiryTauYears, etMinuteOfDay, etWallClockMs, type FairTauProvider } from "./clock.ts";
import { SessionCore, busSha256Of, fidelityOf, requireMeta, resolveSpecs, type FillModelName, type SessionReport } from "./sim.ts";
import {
  authorCutoffTs,
  briefingSnapshot,
  computeWakes,
  projectAuthorFrame,
  scanDateLeak,
  snapshotOf,
  type AuthorFrame,
  type TimeOfDay,
} from "./day.ts";
import {
  OPEN_WAKE_KEY,
  assertHandlerResponseTimeless,
  wakeKeyOf,
  type Action,
  type ActingFrame,
  type Agent,
  type AgentConfig,
  type AgentTurn,
  type CapturedTurn,
  type CapturedTurns,
  type PlaceOrderAction,
  type WakeAt,
  type WakeKey,
  type WakeSource,
} from "./agent.ts";
import { resolveView, windowServableBy, paneById, atmStraddleExtrinsic, type ViewSelection } from "../frame/pane-catalog.ts";
import type { OptionsAnalytics } from "../frame/options-analytics.ts";
import { canonicalizeConfig, cellConfigId as cellConfigIdOf, deriveConfigId, envelopeForConfig, fillSeedOf, sampledQualificationOf } from "./config.ts";
import { carryFrom, emptyCarry, type SessionCarry } from "./carry.ts";
// The stowaway concepts extracted from this driver into sibling modules (kestrel-z473.1) — this file
// keeps ONLY the wake loop. Each is imported back for the loop's own use; the ones this file used to
// export are re-exported below so the public surface is byte-identical.
import { vehicleHealthOf, vehicleBookFromSpot, type VehicleBook } from "./vehicle-health.ts";
import { sizingHeadroomOf, budgetEnvelopeOf } from "./sizing.ts";
import {
  marketPaneOf,
  buildFrameOptions,
  SERVED_TAPE_BUCKET_MIN,
  type ChainFairContext,
  type OptionsOverlayConfig,
} from "./market-pane.ts";
import {
  runOpenAuthoringLoop,
  viewSelectionOfDocument,
  DEFAULT_VIEW_REQUEST_CAP,
  DEFAULT_AUTHORING_TOKEN_BUDGET,
  type EmergenceRecord,
} from "./authoring-loop.ts";
import { wakeFloorForBand, DAY_STALENESS_BACKSTOP_MIN, type FrontierWake, type WakeCtx } from "./wake-frontier.ts";

// Re-export the moved public symbols so `import { … } from ".../session/simulate.ts"` (and the
// `src/session/index.ts` barrel) resolve exactly as before — the extraction is API-transparent.
export { marketPaneOf, SERVED_TAPE_BUCKET_MIN, type ChainFairContext, type OptionsOverlayConfig } from "./market-pane.ts";
export { vehicleHealthOf, vehicleBookFromSpot, type VehicleBook } from "./vehicle-health.ts";
export { sizingHeadroomOf } from "./sizing.ts";
export {
  viewSelectionOfDocument,
  DEFAULT_VIEW_REQUEST_CAP,
  DEFAULT_AUTHORING_TOKEN_BUDGET,
  type EmergenceRecord,
} from "./authoring-loop.ts";
export { type WakeCtx } from "./wake-frontier.ts";

// ─────────────────────────────────────────────────────────────────────────────
// Public surface
// ─────────────────────────────────────────────────────────────────────────────

/**
 * The DAY-COMPAT side-channel (kestrel-5zl.3) — the narrow bridge the {@link import("./day.ts").runDaySession}
 * fileHandshakeAgent and the driver share so the day agent can render its inspectable artifacts + validate
 * revisions against the LIVE core WITHOUT a forked progression path. It carries NOTHING onto the graded
 * stream (it sits entirely ABOVE the determinism line): the driver sets `vantage` at each vantage BEFORE
 * calling `agent.open`/`agent.decide`, and binds `previewSupersede` once to the live engine's pure collision
 * preview. Present ONLY on the actual day file agent; a plain {@link dayCompat} run (e.g. a recordedAgent
 * replay) passes no bridge and the driver never touches it.
 */
export interface DayCompatBridge {
  /** The raw date-blind {@link AuthorFrame} for THIS vantage (OPEN briefing / each wake), set by the driver
   * before the corresponding `agent.open`/`agent.decide`. The day agent names each wake artifact from it
   * (`frame-<n>-<HHMM>.txt`) and serializes it as the `state-<n>.json` machine channel; the TEXT frames
   * render through the canonical `src/frame` renderer over the driver's typed frames (kestrel-wa0j.2). */
  vantage?: AuthorFrame;
  /** The engine's PURE supersede-then-arm collision preview ({@link import("../engine/index.ts").PlanEngine}
   * `supersedeArmRejection`), bound once by the driver to the live core: a rejection reason or `null`. The
   * day agent's reject-retry consults it so the standing book is NEVER torn down for a doomed revision
   * (fail-closed blast-radius, RUNTIME §8) — the collision preview guarantees the driver's subsequent
   * supersede+arm cannot reject. */
  previewSupersede?: (mod: Module) => string | null;
}

/** Options for {@link runSimulateSession}. Exactly one of `busPath`/`events` supplies the bus; the
 * {@link Agent} seam supplies the decisions. The fill/tau/budget knobs mirror {@link import("./sim.ts").RunSimOptions}. */
export interface RunSimulateOptions {
  readonly busPath?: string;
  readonly events?: readonly BusEvent[];
  /** The agent under test — live, recorded, fixed-plan, or file-handshake (the ONE seam). */
  readonly agent: Agent;
  /** Authored wake vantages (ET times-of-day), strictly inside the driven window. */
  readonly wakes?: readonly TimeOfDay[];
  /** The author acting cutoff (an ET wall-clock time-of-day). The OPEN briefing is built ONLY from
   * observations watermarked at or before this instant; defaults to the canonical benchmark's T-5
   * (09:25 ET). Injected + explicit so no post-cutoff print leaks to the agent (kestrel-m9i.11). */
  readonly authorCutoff?: TimeOfDay;
  /** Present the OPEN authoring vantage as an INTRADAY keyframe carrying the observed range
   * (kestrel-1vw): when `true`, the OPEN briefing folds every exec observation at/before {@link
   * authorCutoff} into the range (`hod`/`lod`/`tape` + the current spot) instead of the pre-open
   * keyframe — so an ORB cell authoring at its opening-range close sees the range it must break out of.
   * The causal cutoff fence is unchanged (no post-cutoff print leaks); this ONLY changes whether the
   * admitted prefix is collapsed to the opening keyframe or presented as the range. Absent / `false` ⇒
   * today's pre-open briefing, byte-identical. Set together with an intraday {@link authorCutoff}. */
  readonly authorFromRange?: boolean;
  /** Add the structural cadence into the close (T-2h…T-5m) — see {@link computeWakes}. */
  readonly structural?: boolean;
  readonly fillModel: FillModelName;
  readonly rUsd: number;
  /** The cell-sourced hard {@link Mandate} (ADR-0026) — the objective + R-definition + success
   * criterion + bounded-risk rule the agent is graded against. Rendered in the kernel; the ONLY
   * admission input. A GRADED run must declare one ({@link import("../frame/types.ts").assertGradedMandate});
   * an ungraded/dev run may omit it (the frame renders unchanged). NOT hardcoded — the cell owns it. */
  readonly mandate?: Mandate;
  /** The cell-sourced soft {@link Brief} (ADR-0026) — directional English (goal/approach/persona),
   * rendered as standing context, hashed + attributed, but NEVER an admission input (the hard guard). */
  readonly brief?: Brief;
  readonly instruments?: readonly InstrumentSpec[];
  readonly fairTauYears?: FairTauProvider;
  readonly makerFairParams?: EpisodeSigmoidParams;
  /** The prior session's {@link SessionCarry} (the multi-session horizon design, kestrel-5zl.16). Its `positions` seed this
   * session's opening book and its `document` is re-armed fresh (new plan-instance ids) BEFORE the OPEN
   * turn. Absent — or an `emptyCarry()` — is today's flat open, byte-identical. */
  readonly openingCarry?: SessionCarry;
  /** `true` for a NON-final session of a multi-session Instance: settle carry-marks held inventory (it
   * survives into the returned {@link SimulateResult.carry}) instead of forcing it to intrinsic. Absent /
   * `false` — a standalone or the final session — is today's terminal intrinsic settle exactly. */
  readonly carryClose?: boolean;
  /** This session's ordinal `k` in its Instance (the multi-session horizon design, kestrel-5zl.16.4) — the relative-day
   * coordinate `d{k}`. Absent for a standalone run ⇒ today's coordinate (no `d{k}` prefix), byte-identical. */
  readonly sessionOrdinal?: number;
  /** The bounded OPEN authoring loop's dual budget (ADR-0029 §2). Consulted ONLY when the agent
   * exposes {@link Agent.authoringOpen} (the viewshop arm); a baseline/recorded/fixed run ignores it
   * entirely (single-shot open, byte-identical). Both fields are config axes — a different budget is a
   * different grid column. Absent ⇒ the conservative defaults ({@link DEFAULT_VIEW_REQUEST_CAP} /
   * {@link DEFAULT_AUTHORING_TOKEN_BUDGET}). */
  readonly authoring?: {
    /** Max non-terminal iterations (view-requests + repairs, shared) before fail-closed standDown. */
    readonly viewRequestCap?: number;
    /** Cumulative model-token ceiling (input + output + thinking, summed across iterations). */
    readonly authoringTokenBudget?: number;
  };
  /** The Percept v5 EMERGENCE LOG sink (ADR-0029 §5) — OFF the graded path. When supplied, the driver
   * appends one {@link EmergenceRecord} per non-terminal authoring iteration (BOTH view-requests AND
   * parse-error/repair events), keyed by `(OPEN_ORDINAL, iteration)`. Private application data (the raw
   * data for the emergence study AND the grammar-evolution signal, ADR-0030); never a graded input. */
  readonly emergenceLog?: EmergenceRecord[];
  /**
   * DAY-COMPAT MODE (kestrel-5zl.3 re-run) — the CALLER-OWNS-CADENCE path the {@link import("./day.ts").runDaySession}
   * fileHandshakeAgent refactor drives through. When the caller owns the wake cadence (the day's structural
   * offsets), the driver reproduces the STEPPED runner's cadence + byte stream EXACTLY:
   *  - NO injected platform-default staleness/backstop wakes for this path — the day's own structural wakes
   *    provide the coverage, so the delivered wake set is exactly `computeWakes(...)` (no 30-min DAY backstop
   *    churn), reproducing the frozen day determinism_hash 44cf2cbf;
   *  - CONTROL supersede carries the day's `{target:"wake-N", note:"revision-N"}` byte shape (not the bare
   *    `{note?}` the agent-driven path emits), so `serializeEvent` bytes match the stepped runner.
   *
   * This is NARROW: it is NOT "silence the backstop". It never weakens the band fail-closed logic (16.7) for a
   * normal band run — {@link wakeFloorForBand}/{@link armStaleness} still floor every agent-driven session and
   * {@link tests/simulate.wake-band.test.ts} stays green. Absent / `false` ⇒ today's full agent-driven frontier,
   * byte-identical. (Threaded by the green step; declared here as the contract the TDD-red test targets.)
   */
  readonly dayCompat?: boolean;
  /** The DAY-COMPAT {@link DayCompatBridge} (kestrel-5zl.3) — present ONLY when the caller is the
   * {@link import("./day.ts").runDaySession} file agent (it renders artifacts from `vantage` + validates
   * revisions through `previewSupersede`). Off the graded line: the driver sets `vantage` before each
   * `open`/`decide` and binds `previewSupersede` to the live core, but emits NOTHING from it. A plain
   * `dayCompat` run (a recordedAgent replay) omits it and the driver never touches it. */
  readonly dayBridge?: DayCompatBridge;
  /** The options-analytics OVERLAY (kestrel-4gl.13.13) — the perception arm's OPRA surface, folded
   * causally into `market.options` at every frame cutoff so the `gex`/`iv-skew`/`implied-realized`
   * panes render in a LIVE run. **Config-gated: supplied ONLY for the perception arm** (a View that
   * selects the options-analytics panes). Absent — the minimal arm — leaves `market.options`
   * undefined and every frame byte-identical to before (the panes are off-default; the fold is never
   * paid). Folded per-cutoff with the T-5m guard (only events at/before the cutoff, no look-ahead) and
   * relabeled date-blind before it reaches the agent frame ({@link buildFrameOptions}). */
  readonly optionsOverlay?: OptionsOverlayConfig;
  /**
   * THE MULTIDAY TAPE SEAM (kestrel-wa0j.20 — the DATA half of Train 1B's `tape d-N` address). The
   * PRIOR sessions' tapes (date-blind: relative ordinals + HH:MM clocks, NEVER dates), threaded onto
   * every frame this session serves so a View naming `tape d-N` (N ≥ 1) renders ordinal N's OWN
   * single-session block instead of the Train 1B absence line. Each ordinal renders SEPARATELY — no
   * cross-session folding (that is wa0j.20b, behind PR #194's render unification).
   *
   * INJECTABLE seam: the v1 single-day sim carries no multi-session tape state, so this is typically
   * ABSENT (honestly — `tape d-N` then renders absent-with-reason, byte-identical). A multi-day harness
   * (or a future day/backtest path that has the prior sessions' rows cheaply available) INJECTS them
   * here; the driver threads them, unchanged, into both the OPEN briefing and every wake frame. Absent
   * ⇒ no `priorSessions` field on any frame, byte-identical to today. */
  readonly priorSessions?: readonly PriorSessionTape[];
  /**
   * THE THETA GATE (theta-cell seam b, {@link import("../fill/held-position.ts").heldPositionAsOfGradedBus}).
   * When `true`, after settle the driver asks the held-position owner for the position held as of the
   * graded bus — it reconstructs the net HELD option legs + their blended basis, re-marks them against the
   * tape's own option book at every DELIVERED wake (theta decay between wakes), and returns ONE graded
   * `TELEMETRY theta_bleed` record carrying the stand-down floor (the mark at the LAST wake), which the
   * driver emits verbatim. The Blotter folds that into `totals.floor` (ADR-0011), so a watcher that STANDS PAT on a
   * bleeding straddle realizes a graded NEGATIVE floor instead of paying no running cost for doing nothing
   * — the whole point of the theta cell (it dissolves the doing-nothing-wins degenerate reward).
   *
   * Threaded from the FOMC-OPTIONS {@link import("./harness/plan-fixture.ts").FanFrame} `markToModel`.
   * Absent / `false` (every other cell) ⇒ no reconstruction, no record, no fold — every existing pinned
   * floor is byte-identical. Only binds when a position is actually HELD across ≥1 wake (a flat book, or a
   * watcher that closed out, emits nothing). CLEAN BOUNDARY: the bleed rides the graded Bus / Blotter as a
   * mark-to-model GRADING penalty; it is deliberately NOT folded into the engine-native SessionReport
   * `realized_floor_usd` or the multi-session carry cash (that report/ledger integration is separate work).
   */
  readonly markToModel?: boolean;
  /**
   * The injectable wall clock the driver measures a clock-honest Seat turn with (ADR-0040 /
   * clock-honest wakes §7 — the ONE minting seam, the `opts.now ?? Date.now` idiom of `liveAgent`).
   * Consulted ONLY in a LIVE-shaped clock-honest run: a latency-blind session never measures (its
   * captures stay costless-deterministic), and a REPLAY (an agent exposing `recordedCostMs`) reads
   * recorded costs and never touches this — a replay path that reads a clock is a defect by
   * definition (the poisoned-clock fixture). Defaults to `Date.now`.
   */
  readonly now?: () => number;
  /**
   * The session's DECLARED data rung (ADR-0040 data floor / clock-honest wakes §4) — the tape's
   * observability provenance (`"tick" | "second" | "minute" | "session"`, the `GradingFidelity`
   * lattice), declared on the run options / session catalog and carried with the tape like
   * `fill_model`. Typed loosely (injected provenance bytes) and VERIFIED fail-closed via the isRung
   * discipline: `tick`/`second` ⇒ clock-honest eligible; `minute`/`session` ⇒ latency-blind; an
   * off-lattice or ABSENT rung ⇒ latency-blind (an untrusted rung never compares as eligible).
   * Requesting `clockHonest: true` over an ineligible/undeclared rung REFUSES the run loudly at open —
   * never a silent downgrade to latency-blind. Irrelevant to a latency-blind run (may be omitted).
   */
  readonly dataRung?: string;
}

/** The result of a Simulate session: the graded {@link Blotter} (a PURE projection of the graded Bus,
 * ADR-0011), the {@link CapturedTurns} the run consumed (the deterministic replay input for
 * {@link recordedAgent}), and the agent's {@link AgentConfig} (the comparison axis). */
export interface SimulateResult {
  readonly blotter: Blotter;
  /**
   * The native graded {@link SessionReport} of this run (kestrel-m9i.7.4) — the SAME `core.buildReport`
   * projection {@link import("./day.ts").runDaySession} returns, computed here from the finalized core so a
   * live/handshake Simulate run lands in the run {@link import("../ledger").ledger} WITHOUT a Blotter→report
   * bridge (the tournament runner records this verbatim; `session.settle_ts` is the injected `recorded_at`).
   * A PURE read of the finalized session — no wall clock, no RNG, and byte-identical to a `runDaySession`
   * report of the same graded bus (RUNTIME §0).
   */
  readonly report: SessionReport;
  readonly captured: CapturedTurns;
  readonly config: AgentConfig;
  /** The canonical GRADED bus of this run (`core.gradedBus()` — the judge-stamped META + every emitted
   * engine reaction, re-stamped gap-free): the record itself, surfaced so a caller (and the w7la.1
   * clocked fixtures) can assert bus-level facts — deliberation records, checkpoints, refusal
   * stamping — without any engine-state scrape (ADR-0010: the Bus is the truth). A PURE read of the
   * finalized core; `project(gradedBus)` is byte-identical to {@link SimulateResult.blotter}. */
  readonly gradedBus: readonly BusEvent[];
  /** The {@link SessionCarry} this session hands to the next (the multi-session horizon design, kestrel-5zl.16) — a PURE read of
   * the finalised session. On a final / standalone session (`carryClose` absent) its `positions` are
   * empty (inventory settled at intrinsic). The runner ({@link import("./instance.ts").runInstance})
   * threads it into the next session's `openingCarry`. */
  readonly carry: SessionCarry;
}

// ─────────────────────────────────────────────────────────────────────────────
// Small helpers (pure, deterministic — no wall clock, no RNG)
// ─────────────────────────────────────────────────────────────────────────────

/** Normalize a parsed node into a module (a bare statement → a one-statement module) so it can be armed. */
function toModule(node: KestrelNode): Module {
  return node.kind === "module" ? node : { kind: "module", imports: [], statements: [node] };
}

function msgOf(e: unknown): string {
  return e instanceof Error ? e.message : String(e);
}

// ─────────────────────────────────────────────────────────────────────────────
// Clock-honest eligibility (ADR-0040 data floor / clock-honest wakes §4) — declared, verified, fail-closed
// ─────────────────────────────────────────────────────────────────────────────

/** The rungs of the observability lattice fine enough to ground a clock-honest session (ADR-0040:
 * sub-minute ground truth — 1s bars / event streams). The isRung discipline (`src/series/registry.ts`)
 * applied to THIS question: anything outside the closed lattice is untrusted and never compares as
 * eligible. */
const CLOCK_HONEST_ELIGIBLE_RUNGS: ReadonlySet<string> = new Set(["tick", "second"]);
const OBSERVABILITY_RUNGS: ReadonlySet<string> = new Set(["tick", "second", "minute", "session"]);

/**
 * Why a declared data rung CANNOT ground a clock-honest session, or `null` when it is eligible
 * (clock-honest wakes §4). PURE and fail-closed — declared-then-verified is not trust:
 *  - `"tick"` / `"second"` → eligible (`null`);
 *  - `"minute"` / `"session"` → too coarse (the ADR-0040 data floor) — such a session stays VALID but
 *    latency-blind, and may never claim clock-honesty;
 *  - absent → undeclared provenance — refuse (never a silent default);
 *  - off-lattice → an untrusted rung — refuse (never compared as coarser/finer than anything).
 * The caller (the driver, at open) REFUSES a `clockHonest: true` run whose rung returns non-null —
 * never a silent downgrade to latency-blind (a producer must never *believe* it bought a
 * latency-honest result it didn't get).
 */
export function clockHonestIneligibility(declaredRung: string | undefined): string | null {
  if (declaredRung === undefined) {
    return "the session declares NO data rung (`dataRung`) — clock-honest requires sub-minute ground truth declared with the tape (ADR-0040 data floor); refused at open, never a silent default";
  }
  if (!OBSERVABILITY_RUNGS.has(declaredRung)) {
    return `declared data rung ${JSON.stringify(declaredRung)} is not on the observability lattice (tick, second, minute, session) — an untrusted rung never compares as clock-honest eligible (fail-closed)`;
  }
  if (!CLOCK_HONEST_ELIGIBLE_RUNGS.has(declaredRung)) {
    return `declared data rung "${declaredRung}" is too coarse for clock-honest semantics (ADR-0040 data floor: tick/second only) — run it latency-blind or declare finer ground truth; refused at open, never a silent downgrade`;
  }
  return null;
}

// ─────────────────────────────────────────────────────────────────────────────
// Schedule-time View validation (kestrel-wa0j.19 §1b) — the driver-side guard the wake loop applies
// when a `scheduleWake` is accepted. (The bounded OPEN authoring loop itself + the View-document →
// ViewSelection mapper live in `./authoring-loop.ts`; the wake floors + frontier shapes in
// `./wake-frontier.ts`; extracted from this driver in kestrel-z473.1.)
// ─────────────────────────────────────────────────────────────────────────────

/**
 * SCHEDULE-TIME View value/budget validation (kestrel-wa0j.19 §1b): the checks that are KNOWABLE when a
 * `scheduleWake` is accepted — BEFORE the View ever reaches an (otherwise unguarded) delivery render.
 * Returns a refusal reason when the resolved View carries a defect the constant session context can prove
 * NOW, else `null`. Two checks, both mirroring the exact guards `materializePanes` applies at delivery so
 * the two can never drift:
 *   • **window-arg value** — the served tape bucket is a session constant ({@link SERVED_TAPE_BUCKET_MIN}),
 *     so a `tape <window>` that is sub-resolution or a non-multiple of it is refusable now via the SHARED
 *     {@link windowServableBy} predicate (the same one the arged tape builder enforces at materialization).
 *   • **budget sanity** — if the View declares a token budget already below the SUM of its selected panes'
 *     catalog `tokenCostEstimate`s, it can never fit; refuse now. (The exact per-tokenizer measurement at
 *     materialization stays the precise guard — the delivery seam §1a is the fail-closed backstop for a
 *     View that fits the estimate yet overruns the real count.)
 * PURE. Distinct from the STRUCTURAL/date-leak refusals (unknown pane / reserved id / calendar leak), which
 * stay whole-wake refusals: a structurally-broken or unsafe View is nonsense to honor, whereas a sound View
 * that this session's resolution simply cannot serve drops to the default panes while the wake still fires.
 */
export function scheduleTimeViewDefect(sel: ViewSelection): string | null {
  for (const p of sel.panes) {
    for (const a of p.args ?? []) {
      if (a.kind === "arg-window" && p.name === "tape" && !windowServableBy(SERVED_TAPE_BUCKET_MIN, a.window)) {
        return (
          `pane "tape" window "${a.window.value}${a.window.unit}" is not servable — the tape rows are served ` +
          `at ${SERVED_TAPE_BUCKET_MIN}m, so a renderable window must be a positive multiple of ${SERVED_TAPE_BUCKET_MIN}m`
        );
      }
    }
  }
  if (sel.budget !== undefined) {
    let est = 0;
    for (const p of sel.panes) {
      const entry = paneById(p.name);
      if (entry !== undefined) est += entry.tokenCostEstimate;
    }
    if (est > sel.budget) {
      return `View "${sel.name}" is over its own token budget: the selected panes' estimated cost (~${est} tokens) exceeds the declared budget of ${sel.budget}`;
    }
  }
  return null;
}

/** `HH:MM` ET clock for a ts (dateless — a clock pins no calendar date). */
function clockOf(ts: number): string {
  const m = ((etMinuteOfDay(ts) % 1440) + 1440) % 1440;
  return `${String(Math.floor(m / 60)).padStart(2, "0")}:${String(m % 60).padStart(2, "0")}`;
}

const FRAME_PHASES = new Set<string>(["pre", "open", "regular", "close", "post"]);

/** Map the snapshot's phase string to a {@link FramePhase}, or `null` when unresolved (never a guess). */
function mapPhase(phase: string): FramePhase | null {
  return FRAME_PHASES.has(phase) ? (phase as FramePhase) : null;
}

// ─────────────────────────────────────────────────────────────────────────────
// AuthorFrame → frame/types mappers (the acting Frame is assembled from the SAME date-blind projection
// the stepped day emits — relative time + relative dte only, so no channel can re-leak the calendar)
// ─────────────────────────────────────────────────────────────────────────────

// ─────────────────────────────────────────────────────────────────────────────
// Options-analytics overlay fold (kestrel-4gl.13.13) — the perception arm's live `market.options`
//
// The driver (the impure orchestrator) folds the OPRA overlay tape causally to each frame cutoff and
// hands the pure frame builders the finished, date-blind {@link OptionsAnalytics}. Kept OUT of the
// pure `projectWakeFrame`/`briefingInputOf` seams (they receive the built projection, never the tape),
// so those stay pure functions of their inputs.
// ─────────────────────────────────────────────────────────────────────────────

/** Stream `events` up to and including `tsMax` — the causal T-5m cutoff (no look-ahead). A lazy
 * generator over a lazy source reads only the prefix (the fold stops at the first later event). */
function* untilTs(events: Iterable<BusEvent>, tsMax: number): Generator<BusEvent> {
  for (const e of events) {
    if (e.ts > tsMax) return;
    yield e;
  }
}


/** The plan-lifecycle HALF of the {@link Kernel} superset (positions / resting / fills / budget /
 * plan states), scraped from the date-blind snapshot. The WAKE frame layers the enriched 4gl.3
 * cockpit lead block on top of this base ({@link enrichedKernelOf}); the OPEN briefing carries the
 * base alone (the enriched cockpit at OPEN is out of scope for this slice — m9i.11 briefing). */
/** The cell-sourced STANDING context (ADR-0026) layered onto every frame's kernel: the hard
 * {@link Mandate} (the only admission input) + the soft, directional {@link Brief}. Sourced from
 * the SESSION/CELL ({@link RunSimulateOptions}), NOT hardcoded — different cells declare different
 * objectives. Frame content sits ABOVE the determinism line, so this never perturbs the graded bus. */
export interface KernelStanding {
  readonly mandate?: Mandate;
  readonly brief?: Brief;
}

/** Roll same-(instrument, strike, right) fill legs into ONE net position line (kestrel-dd8): the fill
 * engine SETTLES these netted, so the pane must too — a GROSS per-leg render shows huge OFFSETTING marks
 * that misread as a phantom winner (`+$18,000` on a net-zero book) or invite a churn to "flatten" an
 * already-flat book. Net qty is the signed sum (a net-0 pair renders a single clearly-flat `0 …` line —
 * already flat, nothing to churn); the blended basis is the ABS-qty-weighted average of the leg bases
 * (always well-defined, even for a net-zero pair); the net `unrealUsd` is the SUM of the per-leg unreal
 * (which nets to the TRUE figure). If ANY grouped leg's mark is UNKNOWN (`null`) the net is `null`
 * (fail-closed — never sum a fabricated 0 into a real figure); if EVERY leg omits it the net omits it.
 * Grouping preserves each group's FIRST-APPEARANCE order (deterministic given the deterministic fills),
 * so a book with NO same-(strike,right) duplicates is BYTE-IDENTICAL to the un-netted projection. Pure. */
function netPositionLegs(legs: readonly Position[]): Position[] {
  const groups = new Map<string, Position[]>();
  for (const p of legs) {
    const key = `${p.instrument} ${p.strike} ${p.right}`;
    const grp = groups.get(key);
    if (grp === undefined) groups.set(key, [p]);
    else grp.push(p);
  }
  const out: Position[] = [];
  for (const grp of groups.values()) {
    if (grp.length === 1) {
      out.push(grp[0]!); // the common case — passed through untouched (byte-identical)
      continue;
    }
    const first = grp[0]!;
    const qty = grp.reduce((n, p) => n + p.qty, 0);
    const absQty = grp.reduce((n, p) => n + Math.abs(p.qty), 0);
    const basis = absQty > 0 ? grp.reduce((s, p) => s + Math.abs(p.qty) * p.basis, 0) / absQty : first.basis;
    const anyUnknown = grp.some((p) => p.unrealUsd === null);
    const allAbsent = grp.every((p) => p.unrealUsd === undefined);
    const unrealUsd: number | null | undefined = allAbsent ? undefined : anyUnknown ? null : grp.reduce((s, p) => s + (p.unrealUsd ?? 0), 0);
    // Provenance survives only when every leg agrees; a mixed group has no single opener (drop it).
    const plan = grp.every((p) => p.plan === first.plan) ? first.plan : undefined;
    out.push({
      instrument: first.instrument,
      // ADR-0017: an equity/spot leg carries NEITHER strike NOR right — preserve their absence through the
      // netting (a spot group nets under the `NVDA undefined undefined` key), so the frame renders it as
      // `<instrument> shares`, never a phantom strike. An option group carries both (byte-identical).
      ...(first.strike !== undefined ? { strike: first.strike } : {}),
      ...(first.right !== undefined ? { right: first.right } : {}),
      qty,
      basis,
      ...(plan !== undefined ? { plan } : {}),
      ...(unrealUsd !== undefined ? { unrealUsd } : {}),
    });
  }
  return out;
}

export function kernelOf(
  af: AuthorFrame,
  instrument: string,
  standing: KernelStanding = {},
  // kestrel-c11: the exec contract multiplier (equity/spot 1, option 100) — the SAME scaling the fill
  // engine's `pnl` applies (src/engine/orgfacts.ts), threaded so the surfaced P&L is in DOLLARS, never
  // per-contract points. Defaults to 1 (equity/spot); the OPEN briefing carries no fills so it is moot.
  multiplier: number = 1,
): Kernel {
  const spot = af.spot;
  const markKnown = spot !== null && Number.isFinite(spot);
  // Per-fill legs (kestrel-c11 running $ P&L each), then NETTED per (instrument, strike, right) so the
  // pane matches the engine's netted settle (kestrel-dd8) — a gross render misreads offsetting marks.
  const legs: Position[] = af.fills.map((f) => {
    const qty = f.side === "buy" ? f.qty : -f.qty;
    // kestrel-c11 — the position's running unrealized P&L in DOLLARS: `qty × (mark − basis) × multiplier`,
    // marked to spot (equity/spot, ADR-0017) or intrinsic (option), with the SAME dollar scaling the fill
    // engine's `pnl` uses. So the agent READS `unreal=-$25.97` instead of deriving it and mis-scaling
    // cents-for-dollars (the 100× abandon bug). `null` when the mark is UNKNOWN (no spot) — fail-closed to
    // `—`, never a fabricated 0. An option leg carries a finite strike + a real C/P right; equity does not.
    const isOption = Number.isFinite(f.strike) && (f.right === "C" || f.right === "P");
    const mark = !markKnown ? null : isOption ? intrinsic(spot as number, f.strike, f.right as Right) : (spot as number);
    // single exec instrument per session (ADR-0017); a mixed-multiplier book would need a per-instrument multiplierOf like orgfacts.
    const unrealUsd = mark === null ? null : qty * (mark - f.px) * multiplier;
    return {
      instrument,
      strike: f.strike,
      right: f.right as FrameRight,
      qty,
      basis: f.px,
      plan: f.plan,
      unrealUsd,
    };
  });
  // kestrel-dd8: net same-(instrument, strike, right) legs into ONE line so the pane matches the engine's
  // netted settle — a book with no duplicates is byte-identical to the un-netted per-fill projection.
  const positions: Position[] = netPositionLegs(legs);
  const resting: RestingOrder[] = af.resting.map((r) => ({
    // The AUTHORITATIVE Gate ref the fill engine rests this order under (kestrel-5zl.5): a `cancelOrder`
    // carrying this ref resolves to the real resting order through the SAME Gate a fired Plan cancels
    // through. (It was a synthetic `plan:role:strikeRight` handle that no Gate ref ever matched, so
    // cancel-by-ref silently no-op'd.) The kernel PRINTS it (`ref=o1`) — the ref is what a cancel names.
    ref: r.ref,
    side: r.side as "buy" | "sell",
    instrument,
    strike: r.strike,
    right: r.right as FrameRight,
    qty: r.qty,
    px: r.px,
    plan: r.plan,
  }));
  const plans: PlanStateEntry[] = af.plans.map((p) => ({
    name: p.name,
    state: p.state as PlanStateEntry["state"],
    // kestrel-50w: carry the arm-time gate-block reason into the acting Frame so a plan stuck `authored`
    // on an unsatisfiable regime gate renders `authored (blocked: <reason>)`, never a bare (live-looking)
    // `authored`. Frame content, above the determinism line — the graded bus is untouched.
    ...(p.blockedReason !== undefined ? { blockedReason: p.blockedReason } : {}),
  }));
  return {
    // Cell-sourced standing context (ADR-0026) — present only when the cell declared it (absent ⇒
    // the frame renders unchanged, byte-identical to pre-mandate). Never a fabricated default.
    ...(standing.mandate !== undefined ? { mandate: standing.mandate } : {}),
    ...(standing.brief !== undefined ? { brief: standing.brief } : {}),
    positions,
    resting,
    // Per-vantage fill deltas are a later refinement; the authoritative fill record is the graded Bus.
    fillsSinceLast: [] as FillRecord[],
    budget: { used: af.committedUsd, remaining: af.rUsd - af.committedUsd, total: af.rUsd },
    plans,
  };
}

/** The OPEN briefing input, mapped from the date-blind briefing {@link AuthorFrame}. */
function briefingInputOf(
  af: AuthorFrame,
  meta: MetaEvent,
  instrument: string,
  firstTs: number,
  lastTs: number,
  standing: KernelStanding = {},
  options?: OptionsAnalytics,
  // kestrel-121: the chain-fair context evaluated at the OPEN author cutoff. Absent ⇒ the briefing
  // chain `fair` stays `—` (byte-identical to a pre-fair briefing).
  fairCtx?: ChainFairContext,
  // kestrel-wa0j.20: the injected prior-session tapes, threaded onto the OPEN briefing so `tape d-N`
  // serves ordinal N's block. Absent ⇒ no `priorSessions` field (byte-identical, Train 1B absence).
  priorSessions?: readonly PriorSessionTape[],
): BriefingInput {
  const instruments: FrameInstrumentSpec[] = meta.instruments.map((si) => ({
    symbol: si.symbol,
    assetClass: si.assetClass,
    ...(si.role !== undefined ? { role: si.role } : {}),
  }));
  // The PRESENTED current-time is the frame's OWN vantage, reconstructed from its relative `sinceOpenMs`
  // (projected against this same `firstTs` origin) — NOT a re-assumption that the author acts at the
  // open. For the default (pre-open) briefing `sinceOpenMs === 0`, so `vantageTs === firstTs` and both
  // fields are byte-identical to before. For an intraday `authorFromRange` briefing the vantage is the
  // acting cutoff (kestrel far-cutoff clock), so the clock reads the cutoff and time-to-close shrinks
  // accordingly — the honest "it's 13:45, ~2h15m to close" a live FOMC author must reason over.
  const vantageTs = firstTs + af.sinceOpenMs;
  return {
    timeToCloseMin: Math.round((lastTs - vantageTs) / 60_000),
    phase: mapPhase(af.phase),
    clockET: clockOf(vantageTs),
    instruments,
    market: marketPaneOf(af, instrument, options, fairCtx),
    kernel: kernelOf(af, instrument, standing),
    ...(priorSessions !== undefined ? { priorSessions } : {}),
  };
}

// ─────────────────────────────────────────────────────────────────────────────
// The agent-driven wake frontier (kestrel-5zl.4) — constants + shape
//
// After the T-5 OPEN baseline (m9i.11) the AGENT drives its own monitoring cadence via `scheduleWake`;
// the platform FLOORS it (never replaces it) with a staleness backstop + the optional structural close
// cadence, and coalesces/downgrades past the attention budget. These are author-tunable config knobs,
// NOT removable by the agent — safety can never be silenced (CLAUDE fail-closed). The budget algebra
// proper and per-session structural re-anchoring are scoped to the b3l Wake-router epic.
// ─────────────────────────────────────────────────────────────────────────────

/** Total, deterministic frontier tiebreak when two wakes share a ts: the agent first, then the author
 * seed, then an own-fill management wake, then the structural cadence, then the staleness backstop (safety
 * sorts last, never masking an earlier authored intent). Same bus + same agent turns ⇒ identical frontier
 * order ⇒ identical Blotter. The `own-fill` wake exists only on a seeded (sampled-channel) run — a
 * fire-then-inform management prompt raised when the agent's order fills, ADR-0016 / kestrel-9gu.8.3.
 * `latency-fold` (ADR-0040 / clock-honest wakes §2.3) is a determinism-bearing tie-break PIN: no tie is
 * currently reachable — a frontier wake at exactly `returnTs` folds INTO the catch-up rather than sorting
 * beside it — but the rank is pinned anyway so the sort stays total (RUNTIME §0). */
const WAKE_SOURCE_RANK: Record<WakeSource, number> = { agent: 0, seed: 1, "own-fill": 2, structural: 3, staleness: 4, "latency-fold": 5 };

// ─────────────────────────────────────────────────────────────────────────────
// The SeqWindow + engine-actions-since-last-wake (kestrel-5zl.11 — the 4gl.3 cockpit engine log)
//
// The frame's L0/L1 engine log is the ACTIONS-SINCE-THE-LAST-WAKE, not the whole session: the
// `[prevWakeSeq, thisWakeSeq)` slice of the graded Bus in **seq space** (every event carries a
// monotonic `seq`, the determinism key — bus/types.ts EnvelopeBase). `prevWakeSeq`/`thisWakeSeq`
// are the two adjacent WAKE-checkpoint seqs the driver stamps at each vantage. Reading only events
// with `seq < thisWakeSeq` is frozen-at-wake by construction (no look-ahead), and an `asofSeq` is an
// ORDINAL (date-blind), so the window is deterministic and replay-stable.
// ─────────────────────────────────────────────────────────────────────────────

/** The `[prevWakeSeq, thisWakeSeq)` bus-seq window the engine-actions-since-last-wake ride. Both are
 * WAKE-checkpoint `seq`s (an ordinal, never a wall-clock/date); the half-open window is the gap
 * between the previous vantage and this one. */
export interface SeqWindow {
  readonly prevWakeSeq: number;
  readonly thisWakeSeq: number;
}

/** The pure inputs {@link projectWakeFrame} consumes beyond the graded bus + the seq window: the
 * date-blind vantage projection (market pane + plan-lifecycle base), the exec instrument, the
 * per-vehicle books for the cockpit data-health, and the wake ctx (ordinal / reason / deadlines /
 * attention). Everything here is a pure derivation of the injected bus (no wall clock, no RNG). */
export interface WakeFrameConfig {
  readonly af: AuthorFrame;
  readonly instrument: string;
  /** The exec instrument's contract multiplier (kestrel-m9i.32) — `1` for equity/spot, `100` for a
   * listed option. Drives the cost-basis sizing headroom (equity basis = spot × mult; option basis =
   * premium × mult, ADR-0017). Absent ⇒ treated as `1` (equity/spot). */
  readonly execMultiplier?: number;
  readonly vehicles: readonly VehicleBook[];
  readonly ctx: WakeCtx;
  /** The cell-sourced standing context (ADR-0026 mandate + brief) layered onto the wake kernel. */
  readonly standing?: KernelStanding;
  /** The options-analytics projection for THIS wake's cutoff (kestrel-4gl.13.13) — already folded
   * causally + date-blind by the driver ({@link buildFrameOptions}). Present only for the perception
   * arm; absent leaves `market.options` undefined (the minimal arm, byte-identical). */
  readonly options?: OptionsAnalytics;
  /** The injected time-to-expiry resolver (`fairTauYears`) the chain's `fair` column is priced through
   * (kestrel-121) — the SAME source the fill engine prices `@fair` with, evaluated at THIS wake's cutoff
   * (`ctx.wakeTs`). Absent ⇒ the chain `fair` stays `—` (byte-identical to a pre-fair frame). */
  readonly fairTauYears?: FairTauProvider;
  /** kestrel-wcnd: the exec chain's OWN expiry token at this wake (from the RAW snapshot — the
   * date-blind `af` cannot carry it). Feeds `fairTauYears`'s 2nd argument ONLY; never rendered. */
  readonly fairExpiry?: string;
  /** The prior author vantage's SERVED values (kestrel-wa0j.48) — the typed snapshot the driver served
   * at the PREVIOUS vantage, so the `delta` pane can state what MOVED under stateless-redraw. Present
   * only on a wake AFTER the first (the driver captures it from the prior frame's served levels/book);
   * absent ⇒ the frame carries no `priorVantage` (byte-identical, and the delta pane fails closed). */
  readonly priorVantage?: PriorVantage;
  /** The PRIOR sessions' tapes (kestrel-wa0j.20) — the injected multiday tape (`opts.priorSessions`),
   * threaded so `tape d-N` serves ordinal N's rows as its own block. Absent in the v1 single-day sim ⇒
   * the frame carries no `priorSessions` (byte-identical, and `tape d-N` renders the Train 1B absence). */
  readonly priorSessions?: readonly PriorSessionTape[];
  /** Every armed plan STATEMENT the driver holds, in arm order (kestrel-wa0j.29) — the typed ASTs the
   * `armed-plan` pane's terms are captured from. The seam filters these to the plans in an ENFORCED
   * lifecycle state (per this wake's kernel plan set) and prints each clause through the canonical
   * printer. Absent (or no enforced plan) ⇒ the frame carries no `armedPlan` and the pane fails closed
   * to absent-with-reason, byte-identical to a frame without the field. */
  readonly armedPlanAsts?: readonly PlanStatement[];
  /** The tape's `session_date` (kestrel-wa0j.74) — the reference an ABSOLUTE per-leg `exp 2026-08-21`
   * is date-blinded to a relative `<n>dte` against when the `armed-plan` pane captures the plan's terms.
   * Required so an authored iso-date tenor cannot leak into the acting Frame and trip {@link
   * assertFrameDateBlind}; unused when no plan carries an absolute per-leg expiry (byte-identical). */
  readonly sessionDate: string;
}

/** Map ONE graded-bus event to its {@link EngineAction} bucket, or `null` when it is not an L0/L1
 * engine action (RUNTIME §5–6): an `ORDER place` FIRED, an `ORDER cancel` (reason `cancelled`)
 * CANCELLED, an `ORDER reject` REJECTED, a `TELEMETRY guard` whose directional cap was `applied`
 * CLAMPED. An `ORDER fill` and an esc-reprice cancel (a non-`cancelled` reason) are not engine
 * actions on this SAFETY/CONTROL surface. `id` is the order ref; `asofSeq` is the event's ordinal. */
/** Refusal-reason markers (engine-authored constant strings) that promote a PLAN lifecycle record to a
 * `rejected` engine action so the acting agent sees WHY an order was refused (kestrel-7kt). A normal
 * lifecycle reason (`fired`, `superseded`, `ttl`, `invalidate`, `cancel-if`, `transferred`) is NOT a
 * refusal and stays out of the engine log.
 *
 * The list must cover EVERY reason `PlanEngine.#emitReject` authors (src/engine/plans.ts — the sole
 * producer of a PLAN refusal notice; a plain `#transition` reason is open-vocabulary lifecycle, which is
 * why this seam matches rather than inverts). Matching is the only discriminator the bus schema affords:
 * a reject notice and a transition are the same `PLAN lifecycle` shape, so an unlisted refusal is dropped
 * SILENTLY at the agent's only feedback loop (kestrel-x4j8). Adding an `#emitReject` reason means adding
 * its marker here — tests/simulate.engine-log-refusals.test.ts pins the vocabulary. */
const REFUSAL_MARKERS: readonly string[] = [
  "never naked",
  "uncovered sell",
  "unfillable",
  "unresolvable",
  "exceeds plan budget",
  // kestrel-x4j8 — the fire-time refusals the 7kt list missed, each silently invisible until now:
  // the fail-closed far-OTM cap on unresolved moneyness (plans.ts, kestrel-9gu.6 — its call site asks
  // for it to be surfaced LOUDLY; `unresolvable` above never matched the engine's `unresolved`), the
  // budget-exhausted peg that can no longer chase, and the reprice dropped onto an already-filled intent.
  "unresolved",
  "fill-guard",
  "peg capped",
  "reprice dropped",
  // kestrel-ocyf — the arm-time regime activation-gate notices (`armDocument`): the definitive
  // dead-on-arrival verdict on a pre-scanned regime-less tape, and the conditional not-yet-written
  // block when the future is unknown. Both are #emitReject-authored and must reach the wake frame's
  // engine log, or the acting agent re-learns the phantom-position trap one wake late.
  "never written",
  "not yet written",
];
function isRefusalReason(reason: string | undefined): boolean {
  return reason !== undefined && REFUSAL_MARKERS.some((m) => reason.includes(m));
}

function engineActionOf(e: BusEvent): EngineAction | null {
  if (e.stream === "ORDER") {
    switch (e.type) {
      case "place":
        return { id: e.order_id, kind: "fired", asofSeq: e.seq };
      case "cancel":
        return e.reason === "cancelled" ? { id: e.order_id, kind: "cancelled", asofSeq: e.seq } : null;
      case "reject":
        return { id: e.order_id, kind: "rejected", asofSeq: e.seq, ...(e.reason !== undefined ? { reason: e.reason } : {}) };
      default:
        return null; // fill — not an engine action bucket
    }
  }
  if (e.stream === "TELEMETRY" && e.type === "guard" && e.directional_cap === "applied") {
    return { id: e.order_id, kind: "clamped", asofSeq: e.seq };
  }
  // A never-naked SELL refusal (or a synthesized-order de-arm) is a PLAN lifecycle record, not an ORDER
  // reject — no order was ever submitted. Surface the REFUSAL ones (only) as a `rejected` engine action
  // carrying the reason, so the agent can see why its order never rested (kestrel-7kt).
  if (e.stream === "PLAN" && e.type === "lifecycle" && isRefusalReason(e.reason)) {
    return { id: e.plan, kind: "rejected", asofSeq: e.seq, reason: e.reason! };
  }
  // An agent order-action refuse (cancelOrder no-such-ref, scheduleWake unresolvable/past/beyond) is a
  // CONTROL record — surface it too, so a refused agent action is never invisible to the agent.
  if (e.stream === "CONTROL" && e.type === "refuse") {
    const note = e.note ?? "refused";
    return { id: note.split(":")[0]!.trim(), kind: "rejected", asofSeq: e.seq, reason: note };
  }
  return null;
}

/** The FILLS-SINCE-LAST-WAKE: the `[prevWakeSeq, thisWakeSeq)` slice of the graded stream's ORDER
 * `fill` events, mapped to {@link FillRecord}. Frozen-at-wake (only `seq < thisWakeSeq`) and scoped to
 * the gap (not cumulative-since-open), so an order that filled between vantages reaches the acting agent
 * (kestrel-fud — this was hard-coded `[]`). Pure + deterministic, a projection of the graded bus. */
function fillsInWindow(emitted: readonly BusEvent[], window: SeqWindow): FillRecord[] {
  const out: FillRecord[] = [];
  for (const e of emitted) {
    if (e.seq < window.prevWakeSeq || e.seq >= window.thisWakeSeq) continue; // outside [prev, this)
    if (e.stream !== "ORDER" || e.type !== "fill") continue;
    out.push({
      side: e.side,
      instrument: e.instrument,
      // ADR-0017 (kestrel-1kp): an equity/spot fill carries NEITHER strike NOR right — PRESERVE their
      // absence, never substitute a phantom `0`/`"C"` zero-strike CALL. A concrete `0`/`"C"` defeats
      // {@link isSpotLeg} (which keys on presence), so the since-last fill line MISRENDERED the share leg
      // as `0C` instead of `<instrument> shares` (the same phantom-chrome class kestrel-orx fixed on the
      // kernel/positions surfaces). An OPTION fill carries BOTH — byte-identical to before.
      ...(e.strike !== undefined ? { strike: e.strike } : {}),
      ...(e.right !== undefined ? { right: e.right as FrameRight } : {}),
      qty: e.qty,
      px: e.px ?? 0,
      clock: clockOf(e.ts),
      ...(e.plan !== undefined ? { plan: e.plan } : {}),
    });
  }
  return out;
}

/** The engine-actions-since-the-last-wake: the `[prevWakeSeq, thisWakeSeq)` slice of the graded
 * `emitted` stream, bucketed by {@link engineActionOf}. Frozen-at-wake (only events with
 * `seq < thisWakeSeq`) and scoped to the gap (not cumulative-since-open). Pure + deterministic. */
function engineActionsInWindow(emitted: readonly BusEvent[], window: SeqWindow): EngineAction[] {
  const out: EngineAction[] = [];
  for (const e of emitted) {
    if (e.seq < window.prevWakeSeq || e.seq >= window.thisWakeSeq) continue; // outside [prev, this)
    const a = engineActionOf(e);
    if (a !== null) out.push(a);
  }
  return out;
}

/** Layer the enriched 4gl.3 cockpit lead block onto the plan-lifecycle base {@link Kernel}: the wake
 * ref (RELATIVE `T-Nm` deadline), per-vehicle data-health, the (empty) unavailable set, the cockpit
 * budget envelope, owner acts, the engine-actions-since-last-wake, and predictor/regime claims. Every
 * section is always present (absent renders as an explicit `none`/`UNKNOWN`, never dropped). This is
 * the REAL kernel {@link renderKernel} consumes — not a partial stub. Pure + deterministic. */
function enrichedKernelOf(
  base: Kernel,
  dataHealth: readonly VehicleHealth[],
  engineLog: readonly EngineAction[],
  ctx: WakeCtx,
  sizing?: SizingHeadroom | null,
): Kernel {
  const minutesToClose = Math.round((ctx.lastTs - ctx.wakeTs) / 60_000);
  const wake: WakeRef = {
    reason: ctx.wakeReason,
    severity: "routine",
    deadline: Number.isFinite(minutesToClose) ? minutesToClose : null,
  };
  return {
    ...base,
    // The extended cockpit lead block (4gl.3) — always present (absent-not-hidden).
    wake,
    dataHealth,
    // kestrel-wa0j.47: the v1 harness serves no macro/calendar capability, and the kernel's
    // unavailable-capabilities line is now that absence's ONE rendering (the `macro` pane left the
    // default OPEN set) — an empty list here would hide the absence entirely (absent-not-hidden).
    unavailable: ["macro calendar"],
    budgetEnvelope: budgetEnvelopeOf(base.budget, sizing),
    ownerActs: [],
    engineLog,
    claims: [],
  };
}

/**
 * **The pure WAKE-frame builder** (kestrel-5zl.11): `(graded bus, seq window, config) → ActingFrame`.
 * Assembles the date-blind {@link ActingFrame} handed to the agent at one wake, whose `kernel` is the
 * REAL enriched 4gl.3 cockpit lead block — positions / resting / budget / data-health / owner-acts /
 * the engine-actions-since-last-wake / predictor-regime claims — that {@link renderKernel} consumes,
 * NOT the partial stub. The engine log is the `[prevWakeSeq, thisWakeSeq)` bus-window slice
 * ({@link engineActionsInWindow}), so it is the since-LAST-wake delta, frozen-at-wake (only
 * `seq < thisWakeSeq`) with no look-ahead.
 *
 * PURE: no wall clock, no unseeded RNG — the output is a byte-identical function of its inputs, so the
 * same bus + same seq window + same config projects an identical frame (the determinism the tracer's
 * replay rides on). Frame content sits ABOVE the determinism line (recorded/fixed adapters ignore it),
 * so it never perturbs the graded bus. DATE-BLIND: only relative time, the `HHMM` ET clock, and
 * ordinals reach the frame; {@link assertFrameDateBlind} is the fail-closed backstop at the seam.
 */
export function projectWakeFrame(
  emitted: readonly BusEvent[],
  window: SeqWindow,
  config: WakeFrameConfig,
): ActingFrame {
  const { af, instrument, vehicles, ctx, standing, options } = config;
  const minutesToClose = Math.round((ctx.lastTs - ctx.wakeTs) / 60_000);
  const dataHealth = vehicles.map((v) => vehicleHealthOf(v, ctx.wakeTs));
  const engineLog = engineActionsInWindow(emitted, window);
  // The fills that happened since the last vantage — a graded-bus projection over the same seq window,
  // so an order that filled between wakes reaches the agent (kestrel-fud; the base `kernelOf` carries the
  // OPEN-briefing `[]`, which is correct pre-open).
  const fillsSinceLast = fillsInWindow(emitted, window);
  const base = kernelOf(af, instrument, standing ?? {}, config.execMultiplier ?? 1);
  // The sizing headroom (kestrel-m9i.32): the max fillable size the remaining-R budget admits for the
  // exec instrument, so a model sizes WITHIN the bounded-risk cost basis (ADR-0017) rather than into a
  // silent fire-time clamp. PURE — derived from the plan-lifecycle budget (`remaining $`) + the frame's
  // exec spot + the exec multiplier (equity 1 / option 100). An option's per-leg premium is not sourced
  // at this seam, so the option cue surfaces the remaining-$ ceiling + the basis rule (never a guess).
  const sizing = sizingHeadroomOf({
    instrument,
    remainingUsd: base.budget?.remaining ?? null,
    spot: af.spot,
    multiplier: config.execMultiplier ?? 1,
  });
  const kernel = { ...enrichedKernelOf(base, dataHealth, engineLog, ctx, sizing), fillsSinceLast };
  // The ARMED plans' enforced terms for the `armed-plan` pane (kestrel-wa0j.29) — captured from the armed
  // ASTs the driver holds (`config.armedPlanAsts`), filtered to the plans this wake's kernel reports in an
  // ENFORCED lifecycle state (armed/fired/managing). The watcher manages plans whose document text it
  // never otherwise sees; the terms enter the frame THROUGH this typed input (the renderer invents none).
  // Absent config, or no enforced plan ⇒ `undefined` (absent-not-hidden: the field is unserialized and the
  // pane fails closed to absent-with-reason, byte-identical to a frame without it).
  const enforcedPlanNames = new Set(base.plans.filter((p) => ENFORCED_PLAN_STATES.has(p.state)).map((p) => p.name));
  const armedPlan =
    config.armedPlanAsts !== undefined
      ? armedPlanTermsOf(config.armedPlanAsts, enforcedPlanNames, config.sessionDate)
      : undefined;
  return {
    // WakeDeltaInput
    wakeIndex: af.n,
    minutesSinceLast: Math.round((ctx.wakeTs - ctx.prevVantageTs) / 60_000),
    timeToCloseMin: minutesToClose,
    phase: mapPhase(af.phase),
    clockET: clockOf(ctx.wakeTs),
    wakeReason: ctx.wakeReason,
    // kestrel-121: price the chain `fair` column through the injected `fairTauYears` at this wake's cutoff
    // (`ctx.wakeTs`) — the SAME source the fill engine prices `@fair` with. Absent ⇒ `fair` stays `—`.
    market: marketPaneOf(
      af,
      instrument,
      options,
      config.fairTauYears !== undefined
        ? { tauYears: config.fairTauYears, nowTs: ctx.wakeTs, ...(config.fairExpiry !== undefined ? { expiry: config.fairExpiry } : {}) }
        : undefined,
    ),
    kernel,
    // The prior author vantage's served values (kestrel-wa0j.48) — threaded from the driver so the
    // `delta` pane states what MOVED under stateless-redraw (the renderer invents no value; the prior
    // data must enter through the frame input). Present only on a wake AFTER the first; absent ⇒ the
    // field is unserialized and the frame is byte-identical to today (the delta pane fails closed).
    ...(config.priorVantage !== undefined ? { priorVantage: config.priorVantage } : {}),
    // The prior sessions' tapes (kestrel-wa0j.20) — threaded from the driver so `tape d-N` serves
    // ordinal N's rows as its own single-session block. Present only when the run injects a multiday
    // tape; absent ⇒ the field is unserialized and the frame is byte-identical (Train 1B absence).
    ...(config.priorSessions !== undefined ? { priorSessions: config.priorSessions } : {}),
    // The armed plans' enforced terms (kestrel-wa0j.29) — threaded so the `armed-plan` pane renders the
    // WHEN/entries/exits/invalidation/size the watcher enforces. Present only on a wake with at least one
    // plan in an enforced state; absent ⇒ the field is unserialized and the frame is byte-identical.
    ...(armedPlan !== undefined ? { armedPlan } : {}),
    // acting-kernel strip
    wakeOrdinal: ctx.wakeOrdinal,
    // The stable replay identity (kestrel-5zl.19) — the source that raised this wake + its monotone
    // per-source ordinal, the two halves `wakeKeyOf` joins the captured turns on.
    wakeSource: ctx.wakeSource,
    wakeSourceOrdinal: ctx.wakeSourceOrdinal,
    // The relative-day coordinate (kestrel-5zl.16.4) — present ONLY for a multi-session run (it rides the
    // date-blind author projection), absent + unserialized for a standalone session (goldens unchanged).
    ...(af.sessionOrdinal !== undefined ? { sessionOrdinal: af.sessionOrdinal } : {}),
    severity: "routine",
    deadline: {
      minutesToClose,
      minutesToNextWake: ctx.nextWakeTs === null ? null : Math.round((ctx.nextWakeTs - ctx.wakeTs) / 60_000),
    },
    dataHealth: { asOfClockET: clockOf(ctx.wakeTs), stale: [], unavailable: [] },
    // The scheduled wake's stored View rides the delivery (kestrel-wa0j.4) — the adapter renders THIS
    // wake's panes under it; absent ⇒ the field is unserialized and the frame is byte-identical to today.
    ...(ctx.view !== undefined ? { view: ctx.view } : {}),
    attention: { wakesRemaining: ctx.wakesRemaining, coalesced: ctx.coalesced },
  };
}

/** Fail-closed date-blind fence over the assembled acting Frame (the agent boundary): serialize with the
 * SAME 1e-6 rounding the machine summary uses (so a raw float tail can't trip the epoch grep as a false
 * calendar signal), then run the SHARED {@link scanDateLeak}. A leak is REFUSED, never delivered. */
function assertFrameDateBlind(frame: ActingFrame): void {
  const body = JSON.stringify(frame, (_k, v) =>
    typeof v === "number" && Number.isFinite(v) ? Math.round(v * 1e6) / 1e6 : v,
  );
  const hit = scanDateLeak(body);
  if (hit !== null) {
    throw new Error(
      `simulate: acting Frame leaks a ${hit.name} (${JSON.stringify(hit.match)}) at the agent boundary ` +
        "(fail-closed, EVALUATION contamination fence)",
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// runSimulateSession
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Drive one frozen-at-wake Simulate session through the {@link Agent} seam and return its graded
 * {@link Blotter} + the {@link CapturedTurns} it consumed. Reuses the SAME {@link SessionCore} the stepped
 * day drives (bus-stepping, Gate, `projectAuthorFrame`); the ONE behavioral change is that the wake set is
 * answered by `agent.decide` rather than a file handshake. `async` because the live loop is deliberately
 * non-deterministic; the recorded/fixed adapters resolve synchronously.
 */
export async function runSimulateSession(opts: RunSimulateOptions): Promise<SimulateResult> {
  if (opts.busPath === undefined && opts.events === undefined) {
    throw new Error("simulate: runSimulateSession needs either `busPath` or `events`");
  }
  const events: BusEvent[] = opts.events !== undefined ? [...opts.events] : [...readBus(opts.busPath!)];
  const meta = requireMeta(events);
  const specs = resolveSpecs(meta, opts.instruments);
  const fairTauYears = opts.fairTauYears ?? expiryTauYears(meta.session_date);
  const firstTs = events[0]?.ts ?? 0;
  const lastTs = events[events.length - 1]?.ts ?? firstTs;
  const sessionDate = meta.session_date;

  // ── Clock-honest session semantics (ADR-0040 / kestrel-w7la.1, clock-honest wakes §§2, 4, 7) ─────
  // The switch is the agent config's `clockHonest` (a ConfigId axis — a clocked run never shares a grid
  // column with an unclocked one). EVERY precondition refuses LOUDLY at open — never a silent default,
  // never a silent downgrade to latency-blind (§4).
  const clockHonest = opts.agent.config.clockHonest === true;
  if (clockHonest) {
    const buf = opts.agent.config.latencyBufferMs;
    if (typeof buf !== "number" || !Number.isInteger(buf) || buf < 0) {
      throw new Error(
        `simulate: clock-honest run refused at open — \`latencyBufferMs\` must be a non-negative integer (got ${JSON.stringify(buf)}); there is NO default (never a silent default — a designed default would be a judge-designed weighting, ADR-0030 spirit). \`0\` is legal: it declares a colocated seat.`,
      );
    }
    // Eligibility: the ADR-0040 data floor, declared with the tape and verified fail-closed (§4).
    const ineligible = clockHonestIneligibility(opts.dataRung);
    if (ineligible !== null) {
      throw new Error(`simulate: clock-honest run refused at open — ${ineligible}`);
    }
    // A costless (pre-v6 / latency-blind) capture replays ONLY under latency-blind semantics (§7):
    // replaying it clocked would silently change what the run claims to be. Probed at the OPEN key —
    // the one entry every driver-captured recording holds.
    if (opts.agent.recordedCostMs !== undefined && opts.agent.recordedCostMs(OPEN_WAKE_KEY) === undefined) {
      throw new Error(
        "simulate: clock-honest run refused at open — the recorded capture is COSTLESS (it carries turns but no measured deliberation costs); a costless capture replays only latency-blind (ADR-0040 §7, never a silent downgrade)",
      );
    }
  }
  /** The configured latency buffer, applied to every Seat-answered vantage (0 when latency-blind —
   * never read on that path). */
  const bufferMs = clockHonest ? (opts.agent.config.latencyBufferMs as number) : 0;
  /** The injectable wall clock — consulted ONLY on the live clocked path (§7's one minting seam). */
  const nowFn = opts.now ?? Date.now;

  /**
   * Measure — or, in replay, READ — one Seat turn's deliberation cost (§7: mint once, live-side, at
   * THIS seam; the only minting site). Replay mode (an agent exposing `recordedCostMs`) never touches
   * the clock — a replay path that re-times is a defect by definition (the poisoned-clock fixture).
   */
  const clockedTurn = async (
    key: WakeKey,
    call: () => Promise<AgentTurn> | AgentTurn,
  ): Promise<{ turn: AgentTurn; measuredMs: number; seatAnswered: boolean }> => {
    const costSource = opts.agent.recordedCostMs?.bind(opts.agent);
    if (costSource !== undefined) {
      const turn = assertHandlerResponseTimeless(await call());
      const c = costSource(key);
      // `null` = the capture never held this key — the replay machinery SYNTHESIZED the turn
      // (divergence stand-down / inserted-vantage pass). Engine-minted, not Seat deliberation:
      // cost 0, no buffer, no record (§7 — charging tape for a turn no Seat took fabricates cost).
      if (c === null) return { turn, measuredMs: 0, seatAnswered: false };
      if (c === undefined || !Number.isInteger(c) || c < 0) {
        throw new Error(
          `simulate: clock-honest replay hit a costless/malformed capture entry at wake ${key} — a costless capture replays only latency-blind (fail-closed, ADR-0040 §7)`,
        );
      }
      return { turn, measuredMs: c, seatAnswered: true };
    }
    const t0 = nowFn();
    const turn = assertHandlerResponseTimeless(await call());
    const t1 = nowFn();
    return { turn, measuredMs: Math.max(0, Math.round(t1 - t0)), seatAnswered: true };
  };

  // Capture the a57.14 experimental envelope from the agent's config (kestrel-5zl.6) and stamp it on the
  // graded META at open — the CAPTURE side of a57.14. Only an authoring config declares one; a NO-LLM
  // Backtest (fixedPlan/recorded with BACKTEST_CONFIG) declares none ⇒ no stamp ⇒ the Blotter stays
  // certified (fail-closed by omission — never a fabricated identity). A declared-but-incomplete identity
  // is stamped so the projector fails the Blotter closed to PROVISIONAL (a57.14). The FULL ConfigId
  // rides alongside under the SAME condition (m9i.2 owner tweak): the grid CellKey keys on it, so
  // temperature-only config variants land in DISTINCT cells.
  const envelope = envelopeForConfig(opts.agent.config);
  const configId = envelope !== undefined ? deriveConfigId(canonicalizeConfig(opts.agent.config)) : undefined;
  // The cell config axis (fillSeed stripped — ADR-0016 §3): stamped ONLY when it DIVERGES from configId (the
  // config carried a fillSeed) — a seedless run's cell axis equals configId, so no stamp and the graded bus
  // stays byte-identical. Seed-only variants pool as replicates in ONE cell; configId keeps the seeded RUN id.
  const cellConfigId = envelope !== undefined ? cellConfigIdOf(opts.agent.config) : undefined;
  const cellConfigStamp = cellConfigId !== undefined && cellConfigId !== configId ? cellConfigId : undefined;
  // Arm the seeded sampled fill channel when the agent's config declares a fillSeed (kestrel-9gu.8.3,
  // ADR-0016); a Backtest config (or any omitting the seed) leaves the sampler OFF (fail-closed).
  const fillSeed = fillSeedOf(opts.agent.config);
  // The sampled-channel qualification claim (kestrel-9gu.12), read fail-closed off the config: absent —
  // every config until the 9gu.8.6 study passes — the headline gate resolves to the strict-cross floor.
  const sampledQualification = sampledQualificationOf(opts.agent.config);

  const openingCarry = opts.openingCarry;
  // The wake-frontier floor is a FUNCTION of the cell's timescale band (kestrel-5zl.16.7). Read the band
  // once from the opening carry (an absent carry — a standalone / flat open — is `emptyCarry().band` =
  // `day`, so this run is byte-identical to today), resolve the pure floor, and use its three controls
  // wherever the frontier gates a wake (`popNext` spacing/ceiling, `armStaleness` backstop, the own-fill
  // spacing). The DAY floor reproduces today's exact constants — no churn.
  const floor = wakeFloorForBand((openingCarry ?? emptyCarry()).band);
  const core = new SessionCore({
    meta,
    specs,
    fillModel: opts.fillModel,
    rUsd: opts.rUsd,
    fairTauYears,
    firstTs,
    // NO `tapeRegimeScopes` pre-scan here, DELIBERATELY (kestrel-ocyf round 3): this is the
    // agent-interactive path (day.ts drives through it), and a whole-bus pre-scan is a LOOKAHEAD
    // ORACLE — a mid-session supersede→arm would receive a notice grade that is a function of
    // post-vantage events (definitive notice = "never written all day"; silence = "a REGIME write is
    // coming"), and the REFUSAL_MARKERS seam pipes that onto the acting agent's frame, letting it
    // read tomorrow's regime vocabulary through throwaway supersedes. Violates this file's own
    // charter (no post-cutoff leak / no look-ahead) and the eval contamination firewall. Interactive
    // sessions take the CONDITIONAL wording — derived only from `#tags` (events ingested so far),
    // causally honest at any vantage, still loud at arm. The batch-replay `runSimSession` (a post-hoc
    // report with no author to leak to) keeps the definitive pre-scan.
    ...(opts.makerFairParams !== undefined ? { makerFairParams: opts.makerFairParams } : {}),
    ...(envelope !== undefined ? { envelope } : {}),
    ...(configId !== undefined ? { configId } : {}),
    ...(cellConfigStamp !== undefined ? { cellConfigId: cellConfigStamp } : {}),
    ...(openingCarry !== undefined ? { openingCarry } : {}),
    ...(fillSeed !== undefined ? { fillSeed } : {}),
    ...(sampledQualification !== undefined ? { sampledQualification } : {}),
    // The clock-honest attestation input (ADR-0040 §5): every §4 precondition already held above (the
    // run refuses at open otherwise), so a constructed clocked core is an attested one. `true` or
    // absent — the driver NEVER stamps `false`.
    ...(clockHonest ? { clockHonest: true as const } : {}),
  });
  const instrument = core.execSpec.symbol;
  const instruments = meta.instruments.map((i) => i.symbol);

  // DAY-COMPAT MODE (kestrel-5zl.3): the caller-owns-cadence path `runDaySession` drives through. When set,
  // the driver reproduces the stepped runner's cadence + byte stream EXACTLY — the day's own structural wakes
  // are the coverage, so NO platform staleness/backstop wake is injected (Divergence #1), and the CONTROL
  // supersede carries the day's `{target,note}` bytes (Divergence #2). NARROW + orthogonal to `band`: a normal
  // band run leaves it false, so `armStaleness`/`wakeFloorForBand` (16.7) are untouched and the wake-band
  // fail-closed invariant holds. `dayBridge` (present only for the actual day file agent) is bound to the live
  // core here so the agent can validate a revision against it (collision preview) with no forked path.
  const dayCompat = opts.dayCompat === true;
  if (opts.dayBridge !== undefined) {
    opts.dayBridge.previewSupersede = (mod: Module) => core.engine.supersedeArmRejection(mod);
  }

  const captured = new Map<WakeKey, CapturedTurn>();
  let armed = false; // the FIRST supersede is the initial arm (no CONTROL, `day.ts` plans-0 parity)
  let placeSeq = 0;

  // ── The date-blind seam for agent-authored free text (kestrel-auw) ────────────────────────────────
  // Every agent free-text field that flows into a CONTROL event is a contamination vector: a CONTROL
  // `refuse` note is surfaced by `engineActionOf` into the NEXT wake's engine log, so a calendar token
  // (a month/weekday/date) in agent text re-renders into a later date-blind acting Frame and trips
  // `assertFrameDateBlind` UNCAUGHT — unwinding the whole session with no partial Blotter. So screen at
  // THIS seam (the same refuse-and-log `scheduleWake.reason` uses), NEVER echoing the matched token —
  // that token IS the leak, and the refuse note itself reaches the frame — and let the session continue.
  // `assertFrameDateBlind` stays the last-resort backstop; this is the belt that keeps it from firing.
  const DATE_BLIND_PLACEHOLDER = "[withheld: date-blind fence]";

  /** Pure sanitizer for an agent string EMBEDDED into a runtime-built note (e.g. a `cancelOrder` ref in a
   * refuse note): the original when date-blind, else a fixed placeholder — never the matched calendar token. */
  const dateBlindField = (text: string): string => (scanDateLeak(text) === null ? text : DATE_BLIND_PLACEHOLDER);

  /** Screen an agent free-text field that becomes (or rides in) its own CONTROL note (a `standDown` reason,
   * a `supersede`/`placeOrder` note). Date-blind → returned unchanged (byte-identical). A leak → an auditable
   * CONTROL `refuse` naming the leak CLASS ONLY (never the matched token) is emitted, and the field is
   * replaced with a date-blind placeholder so the originating CONTROL event stays date-blind. */
  const dateBlindNote = (field: string, text: string, ts: number): string => {
    const leak = scanDateLeak(text);
    if (leak === null) return text;
    core.emit({ ts, stream: "CONTROL", type: "refuse", note: `${field} refused: leaks a ${leak.name} (date-blind fence)` });
    return DATE_BLIND_PLACEHOLDER;
  };

  // ── The agent-decision RECEIPT producer (kestrel-a57.18) ──────────────────────────────────────
  // The a57.5 projector (`grade/receipts`) lifts every agent PROPOSAL / DECLINE / STAND-DOWN off the bus
  // — but nothing WROTE them, so `projectReceipts()` returned `[]` on every real session and the
  // benchmark north star (measuring RESTRAINT: the declines and stand-downs) was inert in production.
  // These emits are that missing producer: the driver records what the agent DECIDED at the same three
  // sites it already records what the engine DID, on the unchanged CONTROL stream.
  //
  // The pairing with the arm record is EXACT by construction of `core.arm`, which is all-or-nothing (a
  // per-statement refusal comes back as DATA and is re-thrown as a whole-document `armRefusalError`):
  //   • the arm SUCCEEDS ⇒ one `propose` per PLAN statement, `target` = the plan name the bus will arm;
  //   • the arm ESCAPES (parse or engine refusal) ⇒ a `stand_down` carrying the text the agent left on
  //     the table, and NOTHING armed — so the curation verdict's arm reconciliation stays clean rather
  //     than reading a refused proposal as a phantom arm.
  // That is the driver's own fail-closed ladder ("parse escape → STAND_DOWN", extended to an ARM escape,
  // RUNTIME §8) mirrored onto the receipt channel — the escape is RECORDED, never dropped.
  const receiptMeasurement = driverMeasurementVersions({ fillModel: opts.fillModel, fidelity: fidelityOf(meta.mode) });

  /** Write one agent decision receipt onto the CONTROL stream. `plan_text` rides the SAME date-blind
   * fence every other agent-authored note crosses: a leak is refused-and-placeholdered (never delivered),
   * and the placeholder then fails the projector CLOSED to a logged stand-down rather than banking a
   * scrubbed plan as if the agent had authored it.
   *
   * DAY-COMPAT (Divergence #3, kestrel-5zl.3): the caller-owns-cadence path exists to reproduce the
   * STEPPED runner's byte stream EXACTLY (the frozen day `44cf2cbf`), so it emits no receipt — a new
   * event on that path IS the churn it is defined to have none of. NARROW, and it is not "the producer is
   * optional": every agent-driven session (sim / bench / live — the graded line the benchmark ranks)
   * takes the branch below. The day handshake gets its receipts when it stops replaying frozen bytes. */
  const emitDecision = (d: Omit<DecisionEmit, "measurement_versions">, ts: number): void => {
    if (dayCompat) return;
    const plan_text = d.plan_text === null ? null : dateBlindNote(`${d.control} plan text`, d.plan_text, ts);
    core.emit({ ts, stream: "CONTROL", ...decisionControlFields({ ...d, plan_text, measurement_versions: receiptMeasurement }) });
  };

  /** The PLAN statements a module arms, each as its own canonical source text — one receipt row per plan
   * (a receipt is per-PLAN; `target` is the name the bus's arm record keys on). */
  const planRows = (mod: Module): { name: string; text: string }[] =>
    mod.statements.filter((st) => st.kind === "plan").map((st) => ({ name: st.name, text: print(st) }));

  /** One PROPOSE receipt per plan of a document the engine ACTUALLY armed (call only after a successful
   * `core.arm`, which is all-or-nothing). `novel_plan` is the honest kind for every arm on this surface:
   * the driver has no armory to accept FROM and no prior proposal to reparameterize — the agent authored
   * the document. The finer kinds arrive when the agent states its own (the a57.14 typed envelope). */
  const emitProposals = (mod: Module, ts: number): void => {
    for (const row of planRows(mod)) {
      emitDecision({ control: "propose", target: row.name, decision_kind: "novel_plan", plan_text: row.text }, ts);
    }
  };

  /** The RECEIPT of an ARM escape: the engine refused the document, so nothing armed and the agent's
   * decision produced no position. Recorded as a stand-down carrying the text it authored (curation
   * honesty), NOT as a proposal — a `propose` here would claim an arm the bus's arm record cannot back,
   * which the curation verdict would correctly read as a phantom arm. */
  const emitArmEscape = (document: string, ts: number, e: unknown): void => {
    emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: document, rationale: `arm escape → stand-down: ${msgOf(e)}` }, ts);
  };

  // ── The agent-driven wake frontier (kestrel-5zl.4) ────────────────────────────────────────────
  // A min-ordered set of pending wakes seeded from the agent's scheduleWake actions (open + each
  // decide) and the author/platform floor (authored vantages + optional structural cadence), advanced
  // turn-by-turn. Every ts is pure offset / ET-calendar arithmetic off the injected firstTs /
  // session_date (no wall clock, no RNG) — same bus + same agent turns ⇒ byte-identical evolution.
  const frontier: FrontierWake[] = [];
  let idx = 0;
  let prevVantageTs = firstTs; // the OPEN baseline (T-5, m9i.11) is the first vantage
  let delivered = 0;
  // The DELIVERED wake instants (theta-cell seam b) — the vantages a HELD position is marked-to-model at
  // when `markToModel` is on. Collected in delivery order; consumed once, after settle. Off the graded
  // path unless `markToModel` opts in (then folded into `totals.floor` via a `theta_bleed` record).
  const deliveredWakeTs: number[] = [];
  let coalesced = 0; // agent wakes folded since the last delivery — surfaced on the next retained frame
  /** Wakes RAISED per source so far — the monotone per-source counter each {@link FrontierWake}'s
   * {@link FrontierWake.sourceOrdinal} is minted from at the RAISE (kestrel-5zl.20), the stable half of
   * its {@link wakeKeyOf} replay identity. Counting RAISES not deliveries is the whole fix: a delivery
   * that later folds (an inserted own-fill advancing the budget/spacing, a probe skip) no longer shifts
   * the ordinal a subsequent same-source wake carries, so the replay join never depends on whether a
   * delivery survived folding. Deterministic (a pure count, no clock, no RNG). */
  const raisedOrdinals = new Map<WakeSource, number>();
  /** Mint the next monotone per-source ordinal for a wake being RAISED (kestrel-5zl.20). */
  const nextSourceOrdinal = (source: WakeSource): number => {
    const k = raisedOrdinals.get(source) ?? 0;
    raisedOrdinals.set(source, k + 1);
    return k;
  };

  // ── The language-level WakeBudget (kestrel-wa0j.5) ────────────────────────────────────────────────
  // `WAKE … BUDGET N wakes/day` on the ARMED standing document NARROWS the band's config wake ceiling
  // (min of the two — an authored budget may never widen config; budgets nest, authority only narrows).
  // It caps AGENT-cadence deliveries only: the safety floors (staleness/structural/own-fill) are never
  // capped away, and a wake folded past the budget is COALESCED — surfaced on the next retained
  // delivery's `attention.coalesced`, never a silent drop. The authored budget lives WITH the standing
  // document: a supersede replaces it, a de-arm clears it (back to the config floor alone).
  let authoredWakesPerDay: number | null = null;

  /** Reduce a module's WAKE statements to their authored wakes/day budget — the MIN across statements
   * (the narrowest authored bound wins). `M tokens/day` has NO enforceable meaning in this loop
   * (attention here is budgeted in wakes + coalescing, not a per-day token meter), so it REFUSES by
   * THROW — the arm sites route it through their fail-closed disarm/refuse ladder — rather than arm
   * an authored clause silently inert (kestrel-wa0j.5). */
  const authoredWakeBudgetOf = (mod: Module): number | null => {
    let min: number | null = null;
    for (const s of mod.statements) {
      if (s.kind !== "wake" || s.budget === undefined) continue;
      if (s.budget.tokensPerDay !== undefined) {
        throw new Error(
          `WAKE ${s.name} BUDGET ${s.budget.tokensPerDay} tokens/day is unenforceable in this loop ` +
            `(attention is budgeted in wakes/day + coalescing, not tokens) — refused rather than armed inert`,
        );
      }
      if (s.budget.wakesPerDay !== undefined) {
        min = min === null ? s.budget.wakesPerDay : Math.min(min, s.budget.wakesPerDay);
      }
    }
    return min;
  };

  /** The effective per-session ceiling on delivered wakes: the band's config ceiling, NARROWED (never
   * widened) by the armed document's authored wakes/day. Absent authored budget ⇒ the config floor
   * alone — byte-identical to before the language-level budget was wired. */
  const effectiveMaxWakes = (): number =>
    authoredWakesPerDay === null ? floor.maxWakes : Math.min(floor.maxWakes, authoredWakesPerDay);

  /** ARM `mod` WITH its authored WakeBudget — the ONE place the arm side of the invariant "an
   * authored budget arms and de-arms WITH its document" lives (kestrel-wa0j.5). The budget reduces
   * BEFORE the arm (an unenforceable `tokens/day` clause THROWS here, into the caller's own
   * fail-closed disarm/refuse ladder — an authored budget is never armed silently inert) and binds
   * only when the arm itself succeeds; a throw from `core.arm` leaves the budget untouched. */
  const armWithBudget = (mod: Module): void => {
    const wakesBudget = authoredWakeBudgetOf(mod);
    core.arm(mod);
    armed = true;
    authoredWakesPerDay = wakesBudget;
  };

  /** The de-arm side of the same invariant (kestrel-wa0j.5): a de-armed/superseded document's
   * authored budget de-arms WITH it — back to the config floor alone. */
  const clearAuthoredBudget = (): void => {
    authoredWakesPerDay = null;
  };

  /** Dateless `HHMM` ET clock for a ts (a frontier wake's `label` + the WAKE checkpoint reason). */
  const labelHHMM = (ts: number): string => {
    const m = ((etMinuteOfDay(ts) % 1440) + 1440) % 1440;
    return `${String(Math.floor(m / 60)).padStart(2, "0")}${String(m % 60).padStart(2, "0")}`;
  };

  /** Resolve a {@link WakeAt} to epoch-ms, or `null` when structurally unresolvable (fail-closed).
   * `inMinutes` is an offset off the CURRENT vantage — so it spans ANY horizon natively (intraday or
   * multi-Session, e.g. `+1440` reaches the next session); `atClockET` anchors to `session_date` (the
   * conservative default taken here — per-session re-anchoring is scoped to b3l). */
  const resolveWakeAt = (at: WakeAt, vantageTs: number): number | null => {
    if (at.kind === "inMinutes") return Number.isFinite(at.minutes) ? vantageTs + at.minutes * 60_000 : null;
    const m = /^(\d{1,2}):(\d{2})$/.exec(at.clockET.trim());
    if (m === null) return null;
    const hh = Number(m[1]);
    const mm = Number(m[2]);
    if (hh > 23 || mm > 59) return null;
    return etWallClockMs(sessionDate, hh, mm);
  };

  /** Union a pending wake onto the frontier, de-duplicated by ts (first-wins — deterministic by push
   * order: seed floor before agent before staleness). A same-ts collision keeps the earlier provenance.
   * The RAISED wake is minted its per-source ordinal HERE (kestrel-5zl.20) — the one place a wake enters
   * the frontier — so the identity is fixed at the raise, never at the delivery; a de-duplicated (dropped)
   * push mints nothing (it never becomes a wake). */
  const pushFrontier = (w: Omit<FrontierWake, "sourceOrdinal">): void => {
    if (frontier.some((e) => e.ts === w.ts)) return;
    frontier.push({ ...w, sourceOrdinal: nextSourceOrdinal(w.source) });
  };

  /** Advance the frontier: pop the earliest pending wake in the open gap `(prevVantageTs, lastTs)`. An
   * agent wake within the band's `floor.minWakeSpacingMin` of the last vantage, or past
   * `floor.maxWakes`, is FOLDED (the coalesced counter is bumped, no separate delivery); the
   * staleness/structural floors are exempt and always delivered. Returns `undefined` when the gap holds
   * no further deliverable wake. */
  const popNext = (): FrontierWake | undefined => {
    frontier.sort(
      (a, b) =>
        a.ts - b.ts ||
        WAKE_SOURCE_RANK[a.source] - WAKE_SOURCE_RANK[b.source] ||
        (a.reason < b.reason ? -1 : a.reason > b.reason ? 1 : 0),
    );
    while (frontier.length > 0) {
      const w = frontier.shift()!;
      if (w.ts <= prevVantageTs || w.ts >= lastTs) continue; // outside the open gap (defensive)
      // Safety-class wakes (structural cadence, staleness backstop, and an own-fill management wake) are
      // never folded by spacing/budget — a fill must be surfaced for management (fire-then-inform).
      const isSafety = w.source === "structural" || w.source === "staleness" || w.source === "own-fill";
      if (!isSafety && (w.ts - prevVantageTs < floor.minWakeSpacingMin * 60_000 || delivered >= effectiveMaxWakes())) {
        coalesced++; // folded — surfaced on the next retained delivery's attention.coalesced
        continue;
      }
      return w;
    }
    return undefined;
  };

  /** Whether the book is EXPOSED at the frontier — any net-nonzero option/spot inventory. A pure read of
   * the graded stream's ORDER `fill` events (the SAME source `armOwnFillWakes` and `af.fills` read; a
   * carried `openingCarry.positions` book is seeded as opening `place`+`fill`s BEFORE the first
   * `armStaleness`, so it reads exposed from `firstTs`). Nets buys against sells per instrument/strike/
   * right: a closed round-trip nets to zero (flat), an open lot leaves a residual (held). Deterministic. */
  const isExposed = (): boolean => {
    const net = new Map<string, number>();
    for (const e of core.emitted.events) {
      if (e.stream !== "ORDER" || e.type !== "fill") continue;
      const key = `${e.instrument}|${e.strike ?? ""}|${e.right ?? ""}`;
      net.set(key, (net.get(key) ?? 0) + (e.side === "buy" ? e.qty : -e.qty));
    }
    for (const q of net.values()) if (q !== 0) return true;
    return false;
  };

  /** Whether the cell's OWN staleness backstop lands PAST settle for THIS window (the WIDE-band regime —
   * swing/position on a short window). A session-level constant: when the band's backstop from `firstTs`
   * already overshoots `lastTs`, it overshoots from every later vantage too, so in this regime the band's
   * own backstop is NEVER in-window and every staleness wake `armStaleness` installs is a DAY-floor PROBE
   * (conditionally delivered — see the loop). For DAY/scalp this is `false` (their own backstop is
   * in-window), so no probe path is ever taken — those bands are byte-identical to today. */
  const bandBackstopPastSettle = firstTs + floor.stalenessBackstopMin * 60_000 >= lastTs;

  /** Re-arm the staleness floor relative to `vantageTs`, parameterized by the cell's band
   * (kestrel-5zl.16.7). If no wake that will actually be DELIVERED lands within the band's backstop
   * deadline, insert a safety wake at `vantageTs + floor.stalenessBackstopMin`. A foldable agent wake
   * does NOT satisfy the floor, so the backstop can never be silenced by a sub-spacing (or capped)
   * schedule. There is no Action that removes this — the agent can never disable safety (fail-closed).
   *
   * FAIL-CLOSED while exposed. When a WIDE band's backstop lands PAST settle (`deadline >= lastTs` — the
   * position/swing regime on a short window), the band's own backstop can never cover the gap, so fall
   * back to the DAY backstop (the universal, most-conservative safety floor) and install it as a PROBE —
   * unconditionally, whatever the book reads NOW. Exposure can be acquired AFTER this vantage (a resting
   * order that fills between vantages — kestrel-5zl.16.7), and gating on a flat read HERE is exactly what
   * left a silent no-wake window while later HELD. The probe is DELIVERED only if the book is EXPOSED at
   * its frozen vantage (the loop's conditional-probe skip); a still-FLAT probe is not woken (widening to
   * settle is allowed for a flat book). For the DAY band `safeDeadline` equals `deadline` and lands past
   * settle, so this returns exactly as today (no probe, no churn — the no-churn anchor). */
  const armStaleness = (vantageTs: number): void => {
    const willDeliver = (w: FrontierWake, effDeadline: number): boolean =>
      w.ts > vantageTs &&
      w.ts <= effDeadline &&
      (w.source === "structural" ||
        w.source === "staleness" ||
        (w.ts - vantageTs >= floor.minWakeSpacingMin * 60_000 && delivered < effectiveMaxWakes()));
    const insertBackstop = (deadline: number): void => {
      if (!frontier.some((w) => willDeliver(w, deadline))) {
        pushFrontier({ ts: deadline, reason: "staleness-backstop", source: "staleness", label: labelHHMM(deadline) });
      }
    };

    const deadline = vantageTs + floor.stalenessBackstopMin * 60_000;
    if (deadline < lastTs) {
      insertBackstop(deadline); // the band's backstop lands inside the window — normal path
      return;
    }
    // The band's own backstop lands past settle. Install the DAY floor — the tightest universal safety net
    // — as a PROBE (delivery is gated on exposure in the loop, so a flat book is never woken). For the DAY
    // band `safeDeadline` equals `deadline` and also overshoots settle, so this returns here exactly as
    // today: no probe installed, no churn. If even the day floor lands past settle, settle IS the vantage.
    const safeDeadline = vantageTs + DAY_STALENESS_BACKSTOP_MIN * 60_000;
    if (safeDeadline >= lastTs) return;
    insertBackstop(safeDeadline);
  };

  // Seed the frontier with the author/platform floor: authored vantages + (optional) structural cadence.
  // These are RETAINED as seed vantages (day.ts parity); the agent's scheduleWake set is unioned on top.
  for (const sw of computeWakes(sessionDate, opts.wakes ?? [], opts.structural ?? false, firstTs, lastTs)) {
    pushFrontier({ ts: sw.ts, reason: sw.label, source: sw.structural ? "structural" : "seed", label: sw.label });
  }

  /** Express a placeOrder as a one-shot Plan and arm it — it then crosses the IDENTICAL engine→Gate→fill
   * path a fired Plan crosses (bounded risk enforced by the engine, never re-implemented). A synthesis/parse
   * escape (e.g. an unresolvable price form) is refused-and-logged.
   *
   * The synthesized Plan is **WHEN-less and ttl-less** so it is immediately satisfiable at the wake it
   * was submitted and then RESTS like a real limit order:
   * - **WHEN-less** — an armed plan with no `WHEN` fires unconditionally on the very next engine sweep
   *   (it arms and fires in the SAME `onEvent`), so the order submits at once. The earlier `WHEN phase
   *   open` was the bug: a placeOrder arrives at a WAKE during `phase regular`, so `phase open` never
   *   evaluated true again and the order silently expired un-submitted (kestrel-5zl.5).
   * - **ttl-less** — a `ttl +1m` on the (now firing) plan would make the engine `#doTtlExpire` PULL the
   *   still-unfilled resting order one minute after arm, i.e. before the agent's next wake could ever
   *   see or `cancelOrder` it. A resting order instead rides until it fills, the agent cancels it, or the
   *   session settles worthless-unfilled ($0 floor) — the honest "resting order" semantic.
   * `budget 1R` (bounded risk) and the engine's never-naked per-leg refusal still apply — an uncovered
   * SELL is refused-and-logged by the engine (no order rests), an unresolvable leg is skipped fail-closed. */
  const routePlaceOrder = (action: PlaceOrderAction, ts: number): void => {
    const o = action.order;
    const priceExpr = o.price.trim().replace(/^@/, ""); // "@fair" → "fair" (the grammar's `@` is the separator)
    const name = `agent-order-${placeSeq++}`;
    // FAIL CLOSED, NARROWLY (kestrel-eywk). A synthesized one-shot inherits the standing document's risk
    // envelope, which now carries the author's OWN stated budget — so the ordinary case is ADMITTED and
    // bounded, and the never-naked / budget / intrinsic-floor checks in the engine still judge it. The one
    // case the engine cannot honestly serve is a standing document that states NO budget anywhere: there is
    // no authority to read, and the engine will not manufacture one. Refuse THIS action with a legible typed
    // reason on the author's channel (AX doctrine: no refusal without a reason) — the proportionate response
    // (ADR-0012), never a book-wide stand-down, never a silent clamp. Note: if nothing was ever opened (the
    // opening buy would hit this same refusal) there is no unstopped position to strand, so refusing even a
    // would-be SELL here never leaves inventory naked.
    if (!core.engine.synthesisEnvelopeBounded()) {
      core.emit({
        ts,
        stream: "CONTROL",
        type: "refuse",
        note: `placeOrder ${name} refused (no-bounded-envelope): the standing document states no budget anywhere — no POD/BOOK and no plan \`budget NR\` — so a synthesized order would inherit no bound. State a budget (fail-closed, RUNTIME §8)`,
      });
      // The refused order is a recorded stand-down (a57.18). No plan text: the driver refused BEFORE it
      // synthesized one, so there is no authored candidate to carry — it records what happened, not a
      // document that never existed.
      emitDecision({ control: "stand_down", target: name, decision_kind: "stand_down", plan_text: null, rationale: `placeOrder ${name} refused (no-bounded-envelope): the standing document states no budget anywhere` }, ts);
      return;
    }
    // The ADR-0017 leg convention: BOTH strike+right absent ⇒ an EQUITY/SPOT order, synthesized as an
    // equity leg (`USING exec <SYM>` + `DO buy N shares`) so it routes to the IDENTICAL spot-fill path a
    // fired plan's `DO buy N shares` crosses; else an OPTION leg (the option-chain fill path, unchanged).
    const isEquity = o.strike === undefined && o.right === undefined;
    const doc = isEquity
      ? `PLAN ${name} budget 1R\n  USING exec ${o.instrument}\n  DO ${o.side} ${o.qty} shares @ ${priceExpr}`
      : `PLAN ${name} budget 1R\n  DO ${o.side} ${o.qty} ${o.strike} ${o.right} @ ${priceExpr}`;
    let mod: Module;
    try {
      mod = toModule(parse(doc));
    } catch (e) {
      core.emit({ ts, stream: "CONTROL", type: "refuse", note: `placeOrder ${name} parse escape: ${msgOf(e)}` });
      // Curation honesty (a57.18): the order the agent wanted and did not get is a recorded stand-down
      // carrying the text that escaped — never a dropped row.
      emitDecision({ control: "stand_down", target: name, decision_kind: "stand_down", plan_text: doc, rationale: `placeOrder ${name} parse escape: ${msgOf(e)}` }, ts);
      return;
    }
    core.emit({ ts, stream: "CONTROL", type: "author", target: name, ...(action.note !== undefined ? { note: dateBlindNote("placeOrder note", action.note, ts) } : {}) });
    // `synthesizedOrder` — this is an agent placeOrder, not an authored document (kestrel-5zl.5): the engine
    // covers a SELL leg against the whole BOOK (the never-naked doctrine formula, since a one-shot has no
    // authored plan structure to scope to) and de-arms terminally-and-once if the leg is uncovered/unbuildable
    // (no per-sweep refusal storm). Authored plans keep the plan-scoped boundary (kestrel-22j.14).
    core.arm(mod, { synthesizedOrder: true });
    // The PROPOSE receipt for the synthesized one-shot (a57.18). A placeOrder arms a real plan under a
    // real name, so it lands in the bus's arm record exactly like an authored plan — without this row it
    // would be an UNRECEIPTED ARM (the engine arming what the curation record does not own) and the
    // verdict would refuse to grade the whole session. `novel_plan`: the agent authored this order.
    emitProposals(mod, ts);
    armed = true;
  };

  const routeAction = (action: Action, ts: number, dayOrdinal?: number): void => {
    switch (action.kind) {
      case "supersede": {
        let mod: Module;
        try {
          mod = toModule(parse(action.document));
        } catch (e) {
          // Fail-closed: a parse escape at the driver de-arms clean with a logged reason (never a crash).
          core.emit({ ts, stream: "CONTROL", type: "disarm", note: `supersede parse escape: ${msgOf(e)}` });
          // The RECEIPT of the same escape (a57.18): the agent decided something and it did not survive
          // the parse. The row is KEPT carrying the text it tried to author — the projector re-derives the
          // degrade itself ("parse escape → STAND_DOWN"), so the curation record cannot quietly lose the
          // decision that produced no arm.
          emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: action.document, rationale: `supersede parse escape: ${msgOf(e)}` }, ts);
          if (armed) core.supersede(ts);
          clearAuthoredBudget(); // the de-armed document's authored budget de-arms with it
          return;
        }
        if (!armed) {
          try {
            // The authored WakeBudget reduces BEFORE the arm (kestrel-wa0j.5, `armWithBudget`): an
            // unenforceable `tokens/day` clause throws here and rides the SAME fail-closed disarm
            // ladder — an authored budget is never armed silently inert.
            armWithBudget(mod); // initial arm — no CONTROL record (matches the stepped day's plans-0)
            emitProposals(mod, ts);
          } catch (e) {
            // Fail-closed: an initial document the engine refuses to arm de-arms clean with a logged reason
            // (never a crash — the parse-escape ladder extended to an ARM escape, RUNTIME §8).
            core.emit({ ts, stream: "CONTROL", type: "disarm", note: `arm escape: ${msgOf(e)}` });
            emitArmEscape(action.document, ts, e);
          }
        } else {
          if (dayCompat && dayOrdinal !== undefined) {
            // DAY-COMPAT (kestrel-5zl.3, Divergence #2): reproduce the stepped runner's CONTROL supersede
            // bytes EXACTLY — `{stream, type, target:"wake-N", note:"revision-N"}` (day.ts). `serializeEvent`
            // is `JSON.stringify` over all fields in insertion order, so the key order here
            // (ts, stream, type, target, note) MUST match `day.ts` for the frozen `44cf2cbf` to reproduce.
            core.emit({ ts, stream: "CONTROL", type: "supersede", target: `wake-${dayOrdinal}`, note: `revision-${dayOrdinal}` });
          } else {
            core.emit({ ts, stream: "CONTROL", type: "supersede", ...(action.note !== undefined ? { note: dateBlindNote("supersede note", action.note, ts) } : {}) });
          }
          core.supersede(ts);
          clearAuthoredBudget(); // the superseded document's authored budget de-arms with it
          try {
            // Same pre-arm WakeBudget reduction as the initial arm (kestrel-wa0j.5, `armWithBudget`):
            // the replacement's authored budget binds only when the replacement actually arms;
            // `tokens/day` refuses here.
            armWithBudget(mod);
            emitProposals(mod, ts);
          } catch (e) {
            // Fail-closed: a replacement the engine refuses to arm (e.g. a name still owned by a managing
            // lineage — names are lineage, ENGINE armDocument) leaves the just-superseded book riding its
            // TP/EXIT under its own record; a logged refuse, never a crash (RUNTIME §8).
            core.emit({ ts, stream: "CONTROL", type: "refuse", note: `supersede arm escape: ${msgOf(e)}` });
            emitArmEscape(action.document, ts, e);
          }
        }
        return;
      }
      case "standDown": {
        // Fence ONCE and reuse: `dateBlindNote` emits the auditable `refuse` on a leak, so calling it
        // twice for the same field would double-log the same refusal.
        const reason = dateBlindNote("standDown reason", action.reason, ts);
        core.emit({ ts, stream: "CONTROL", type: "disarm", note: reason });
        // The RESTRAINT row (a57.18) — the decision the benchmark north star is actually about. The agent
        // named no candidate (this surface's stand-down is a whole-book de-arm), so the plan is `null`:
        // the producer records the reason the agent gave and invents no plan it did not author.
        emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: null, rationale: reason }, ts);
        if (armed) core.supersede(ts); // de-arm clean; inventory rides its TP/EXIT (never liquidates)
        clearAuthoredBudget(); // the de-armed document's authored budget de-arms with it
        return;
      }
      case "scheduleWake": {
        // Fail-closed at the seam. A reason that itself carries calendar identity would re-leak into the
        // date-blind acting Frame — refuse-and-log it (the book rides the floor), never deliver it.
        const leak = scanDateLeak(action.reason);
        if (leak !== null) {
          // Name the leak CLASS only — echoing `leak.match` would re-inject the calendar token into this
          // refuse note, which `engineActionOf` surfaces into the next date-blind Frame (kestrel-auw).
          core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake reason refused: leaks a ${leak.name} (date-blind fence)` });
          return;
        }
        // Resolve the target; a past / beyond-window / unresolvable target is the PROPORTIONATE
        // refuse-that-action (the book stays armed on the staleness backstop), NOT a book-wide stand-down
        // and NEVER a forward peek past the driven window (agent.ts §Fail-closed; CLAUDE fail-closed).
        const at = resolveWakeAt(action.at, ts);
        if (at === null) {
          core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: unresolvable target` });
          return;
        }
        if (at <= ts) {
          core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: target in the past (rides the staleness backstop)` });
          return;
        }
        if (at >= lastTs) {
          core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: target beyond the driven window (no forward peek)` });
          return;
        }
        // The stored View is validated AT SCHEDULE TIME, fail-closed (kestrel-wa0j.4 / kestrel-wa0j.19 §1b):
        // it rides the WAKE `scheduled` record and the delivered frame, so a defect is caught NOW — never
        // carried to an (otherwise unguarded) delivery render where it could crash the wake. TWO
        // dispositions, by defect class:
        //   • date-leak / STRUCTURAL (unknown pane, reserved kernel id, un-understood args) — the View is
        //     unsafe or nonsense; refuse the WHOLE scheduleWake (the book rides the floor), the existing
        //     contract. Screened through the SAME date-blind fence as the reason, then `resolveView`.
        //   • VALUE / BUDGET knowable now (a `tape <window>` the constant tape bucket can't serve, a View
        //     already over its own token budget vs the catalog estimates) — the View is SOUND but this
        //     session's resolution can't serve it; DROP the View and still fire the wake under the DEFAULT
        //     panes, with a logged refuse (the proportionate disposition the delivery seam §1a reaches
        //     anyway, moved earlier). The wake intent is honored; only the unrenderable lens is dropped.
        let scheduledView: ViewSelection | undefined;
        if (action.view !== undefined) {
          const viewLeak = scanDateLeak(action.view);
          if (viewLeak !== null) {
            core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view refused — leaks a ${viewLeak.name} (date-blind fence)` });
            return;
          }
          let sel: ViewSelection;
          try {
            sel = viewSelectionOfDocument(action.view);
            resolveView(sel, "WAKE"); // fail-closed: unknown pane id / reserved kernel id / refused args
          } catch (e) {
            core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view refused — ${msgOf(e)}` });
            return;
          }
          const defect = scheduleTimeViewDefect(sel);
          if (defect !== null) {
            // Sound View this session can't serve — drop it, keep the wake (default panes), log the refuse.
            core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view dropped to default panes — ${defect}` });
          } else {
            scheduledView = sel;
          }
        }
        // Record the request (the audit) AND union it onto the wake frontier (the mechanism). The `view`
        // rides the record ONLY when it was ACCEPTED — a dropped View is not advertised as if it will render.
        core.emit({
          ts,
          stream: "WAKE",
          type: "wake",
          wake: "scheduled",
          reason: action.reason,
          ...(scheduledView !== undefined ? { view: action.view } : {}),
        });
        pushFrontier({
          ts: at,
          reason: action.reason,
          source: "agent",
          label: labelHHMM(at),
          ...(scheduledView !== undefined ? { view: scheduledView } : {}),
        });
        return;
      }
      case "placeOrder":
        routePlaceOrder(action, ts);
        return;
      case "flatten": {
        // FLATTEN (bd if0 / 75n): the agent's first-class close. The engine cancels the managing plan's
        // resting orders for the instrument (neutralizing the rolling TP re-post) AND crosses a COVERED
        // close through the SAME Gate — never-naked holds (a flatten of a held long is a covered sell) and
        // it can NEVER create a naked position. A flat book is a clean no-op, surfaced (never silent).
        const sym = dateBlindField(action.instrument);
        const out = core.flatten(action.instrument, ts);
        core.emit({
          ts,
          stream: "CONTROL",
          type: out.plansFlattened > 0 ? "disarm" : "refuse",
          note:
            out.plansFlattened > 0
              ? `flatten ${sym}: closed ${out.closedQty} across ${out.plansFlattened} plan(s)${action.note !== undefined ? ` — ${dateBlindField(action.note)}` : ""}`
              : `flatten ${sym}: no held position to close (no-op)`,
        });
        return;
      }
      case "cancelOrder": {
        try {
          // Route through the engine (kestrel-5zl.5 / #3c ow8): `core.cancelOrder` marks the engine child
          // cancelled AND drains the Gate's ORDER `cancel` in the SAME step, so the wake snapshot's
          // `resting[]` (an engine-dump scrape) and `engineLog` (a bus projection) AGREE within one
          // snapshot — never one wake late (the anomaly the capstone agent flagged). `cancel` returns
          // whether a resting order was actually removed; a ref that matches nothing currently resting
          // (unknown / already filled / already cancelled) is refused-and-logged — proportionate
          // fail-closed (never a stand-down, never a silent no-op), as CancelOrderAction specifies.
          if (!core.cancelOrder(action.ref, ts)) {
            // `action.ref` is agent free text that lands in this refuse note (→ next Frame via engineActionOf,
            // kestrel-auw) — sanitize a calendar token out of it so a bad ref can't trip the date-blind fence.
            core.emit({ ts, stream: "CONTROL", type: "refuse", note: `cancelOrder ${dateBlindField(action.ref)}: no resting order for ref` });
          }
        } catch (e) {
          core.emit({ ts, stream: "CONTROL", type: "refuse", note: `cancelOrder ${dateBlindField(action.ref)}: ${msgOf(e)}` });
        }
        return;
      }
      default:
        return assertNever(action, "simulate: unknown Action kind");
    }
  };

  /** Route one turn at the injected `ts`: the pre-hoc JOURNAL first (provably pre-hoc by `seq`), then the
   * actions in author order. An empty `actions[]` with no journal is a legitimate pass (emits nothing). */
  const routeTurn = (turn: AgentTurn, ts: number, dayOrdinal?: number): void => {
    if (turn.journal !== undefined) core.emit({ ts, stream: "JOURNAL", kind: "author", body: turn.journal });
    for (const action of turn.actions) routeAction(action, ts, dayOrdinal);
  };

  // ── Clock-honest delivery machinery (ADR-0040 / clock-honest wakes §§2.1–2.6) ────────────────────

  /** The segment tape carried between deliveries: exec SPOT/BOOK prints stepped since the last
   * delivered vantage — including a clocked OPEN overrun and each deliberation gap — drained into the
   * next delivery's snapshot. For a latency-blind run this is exactly the old per-wake segment. */
  const segmentTapeCarry: { ts: number; px: number }[] = [];
  /** Step every input event with `ts < tsMax` through the core (fills-before-sweep — armed Plans keep
   * firing at machine speed in a deliberation gap; the armed plan governs the gap), collecting the
   * exec tape into the carry. */
  const stepUntil = (tsMax: number): void => {
    while (idx < events.length && events[idx]!.ts < tsMax) {
      const ev = events[idx]!;
      if (ev.stream === "TICK" && ev.type === "SPOT" && ev.instrument === instrument) {
        segmentTapeCarry.push({ ts: ev.ts, px: ev.px });
      } else if (ev.stream === "TICK" && ev.type === "BOOK" && ev.instrument === instrument) {
        segmentTapeCarry.push({ ts: ev.ts, px: ev.underlier_px });
      }
      core.step(ev);
      idx++;
    }
  };

  /**
   * The latency-fold (§2.3): remove every frontier entry inside the open deliberation window
   * `(fromTs, returnTs]` — half-open below, closed above; a zero-cost window is empty. Each folded
   * wake counts ONCE toward the visible squelch; a FLAT-BOOK staleness PROBE inside the window is
   * SKIPPED, not folded (rule d — a probe is not attention owed to the Seat; the next probe re-arms
   * from the return). This is the §2.3(g) guard REDIRECT made structural: in-window entries route
   * HERE (to the fold) before `popNext`'s defensive out-of-gap skip could ever silently discard a
   * safety-class wake. Returns the folded count — >0 ⇒ exactly ONE catch-up delivery at `returnTs`.
   */
  const foldDeliberationWindow = (fromTs: number, returnTs: number): number => {
    let folded = 0;
    for (let i = frontier.length - 1; i >= 0; i--) {
      const e = frontier[i]!;
      if (e.ts <= fromTs || e.ts > returnTs) continue; // outside (fromTs, returnTs]
      frontier.splice(i, 1);
      if (bandBackstopPastSettle && e.source === "staleness" && !isExposed()) continue; // (d) probe skip
      folded++;
    }
    return folded;
  };

  /** §2.5 — the past-settle tail: a control returning at/past the session's last tape instant has no
   * market left to execute against. It is NOT lapse-to-null (the Seat gains nothing from silence — it
   * holds whatever its standing authority held): each action is refused with the logged reason,
   * stamped at the TRUE `returnTs`; the journal (author metadata) still rides pre-hoc-by-seq. Settle
   * itself stamps later at `lastTs`, its normal ts — emission order record → refusals → settle. */
  const refuseAfterSettle = (turn: AgentTurn, returnTs: number): void => {
    if (turn.journal !== undefined) core.emit({ ts: returnTs, stream: "JOURNAL", kind: "author", body: turn.journal });
    for (const action of turn.actions) {
      core.emit({
        ts: returnTs,
        stream: "CONTROL",
        type: "refuse",
        note: `${action.kind}: control returned after settle (no market left to execute against — ADR-0040 §2.5)`,
      });
    }
  };

  /** The pending latency-fold catch-up delivery (§2.3a): set when a deliberation window folded ≥1
   * frontier wake — ONE normal frozen-at-wake delivery at the Seat's return time, consumed by the
   * next loop pass INSTEAD of `popNext` (safety-class by construction: it bypasses the spacing/budget
   * folds, yet still counts against `delivered` and the wake budget — §2.3b). */
  let pendingCatchUp: FrontierWake | undefined;

  // 0. Multi-session re-arm (the multi-session horizon design, kestrel-5zl.16.2): re-arm the carried STANDING document fresh
  //    BEFORE the OPEN turn, minting new plan-instance ids for this session (the engine mints per-arm, so
  //    a fresh arm = fresh ids; a d0 `ttl 16:00` therefore CANNOT persist into d1 — it re-anchors to this
  //    session's open). The agent's OPEN turn may still supersede it (a CONTROL supersede, since `armed`).
  //    A session with no carried document opens exactly as today (`armed` stays false → the OPEN supersede
  //    is the initial arm, plans-0 parity). Only a multi-session run reaches this branch.
  if (openingCarry?.document != null) {
    try {
      // The carried document's authored WakeBudget re-arms with it (kestrel-wa0j.5, `armWithBudget`).
      // An unenforceable `tokens/day` throws — unreachable for a carry that passed the arm-time guard
      // in its prior session, but not trusted: it rides the same disarm ladder as any arm escape.
      armWithBudget(openingCarry.document);
    } catch (e) {
      // Fail-closed: a carry the engine refuses to re-arm opens the session un-armed with a logged
      // reason (never a crash — the arm-escape ladder, RUNTIME §8); the OPEN turn may still arm fresh.
      core.emit({ ts: firstTs, stream: "CONTROL", type: "disarm", note: `carry re-arm escape: ${msgOf(e)}` });
    }
  }

  // 1. OPEN — briefing (bounded by the author acting cutoff, T-5 by default — never a forward peek past
  //    the cutoff, m9i.11) → agent.open → route the initial arm.
  const cutoffTs = authorCutoffTs(sessionDate, opts.authorCutoff);
  // kestrel-wcnd: hold the RAW briefing snapshot — `projectAuthorFrame` strips the chain's absolute
  // expiry (the date-blind seam keeps only a relative `dte`), but τ must be resolved against that
  // absolute expiry. It feeds the pricer only; the frame the agent reads is untouched.
  const briefingSnap = briefingSnapshot(meta, instrument, events, opts.rUsd, cutoffTs, { carryRange: opts.authorFromRange === true });
  const briefingAf = projectAuthorFrame(briefingSnap, firstTs, sessionDate, opts.sessionOrdinal);
  const standing: KernelStanding = {
    ...(opts.mandate !== undefined ? { mandate: opts.mandate } : {}),
    ...(opts.brief !== undefined ? { brief: opts.brief } : {}),
  };
  // Perception arm (kestrel-4gl.13.13): fold the options overlay to the OPEN author cutoff (T-5m
  // guard — only events at/before the cutoff). Absent overlay ⇒ undefined ⇒ minimal arm, byte-identical.
  const openOptions = opts.optionsOverlay !== undefined ? buildFrameOptions(opts.optionsOverlay, cutoffTs) : undefined;
  const briefingInput = briefingInputOf(
    briefingAf,
    meta,
    instrument,
    firstTs,
    lastTs,
    standing,
    openOptions,
    {
      // kestrel-121: price the OPEN briefing chain `fair` through the SAME `fairTauYears` the fill engine
      // uses, evaluated at the author cutoff `cutoffTs` (the T-5 baseline — no forward peek).
      tauYears: fairTauYears,
      nowTs: cutoffTs,
      // kestrel-wcnd: …and against the SAME chain expiry, so the briefing's `fair` is the contract's,
      // not the session close's. Absent ⇒ τ `null` ⇒ `fair` renders `—` (fail-closed).
      ...(briefingSnap.chain?.expiry !== undefined ? { expiry: briefingSnap.chain.expiry } : {}),
    },
    // kestrel-wa0j.20: the injected prior-session tapes ride onto the OPEN briefing (absent ⇒ unchanged).
    opts.priorSessions,
  );
  // DAY-COMPAT: hand the day file agent the raw OPEN {@link AuthorFrame} (kestrel-5zl.3) — the SAME
  // projection this driver's own `briefingInputOf` consumed; `briefing.txt` itself renders from the typed
  // BriefingInput through the canonical renderer (kestrel-wa0j.2).
  if (opts.dayBridge !== undefined) opts.dayBridge.vantage = briefingAf;
  // The OPEN turn: the bounded ADR-0029 authoring loop when the agent is viewshop-enabled (it exposes
  // `authoringOpen` — the driver's config gate), else the single-shot open() (baseline / recorded /
  // fixed-plan). Only the TERMINAL turn crosses to the Bus + CapturedTurns; the shopping/repair
  // iterations are evidence above the determinism line, so recordedAgent (no authoringOpen) replays
  // byte-identically whether the live run shopped/repaired N times or committed immediately.
  const callOpen = (): Promise<AgentTurn> | AgentTurn =>
    opts.agent.authoringOpen !== undefined
      ? runOpenAuthoringLoop(opts.agent, briefingInput, {
          viewRequestCap: opts.authoring?.viewRequestCap ?? DEFAULT_VIEW_REQUEST_CAP,
          authoringTokenBudget: opts.authoring?.authoringTokenBudget ?? DEFAULT_AUTHORING_TOKEN_BUDGET,
          ...(opts.emergenceLog !== undefined ? { emergenceLog: opts.emergenceLog } : {}),
          model: opts.agent.config.model,
        })
      : opts.agent.open(briefingInput);
  if (!clockHonest) {
    // Latency-blind (the default): byte-identical to before — no checkpoint, no measurement, no record.
    const openTurn = assertHandlerResponseTimeless(await callOpen());
    routeTurn(openTurn, firstTs);
    captured.set(OPEN_WAKE_KEY, { turn: openTurn });
  } else {
    // §2.6 — the OPEN turn is clocked, WITH the checkpoint it was missing: the OPEN vantage becomes a
    // real, named anchor on the bus at the author cutoff (exactly what the record's wake_seq needs).
    // The whole bounded authoring loop (view iterations AND repair retries) is inside ONE measured
    // window — one vantage, one record, cumulative cost (§2.7).
    const openCheckpoint = core.emit({ ts: cutoffTs, stream: "WAKE", type: "wake", wake: "checkpoint", reason: labelHHMM(cutoffTs) });
    const { turn: openTurn, measuredMs, seatAnswered } = await clockedTurn(OPEN_WAKE_KEY, callOpen);
    const costMs = seatAnswered ? measuredMs + bufferMs : 0;
    const returnTs = cutoffTs + costMs; // the RECORD ts — the cost is truth, unclamped
    const landTs = Math.max(firstTs, returnTs); // where the OPEN control LANDS (§2.6 — a separate pin)
    // The overrun arm: a Seat that overruns its pre-open window arms late into a MOVING open — the
    // tape advances to the landing instant first (a within-window author steps nothing: no event
    // precedes firstTs).
    stepUntil(landTs);
    core.gate.now = landTs;
    if (seatAnswered) {
      core.emit({
        ts: returnTs,
        stream: "WAKE",
        type: "deliberation",
        wake_seq: openCheckpoint.seq,
        measured_ms: measuredMs,
        buffer_ms: bufferMs,
      });
    }
    if (returnTs >= lastTs) refuseAfterSettle(openTurn, returnTs);
    else routeTurn(openTurn, landTs);
    captured.set(OPEN_WAKE_KEY, seatAnswered ? { turn: openTurn, measuredMs } : { turn: openTurn });
    prevVantageTs = landTs;
    // The OPEN-overrun fold: seed/structural wakes falling in (firstTs, landTs] were owed while the
    // Seat authored — they fold into ONE catch-up delivery at the landing instant, exactly §2.3.
    const folded = foldDeliberationWindow(firstTs, landTs);
    if (folded > 0 && landTs < lastTs) {
      coalesced = folded;
      pendingCatchUp = { ts: landTs, reason: "latency-fold", source: "latency-fold", label: labelHHMM(landTs), sourceOrdinal: nextSourceOrdinal("latency-fold") };
    }
  }

  // The lower edge of the FIRST wake's engine-log window (kestrel-5zl.11): the seq the next emitted
  // event will carry, so the first `[prevWakeSeq, thisWakeSeq)` window is exactly the gap AFTER the
  // OPEN vantage (the OPEN arm's own PLAN records sit at/before this edge, never re-attributed as a
  // since-last engine action). Advanced to each delivered wake's checkpoint seq as the loop runs.
  let prevWakeSeq = core.emitted.events.length;

  // 2. The agent-driven wake frontier (frozen-at-wake), floored by the staleness backstop. The OPEN
  //    baseline is the first vantage; from here the agent's scheduleWake cadence drives, the platform
  //    floors (never replaces) it, and folds are surfaced on the retained delivery (never silently dropped).
  //    DAY-COMPAT (kestrel-5zl.3, Divergence #1): the caller (the day driver) OWNS the cadence — its own
  //    structural wakes ARE the coverage — so the platform injects NO staleness backstop on this path,
  //    reproducing the stepped runner's sparse `{OPEN, authored/structural}` wake set (no 30-min DAY-band
  //    churn → the frozen `44cf2cbf`). This is orthogonal to `band`: a normal band run leaves `dayCompat`
  //    false, so the 16.7 fail-closed backstop below still floors every agent-driven session.
  // (Clock-honest: the floor re-arms from the OPEN control's LANDING instant — `prevVantageTs` is the
  // landTs a clocked OPEN advanced it to; latency-blind it still equals `firstTs`, byte-identical.)
  if (!dayCompat) armStaleness(prevVantageTs);

  // Own-fill management wake (kestrel-9gu.8.3, ADR-0016) — ONLY on a seeded (sampled-channel) run, so
  // this is purely additive to a Backtest (no fillSeed ⇒ never armed ⇒ byte-identical). When the agent's
  // resting order fills — a strict-cross floor OR a causal sampled draw — a management wake is armed a
  // spacing beyond the fill so the agent can react to owning the position (fire-then-inform). It is a
  // safety-class wake (never folded), floored by the staleness backstop just like the platform wake.
  let fillWatermark = core.emitted.events.length;
  // Arm a management wake a spacing beyond `afterTs` (the current vantage being delivered) for any own-fill
  // in the segment just stepped — floored to `afterTs` so the wake is always in a FUTURE gap (the frozen-at-
  // wake model only steps forward; a past ts would be dropped). Deduped by ts; deliverable next popNext.
  const armOwnFillWakes = (afterTs: number): void => {
    const fresh = core.emitted.events.slice(fillWatermark);
    fillWatermark = core.emitted.events.length;
    if (fillSeed === undefined) return;
    if (!fresh.some((e) => e.stream === "ORDER" && e.type === "fill")) return;
    const wakeTs = afterTs + floor.minWakeSpacingMin * 60_000;
    if (wakeTs > prevVantageTs && wakeTs < lastTs) {
      pushFrontier({ ts: wakeTs, reason: "own-fill-management", source: "own-fill", label: labelHHMM(wakeTs) });
    }
  };

  // The prior author vantage's SERVED values (kestrel-wa0j.48) — captured at the END of each wake from
  // the frame THIS driver served, and threaded into the NEXT wake so the `delta` pane can state what
  // MOVED under stateless-redraw. `undefined` on the first wake (no prior author vantage yet) ⇒ that
  // frame carries no `priorVantage` and the delta pane fails closed to absent-with-reason.
  let priorServedVantage: PriorVantage | undefined = undefined;
  let n = 0;
  for (;;) {
    // A pending latency-fold catch-up (§2.3a) delivers INSTEAD of the frontier pop: it is
    // safety-class (never itself spacing- or budget-folded), yet counts like any delivery below.
    const w = pendingCatchUp ?? popNext();
    pendingCatchUp = undefined;
    if (w === undefined) break;

    // Drive events strictly before the wake, collecting the segment's underlier tape (day.ts parity;
    // the carry also holds anything a clocked OPEN overrun / deliberation gap already stepped).
    stepUntil(w.ts);
    const segmentTape = segmentTapeCarry.splice(0);
    armOwnFillWakes(w.ts); // seeded runs only — arm a management wake after any own-fill in this segment

    // Fail-closed conditional probe (kestrel-5zl.16.7): in a WIDE band whose own backstop lands past
    // settle, `armStaleness` installs a DAY-floor staleness PROBE at every vantage so exposure acquired
    // BETWEEN vantages (a resting order that fills after the last frontier evaluation — the marketable-
    // order-at-open case) is never left in a silent no-wake window while HELD. The probe is a REAL safety
    // wake only when the book is EXPOSED at this frozen vantage (segment fills are already stepped, so
    // `isExposed()` reads the book AT `w.ts`); a still-FLAT probe is not delivered (widening to settle is
    // allowed for a flat book) — skip it, re-arm the next DAY-floor probe from here, and step on. For
    // DAY/scalp this is unreachable (`bandBackstopPastSettle` is false — their own backstop is in-window,
    // never a probe), so those bands are byte-identical to today.
    if (bandBackstopPastSettle && w.source === "staleness" && !isExposed()) {
      armStaleness(w.ts); // re-arm the next probe from this point; a flat probe is never woken
      continue;
    }

    // Freeze market time at the wake ts and record the WAKE checkpoint (unconditional — part of freezing).
    // Its reason is the dateless HHMM clock (the unchanged bus contract); the wake's SEMANTIC reason rides
    // the acting Frame's wakeReason (agent reason / "staleness-backstop" / the seed HHMM label).
    core.gate.now = w.ts;
    const checkpoint = core.emit({ ts: w.ts, stream: "WAKE", type: "wake", wake: "checkpoint", reason: w.label });
    // The upper edge of THIS wake's engine-log window — the checkpoint's own seq. Every engine action
    // in `[prevWakeSeq, thisWakeSeq)` happened strictly after the previous vantage and at/before this
    // one (frozen-at-wake by construction: only events with `seq < thisWakeSeq` are read).
    const thisWakeSeq = checkpoint.seq;

    // Project the frozen-at-wake acting Frame through the PURE `projectWakeFrame` seam: the date-blind
    // snapshot (market pane + plan-lifecycle base) + the enriched 4gl.3 cockpit kernel (per-vehicle
    // data-health + the `[prevWakeSeq, thisWakeSeq)` engine-actions-since-last-wake). The market/positions
    // half still derives from the SAME snapshot the stepped day renders; the cockpit engine log is a bus
    // projection (bus-as-truth, ADR-0010/0011).
    const snap = snapshotOf(core, "delta", n, w.label, w.ts, instruments, opts.rUsd, segmentTape);
    const af = projectAuthorFrame(snap, firstTs, sessionDate, opts.sessionOrdinal);
    const nextWakeTs = frontier.length > 0 ? Math.min(...frontier.map((e) => e.ts)) : null;
    // Perception arm (kestrel-4gl.13.13): fold the options overlay to this wake's cutoff `w.ts`.
    const wakeOptions = opts.optionsOverlay !== undefined ? buildFrameOptions(opts.optionsOverlay, w.ts) : undefined;
    const frame = projectWakeFrame(
      core.emitted.events,
      { prevWakeSeq, thisWakeSeq },
      {
        af,
        instrument,
        // The exec contract multiplier drives the cost-basis sizing headroom (kestrel-m9i.32): equity 1,
        // listed option 100. Sourced from the live exec spec — never re-derived in the pure seam.
        execMultiplier: core.execSpec.multiplier,
        // The exec vehicle's data-health: an option instrument reads its chain book from `core.books`;
        // a plain EQUITY instrument has no chain book, so its liquidity is sourced from the live SPOT
        // NBBO `core.spotFill` tracks — the SAME quote pricing executes against (kestrel-710). Fail-closed.
        vehicles: [vehicleBookFromSpot(instrument, core.books.get(instrument), core.spotFill.currentQuote(instrument))],
        ctx: {
          wakeOrdinal: n,
          wakeSource: w.source,
          // The stable per-source ordinal minted at the RAISE (kestrel-5zl.20) — read straight off the
          // FrontierWake, so a folded delivery (own-fill/spacing/probe) never shifts this survivor's key.
          wakeSourceOrdinal: w.sourceOrdinal,
          wakeReason: w.reason,
          wakeTs: w.ts,
          prevVantageTs,
          nextWakeTs,
          lastTs,
          // Agent-driven with NO authored budget ⇒ open-ended (`null`, byte-identical to before). An
          // authored `BUDGET N wakes/day` (kestrel-wa0j.5) makes the narrowed remaining count VISIBLE
          // on every delivery — the attention accounting the squelch doctrine requires. THIS delivery
          // is already spent (`- 1`); a safety wake past the ceiling clamps at 0, never negative.
          wakesRemaining: authoredWakesPerDay === null ? null : Math.max(0, effectiveMaxWakes() - delivered - 1),
          coalesced,
          // The scheduled wake's stored View rides to the delivery it selects (kestrel-wa0j.4).
          ...(w.view !== undefined ? { view: w.view } : {}),
        },
        standing,
        // Perception arm (kestrel-4gl.13.13): the options-analytics projection folded to THIS wake's
        // cutoff `w.ts` (causal, no look-ahead). Absent overlay (or an empty fold) ⇒ minimal arm.
        ...(wakeOptions !== undefined ? { options: wakeOptions } : {}),
        // kestrel-121: the SAME `fairTauYears` the fill engine prices `@fair` with, so the chain `fair`
        // column is anchored on ExecutionFair at this wake's cutoff (`w.ts`) — never a mid, never `—`.
        fairTauYears,
        // kestrel-wcnd: …resolved against the RAW snapshot chain's own expiry (the projected `af` is
        // date-blind and carries only a relative `dte`). Pricer-only — never served to the author.
        ...(snap.chain?.expiry !== undefined ? { fairExpiry: snap.chain.expiry } : {}),
        // The prior author vantage's served values (kestrel-wa0j.48) — captured below at the end of the
        // previous iteration; absent on the first wake (the delta pane fails closed there).
        ...(priorServedVantage !== undefined ? { priorVantage: priorServedVantage } : {}),
        // The injected prior-session tapes (kestrel-wa0j.20) — threaded onto every wake so `tape d-N`
        // serves ordinal N's block. Absent in the v1 single-day sim ⇒ byte-identical (Train 1B absence).
        ...(opts.priorSessions !== undefined ? { priorSessions: opts.priorSessions } : {}),
        // The armed plan ASTs the core currently holds (kestrel-wa0j.29) — the seam filters them to the
        // plans in an enforced state and captures their terms for the `armed-plan` pane. An empty set (no
        // plan armed yet) yields no `armedPlan` on the frame — byte-identical, the pane fails closed.
        armedPlanAsts: core.armedPlanStatements,
        // The tape's session_date (kestrel-wa0j.74) — the reference the `armed-plan` pane blinds an
        // absolute per-leg `exp <iso-date>` to a relative `<n>dte` against, so no calendar token leaks.
        sessionDate,
      },
    );
    assertFrameDateBlind(frame);

    // DAY-COMPAT: hand the day file agent the raw wake {@link AuthorFrame} (kestrel-5zl.3) — it names the
    // artifact (`frame-<n>-<HHMM>.txt`) and serializes `state-<n>.json`; the TEXT frame renders from THIS
    // driver's typed ActingFrame through the canonical renderer (kestrel-wa0j.2).
    if (opts.dayBridge !== undefined) opts.dayBridge.vantage = af;
    // Key the capture on the SAME stable identity `recordedAgent` replays on (kestrel-5zl.19) — never the
    // global ordinal `n`, which any inserted vantage shifts.
    const key = wakeKeyOf(frame);
    /** Where this delivery leaves the vantage clock — `w.ts` latency-blind; `returnTs` clocked. */
    let vantageEnd = w.ts;
    if (!clockHonest) {
      // Latency-blind (the default): byte-identical to before — decide free, land at the wake ts.
      const turn = assertHandlerResponseTimeless(await opts.agent.decide(frame));
      // DAY-COMPAT: pass the wake ordinal `n` so `routeAction`'s supersede emits the day's `{target,note}`
      // CONTROL bytes (Divergence #2); ignored on the normal agent-driven path (`dayCompat` false).
      routeTurn(turn, w.ts, n); // re-seeds the frontier from this turn's scheduleWake actions (resolved off w.ts)
      captured.set(key, { turn });
    } else {
      // §2.1 the clocked turn: the Seat still decides on the frozen-at-wake frame (ADR-0012 §2's honest
      // comparison basis — what changes is when its answer LANDS, not what it saw). Its measured cost +
      // the configured buffer advance the tape to `returnTs`; the record prices the vantage; the control
      // executes against the book as of the return — the strict-cross floor prices whatever the market
      // did during deliberation (no synthetic slippage model, §2.2).
      const { turn, measuredMs, seatAnswered } = await clockedTurn(key, () => opts.agent.decide(frame));
      const costMs = seatAnswered ? measuredMs + bufferMs : 0;
      const returnTs = w.ts + costMs;
      stepUntil(returnTs); // fire-then-inform: the ARMED PLAN governs the gap at machine speed
      armOwnFillWakes(returnTs); // (f) an in-window own-fill manages forward from when the Seat can next look
      core.gate.now = returnTs;
      if (seatAnswered) {
        core.emit({
          ts: returnTs,
          stream: "WAKE",
          type: "deliberation",
          wake_seq: checkpoint.seq,
          measured_ms: measuredMs,
          buffer_ms: bufferMs,
        });
      }
      if (returnTs >= lastTs) refuseAfterSettle(turn, returnTs); // §2.5 — refused per action, still settles
      else routeTurn(turn, returnTs, n); // scheduleWake targets resolve off returnTs (§2.4)
      captured.set(key, seatAnswered ? { turn, measuredMs } : { turn });
      vantageEnd = returnTs;
    }
    // (kestrel-5zl.20) the per-source ordinal is minted at the RAISE (`pushFrontier`), not counted here at
    // delivery — so a wake folded before delivery no longer shifts a later same-source wake's replay key.

    prevWakeSeq = thisWakeSeq; // advance the window's lower edge to this wake's checkpoint
    prevVantageTs = vantageEnd;
    // Capture the TYPED values THIS frame served (never the rendered bytes, ADR-0041 §1) as the prior
    // vantage the NEXT wake's `delta` pane diffs against (kestrel-wa0j.48). Off the served market pane:
    // spot/hod/lod/vwap from the levels, the ATM straddle extrinsic via the SAME shared helper the delta
    // pane reads with — so prior and current are computed identically. `baseSeq` is the wake ordinal
    // (relative, date-blind); `baseClockET` is the served HH:MM ET clock (date-blind).
    priorServedVantage = {
      baseSeq: n,
      ...(frame.clockET !== undefined ? { baseClockET: frame.clockET } : {}),
      spot: frame.market.levels.spot ?? null,
      hod: frame.market.levels.hod ?? null,
      lod: frame.market.levels.lod ?? null,
      vwap: frame.market.levels.vwap ?? null,
      atmExtrinsic: atmStraddleExtrinsic(frame.market),
    };
    deliveredWakeTs.push(w.ts); // a vantage a held position is marked-to-model at (theta-cell seam b)
    delivered++;
    n++;
    coalesced = 0; // the folds gathered while finding w were surfaced on THIS delivery — reset for the next gap
    // The latency-fold (§2.3): frontier wakes inside the just-closed deliberation window (w.ts,
    // returnTs] coalesce — visibly — into ONE catch-up delivery at the Seat's return. Termination is
    // structural (§2.3e): a 0-cost window is empty, so the recursion only sustains while the Seat
    // keeps paying real cost against real frontier entries; past settle there is no market left and
    // §2.5 already graded the episode.
    if (clockHonest) {
      const folded = foldDeliberationWindow(w.ts, vantageEnd);
      if (folded > 0 && vantageEnd < lastTs) {
        coalesced = folded; // surfaced on the catch-up frame's attention.coalesced (§2.3c) — never silent
        pendingCatchUp = { ts: vantageEnd, reason: "latency-fold", source: "latency-fold", label: labelHHMM(vantageEnd), sourceOrdinal: nextSourceOrdinal("latency-fold") };
      }
    }
    if (!dayCompat) armStaleness(vantageEnd); // re-arm the floor from the Seat's return (DAY-COMPAT owns its cadence)
  }

  // 3. Drive to settle. A non-final session of an Instance (`carryClose`) carry-marks held inventory to
  //    close (it survives into the returned carry); a standalone / final session settles at intrinsic
  //    (today's behaviour exactly). `settle()` with no carry is byte-identical to the pre-16.3 call.
  while (idx < events.length) {
    core.step(events[idx]!);
    idx++;
  }
  const settle = core.settle(opts.carryClose === true ? { carry: true } : undefined);

  // THETA-CELL seam b (kestrel theta-cell): ask the HELD-POSITION OWNER what the position held as of the
  // graded bus is worth — it reconstructs the net held legs + their blended basis, marks them against the
  // tape's option book at every DELIVERED wake (theta decay between wakes), and DECIDES the stand-down
  // floor. The driver adds no judgement of its own: it emits verbatim whatever `thetaBleed` the owner
  // returns (`null` ⇒ nothing at all), so the tested surface — not driver glue — decides the floor
  // (kestrel-pta5). Emitted HERE — after settle, BEFORE `core.blotter()`/`buildReport` project the
  // finalized stream — so the Blotter's `totals.floor` carries the bleed (ADR-0011). GATED + additive: a
  // cell that did not opt into `markToModel` (every cell but FOMC-OPTIONS) emits nothing ⇒ every existing
  // pinned floor is byte-identical. The bleed only binds when a position is actually HELD across ≥1
  // delivered wake — a flat book, or a watcher that closed out (net-zero inventory), holds no legs and
  // emits nothing. CLEAN BOUNDARY: this rides the graded Bus / Blotter as a mark-to-model GRADING penalty,
  // distinct from realized settle cash — it is deliberately NOT folded into the engine-native
  // SessionReport `realized_floor_usd`, `settle.floorTotal`, or the carry cash (that report/ledger
  // integration is separate, out-of-scope work).
  const heldOpt = opts.markToModel === true ? { markToModel: true as const } : {};
  const held = heldPositionAsOfGradedBus({
    graded: core.emitted.events,
    tape: events,
    instrument,
    wakeTsList: deliveredWakeTs,
    recordTs: lastTs,
    ...heldOpt,
  });
  if (held.thetaBleed !== null) {
    // `ts` FIRST so the serialized field order is canonical (seq, ts, stream, type, payload) —
    // SessionCore.emit prepends `seq` verbatim without re-canonicalizing (src/session/sim.ts), and
    // serializeEvent (src/bus/write.ts) is insertion-order-dependent, so a spread that left `ts`
    // after `type` put a non-canonical record onto the trust-substrate graded bus (kestrel-pta5, C3b).
    const { ts, ...rest } = held.thetaBleed;
    core.emit({ ts, stream: "TELEMETRY", type: "theta_bleed", ...rest });
  }

  // The Blotter is a PURE projection of the graded Bus (ADR-0011) — no engine-state scrape. The carry is
  // a PURE read of the finalised session (the multi-session horizon design) — never a second writer onto bus or Blotter.
  const prior = openingCarry ?? emptyCarry();
  const carry = carryFrom({ core, settle, prior, ordinal: opts.sessionOrdinal ?? prior.priorOrdinal + 1 });
  // The native SessionReport, from the SAME finalized core `runDaySession` reports off (no Blotter→report
  // bridge): the ledger's record() consumes this verbatim, and its `session.settle_ts` is the deterministic
  // injected `recorded_at` (kestrel-m9i.7.4). Additive — the Blotter/carry above are byte-identical to before.
  // Always present (the tournament runner records it on every arm); this is also the frozen-basis report
  // `runDaySession` surfaces under DAY-COMPAT (kestrel-5zl.3) — `determinism_hash = emitted.hash()`, the
  // 0-based no-META basis the day reference `44cf2cbf` lives on — from this SAME single driver run.
  const report = core.buildReport(events.length, busSha256Of(events));
  // The graded bus is surfaced BESIDE its projection (ADR-0010: the Bus is the truth; the Blotter its
  // regenerable projection) — one assembly feeds both, so they can never drift.
  const gradedBus = core.gradedBus();
  return { blotter: project(gradedBus), report, captured, config: opts.agent.config, carry, gradedBus };
}
