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.

144 lines 10.9 kB
/** * # frame/render-arm — the token-optimal percept renderer ARM (kestrel-4gl.9 / wa0j.27 / 5ine) * * A SECOND, explicit rendering of the SAME typed Frame inputs, restructured to spend fewer * tokens under a BPE tokenizer while carrying the IDENTICAL fact set. This module NEVER touches * the canonical renderer ({@link ./render.ts}) — canonical stays the frozen leaderboard control * (wa0j.27). The arm is selectable as a HARNESS PROPERTY ({@link RenderArm} / {@link renderPercept}) * so a run picks its renderer the way it picks its model — the renderer rides the harness bundle, * it is never a leaderboard facet (kestrel-5ine). * * ## Why an arm (the hypothesis, wa0j.27) * The percept is dense numeric/tabular data — exactly where BPE fragmentation bites. Three * measured hotspots (see `docs/results/gemini-token-optimal/report.md`, measured on the real * `src/frame` output under the o200k_base + cl100k_base BPE tables): * 1. **Alignment padding** — the chain table's `pad(...)` runs and the kernel's fixed gutters * emit runs of spaces; a run of 2+ spaces is often its own BPE token, spent per row per column. * 2. **Non-ASCII glyphs** — `·` `→` `–` `—` `█` `─` are multi-byte and frequently 1+ token each; * the rotated-candlestick tape is a WALL of `█`/`─` glyphs (dozens of tokens per row) that * encodes price only approximately (column position), so it is both the costliest pane AND * lossy vs the numbers it is drawn from. * 3. **Repeated skeleton** — the verbose banners (`==== SAFETY / CONTROL KERNEL … ====`) and the * re-spent column labels cost tokens on every frame. * * The arm's fixes are UNIVERSAL to BPE tokenizers (Gemini's SentencePiece, GPT's o200k, Claude's * proprietary BPE all fragment padded decimals + rare glyphs): collapse alignment to a single * delimiter, render ASCII, render the tape as compact numeric OHLC (cheaper AND exact), and shorten * the skeleton. See the report for per-family caveats (only the GPT-family o200k/cl100k counts are * measured precisely here; the Gemini/Claude hosted count endpoints were unreachable in-env). * * ## Information parity is a GATE wired into the RUNTIME emit path (review F1) * The arm carries the SAME facts as canonical — a compaction that DROPS a level, a strike, a P&L, or * a wake reason is a safety regression, not a token win. {@link assertInformationParity} extracts the * numeric fact MULTISET from BOTH renders and asserts the arm carries every occurrence canonical * does, plus every free-text fact collected from the typed INPUT. The gate runs INLINE inside * {@link renderTokenOptimal} — the production entry point — so a lossy arm REFUSES to emit at * runtime, not only under test (the house guard-wiring rule: a guard present but unwired is inert). * `tests/render-arm.parity.test.ts` ships DELIBERATELY-LOSSY fixtures that the gate must catch * through that runtime path — unwire the inline assert and those tests go red. */ import type { BriefingInput, WakeDeltaInput } from "./types.ts"; /** * A renderer arm id. `canonical` is the frozen leaderboard control ({@link ./render.ts}); the * `token-optimal-*` arms are this module's compaction, NAMED per target model family so the harness * can default a family's renderer (kestrel-5ine: claude-code→fable, codex→gpt, …). * * MEASURED DIVERGENCE (2026-07-15, native Gemini `countTokens` — the follow-up leg): the two family * arms share the universal compaction (ASCII separators, single-space delimiting, compact skeleton, * one-line engine log) but DIVERGE on the TAPE: * - `token-optimal-fable` renders the tape as exact numeric OHLC (the comprehension winner — * preferred 9–1 by the reader models, +2.7pp quiz accuracy); * - `token-optimal-gemini` KEEPS the canonical rotated-candlestick glyph tape, because Gemini's * tokenizer prices the glyph runs CHEAP and the OHLC decimals DEAR (candlestick row 18 native * tokens vs 39 for the same bucket as OHLC; the OHLC-tape arm LOST 26.9% on the tape-heavy * percept under native Gemini counts). Data: docs/results/gemini-token-optimal/ * gemini-token-audit.json. */ export type RenderArm = "canonical" | "token-optimal-gemini" | "token-optimal-fable"; /** The arm ids this module materializes (canonical is served by {@link ./render.ts}, not here). */ export declare const TOKEN_OPTIMAL_ARMS: readonly RenderArm[]; /** Is `arm` one of the token-optimal arms this module renders? */ export declare function isTokenOptimalArm(arm: RenderArm): boolean; /** How an arm renders the TAPE pane — the one measured per-family divergence (see {@link RenderArm}). */ export type ArmTapeStyle = "ohlc" | "candlestick"; /** The measured tape style per token-optimal arm (native-count driven, never taste). */ export declare const ARM_TAPE_STYLE: Readonly<Record<Exclude<RenderArm, "canonical">, ArmTapeStyle>>; /** Render the OPEN keyframe under a token-optimal arm (default View). Same facts as * {@link ./render.ts renderBriefing}, compacted; the tape style is the arm's ONE measured * divergence ({@link ArmTapeStyle}, default `ohlc` = the Fable arm). Kernel leads. PURE. */ export declare function renderBriefingArm(input: BriefingInput, tape?: ArmTapeStyle): string; /** Render the WAKE delta under a token-optimal arm (default View). Same facts as * {@link ./render.ts renderWakeDelta}, compacted; tape style per the arm ({@link ArmTapeStyle}, * default `ohlc` = the Fable arm). Kernel leads. PURE + deterministic. */ export declare function renderWakeDeltaArm(input: WakeDeltaInput, tape?: ArmTapeStyle): string; /** The frame kind + its typed input, tagged so {@link renderPercept} can dispatch canonically. */ export type PerceptInput = { readonly kind: "OPEN"; readonly input: BriefingInput; } | { readonly kind: "WAKE"; readonly input: WakeDeltaInput; }; /** Thrown when a token-optimal arm render DROPS a fact the canonical render carried — a safety * regression masquerading as a token win. The gate fails CLOSED (the arm is refused, never shipped). */ export declare class InformationParityError extends Error { constructor(message: string); } /** The numeric literals in a rendered percept as a MULTISET (token → occurrence count) — a strike, * a level, a budget, a P&L. Signs are kept (`-25.97` ≠ `25.97`). A true multiset (review F4): the * arm must carry every occurrence canonical does, so a dropped duplicate can never hide behind * another rendering of the same number (the Set version's blind spot — e.g. a strike shown in both * the kernel and the acting detail). Fixed skeleton labels are stripped first ({@link stripSkeleton}) * so a digit-bearing label (`-- L0/L1 ENGINE LOG --`) is never mistaken for a market value. */ export declare function numericFacts(text: string): Map<string, number>; /** Collect the FREE-TEXT (non-numeric) facts from a typed percept input — the values a numeric-only * check cannot see (wake reasons, plan names/states, order refs, notes, unavailable capabilities, * claim sources, instrument symbols). Driven from the INPUT (not re-parsed from text) so it is a * precise, non-brittle list of exactly what the arm MUST still contain. */ export declare function freeTextFacts(p: PerceptInput): string[]; /** * The information-parity GATE. Given the typed input, the canonical render, and the arm render, * assert the arm carries EVERY fact canonical does: * (1) numeric multiset: every numeric literal in canonical appears in the arm at least as often; * (2) free-text: every free-text fact from the INPUT appears as a substring of the arm. * Fails CLOSED ({@link InformationParityError}) on the FIRST dropped fact. PURE. This is the driver * a deliberately-lossy arm fixture must trip (the house rule: a guard ships with a failing fixture). */ export declare function assertInformationParity(p: PerceptInput, canonicalText: string, armText: string): void; /** A token-optimal render implementation — the injectable seam {@link renderTokenOptimal} gates. * Production uses {@link renderTokenOptimalUnchecked}; a test fixture injects a deliberately-lossy * impl to prove the runtime gate is WIRED (never bypassed by production callers). */ export type TokenOptimalRenderImpl = (p: PerceptInput, arm: Exclude<RenderArm, "canonical">) => string; /** The UNGATED arm render (frame-kind dispatch + the arm's measured tape style). INTERNAL BUILDING * BLOCK: production callers MUST go through {@link renderTokenOptimal}, which runs the fail-closed * information-parity gate on every emit — this function exists as the emitter's default impl and as * the base a parity-fixture wraps. Exported for those two uses only. */ export declare function renderTokenOptimalUnchecked(p: PerceptInput, arm?: Exclude<RenderArm, "canonical">): string; /** One pane's population status: its first line (the pane label) + whether it carries ANY numeric * fact (a digit-token after skeleton stripping). A DEAD pane is structure + placeholders only. */ export interface PanePopulation { readonly pane: string; readonly dead: boolean; } /** * Classify each blank-line-separated pane of a rendered percept as POPULATED (carries at least one * numeric fact) or DEAD (skeleton + placeholders only — `—`/`na`/`none`/`no prints`/`no legs`). * Works on BOTH the canonical and the arm render (the pane separator is the same `\n\n`). A frame * header pane (clock digits) counts as populated — the detector's target is FACT panes that show no * fact. Pure. A monitoring consumer flags a pane that is dead across ALL frames of a run (the * failed-breaks failure mode); a single degraded frame's dead pane is honest rendering, not a defect. */ export declare function panePopulation(rendered: string): readonly PanePopulation[]; /** The dead panes of a rendered percept (see {@link panePopulation}) — convenience projection. */ export declare function deadPanes(rendered: string): readonly string[]; /** * Render a percept under a token-optimal arm — the PRODUCTION entry point, with the * information-parity gate WIRED INLINE (review F1; the house guard-wiring pattern): every emit * renders the canonical control from the SAME typed input and runs {@link assertInformationParity} * before the arm text is returned. A parity failure THROWS — the arm REFUSES to emit a percept that * dropped a fact, in production, not only under test. The `impl` parameter is the injectable seam a * failing fixture uses to prove this gate is wired through THIS path (unwire the assert below and * `tests/render-arm.parity.test.ts`'s runtime-gate fixture goes red). PURE + deterministic. */ export declare function renderTokenOptimal(p: PerceptInput, arm?: Exclude<RenderArm, "canonical">, impl?: TokenOptimalRenderImpl): string; //# sourceMappingURL=render-arm.d.ts.map