/**
 * # session/day — the STEPPED session (the agent-day of EVALUATION.md Part 1)
 *
 * The supervised, wake-by-wake run of a single session in ONE process (RUNTIME §7 + EVALUATION
 * Part 1). Where {@link runSimSession} drives a bus straight through with a fixed document set,
 * {@link runDaySession} drives the SAME {@link SessionCore} but pauses at wake checkpoints and
 * hands control to an **external author** (an agent in another process) through a **file
 * handshake**: it writes a Frame + a machine summary to the run directory, then BLOCKS for the
 * author's reply (a revised document, or an explicit pass) before continuing. The revised document
 * **supersedes** the standing one (RUNTIME §5, "document supersession").
 *
 * ## The handshake protocol (files under `<dir>`)
 * 1. `briefing.txt` — the OPEN keyframe, written before the first event. The runner then BLOCKS
 *    for `plans-0.kestrel` (the day's authored plan document), parses + arms it.
 * 2. At each wake `n` (authored triggers + the structural cadence into the close), the runner
 *    drives events up to the wake's sim-time, then writes `frame-<n>-<HHMM>.txt` (a delta Frame:
 *    tape since the last vantage, positions, resting, fills, budget, plan states) and
 *    `state-<n>.json` (the machine summary), and BLOCKS for either `revision-<n>.kestrel`
 *    (supersede) OR `pass-<n>` (an empty file = no change).
 * 3. After the last wake it drives to settle, writes `report.json`, and the caller records the run
 *    with the FULL concatenated authored text as `plansText`.
 *
 * ## The injected-time boundary (documented, deliberate) — a LATENCY-BLIND clause
 * The **sim clock is entirely injected** from the bus (`now` = the current event's `ts`, RUNTIME
 * §0) — the graded computation reads no wall clock. The **host wait loop** (polling the filesystem
 * for the author's reply, and the `--max-wait` safety timeout) DOES read the host wall clock: it is
 * an out-of-band author interaction, not part of the graded computation. Determinism is unaffected
 * because the graded output is a pure function of `(bus, wake set, handshake file contents)` — how
 * long the host waited never enters it. With identical revision files pre-staged, a re-run replays
 * byte-identically (the certification test asserts this).
 *
 * **This "host wall-clock wait is off the graded clock" clause is scoped to LATENCY-BLIND sessions**
 * (ADR-0040 / clock-honest-wakes §3, RUNTIME §7 edit). `runDaySession` reaches the driver
 * ({@link runSimulateSession}) with `BACKTEST_CONFIG` — a NO-LLM config that declares no `clockHonest`
 * — so a stepped DAY is always latency-blind today: no deliberation record, the `--max-wait` poll never
 * touches the graded tape, and the frozen `44cf2cbf` reference is preserved byte-for-byte. **There is no
 * transport special-case.** Were an operator to hand the driver a `clockHonest: true` config over an
 * eligible tape (§4 data floor), the SAME uniform driver seam that clocks an in-process `decide`
 * (`clockedTurn` in {@link runSimulateSession}) would clock the file-handshake `await` — the author's
 * wall time (the block-with-retries) becomes `measured_ms`, priced into the tape like any deliberation.
 * A handshake driven by a *human* would then grade terribly clock-honest; operators run those
 * latency-blind. The day driver does not special-case the file transport — the clock-honest eligibility
 * gate (not the handshake) decides admissibility, and this file threads no `now`/`clockHonest` of its
 * own (it inherits the driver's seam unchanged). See docs/design/clock-honest-wakes.md §3.
 *
 * ## Fail-closed (RUNTIME §8)
 * Missing META / no instruments / unknown fill model → refuse (via {@link SessionCore}). An
 * abandoned handshake (no reply within `--max-wait`) exits LOUDLY rather than hanging forever. A
 * malformed `plans-0` / `revision-n` document is a loud parse error (never a silent skip).
 *
 * ## No handshake wait is ever silent (kestrel-4fc9)
 * A blocked day must not look like a hung one. Before EVERY handshake block — the OPEN wait for
 * `plans-0` and each wake's wait for a `revision-<n>`/`pass-<n>` — the runner ANNOUNCES the contract on
 * the host status channel ({@link DayHooks.notify} → stderr): which artifact it just wrote, which file(s)
 * it now wants, and the budget it will actually enforce. While blocked (only ever under `--await-author`)
 * it emits a HEARTBEAT every {@link HEARTBEAT_MS}, so a day waiting on a slow author is observably
 * distinct from a hung process without truncating the real workflow.
 *
 * ## The default TERMINATES; the out-of-band author wait is OPT-IN (kestrel-4fc9, supersedes the 0.4.x default)
 * `kestrel day --dir <empty> </dev/null` (the kestrel-4fc9 repro, and the site's published copy-button) has
 * no author and never will. The runner CANNOT infer author presence/absence from the host — a non-interactive
 * stdin is also exactly what the primary agentic path looks like (an LLM authoring out-of-band from a
 * piped/CI harness), and sniffing `isTTY` would both mis-serve a real caller and put a host property on the
 * control-flow path. So BOTH presence and absence are DECLARED, never detected — symmetric flags:
 *
 * - **default** (neither flag): the day runs from whatever is STAGED in `--dir` and, on a missing document,
 *   refuses PROMPTLY after {@link NO_AUTHOR_GRACE_MS} with a typed {@link DayHandshakeError} (code `NO_AUTHOR`,
 *   exit 6) that names the missing file and both ways forward. A published command therefore always
 *   TERMINATES under plain node — it never rides a 900s poll for a reply the caller never said was coming.
 * - **`--await-author`** ({@link RunDayOptions.awaitAuthor}): the caller DECLARES an out-of-band author will
 *   reply, so each handshake blocks up to `--max-wait` (default 900s), announcing + heartbeating, and
 *   abandons LOUDLY (`HANDSHAKE_ABANDONED`, exit 6) only past that budget. This is the pre-0.4.x default
 *   behaviour, now explicit. Supplying `--max-wait` implies it.
 * - **`--no-author`** ({@link RunDayOptions.noAuthor}): the explicit form of the default — documents are
 *   pre-staged; a miss is the same prompt `NO_AUTHOR` refusal. Kept for self-documenting callers.
 *
 * The 0.4.x contract (a bare `day` rides `--max-wait` 900s for the author) is SUPERSEDED: a shipped,
 * published verb that polls 900s under plain node never terminated inside a caller's budget (the web repo's
 * offline command guard, 120s) — a fail-closed violation on a live surface (RUNTIME §7/§8, this bead's P0
 * re-groom). The real author path is unchanged in substance — it simply says `--await-author` now.
 */
