/**
 * # fill/engine — SimFillEngine, the pure resting-order state machine (RUNTIME §6–7)
 *
 * A deterministic, time-injected engine that holds resting orders, reassesses them against
 * book updates through a {@link FillModel}, and cash-settles the outcome at session close.
 * It owns no clock and no RNG on its default path (RUNTIME §0): every timestamp is passed in,
 * and the only randomness — an *optional* seeded sampler for Monte-Carlo realization — is
 * injected. **Same event sequence ⇒ same outcomes** (the determinism invariant).
 *
 * Lifecycle of one order:
 *
 * 1. {@link SimFillEngine.place} — the order rests; a `place` ORDER event is emitted.
 * 2. {@link SimFillEngine.cancel} — **effective immediately**; a cancelled order can never
 *    later fill, no matter what the tape does afterward.
 * 3. {@link SimFillEngine.onBook} — every resting order on the updated leg is reassessed. A
 *    strict-cross result is a **floor fill**: the order leaves the book into filled inventory
 *    and a `fill` ORDER event is emitted. A hazard result accrues into the order's survival
 *    product for expected-value accounting; the order keeps resting.
 * 4. {@link SimFillEngine.settle} — at the settle spot: filled inventory settles at
 *    **intrinsic**; still-resting orders **expire worthless-unfilled** (no position, $0
 *    floor). The report carries both the floor outcome and the E[$] under `pFill`
 *    (RUNTIME §6).
 *
 * Expected-value accounting: for each resting order the engine keeps a **survival** product
 * `S = Π(1 − pFillᵢ)`; its expected fill probability is `1 − S`. A floor fill pins that to
 * `1`. At settle, `floorPnl` counts only floor fills, while `expectedPnl` weights every fill's
 * settle P&L by its expected fill probability — so a single grade reports the conservative
 * floor and the calibrated expectation side by side.
 */
import type { NewBusEvent, OptionQuote, Right } from "../bus/index.ts";
import { type FillModel, type FillSupport, type Moneyness } from "./model.ts";
/**
 * The **reference re-mint cadence** for a resting episode-keyed order (ADR-0016 §episode-identity,
 * boundary **B4**, kestrel-9gu.13). A per-EPISODE hazard model (`MakerFairCalV1`) folds one Bernoulli
 * per resting *episode*, and episodes previously minted ONLY on placement/reprice/dark↔lit-flip — so a
 * STATIC resting order (no reprice, no regime flip) took a single draw all session and its cumulative
 * fill could never approach the calibrated ground truth (a patient at-fair BUY pinned at p≈0.25 rather
 * than saturating). B4 re-mints **one lit episode per `DT_REF` of continuous rest in the SAME regime**,
 * matching the upstream reference model's per-observation-at-DT_REF draw (its measured time-to-fill
 * median ≈ 0s makes the per-episode rate a per-`DT_REF`-window rate).
 *
 * It is keyed on the **injected tape clock** (`ts`), never wall time or observation COUNT: the number of
 * re-mints over a rest span is `floor(restMs / DT_REF)`, so a dense tape and a sparse tape covering the
 * same span mint the same episodes (density-independent — "a bus's book cadence is an artifact of
 * recording", ADR-0016 §Context). A re-look INSIDE a window mints nothing (the N1 anti-double-count core
 * is preserved: `windows = 0`). `5_000` ms = the reference model's DT_REF (5s).
 */
export declare const EPISODE_REMINT_DT_REF_MS = 5000;
/** An order handed to {@link SimFillEngine.place}. A single defined-risk option leg resting
 * at a limit price. `ref` is the caller's stable id (echoed as `order_id` on the bus). */
export interface FillOrder {
    readonly ref: string;
    /** The plan NAME (Lineage key) that authored the order, when it came from one (carried onto bus events). */
    readonly plan?: string;
    /** The authoring plan's exact INSTANCE identity (kestrel-22j.15), carried onto the order's bus events so
     * an order joins its exact instance, not merely its recurring name. */
    readonly plan_instance?: string;
    readonly instrument: string;
    readonly side: "buy" | "sell";
    readonly qty: number;
    readonly px: number;
    readonly strike: number;
    readonly right: Right;
    /** Coarse moneyness vs the underlier for the directional far-OTM guard. Absent
     * ⇒ the symmetric legacy path (the guard cannot fire on an unclassified leg). Threaded to the
     * {@link FillModel} as {@link FillOrderView.moneyness}. */
    readonly moneyness?: Moneyness;
    /** `true` when this leg is the covering wing of a multi-leg defined-risk package (exempt from the
     * sell-far-OTM cap — it fills as a combo). Threaded as {@link FillOrderView.covered}. */
    readonly covered?: boolean;
}
/** The optional Monte-Carlo sampled outcome (present only when the engine was given a seeded
 * sampler — a `fillSeed`, kestrel-9gu.8.1). Deterministic under its seed. `filled` is the causal
 * realization: `true` iff the order took a strict-cross floor fill (containment: floor ⊆ sampled) OR
 * an episode's draw realized a hazard fill (`draw < pFill`). `pnl` is its settle P&L when filled
 * (else `0`). Off the deterministic floor/expected accounting path — a seeded run is one replicate of
 * the ensemble (ADR-0016). */
