kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
458 lines • 30.3 kB
TypeScript
/**
* # blotter/types — the Blotter v1 typed record (kestrel-a57.1, ADR-0011; epic a57 schema)
*
* The **Blotter** is the deterministic projection of one Session {@link ../bus Bus} into the canonical
* typed record of that Session (CONTEXT: Blotter). The Bus is the truth; the Blotter is its projection —
* regenerable, byte-stable, never a second writer (ADR-0010). This file is the SHAPE only; the fold that
* produces it is {@link ./project.ts}, its canonical bytes are {@link ./serialize.ts}, and the
* determinism leg that proves the fold is pure is {@link ./certify.ts}.
*
* Two orthogonal stamps ride a Blotter and must never be conflated (ADR-0011):
* **Certification** — is this record faithful and reproducible? (a set of pass/fail/na legs; the
* determinism leg is a57.1's, the paper/live legs land in a57.3) — and **Fidelity** — how real are its
* fills? (the `modeled|realized` level from the graded META, plus the judge's self-limitation stamp — what
* it could NOT observe — derived from the fill model in a57.4). Certified never means good.
*/
import type { DirectionalCap, ExperimentalEnvelope, Fidelity, FillModelStamp, FillSupport, InstanceIdentity, MoneynessBucket, PlanOutcome, PlanState, RankableReason, Right, SessionInstrument } from "../bus/index.ts";
import type { PnlChannel, SampledQualification } from "../grade/headline.ts";
export type { ExperimentalEnvelope, TokenAccounting } from "../bus/index.ts";
/** The bus receipt: how many events the graded bus held, the sha256 over its canonical JSONL
* serialization (the truth this Blotter projects from), and the bus schema it was written at. */
export interface BusReceipt {
readonly events: number;
readonly sha256: string;
readonly schema: number;
}
/**
* One thing the judge (the fill model that produced this graded bus's fills) **structurally could NOT
* observe** — a stable machine `code` plus an honest human `note` (a57.4). These are not fabricated: each
* is a documented structural fact of the named fill model (e.g. a strict-cross judge credits a fill only
* on a tape cross; no judge in this build sees queue position), so a consumer cannot OVER-CLAIM realism the
* judge never had.
*/
export interface FidelityLimit {
/** A stable, lexical machine token for the limit (e.g. `no-queue-position`). */
readonly code: string;
/** The honest human phrasing of what the judge could not see. */
readonly note: string;
}
/**
* The judge's self-limitation declaration (a57.4): the fill model that produced the fills, and the ordered
* list of what it structurally could NOT observe. Sourced deterministically from the graded META's
* `fill_model` — never fabricated — so it re-projects byte-identically. An unrecognized fill model
* fails closed to a single `observability-unstated` limit rather than inventing observability the judge may
* not have (a consumer then treats the record as maximally limited).
*/
export interface FidelitySelfLimitation {
/** The fill model these limits belong to (`fill_model.name` on the graded META — the judge). */
readonly fill_model: string;
/** What the judge could not observe, in a stable order (byte-stable across re-projection). */
readonly limits: readonly FidelityLimit[];
}
/**
* The Blotter's Fidelity stamp (CONTEXT: Fidelity; a57.4): the realism `level` a session may CLAIM
* (`modeled` in sim/paper, `realized` in live — a META pass-through), PLUS a `self_limitation` declaring
* what the judge could not see. The two together are how a consumer reads fill realism WITHOUT over-claiming
* it: the level says how real the fills are, the self-limitation bounds what "real" even means for this judge.
* Orthogonal to Certification (a sim Blotter can be certified yet low-fidelity).
*/
export interface BlotterFidelity {
/** The fill realism level (`modeled` | `realized`) — the graded META pass-through. */
readonly level: Fidelity;
/** What the judge structurally could not observe — sourced from the fill model, never fabricated. */
readonly self_limitation: FidelitySelfLimitation;
}
/** The Session header of a Blotter — its Instance identity + judge + fidelity + the bus it projects
* from. Every field is a pure read of the graded bus's opening META (ADR-0011 part B). */
export interface BlotterSession {
/** Instance identity (lineage/version/mode, pod when a Pod document ran) — ADR-0011 recommendation 1. */
readonly instance: InstanceIdentity;
/** The session's instruments (from the input META, carried through the graded META). */
readonly instruments: readonly SessionInstrument[];
/** The bus this Blotter projects from — the recorded truth (ADR-0010). */
readonly bus: BusReceipt;
/** sha256 over the graded bus's ENGINE-OUTPUT events (everything after the opening META) — pins the
* engine's decisions, mirroring {@link ../session EpisodeReport}'s `determinism_hash`. A pure function
* of the bus. (It re-pins the output from the graded bus, whose seq are re-stamped from the META, so it
* need not byte-equal the report's hash — see the report→Blotter unification note in project.ts.) */
readonly determinism_hash: string;
/** The fill model that produced this graded bus's fills (the judge). */
readonly fill_model: FillModelStamp;
/** The fill realism this session may claim — the `modeled|realized` level PLUS the judge's
* self-limitation (what it could not observe). Orthogonal to Certification (a57.4). */
readonly fidelity: BlotterFidelity;
/**
* The author's experimental envelope (kestrel-a57.14): the agent/model identity that produced this
* session, projected VERBATIM from the graded META's injected `envelope` (symmetric with `fill_model`,
* the judge). Present ONLY when the graded bus declared a COMPLETE envelope; a bus that declared none
* (a pre-a57.14 / input-derived graded bus) carries no envelope, and a declared-but-INCOMPLETE envelope
* is NOT recorded here — a broken identity is never stamped as identity; it fails the record closed to a
* PROVISIONAL {@link Certification} with the missing field named in `certification.reasons` instead.
*/
readonly envelope?: ExperimentalEnvelope;
/**
* The FULL `ConfigId` of the run's config descriptor (`sha256(canonical AgentConfig)`, kestrel-5zl.6),
* projected VERBATIM from the graded META's `config_id` (m9i.2 owner tweak). A SUPERSET identity of the
* envelope — it additionally folds the sampling axis (`temperature`/`thinkingLevel`), `format`, and
* `label` — so temperature-only config variants carry DISTINCT ids: the config axis the grid CellKey
* keys on (`cellOf`, run-identity.ts). Additive/OPTIONAL: absent on a config-less graded bus and on a
* pre-tweak graded bus (whose cell falls back to the envelope identity — a legacy cell, never pooled
* with a ConfigId-keyed cell).
*/
readonly config_id?: string;
/**
* The **cell config axis** — the full ConfigId with the `fillSeed` REPLICATE axis STRIPPED (kestrel-9gu.8.1 /
* ADR-0016 §3), projected VERBATIM from the graded META's `cell_config_id`. This is the config axis `cellOf`
* keys the cell on: seed-only variants share it (replicates in one cell, each a distinct `SimRunId`), while
* temperature/behavioral variants still split. Present ONLY when it DIVERGES from `config_id` (the config
* carried a `fillSeed`); a seedless run's cell axis EQUALS `config_id`, so `cellOf` reads `config_id`
* directly. Additive/OPTIONAL: absent on a config-less, pre-tweak, or seedless graded bus.
*/
readonly cell_config_id?: string;
}
/** One certification leg's state (CONTEXT: Certification). `na` = not applicable to this mode. */
export type CertLeg = "pass" | "fail" | "na";
/** The certification verdict: `certified` only when every APPLICABLE leg passes, else `provisional`
* (CONTEXT: Certification). Numbers always render with the verdict attached. */
export type Verdict = "certified" | "provisional";
/**
* Certification — the verdict on whether this Blotter is a faithful, reproducible record of its Session.
* a57.1 owns the SHAPE of all four legs and implements the **determinism** leg (re-project + byte-compare,
* {@link ./certify.ts}); the paper/live legs (`detectors_bit_for_bit`, `fills_subset_of_live`,
* `lifecycle_divergence_explained`) are `na` in sim and land as real legs with paper/live in a57.3.
*/
export interface Certification {
readonly legs: {
/** Re-project the Bus → byte-identical Blotter (the projector's core invariant, sim-applicable). */
readonly determinism: CertLeg;
/** Detectors reproduce bit-for-bit under replay (paper/live; `na` in sim — a57.3). */
readonly detectors_bit_for_bit: CertLeg;
/** Simulated fills are a subset of live fills (paper/live; `na` in sim — a57.3). */
readonly fills_subset_of_live: CertLeg;
/** Lifecycle divergence from live is explained (paper/live; `na` in sim — a57.3). */
readonly lifecycle_divergence_explained: CertLeg;
};
readonly verdict: Verdict;
/**
* The recorded reasons a verdict is `provisional` — fail-closed, never silent (kestrel-a57.14). Parallel
* to {@link HeadlineFlag.reasons}: each reason NAMES the cause (e.g. an experimental-envelope identity
* field that was declared-missing), so a `provisional` number never renders without its cause attached.
* Present ONLY when there ARE reasons (a byte-minimal `certified` record carries none). Byte-stable:
* derived deterministically, in a fixed order, from the bus.
*/
readonly reasons?: readonly string[];
}
/** One rankable leg's state (kestrel-m9i.25). `pass`/`fail` mirror {@link CertLeg}; `unknown` is the
* fail-closed state — an ABSENT or malformed leg input is UNKNOWN, never silently passed. There is no `na`:
* every leg is applicable to leaderboard eligibility. */
export type RankableLeg = "pass" | "fail" | "unknown";
/**
* Rankability — the DERIVED leaderboard-ELIGIBILITY axis (kestrel-m9i.25), a sibling of {@link Certification}
* but an ORTHOGONAL question. Certification asks "is this record honest + reproducible?"; rankability asks
* "is this row COMPARABLE on the leaderboard?". It is a CONJUNCTION of five legs —
*
* rankable = CERTIFIED ∧ POST-CUTOFF ∧ DATE-BLIND ∧ (SEASON) FROZEN ∧ CLOCK-HONEST
*
* — DERIVED at projection from already-stamped fields (the certification verdict, the kestrel-m9i.23 cutoff
* cross-check on the a57.14 envelope, and the three ATT/Layer-3 attestations `date_blind`/`season_frozen`/
* `clock_honest`), NEVER a field a producer stamps (a producer-stamped `rankable` on the bus is ignored —
* the projector recomputes the conjunction from the legs). It ENDS "certified" doing double duty: a
* CERTIFIED run on a PRE-CUTOFF tape (the model already knew the outcome) is
* `certification.verdict === "certified"` yet `rankable === false`. FAIL-CLOSED: an UNKNOWN leg input ⇒ not
* rankable + a NAMED reason, never a silent `rankable: true`.
*
* The CLOCK-HONEST leg (ADR-0040 / kestrel-w7la.3, appended LAST so every pre-existing reason ordering is
* byte-stable) is "no governed season runs latency-blind" (AGENTS.md) made mechanical: a latency-blind
* session stays VALID — certified, gradable, comparable in exploratory grids — but is never
* governed-leaderboard-rankable and can never ground a latency claim ({@link ./claims.ts latencyClaimGate}).
*/
export interface Rankability {
readonly legs: {
/** The certification verdict is `certified` (not `provisional`). */
readonly certified: RankableLeg;
/** The tape date is STRICTLY after the model's knowledge cutoff (m9i.23 `isPostCutoff`); `unknown` when
* the cutoff is unverifiable (no complete envelope / unknown model id / declared-registry mismatch). */
readonly post_cutoff: RankableLeg;
/** The run is attested date-blind (`meta.date_blind`); `unknown` when the attestation is absent/malformed. */
readonly date_blind: RankableLeg;
/** The benchmark season is frozen (`meta.season_frozen`); `unknown` when the attestation is absent/malformed. */
readonly season_frozen: RankableLeg;
/** The session is attested clock-honest (`meta.clock_honest`, ADR-0040 / kestrel-w7la.3): deliberation
* consumed tape time on eligible (sub-minute) ground truth. The driver stamps `true` or NOTHING — so
* `unknown` (absent/malformed) is the latency-blind/unattested case, and `fail` is reachable only via a
* platform-side revocation (`false`). This is the leg the platform's FORBIDDEN-CLAIMS lint reads
* ({@link ./claims.ts latencyClaimGate}): a latency claim may cite only a `pass` session. */
readonly clock_honest: RankableLeg;
};
/** The headline conjunction: `true` iff EVERY leg passes. */
readonly rankable: boolean;
/**
* The recorded reasons `rankable` is false — fail-closed, never silent, one per non-passing leg, in a
* FIXED leg order (certified → post_cutoff → date_blind → season_frozen → clock_honest; the fifth leg is
* appended LAST so every pre-w7la.3 ordering is byte-stable) for byte-stability. Each NAMES which leg
* failed (and whether it was a hard-false or a fail-closed UNKNOWN). Present ONLY when `rankable` is
* false (a rankable row is byte-minimal, carrying none).
*/
readonly reasons?: readonly RankableReason[];
}
/** One JOURNAL record projected into the Blotter — full markdown `body` inline (text is truth,
* ADR-0010). `seq` is the source of truth a plan's {@link ReasoningRef} references. */
export interface JournalEntry {
readonly seq: number;
readonly kind: string;
readonly ts: number;
readonly body: string;
}
/** One reason-carrying de-arm on the Blotter, projected from a CONTROL `disarm` record (kestrel-2pl).
* The author's `standDown` (inventory rides its TP/EXIT, never liquidates) and a fail-closed
* supersede-parse-escape de-arm both emit this — so the WHY of a stand-down is an explicit audit record,
* not merely INFERABLE from plans going `expired(superseded)`. `reason` is the note the CONTROL carried.
* The de-arm discriminant + reason vocabulary this projects from live in `src/engine/disarm.ts`
* (`DISARM_CONTROL_TYPE`, kestrel-z473.5). */
export interface DisarmRecord {
readonly seq: number;
readonly ts: number;
readonly reason?: string;
}
/** One transition in a plan's lifecycle, reconstructed from the PLAN stream — carrying the `seq`
* so the trace is anchored to the bus. */
export interface BlotterLifecycleStep {
readonly seq: number;
readonly ts: number;
readonly state: PlanState;
readonly outcome?: PlanOutcome;
readonly reason?: string;
}
/**
* A reference (never a copy) to the author's reasoning for a plan (ADR-0011 recommendation 2): the
* `seq` into {@link Blotter.journals} is the source of truth, and `excerpt` is a mechanical,
* deterministic preview — the body's first non-empty line, trimmed, capped ~120 chars with an ellipsis.
* No markdown interpretation.
*/
export interface ReasoningRef {
readonly seq: number;
readonly excerpt: string;
}
/** A plan's lifecycle trace + terminal state, plus a reference to its pre-hoc author reasoning when a
* JOURNAL precedes its first lifecycle transition. One record is one exact Plan **instance** (kestrel-22j.15):
* a legal same-name replacement projects as its OWN record beside its predecessor, never collapsed into it. */
export interface PlanRecord {
/** The authored plan NAME — the Lineage aggregation key (a consumer rolls instances up BY this; a name may
* legally recur, so it is NOT the instance identity). */
readonly plan: string;
/** The exact Plan-instance identity this record traces (kestrel-22j.15): the `plan_instance` minted by the
* engine on a v5 bus, or a deterministic sessionized key migrated from a pre-v5 bus. Distinct per instance,
* so two same-name instances are two records. */
readonly plan_instance: string;
readonly lifecycle: readonly BlotterLifecycleStep[];
/** The terminal outcome when `done`, else the last lifecycle state. */
readonly final_state: PlanState | PlanOutcome;
/** The pre-hoc author JOURNAL this plan references (absent when none precedes it). */
readonly reasoning_ref?: ReasoningRef;
}
/** An order's terminal disposition, read from the ORDER stream. */
export type OrderFinalState = "filled" | "cancelled" | "expired" | "rejected" | "working";
/**
* One placed order, projected by joining the ORDER stream (place/fill/cancel/reject) with the engine's
* per-order TELEMETRY (`order` → esc rung + reprice tally; `settle` → the probabilistic accounting +
* the 9gu.3 support flag). Every field is re-derived from bus bytes — never scraped from engine state
* (ADR-0011). Per-order `support` is here; its session-level rollup is {@link Blotter.fill_claim} (a57.4).
*/
export interface OrderRecord {
readonly order_id: string;
readonly plan?: string;
/** The exact Plan-instance identity that authored this order (kestrel-22j.15), when it came from a plan on a
* v5 bus — 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;
/** The option strike, present IFF this order carries an option leg. ABSENT for an ADR-0017 equity/spot
* order (which has NEITHER a strike NOR a right) — never a fictional zero-strike. The machine surface
* mirrors the frame's spot/option boundary ({@link ../frame/format.ts}:isSpotLeg): both absent ⇒ spot.
* A prior projection substituted `strike: 0` here, planting a phantom zero-strike CALL contract in the
* recomputability substrate (report.json/ledger) that an agent parsing an equity order would misread
* (kestrel-ldqt; same failure kestrel-1kp fixed on the frame surface). */
readonly strike?: number;
/** The option right, present IFF this order carries an option leg. ABSENT for an ADR-0017 equity/spot
* order — never a fictional `"C"`. Rides in lockstep with {@link strike} (both present ⇒ option; both
* absent ⇒ spot); a mixed presence is never emitted. */
readonly right?: Right;
/** Limit price at placement. */
readonly px: number;
/** The esc-ladder rung this order last occupied (last `esc_stage` on its TELEMETRY `order` records). */
readonly esc_stage: number;
/** Count of cancel/replace reprices for this order (sum of `reprice` on its TELEMETRY `order` records). */
readonly reprice_count: number;
readonly final_state: OrderFinalState;
/** Did the strict-cross floor fire (a definite fill)? */
readonly filled: boolean;
/** Accrued expected fill probability `1 − survival` (`1` on a floor fill). */
readonly pFill: number;
/** The order-level fill-support flag (9gu.3): a grader refuses to bank `expected` from `extrapolated`. */
readonly support: FillSupport;
/** Realized $ under the strict-cross floor (0 unless floor-filled). */
readonly floor_pnl: number;
/** E[$] under `pFill`. */
readonly expected_pnl: number;
/** A cancel/reject reason, when the terminal ORDER event carried one. */
readonly reason?: string;
/** The coarse moneyness bucket the fill-guard assessed (kestrel-9gu.6), when this order was
* submitted in the far-OTM wing (the only wing the directional guard acts on) — from the `guard`
* TELEMETRY record. Absent for a near-the-money / unclassified order (no guard record). */
readonly moneyness?: MoneynessBucket;
/** The covered-state the guard threaded (kestrel-9gu.6): `true` = a covering wing (exempt from the
* SELL far-OTM cap), `false` = a standalone offer. Present iff a `guard` record rode for this order. */
readonly covered?: boolean;
/** The directional far-OTM cap decision (kestrel-9gu.6): `applied` (standalone SELL floored to the
* no-fill cap), `exempt` (covering wing left uncapped), or `na` (far-OTM BUY, unlocked not capped).
* Present iff a `guard` record rode for this order. */
readonly directional_cap?: DirectionalCap;
}
/**
* The headline record on the totals (kestrel-9gu.12): WHICH channel is the headline (`channel`/`usd`,
* selected through the ONE gate policy in {@link ../grade/headline.ts} — `floor` until the sampled
* channel's 9gu.8.6 qualification is on the record, never an extrapolated-support sampled result), the
* `gate` verdict that made the selection (its reasons on the record when floor holds), and the honesty
* taint: `tainted` is `true` when any non-zero `expected` contribution rode on `extrapolated` support
* (a cell a grader refuses to bank, CONTEXT: Support flag) or the settle mark itself was untrustworthy
* (kestrel-xwf) — a taint rides EVERY channel (all three settle against the same mark), so the headline
* number always renders with its taint attached, never silently.
*/
export interface HeadlineFlag {
/** The selected headline channel: `floor` (fail-closed default) or `sampled` (once qualified). */
readonly channel: PnlChannel;
/** The selected channel's $ value (the other channels stay beside it as honest bounds). */
readonly usd: number;
/** The qualification-gate verdict (kestrel-9gu.8.6 seam) that selected the channel. */
readonly gate: SampledQualification;
readonly tainted: boolean;
readonly reasons: readonly string[];
}
/**
* The settle mark's provenance + fail-closed staleness verdict (kestrel-xwf), re-derived from the
* `settle_mark` TELEMETRY record: WHAT spot the book cash-settled against, WHEN that value was last
* established on the input tape (`as_of_ts` — a frozen feed re-printing the same px does not refresh
* it), and whether it was `stale` at the settle instant under the declared threshold.
* `stale: true` taints {@link Totals.headline}: the settled P&L is graded against a mark the tape
* stopped supporting (the 2025-04-09 frozen-underlier phantom loss), so it is NON-BANKABLE — honest
* provenance, never an invented "true close". Explicit `null` = unstated (itself a stale verdict).
*
* `source`/`mark_uncertain`/`note` carry the ANNOTATED-RECOVERY layer (kestrel-xwf unification): a
* STALE mark that could be recovered from closing put-call parity settles against the recovered spot
* (`source: "parity"`, `px` = the recovered value) — but recovery ANNOTATES, it never PARDONS: the
* staleness taint stands (`stale: true` still taints the headline, kestrel-9gu.12). One that could not
* be recovered is retained (`source: "stale"`, `mark_uncertain: true` — the loudest taint). A live mark
* is `source: "market"`.
*/
export interface SettleMarkRecord {
readonly px: number;
readonly as_of_ts: number | null;
readonly last_observed_ts: number | null;
readonly age_ms: number | null;
readonly stale_after_ms: number;
readonly stale: boolean;
readonly source: "market" | "parity" | "stale";
readonly mark_uncertain: boolean;
readonly note: string | null;
}
/** The session totals — the THREE-channel P&L contract (kestrel-9gu.12), re-derived from the
* settle-outcome TELEMETRY (the sum of the unrounded per-order P&L, rounded once on the 1e-8 grid —
* byte-matching {@link ../session EpisodeReport}'s totals). Floor and expected are always present;
* `sampled` only on a seeded run — the headline is SELECTED among the realizations by the gate. */
export interface Totals {
/** Definite-fill $ only — the conservative floor (`realized_floor_usd` in the report). */
readonly floor: number;
/** E[$] weighted by `1 − survival` (`expected_usd` in the report). */
readonly expected: number;
/** The seeded causal realization (`sampled_usd` in the report). ABSENT — not `0` — when the sampled
* channel is off (an un-run channel is never conflated with a zero outcome, kestrel-9gu.12). */
readonly sampled?: number;
readonly headline: HeadlineFlag;
/** The settle mark's provenance + staleness verdict (kestrel-xwf), when the graded bus carries the
* `settle_mark` TELEMETRY record. ABSENT on a pre-xwf graded bus (provenance unrecorded — the
* additive-optional convention, like `guard`); a stale record taints {@link headline}. */
readonly settle_mark?: SettleMarkRecord;
}
/**
* One support class's slice of the Blotter's expected-$ (a57.4) — the aggregate rollup deferred from a57.1
* (`OrderRecord.support` is the per-order flag; this is its session-level partition). Derived PURELY from
* the per-order `support` on the settle telemetry: it splits `totals.expected` into the portion resting on
* `calibrated` support (which a grader banks) and the portion resting on `extrapolated` support (which a
* grader **refuses to bank** — the bankableEv doctrine, 9gu.3). The two claims partition
* the whole: `Σ fill_claim[i].expected` reconstructs `totals.expected`.
*
* SIGNED SUB-CELLS (kestrel-dpy, ADR-0014): each slice carries the partition WRITTEN ONCE — a `gain`
* (Σ non-negative expected-$) and a `loss` (Σ negative), with `expected === gain + loss`. This closes
* a fail-open gap: a consumer that re-banks by SUBTRACTING the extrapolated slice must subtract only its
* `gain`, so extrapolated LOSSES survive (they are kept by the `bankableEv` doctrine, 9gu.3) and can
* never be zeroed. Subtracting the unsigned `expected` (the old shape) would have erased extrapolated
* gains and losses together — flattering the loss-parking strategy the doctrine exists to punish. Same
* bus ⇒ byte-identical claims.
*/
export interface FillClaim {
/** The support class this slice aggregates (CONTEXT: Support flag). */
readonly support: FillSupport;
/** How many settled orders rest on this support class. */
readonly orders: number;
/** Σ `expected_pnl` over those orders (rounded once on the 1e-8 grid, like {@link Totals}).
* Equals `gain + loss` — the net of this slice's signed sub-cells. */
readonly expected: number;
/** The slice's GAINS: Σ non-negative `expected_pnl` (≥ 0, on the 1e-8 grid). A subtracting consumer
* removes ONLY this to re-bank, so extrapolated losses are never erased (ADR-0014). */
readonly gain: number;
/** The slice's LOSSES: Σ negative `expected_pnl` (≤ 0, on the 1e-8 grid). KEPT for extrapolated cells
* — `bankableEv` refuses extrapolated gains but never forgives a loss. */
readonly loss: number;
}
/** One `WAKE`/`deliberation` record projected verbatim (bus_schema v6, CONTEXT "Deliberation record"):
* the cost of one clocked Seat turn. `ts` IS the derived return time (`checkpoint.ts + measured_ms +
* buffer_ms` — the reader enforces the identity); `wake_seq` names the WAKE checkpoint it prices. */
export interface DeliberationTraceEntry {
/** The record's own `seq` on the graded bus. */
readonly seq: number;
/** The `seq` of the WAKE checkpoint this cost belongs to (the vantage the Seat answered). */
readonly wake_seq: number;
/** The derived return time — when the Seat's control landed back on the tape. */
readonly ts: number;
/** Measured wall time of the Seat's whole turn (bounded authoring loop + repairs included). */
readonly measured_ms: number;
/** The configured latency buffer added to every measured turn. */
readonly buffer_ms: number;
}
/** The Blotter's wake trace (clock-honest wakes §6): the session's deliberation records — per-wake
* cost and the session total. RECORD COMPLETENESS, not a score (ADR-0011: the Blotter is the whole
* record) — latency is already priced inside alpha by the fills landing at return-time prices; there
* is no separate latency score to game. Present ONLY when the graded bus carries deliberation records
* (a clock-honest session); a latency-blind blotter omits it, byte-identical to before. */
export interface WakeTrace {
readonly deliberations: readonly DeliberationTraceEntry[];
/** Σ (`measured_ms + buffer_ms`) over the session — the total tape time deliberation consumed. */
readonly deliberation_ms_total: number;
}
/** Blotter v1 — the complete, replayable record of one Session, projected deterministically from its
* Bus (CONTEXT: Blotter; a57 epic schema; ADR-0011). */
export interface Blotter {
readonly session: BlotterSession;
readonly certification: Certification;
/** The DERIVED leaderboard-ELIGIBILITY axis (kestrel-m9i.25) — `certified ∧ post-cutoff ∧ date-blind ∧
* (season) frozen`, computed at projection from stamped fields, a DISTINCT axis from `certification` (a
* row can be `certification.verdict === "certified"` yet `rankability.rankable === false`). */
readonly rankability: Rankability;
readonly journals: readonly JournalEntry[];
/** Reason-carrying stand-down / de-arm audit records (kestrel-2pl), in bus order. Empty when the
* session never de-armed. Projected from CONTROL `disarm` — a pure bus read (ADR-0011). */
readonly disarms: readonly DisarmRecord[];
readonly plans: readonly PlanRecord[];
readonly orders: readonly OrderRecord[];
readonly totals: Totals;
/** The session's expected-$ partitioned by fill support (a57.4): the `calibrated` slice a grader banks
* and the `extrapolated` slice it refuses to bank (9gu.3). Always two entries, in the fixed order
* `[calibrated, extrapolated]` — deterministic and byte-stable. Partitions {@link Totals.expected}. */
readonly fill_claim: readonly FillClaim[];
/** The clock-honest deliberation trace (ADR-0040 / kestrel-w7la.1) — per-wake cost + session total,
* a pure fold of the bus's `WAKE`/`deliberation` records. ABSENT on a latency-blind bus (which
* carries none), so every existing projected Blotter is byte-identical. */
readonly wake_trace?: WakeTrace;
}
//# sourceMappingURL=types.d.ts.map