import type { BusEvent, MetaEvent, OptionQuote } from "../bus/index.ts";
import { type ActingFrame, type CapturedTurns } from "./agent.ts";
import type { PendingWake } from "./carry.ts";
import type { Blotter } from "../blotter/index.ts";
import type { EpisodeSigmoidParams } from "../fill/index.ts";
import { SessionCore, type FillModelName, type EpisodeReport } from "./sim.ts";
import { type InstrumentSpec } from "../engine/index.ts";
/** An ET wall-clock time-of-day (a wake vantage). */
export interface TimeOfDay {
    readonly hour: number;
    readonly minute: number;
}
/** The host-interaction seam — the ONLY wall-clock/filesystem/stderr touch points, all off the graded
 * computation (see the file header's injected-time boundary). Defaults use `node:fs` + a sleep +
 * `Date.now` + `process.stderr`; a test injects deterministic hooks so no real wait ever happens.
 *
 * NOTE ON OMISSION: {@link RunDayOptions.hooks} is spread OVER {@link DEFAULT_HOOKS}, so an omitted
 * field inherits the REAL host — an omitted `notify` writes to the process's actual stderr, it is not
 * silenced. A test that must not leak status lines pins `notify` explicitly. */
export interface DayHooks {
    exists(path: string): boolean;
    read(path: string): string;
    write(path: string, content: string): void;
    /** Block the HOST briefly between polls (NOT sim time). */
    sleep(ms: number): void;
    /** HOST wall clock (ms) for the `--max-wait` timeout (NOT sim time). */
    clock(): number;
    /** Announce host status lines — the handshake contract the runner is about to block on, and the
     * heartbeat while it is blocked (kestrel-4fc9). NOT an author artifact: never date-fenced, never
     * graded, never on stdout (the report owns that). Omitted ⇒ the real `process.stderr` (see the
     * interface note); pin it to `() => {}` in a test that must stay quiet. */
    notify(line: string): void;
}
/** Options for {@link runDaySession}. Exactly one of `busPath`/`events` supplies the bus. */
export interface RunDayOptions {
    readonly busPath?: string;
    readonly events?: readonly BusEvent[];
    /** The run directory the handshake files live in. */
    readonly dir: string;
    /** Authored wake vantages (ET times-of-day). */
    readonly wakes?: readonly TimeOfDay[];
    /** The author acting cutoff (an ET wall-clock time-of-day). The OPEN keyframe is built ONLY from
     * observations watermarked at or before this instant — never a forward peek. Defaults to the
     * canonical benchmark's T-5 (the 09:30 regular open minus 5 min = 09:25 ET). Injected + explicit so
     * no post-cutoff (e.g. 09:30-or-later) print can leak to the author (kestrel-m9i.11, fail-closed). */
    readonly authorCutoff?: TimeOfDay;
    /** Add the structural cadence into the close: T-2h, T-1h, T-30m, T-15m, T-10m, T-5m (RUNTIME
     * §5 / EVALUATION Part 1). */
    readonly structural?: boolean;
    readonly fillModel: FillModelName;
    readonly rUsd: number;
    readonly instruments?: readonly InstrumentSpec[];
    readonly fairTauYears?: (now: number) => number | null;
    readonly makerFairParams?: EpisodeSigmoidParams;
    /** The safety timeout (seconds) an abandoned handshake exits loudly after — the budget the
     * out-of-band author wait rides. Only consulted when the caller has DECLARED it will wait
     * ({@link awaitAuthor}, or supplying this value at all). Default 900. */
    readonly maxWaitSec?: number;
    /** DECLARE that an external author WILL reply out-of-band (`--await-author`, kestrel-4fc9): block at
     * each handshake for the author's document, riding {@link maxWaitSec} (default 900s), announcing +
     * heartbeating while blocked, and abandoning LOUDLY (`HANDSHAKE_ABANDONED`) only past that budget. This
     * is the primary agentic path (an LLM authoring from a piped/CI harness). Supplying {@link maxWaitSec}
     * IMPLIES it — bounding a wait is itself a declaration that you intend to wait. Default false. */
    readonly awaitAuthor?: boolean;
    /** DECLARE that no external author will reply (`--no-author`, kestrel-4fc9): the handshake documents
     * must already be staged in {@link dir}, and any miss is a prompt typed refusal after
     * {@link NO_AUTHOR_GRACE_MS}. This is a caller ASSERTION, never an inference — the runner cannot tell a
     * `</dev/null` repro from a real out-of-band agent harness. Redundant with the default now (which also
     * refuses promptly) but kept as an explicit, self-documenting assertion; it wins over {@link awaitAuthor}
     * if both are somehow set. */
    readonly noAuthor?: boolean;
    /** Host poll interval (ms) between handshake-file checks. Default 50. */
    readonly pollMs?: number;
    /** Write the report to this path too (pretty JSON). */
    readonly out?: string;
    /** Host-interaction hooks (test seam). */
    readonly hooks?: Partial<DayHooks>;
}
/** One wake vantage as it was actually delivered + answered. */
export interface WakeRecord {
    readonly n: number;
    readonly ts: number;
    readonly label: string;
    readonly structural: boolean;
    /** Did the author supersede here (a `revision-<n>` reply), or pass? */
    readonly revised: boolean;
}
/** The result of a stepped day: the graded report, the concatenated authored text (the ledger
 * `plansText`), and the delivered wake sequence (the decision trace scaffold). */