export interface SampledOutcome {
    readonly filled: boolean;
    readonly pnl: number;
}
/** One order's settle outcome — the floor and the expectation, side by side (RUNTIME §6). */
export interface OrderOutcome {
    readonly ref: string;
    readonly plan?: string;
    /** The authoring plan's exact INSTANCE identity (kestrel-22j.15), when the order came from one. */
    readonly plan_instance?: string;
    readonly instrument: string;
    readonly side: "buy" | "sell";
    readonly qty: number;
    readonly px: number;
    readonly strike: number;
    readonly right: Right;
    /** Did the strict-cross floor fire for this order? */
    readonly floorFilled: boolean;
    /** The price the floor fill happened at (the resting price), else `null`. */
    readonly floorFillPx: number | null;
    /** `1` if floor-filled, else the accrued expected fill probability `1 − survival`. */
    readonly expectedFillProb: number;
    /** The order-level fill-support flag (9gu.3): `calibrated` iff every assessment folded into this
     * order's survival product was calibrated (a definite floor fill is a structural fact ⇒ always
     * `calibrated`), else `extrapolated` — the conservative, non-bankable default a grader honours. */
    readonly support: FillSupport;
    /** Per-contract intrinsic at the settle spot. */
    readonly intrinsicAtSettle: number;
    /** Realized $ under the strict-cross floor (0 for an unfilled order). */
    readonly floorPnl: number;
    /** E[$] under `pFill`: `expectedFillProb × (settle P&L of the fill)`. */
    readonly expectedPnl: number;
    /** The optional seeded-sampler realization, when a sampler was supplied. */
    readonly sampled?: SampledOutcome;
}
/**
 * The declared default settle-mark staleness threshold (kestrel-xwf): a settle spot whose value was
 * last established more than this many ms before the settle instant grades STALE and taints the
 * headline. 5 minutes — comfortably coarser than the tape's event cadence and the 1-minute structural
 * wake grid (a live feed refreshes the mark many times per threshold), yet orders of magnitude finer
 * than the hours-frozen failure it exists to catch (2025-04-09: frozen from 13:01 through the close).
 */
export declare const SETTLE_MARK_STALE_AFTER_MS = 300000;
/** The settle mark's source provenance, threaded INTO {@link SimFillEngine.settle} by the session
 * driver (which sees the input tape — the engine itself never scrapes it). `null` means unstated —
 * the fail-closed default the verdict treats as stale (kestrel-xwf). All fields are injected-clock
 * `ts`, never `seq`: an input event's seq shifts under JOURNAL/TELEMETRY interleaving, and emitted
 * bytes must not depend on that (the a57.11 invariant). */
export interface SettleMarkProvenance {
    /** `ts` of the input event that last ESTABLISHED the settle spot's value (a frozen feed
     * re-printing the same px does not refresh it), or `null` when unstated. */
    readonly asOfTs: number | null;
    /** `ts` of the last spot-bearing input event of ANY kind (feed-death vs frozen-value
     * disambiguation), or `null` when none was observed. */
    readonly lastObservedTs: number | null;
    /** A closing put-call-parity CANDIDATE recovery for a frozen mark (kestrel-xwf annotated
     * recovery), derived by the session driver from the last folded two-sided closing book
     * (`S = K + C_mid − P_mid` at the strike nearest the frozen mark). The engine applies it ONLY
     * when the core verdict grades STALE — the book then cash-settles against `spot` with
     * `source: "parity"`. Absent/`null` = not derivable (dark or one-legged closing book): a stale
     * mark is then retained `mark_uncertain` (honestly refused, never fabricated). */
    readonly parity?: {
        readonly spot: number;
        readonly strike: number;
    } | null;
}
/** How a settle mark was resolved (kestrel-xwf; mirrors the bus's `SettleMarkSource` — redeclared
 * here so `src/fill` documents its own vocabulary): `market` = live within the threshold; `parity` =
 * stale primary mark recovered via closing put-call parity (annotated); `stale` = stale and
 * unrecoverable — retained mark-uncertain. */
