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
text/typescript
/**
* # 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;
}