export interface DaySessionResult {
    readonly report: EpisodeReport;
    readonly plansText: string;
    readonly wakes: readonly WakeRecord[];
    /** The turns the run consumed, keyed by wake ordinal (kestrel-5zl.3 re-run — the fileHandshakeAgent
     * refactor over the ONE shared {@link import("./simulate.ts").runSimulateSession} driver). Populated ONLY
     * once `runDaySession` delegates to the driver in DAY-COMPAT MODE: it is the SINGLE driver run's
     * {@link CapturedTurns}, so the day is re-runnable as a Backtest — {@link import("./agent.ts").recordedAgent}
     * replays it through `runSimulateSession` byte-identically, proving there is no forked second progression
     * path. Absent on the pre-refactor stepped path (this field is what makes the TDD-red contract observable). */
    readonly captured?: CapturedTurns;
    /** The graded {@link Blotter} from that SAME single driver run (a pure projection of the graded Bus,
     * ADR-0011) — never a second run stapled on for the Blotter. Present under the driver delegation; absent
     * on the pre-refactor stepped path. */
    readonly blotter?: Blotter;
}
/** The US regular-session open (ET). The canonical benchmark's acting cutoff is measured back from here. */
export declare const REGULAR_OPEN: TimeOfDay;
/** The canonical benchmark's acting-cutoff LEAD in minutes before the open: T-5. The default author
 * cutoff is `REGULAR_OPEN − AUTHOR_CUTOFF_LEAD_MIN` = 09:25 ET. */
