UNPKG

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.

129 lines (121 loc) 7.81 kB
/** * # src/pm/oracle — THE PINNED ORACLE DEFINITION (design blocker B5, formal) * * (bd kestrel-markets-n7jx.2 / PM-persona-benchmark design §11 B5.) The separability factorial * (PM-8) freezes the strategist+watcher downstream as an ORACLE so that what varies is only the PM * seat's allocation. An undefined oracle ⇒ no separability isolation. This module PINS it, and * pins the doctrine that governs how it may and may not be used. * * ## The interim oracle * * The interim oracle is the **per-pole best-known book + play-EV table** — exactly the PM-1 / PM-3 * pattern already shipped in `tests/bench/pm-item-bank.ts` and `tests/bench/pm3-bank.ts`: * * - for each pole of each matched pair, a frozen `ev: Record<play, realizedEV>` table giving each * candidate play's realized play-EV under THAT pole's known outcome, and * - an `oracleBook` = the best-known allocation for the pole (the α normalizer). * * The oracle DATA lives with the banks (closed holdback + public split); this module owns only the * TYPE and the DOCTRINE, so the OSS spine carries no repertoire. * * ## THE ORACLE DOCTRINE (verbatim — this text is load-bearing; do not paraphrase in derived docs) * * The oracle is a **grading yardstick, never a supervision target, never an expected-achievable * bar.** Floors are **re-derivable with a latency parameter L** when the clock-honest track lands * (`floors(L)`, regime declared per row). Teacher-corpus admissibility is **gated on the teacher * clearing the comprehension gate on the corpus's render regime.** * * Unpacked (each clause is a rail, cross-referenced to where it is enforced): * * - **Grading yardstick, never a supervision target.** The oracle normalizes α (`bookα/oracleα`); * it is NEVER shown to a graded seat and NEVER used as a training/imitation label. A seat that * is handed the oracle is measuring nothing. (Mirrors the OSS grading firewall; the frozen table * is read only by the grader, never by the PM.) * - **Never an expected-achievable bar.** `oracleα` is best-known, not a floor a good seat "should" * reach; scores are reported relative to it AND to the sham/chance floors, never as "% of a bar a * competent PM must clear." Creative-α (design §12b) can legitimately exceed the oracle on * open-menu items — where the oracle would misgrade a genuinely-better book as error, the oracle * does not apply. * - **`floors(L)` — re-derivable with a latency parameter.** The current oracle is latency-blind. * When the clock-honest track lands, every floor becomes a FUNCTION of an execution-latency * parameter `L`, and each graded row DECLARES the regime `L` it was derived under (a latency-blind * row and a clock-honest row are not comparable and must never be pooled). See {@link Floors}. * - **Teacher-seat comprehension gate** (the TEACHER-SEAT GATE, percept-session corollary to * distill-the-judge). If a reference seat's output becomes a distillation corpus, the ADR-0044 * comprehension gate applies to the TEACHER too: a teacher that misreads the render frame teaches * frame-unconditioned noise with perfect confidence. Before any scrimmage/roster raw JSONL is used * as teacher corpus: (1) the teacher seat MUST clear the comprehension gate on the EXACT render * regime the corpus was generated under (regime id stamped — see {@link TeacherCorpusAdmission}); * (2) the render is the student's ENTIRE observable universe, so corpus admissibility inherits the * percept-gap question — if the frame-probe ≫ render-probe control (OSS wa0j.60) shows canonical * drops decision-relevant state, corpora generated on that render are bounded by it. The * information-parity gate guarantees the arm carries ≥ canonical CONTENT; wa0j.60's frame-probe is * the deeper question of whether canonical itself is lossy where it matters — owned by the percept * epic, but admissibility here fails closed on it. */ /** A candidate play's realized EV under a pole's known outcome — the frozen oracle downstream. */ export type PlayEvTable = Readonly<Record<string, number>>; /** One entry of an oracle allocation (structurally the bank's `BookEntry`). */ export interface OracleBookEntry { readonly play: string; readonly size: number; } /** * The interim oracle for one pole: the frozen play-EV table plus the best-known allocation. This is * the exact shape the banks already carry (`Pole.ev` + `Pole.oracleBook`) — pinned here as the * canonical type so PM-7/PM-8 consume a named contract, not an ad-hoc record. */ export interface PoleOracle { /** Realized play-EV per candidate under this pole's known outcome. */ readonly ev: PlayEvTable; /** The best-known allocation for this pole — the α normalizer (`Σ size·EV`). */ readonly oracleBook: readonly OracleBookEntry[]; } /** * The latency regime a floor/oracle row was derived under. `latency-blind` is the CURRENT interim * regime (no execution clock); `clock-honest` rows carry the execution-latency parameter `L` (ms) * they were derived at. Rows of different regimes are NOT comparable and must never be pooled. */ export type FloorRegime = { readonly kind: "latency-blind" } | { readonly kind: "clock-honest"; readonly L: number }; /** * `floors(L)` — the doctrine's promise made a signature. A floor is re-derivable as a function of the * latency parameter `L` once the clock-honest track lands; every derived floor stamps the * {@link FloorRegime} it was computed under so the grader can refuse to pool across regimes. Until * the clock-honest track lands this evaluates the latency-blind regime only. */ export interface Floors { /** The floor value under the given regime (interim: latency-blind returns the latency-blind floor). */ readonly value: number; /** The regime this floor was derived under — DECLARED per row, never elided. */ readonly regime: FloorRegime; } /** * Teacher-corpus admissibility record (the TEACHER-SEAT GATE made checkable). A raw JSONL corpus is * admissible as teacher/distillation input ONLY if the teacher seat that generated it cleared the * comprehension gate on the corpus's own render regime. Both fields must be present and true, and the * `renderRegimeId` must match the corpus's stamped regime, or the corpus is inadmissible (fail closed). */ export interface TeacherCorpusAdmission { /** The render regime id the corpus was generated under (stamped on the corpus). */ readonly renderRegimeId: string; /** True iff the teacher seat cleared the ADR-0044 comprehension gate on THIS render regime. */ readonly teacherClearedComprehensionGate: boolean; /** True iff the frame-probe ≫ render-probe percept-gap control (OSS wa0j.60) did NOT fire on this render. */ readonly perceptGapClear: boolean; } /** * Fail-closed admissibility check for a teacher corpus. A corpus is admissible only when the teacher * cleared the comprehension gate on the corpus's own render regime AND the percept-gap control is * clear for that render. Returns the reason it is inadmissible, or `null` if admissible. */ export function teacherCorpusInadmissibleReason(a: TeacherCorpusAdmission): string | null { if (!a.teacherClearedComprehensionGate) { return `teacher did not clear the comprehension gate on render regime ${JSON.stringify(a.renderRegimeId)} — ` + `a teacher that misreads the frame teaches frame-unconditioned noise with perfect confidence`; } if (!a.perceptGapClear) { return `percept-gap control (frame-probe ≫ render-probe, wa0j.60) fired on render regime ` + `${JSON.stringify(a.renderRegimeId)} — canonical drops decision-relevant state; corpus is bounded by the render`; } return null; }