export type SettleMarkResolution = "market" | "parity" | "stale";
/**
 * The settle mark WITH its provenance + fail-closed staleness verdict (kestrel-xwf): what spot the book
 * cash-settled against, when that value was established, and whether it was stale at the settle instant.
 * `stale === true` means the settled P&L is graded against a mark the tape stopped supporting — a
 * consumer treats it as NON-BANKABLE (the taint rides {@link ../blotter Blotter} `totals.headline`),
 * never silently as a fresh number. The fix is honest provenance, not a better guess: no "true close"
 * is ever invented (RUNTIME §8 fail-closed).
 */
export interface SettleMark {
    /** The settle spot the book marked to (the parity-recovered value when `source: "parity"`;
     * 0 when no spot was ever observed — and then `stale`). */
    readonly px: number;
    readonly asOfTs: number | null;
    readonly lastObservedTs: number | null;
    /** `settle ts − asOfTs`, clamped ≥ 0; `null` when the as-of is unstated. */
    readonly ageMs: number | null;
    /** The declared threshold this verdict was graded under. */
    readonly staleAfterMs: number;
    /** Fail-closed: `true` when `ageMs` is unstated or exceeds `staleAfterMs`. A parity recovery does
     * NOT clear it — the verdict grades the primary feed, not the fallback (non-bankable either way). */
    readonly stale: boolean;
    /** How the mark was resolved (`"market"` iff not `stale`). */
    readonly source: SettleMarkResolution;
    /** `true` iff stale AND unrecovered (`source: "stale"`) — the retained mark is untrustworthy. */
    readonly markUncertain: boolean;
    /** An honest human note naming the condition (frozen level, age, parity strike) — present iff `stale`. */
    readonly note?: string;
}
/** The settle report (RUNTIME §6–7). Stamps its judge — fill-model name/version and hazard
 * calibration — because EVs across fill-model versions do not naively compare (ADR-0006). */
export interface SettleReport {
    readonly settleSpot: number;
    /** The settle spot's provenance + staleness verdict (kestrel-xwf) — `settleSpot` never travels
     * without it, so a stale mark can never grade as a silently fresh-looking number. */
    readonly settleMark: SettleMark;
    readonly fillModel: string;
    readonly hazardVersion?: string;
    readonly calibrated?: boolean;
    readonly multiplier: number;
    readonly outcomes: readonly OrderOutcome[];
    readonly floorTotal: number;
    readonly expectedTotal: number;
    /** Present only when a seeded sampler was supplied. */
    readonly sampledTotal?: number;
}
/** Construction options. `model` is the one required seam; `multiplier` scales per-contract
 * P&L to dollars (default `1` — a caller sets the instrument's contract size); `sampler` is the
 * optional seeded fill sampler (ADR-0016). When present, its `runSeed` keys a per-episode
 * mulberry32 substream (`hash(runSeed, model.version, order.ref, episodeIndex)`) and a draw at each
 * episode mint realizes a **causal** sampled fill when `draw < pFill` — a real `fill` ORDER event at
 * the resting price, fed back into Plan management. **Absent ⇒ the sampled channel is OFF**
 * (fail-closed): the run grades floor + expected only, taking no draws.
 * `staleMarkAfterMs` overrides the declared settle-mark staleness threshold
 * ({@link SETTLE_MARK_STALE_AFTER_MS}, kestrel-xwf). */
export interface SimFillEngineOptions {
    readonly model: FillModel;
    readonly multiplier?: number;
    readonly sampler?: {
        readonly runSeed: number;
    };
    readonly staleMarkAfterMs?: number;
}
/** A held lot that a **carry-mark** settle (kestrel-5zl.16.3) marked to the session close and let
 * SURVIVE — the multi-session hand-off (the multi-session horizon design). Its `basis` is the carry-mark (the mark price
 * at close), re-baselined so the NEXT session's P&L is measured from it; `order` carries that basis as
 * its `px`, so seeding it into the next session ({@link SimFillEngine.seedFilled}) re-opens the exact
 * position. Only produced by a `settle(…, { carry: true })`; an intrinsic (final/length-1) settle
 * leaves this empty (the position dies), so a length-1 sequence is byte-identical to today. */
export interface CarriedLot {
    readonly order: FillOrder;
    /** The carry-mark (mark-at-close) — the re-baselined basis for the next session. */
    readonly basis: number;
}
/**
 * The resting-order state machine. Construct one per book (or per session); drive it with
 * `place` / `cancel` / `onBook`, then `settle`. Every mutator returns the typed bus events it
 * produced (seq-less {@link NewBusEvent}s — the owner {@link ../bus/write.ts BusWriter} stamps
 * `seq`); the same events are also appended to the engine's cumulative {@link events} log.
 */