export declare const AUTHOR_CUTOFF_LEAD_MIN = 5;
/**
 * The acting-cutoff epoch-ms for a session: an explicit `authorCutoff` (an ET wall-clock time-of-day)
 * mapped onto `sessionDate`, or — when unset — the canonical-benchmark default T-5 (the 09:30 regular
 * open minus 5 min = 09:25 ET). Pure ET calendar arithmetic (no wall clock, RUNTIME §0), so replay is
 * byte-stable.
 */
export declare function authorCutoffTs(sessionDate: string, authorCutoff?: TimeOfDay): number;
/** Parse a `--wakes HH:MM,HH:MM,…` string into times-of-day (loud on a malformed token). */
export declare function parseWakeTimes(spec: string): TimeOfDay[];
/** Parse an `HH:MM` ET clock (an `atClockET` wake field) into a {@link TimeOfDay}, or `null` when it is
 * structurally unresolvable (a malformed token, or hour/minute out of range). The FAIL-CLOSED sibling of
 * {@link parseWakeTimes} (which THROWS on a bad CLI token) — a `null` is dropped-and-logged by the caller,
 * never a silent-default vantage. */
export declare function parseClockET(clockET: string): TimeOfDay | null;
/** Re-anchor a carried wake {@link PendingWake} frontier onto the NEXT session (kestrel-5zl.16.9, ADR-0015
 * D3/D1). An `atClockET` pending wake becomes an authored {@link TimeOfDay} vantage: {@link computeWakes}
 * then maps it onto the TARGET session's `session_date`, so "16:00" fires at 16:00 on the NEXT session's
 * date — never the origin's. A structurally-unresolvable clock is DROPPED into `dropped` with its `reason`
 * (fail-closed — never injected as a silent-default vantage).
 *
 * **The fate of an `inMinutes` offset at THIS seam (kestrel-5zl.16.9 mustFix D — a DELIBERATE decision).**
 * This consumer seam re-expresses a pending wake as a dateless {@link TimeOfDay} clock that
 * {@link computeWakes} anchors to the TARGET `session_date`. An `inMinutes` offset is NOT a clock and has
 * NO vantage in the target session to measure from (its origin vantage died with the prior session), so it
 * cannot be honestly re-injected here. Under fail-closed there is no third option: it is DROPPED into
 * `dropped` WITH a reason — SURFACED, never silently swallowed (the pre-fix `continue` vanished it, the
 * review's finding 4). Native `inMinutes` carry (riding an offset across the boundary off a real target
 * vantage) is the b3l Wake-router producer's concern (kestrel-b3l.1), a different mechanism than this
 * `atClockET` re-anchoring; until it lands, an `inMinutes` on the carry frontier fails closed here.
 *
 * Pure ET calendar arithmetic on the caller's side (this returns dateless vantages), so replay is
 * deterministic. */
export declare function reanchorFrontier(frontier: readonly PendingWake[]): {
    readonly wakes: readonly TimeOfDay[];
    readonly dropped: readonly {
        readonly reason: string;
        readonly why: string;
    }[];
};
/** Compute the ordered, de-duplicated wake sequence for a session, in epoch-ms sim time. Authored
 * wakes + (optionally) the structural cadence, mapped onto `session_date` via the ET calendar,
 * filtered to strictly inside `(firstTs, lastTs)` — a wake before the first event or at/after the
 * settle delivers nothing actionable. Structural provenance is retained (for the decision trace). */
export declare function computeWakes(sessionDate: string, authored: readonly TimeOfDay[], structural: boolean, firstTs: number, lastTs: number): {
    ts: number;
    label: string;
    structural: boolean;
}[];
/** A resting/filled child order, projected from the engine's deterministic dump. */
interface OrderLine {
    /** The authoritative Gate ref the fill engine rests this order under (the engine child's `ref`, e.g.
     * `o1`). Threaded so an acting agent can `cancelOrder` a resting order by its REAL ref (kestrel-5zl.5).
     * The canonical kernel PRINTS resting refs (`ref=o1` — deliberate: the ref is what a cancel names), so
     * since the renderer swap (kestrel-wa0j.2) it is visible in the day artifacts too. */
    readonly ref: string;
    readonly plan: string;
    readonly role: string;
    readonly side: string;
    readonly qty: number;
    readonly strike: number;
    readonly right: string;
    readonly px: number;
    readonly filled: boolean;
}
/** A plan's state at a vantage. */
interface PlanLine {
    readonly name: string;
    readonly state: string;
    readonly heldQty: number;
    /** kestrel-50w: WHY an `authored` plan is stuck (an unsatisfiable/UNKNOWN regime gate). Present ⇒ the
     * frame renders `authored (blocked: <reason>)`; absent ⇒ a bare `authored` (a live plan awaiting WHEN). */
    readonly blockedReason?: string;
}
/** The typed bundle a Frame renders — the narrow seam between the day runner and `renderFrame`. */
export interface DaySnapshot {
    readonly kind: "keyframe" | "delta";
    readonly n: number;
    readonly label: string;
    readonly nowTs: number;
    readonly instruments: readonly string[];
    readonly phase: string;
    readonly spot: number | null;
    /** The epoch-ms the SPOT tick behind `spot` printed at (kestrel-rs4) — a REPLAY-side wall epoch,
     * blinded to the relative {@link AuthorFrame.spotAgeMs} at the projection seam. `null`/absent ⇒
     * never observed (`spot` is `null` too, and reads UNKNOWN). */
    readonly spotTs?: number | null;
    readonly priorClose: number | null;
    readonly hod: number | null;
    readonly lod: number | null;
    readonly vwap: number | null;
    /** The frozen opening-range high/low (`CanonicalState.orHigh`/`orLow`) — `null` until the first spot
     * anchors the range. Carried so the `failed-breaks` pane's ORB fake-out level reaches the author on the
     * driver path (kestrel-wa0j.58): the state computed it, but the projection used to drop it, so the pane
     * rendered all-dashes on every corpus frame. */
    readonly orHigh: number | null;
    readonly orLow: number | null;
    readonly chain: {
        readonly underlierPx: number;
        readonly expiry?: string;
        readonly legs: readonly OptionQuote[];
    } | null;
    /** Delta-only: the underlier tape since the last vantage (`[ts, px]`). */
    readonly tape: readonly {
        readonly ts: number;
        readonly px: number;
    }[];
    readonly plans: readonly PlanLine[];
    readonly resting: readonly OrderLine[];
    readonly fills: readonly OrderLine[];
    readonly committedUsd: number;
    readonly rUsd: number;
}
/**
 * The **date-blind AUTHOR projection** of a {@link DaySnapshot} — the ONE shared seam every
 * delivered author artifact (briefing, delta frames, machine JSON, and therefore their filenames)
 * derives from. Calendar identity is stripped HERE, once, so no downstream channel can re-leak it:
 *
 * - every wall-clock epoch (`nowTs`, each `tape[].ts`) becomes **relative ms since session open**
 *   (`sinceOpenMs`) — a small dateless integer — plus an `HHMM` ET time-of-day `label` (a clock,
 *   which pins no calendar date);
 * - an **absolute chain expiry** (`2026-07-17`) becomes a **relative days-to-expiry** offset
 *   (`dte`) measured from the session date (0 for a 0dte) — a relative label pins no date.
 *
 * Replay-only calendar identity (the raw session date, wall epochs) stays OUTSIDE this projection,
 * on the host/replay side. A leak that still reaches the boundary is caught by {@link assertDateBlind}
 * (fail-closed), never silently emitted.
 */