export declare class SimFillEngine {
    #private;
    constructor(opts: SimFillEngineOptions);
    /** The cumulative typed bus events this engine has produced, in order. Read-only. */
    get events(): readonly NewBusEvent[];
    /** The refs of all currently-resting (placed, not cancelled, not floor-filled) orders. */
    restingRefs(): readonly string[];
    /** A resting order's current expected fill probability (`1 − survival`), or `undefined` if
     * no such order is resting. Exposed for grading/inspection. */
    expectedFillProb(ref: string): number | undefined;
    /**
     * Place a resting order. The `ref` must be unique across the engine's lifetime (a re-used
     * ref is refused loudly — fail-closed, RUNTIME §8). Emits a `place` ORDER event. Returns the
     * order's `ref`.
     */
    place(order: FillOrder, ts: number): string;
    /**
     * Seed a **carried** position (kestrel-5zl.16.2 — the multi-session open). Re-opens a lot handed
     * over by the prior session's carry-mark settle at its carry-mark `basis`: emits a `place` then a
     * `fill` ORDER event (both at `basis`, at the session's open `ts`) so the GRADED bus is
     * self-consistent — the position appears as an opening fill the Blotter projects — and pushes it into
     * filled inventory, where {@link settle} marks it. Never reassessed by {@link onBook} (it is inventory,
     * not a resting order). `ref` must be unique across the engine's lifetime (fail-closed on reuse). No
     * caller seeds this on a length-1 sequence, so this path never runs for an existing single-session run.
     */
    seedFilled(order: FillOrder, basis: number, ts: number): void;
    /** The lots a carry-mark {@link settle} marked to close and let survive — the next session's opening
     * inventory (kestrel-5zl.16.3). Empty until (and unless) a `settle(…, { carry: true })` ran. */
    carriedInventory(): readonly CarriedLot[];
    /**
     * Cancel a resting order, **effective immediately**: it is removed from the book and can
     * never later fill. A no-op (no event) if the ref is not currently resting (already filled,
     * already cancelled, or unknown). Returns whether a resting order was removed.
     */
    cancel(ref: string, ts: number): boolean;
    /**
     * Reassess every resting order on one leg against a new quote. `fair` is the engine's
     * ExecutionFair for the leg (omit when unbuildable — the model then degrades to the floor).
     * Floor (strict-cross) fills leave the book and emit a `fill` event; hazard results accrue
     * into the survival product and keep resting. Returns the events produced this call.
     */
    onBook(instrument: string, leg: OptionQuote, ts: number, fair?: number): readonly NewBusEvent[];
    /**
     * Cash-settle at the close (RUNTIME §6). Filled inventory settles at **intrinsic** from the
     * settle spot; every still-resting order **expires worthless-unfilled** (no position, $0
     * floor) and emits a `cancel` event annotated `expired-unfilled`. Idempotent: a second
     * settle finds an empty book and reports only the (already-final) filled inventory.
     *
     * The report carries both the floor outcome and the E[$] under `pFill`, plus the sampled
     * total when a seeded sampler was supplied. Determinism: outcomes are emitted filled-first
     * (fill order), then resting (placement order).
     *
     * **Carry-mark (the multi-session horizon design, kestrel-5zl.16.3).** With `{ carry: true }` — a NON-final session of a
     * multi-session Instance — held inventory is marked to the session-close spot and RECORDED to
     * {@link carriedInventory} with its basis re-baselined to that mark, so the position survives to the
     * next session. The realized P&L, the emitted ORDER/TELEMETRY bytes, and the returned report are
     * **byte-identical** to a plain intrinsic settle (mark == `intrinsic(settleSpot, …)`, the same
     * per-session mark-to-market); the ONLY difference is the additional (bus-silent) carried-lot
     * hand-off. The default / final settle (`carry` absent or `false`) is today's behaviour exactly — the
     * position dies at intrinsic — so a length-1 sequence is byte-for-byte unchanged.
     *
     * **`opts.mark` is the settle spot's source provenance (kestrel-xwf)**, threaded by the session
     * driver. FAIL-CLOSED: omitted/unstated provenance grades STALE (never a silently fresh-looking
     * mark), as does an as-of older than the declared threshold — the verdict rides the report's
     * `settleMark` AND the bus (a `settle_mark` TELEMETRY record) so the Blotter re-derives the
     * taint from bytes. A STALE mark applies `opts.mark.parity` — the session's closing put-call-parity
     * candidate — when present (`source: "parity"`, an ANNOTATED recovery: the book cash-settles
     * against the recovered spot, the staleness verdict unchanged) and is otherwise retained
     * `markUncertain` (`source: "stale"` — honestly refused, never fabricated).
     */
    settle(settleSpot: number, ts: number, opts?: {
        readonly carry?: boolean;
        readonly mark?: SettleMarkProvenance;
    }): SettleReport;
}
//# sourceMappingURL=engine.d.ts.map