export interface AuthorFrame {
    readonly kind: "keyframe" | "delta";
    readonly n: number;
    /** `HHMM` ET time-of-day of this vantage (a clock — dateless). For a session that is part of a
     * multi-session Instance the label is prefixed with the relative-day ordinal `d{k}` (e.g. `d2 0935`);
     * a standalone session (no ordinal) keeps the bare `HHMM` — byte-identical to today. */
    readonly label: string;
    /** Relative ms since the session's first bus event (dateless). */
    readonly sinceOpenMs: number;
    /** The relative-day coordinate `k` (kestrel-5zl.16.4) — the session's ordinal in its Instance (`d0,
     * d1, …`), pinning no calendar date. Present ONLY for a multi-session run; absent (and unserialized)
     * for a standalone session, so existing single-session frames are byte-identical. Paired with the
     * per-session `sinceOpenMs` (which RESETS at each session's open), this is the date-blind coordinate
     * that lets a horizon span any number of sessions without `sinceOpenMs` ever reaching the 10-digit
     * epoch signature — the ~11.57-day fence limit disappears structurally, the pattern unchanged. */
    readonly sessionOrdinal?: number;
    readonly instruments: readonly string[];
    readonly phase: string;
    readonly spot: number | null;
    /**
     * How long `spot` has been standing without a reprint at this vantage — ms since the SPOT tick
     * that established it (kestrel-rs4). Dateless by construction: a duration, the {@link sinceOpenMs}
     * idiom, never the epoch it was derived from. This is the ONLY channel that tells a genuinely
     * frozen market apart from a feed that stopped printing — the two produce an identical `spot`.
     * Absent (and unserialized) when nothing was ever observed, so a spot-less frame is byte-identical.
     */
    readonly spotAgeMs?: number;
    readonly priorClose: number | null;
    readonly hod: number | null;
    readonly lod: number | null;
    readonly vwap: number | null;
    /** The frozen opening-range high/low, passed through from the {@link DaySnapshot} (kestrel-wa0j.58). A
     * price pins no calendar date, so it rides the date-blind projection unchanged; `null` before the range
     * anchors. Without it every driver-path frame's OR reads `—` and the `failed-breaks` pane is inert. */
    readonly orHigh: number | null;
    readonly orLow: number | null;
    /** The chain, with its absolute expiry replaced by a relative days-to-expiry offset (`dte`). */
    readonly chain: {
        readonly underlierPx: number;
        readonly dte: number | null;
        readonly legs: readonly OptionQuote[];
    } | null;
    /** The underlier tape since the last vantage — dateless (`HHMM` label + relative ms). */
    readonly tape: readonly {
        readonly label: string;
        readonly sinceOpenMs: number;
        readonly px: number;
    }[];
    readonly plans: readonly PlanLine[];
    readonly resting: readonly OrderLine[];
    readonly fills: readonly OrderLine[];
    readonly committedUsd: number;
    readonly rUsd: number;
}
/** Project a raw {@link DaySnapshot} into the date-blind {@link AuthorFrame} (the single seam).
 * `openTs` is the session's first bus-event `ts` (the injected clock origin, RUNTIME §0). `sessionOrdinal`
 * (kestrel-5zl.16.4), when supplied, is the relative-day coordinate `k`: it prefixes the label with `d{k}`
 * and rides the frame as {@link AuthorFrame.sessionOrdinal}. Absent (every standalone caller) ⇒ today's
 * bare `HHMM` label and no ordinal field — byte-identical. */
export declare function projectAuthorFrame(s: DaySnapshot, openTs: number, sessionDate: string, sessionOrdinal?: number): AuthorFrame;
export declare const DATE_LEAK_PATTERNS: readonly {
    readonly name: string;
    readonly re: RegExp;
}[];
/** The first calendar-leak in `body`, or `null` when it is date-blind. Deterministic. */
export declare function scanDateLeak(body: string): {
    readonly name: string;
    readonly match: string;
} | null;
/** Fail-closed guard: throw loudly if `body` (an emitted author artifact, or its filename `what`)
 * carries any calendar identity. Called at the author boundary before every write — a leak is caught,
 * never silently emitted (EVALUATION contamination fence; CLAUDE fail-closed). */
export declare function assertDateBlind(what: string, body: string): void;
/** The session phase as a legible label, or an explicit `"—"` when canonical phase is UNRESOLVED
 * (F3): the renderer invents no value — it never substitutes a plausible `"pre"` for a state the
 * canonical series has not actually resolved (RUNTIME §2/§3, UNKNOWN is never a guess). */
export declare function phaseLabel(phase: unknown): string;
/**
 * The DAY wake-frame body: THE canonical {@link renderWakeDelta} screen over the driver's typed
 * {@link ActingFrame}, rendered under the frame's DELIVERED View (kestrel-wa0j.19 §2 — the day runner
 * threads `frame.view` exactly like the live-agent + file-handshake adapters; the pre-fix omission was a
 * latent screen divergence where the day artifact ignored a View the other adapters honored). Absent
 * view ⇒ the default WAKE panes, BYTE-IDENTICAL to before.
 *
 * FAIL-CLOSED, NEVER CRASH (§1a): a delivered View that resolves but cannot MATERIALIZE (a window arg the
 * frame can't serve, an over-budget View) falls back to the default WAKE panes with the refusal LEADING
 * the artifact — surfaced, never silent, and never a dead day session. A throw with NO View to blame is a
 * genuine render defect and is re-thrown. Pure (no I/O, no clock) — exported so the threading + the
 * fallback are directly testable.
 */
export declare function dayWakeFrameText(frame: ActingFrame): string;
/**
 * The machine summary (`state-<n>.json`) — the deterministic JSON an agent author reads. It
 * serializes the date-blind {@link AuthorFrame} DIRECTLY: the projection already rewrote every
 * wall-clock epoch to relative `sinceOpenMs` and the absolute chain expiry to a relative `dte`, so
 * the machine channel carries the SAME blinded fields the txt frames do — no channel can re-leak.
 */
export declare function machineSummary(f: AuthorFrame): string;
/** Build the frame snapshot from the live core at a vantage. Pure over the core's state. Exported so
 * the Simulate driver (`./simulate.ts`) assembles its acting Frame from the SAME snapshot the stepped
 * day renders — one snapshot shape, one date-blind projection (no forked vantage). */
export declare function snapshotOf(core: SessionCore, kind: "keyframe" | "delta", n: number, label: string, nowTs: number, instruments: readonly string[], rUsd: number, tape: readonly {
    ts: number;
    px: number;
}[]): DaySnapshot;
/** Options for {@link briefingSnapshot}. */
export interface BriefingSnapshotOptions {
    /** Present the observed range (an INTRADAY authoring vantage) rather than the pre-open keyframe
     * (kestrel-1vw). When `true`, the OPEN briefing folds every exec observation at/before the cutoff into
     * `spot` (current)/`hod`/`lod`/`tape` — the opening range an ORB cell authors at its OR-close. Absent /
     * `false` ⇒ the pre-open keyframe (first spot/chain only, range UNKNOWN), byte-identical to before. */
    readonly carryRange?: boolean;
}
/**
 * Build the OPEN-briefing snapshot BEFORE the first event — the OPEN keyframe of EVALUATION Part 1.
 *
 * It is bounded by the **author acting cutoff** (`cutoffTs`, kestrel-m9i.11): it admits ONLY the exec
 * SPOT/BOOK observations whose watermark is AT OR BEFORE the cutoff, and NEVER peeks past it — so a
 * regular-session print at/after the 09:30 open (a T-5 benchmark, or a delayed feed) does NOT leak into
 * the author's keyframe (a look-ahead that contaminates the benchmark).
 *
 * By DEFAULT it is the pre-open keyframe: it takes the first exec spot/chain at/before the cutoff and
 * leaves the range (`hod`/`lod`/`tape`) UNKNOWN — the renderer shows the dash + a coverage reason
 * (fail-closed: missing → UNKNOWN). `opts.carryRange` opts into an **intraday authoring vantage**
 * (kestrel-1vw): an ORB cell authoring at its opening-range close (~10:00 ET) folds EVERY exec
 * observation at/before the cutoff, so the OPEN briefing surfaces the range as of the cutoff — `spot`
 * is the current print, `hod`/`lod` are the session high/low (the OR high/low at OR-close), and `tape`
 * is the observed range. The causal fence is identical in both paths (no post-cutoff print is ever
 * admitted); the flag only decides whether the admitted prefix is COLLAPSED to the opening keyframe or
 * PRESENTED as the range. `priorClose`/`vwap` remain UNKNOWN — admitted ONLY through governed context
 * that carries its own as-of/source watermark, never inferred here. Folds nothing into the core (no
 * order can act pre-briefing; the read is informational).
 */
export declare function briefingSnapshot(meta: MetaEvent, execSym: string, events: readonly BusEvent[], rUsd: number, cutoffTs: number, opts?: BriefingSnapshotOptions): DaySnapshot;
/** A handshake refusal carrying a STABLE code, so the CLI seam can classify it instead of dropping it
 * into the GENERIC "unexpected/uncaught" bucket (kestrel-4fc9). Lives here rather than importing
 * `cli/errors.ts` (which would invert the layering: `session` is below `cli`); the seams map it —
 * {@link import("../cli/commands/grade.ts").dayCommand} and {@link import("./cli.ts")} — onto a
 * `CliError` with the matching code and a dedicated exit.
 *
 * - `NO_AUTHOR` — the caller DECLARED `--no-author` and a required document was not staged.
 * - `HANDSHAKE_ABANDONED` — a real author was expected but did not reply within `--max-wait`. */
export declare class DayHandshakeError extends Error {
    readonly name = "DayHandshakeError";
    readonly code: "NO_AUTHOR" | "HANDSHAKE_ABANDONED";
    readonly hint: string;
    constructor(o: {
        code: "NO_AUTHOR" | "HANDSHAKE_ABANDONED";
        message: string;
        hint: string;
    });
}
/** The LOUD no-wake notice (kestrel-zox3): a staged `revision-<n>`/`pass-<n>` that no wake will ever
 * deliver would otherwise be SILENTLY unused while the run reports a green, profitable summary — a
 * fail-closed/honesty violation (the AX wave-6 footgun: trimming `--wakes` from the adopt walkthrough
 * gives a false "it worked" on the exact lesson being taught). Emitted on the HOST status channel
 * ({@link DayHooks.notify} → stderr), never on stdout/the report, never graded. Exported for the fixture. */
export declare function renderIgnoredRevisionNotice(dir: string, firedWakes: number, ignored: readonly {
    readonly n: number;
    readonly file: string;
}[]): string;
/** The LOUD adoption-bound-nothing notice on the DEFAULT day terminal (kestrel-gjx5 residual). A valid
 * `ARM … foreach held leg` adopter that bound ZERO held legs (no superseded, inventory-holding sibling to
 * adopt from) ARMS and expires quietly — its exit protection INERT — and grades GREEN. The engine
 * (kestrel-c25w) already writes the teaching reason onto the plan's OWN lifecycle trace, but that lands
 * ONLY in `report.json` (`/plans[N]/lifecycle/…`); a newcomer running plain `day` reads the default
 * terminal (the {@link DayHooks.notify} → stderr status channel), sees only the armed/expired counts, and
 * never opens the JSON. Echo the notice to that channel, NAMING each affected plan, so the lesson reaches
 * the terminal. Off the graded line (never on stdout/the report, never graded), like every other day
 * notice. Exported for the fixture. */
export declare function renderArmBoundNothingNotice(plans: readonly string[]): string;
/** Scan a settled report for plans whose lifecycle carries the {@link ARM_BOUND_NOTHING_MARKER} reason
 * (kestrel-c25w) — a valid adopter that bound zero held legs. Returns each affected plan name ONCE, in
 * first-seen lifecycle order, so {@link renderArmBoundNothingNotice} can name them on the terminal. */
export declare function armBoundNothingPlans(report: EpisodeReport): string[];
/** The author-facing rejection note (`reject-<n>.txt`) written when a `revision-<n>` fails to PARSE
 * or would fail to ARM. It states the reason, affirms the standing book is untouched, and re-requests
 * the wake. Date-blind (routed through the same fence as every author artifact). */
export declare function renderRejection(n: number, reason: string): string;
/** The author-facing rejection note (`reject-open.txt`) written when `plans-0.kestrel` fails to
 * PARSE or would fail to ARM (bead kestrel-p48s). States the repair-guiding reason, affirms the
 * session has NOT opened, and names the exact retry file the runner now blocks on. Date-blind
 * (routed through the same fence as every author artifact). */
export declare function renderOpenRejection(attempt: number, reason: string, retryName: string): string;
/**
 * Drive one STEPPED `sim` day with the wake handshake (RUNTIME §7 / EVALUATION Part 1) — now OVER the ONE
 * shared {@link runSimulateSession} driver (kestrel-5zl.3), NOT a bespoke second progression. Builds the
 * {@link dayFileHandshakeAgent} (open/decide over the DAY file protocol) and runs it through the driver in
 * DAY-COMPAT MODE, which reproduces the stepped runner's cadence + byte stream EXACTLY (the frozen day
 * `determinism_hash` is preserved). Writes the briefing + per-wake frames/state to `dir`, blocking for the
 * author's replies, applies document supersession on each accepted revision, settles, and returns the
 * graded report + the concatenated authored text + the single run's {@link CapturedTurns}/{@link Blotter}
 * (the re-runnable-as-Backtest contract). Fails closed on a missing META / no instruments / an abandoned
 * handshake / a malformed authored document.
 *
 * `async` because the delegation awaits the driver ({@link runSimulateSession} is `async` — the live agent
 * loop is deliberately non-deterministic). The day agent itself resolves synchronously (injected host hooks),
 * so a re-run with the same pre-staged files replays byte-identically (RUNTIME §0).
 */
export declare function runDaySession(opts: RunDayOptions): Promise<DaySessionResult>;
export {};
//# sourceMappingURL=day.d.ts.map