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.

38 lines 2.67 kB
/** * # session/harness/bounded-numerics — the BOUNDED-NUMERICS emission guard (fail-closed, never scored) * * A strict schema / constrained-decoding grammar can force a syntactically-VALID but DEGENERATE number: a * `json_schema` `qty:integer` probe forced digits and the model looped to an **8,173-digit integer** — * valid JSON, garbage. Such an emission is a GENERATION FAILURE, not a decision. It classifies INVALID * (fail-closed) and is NEVER scored — the same "reject unknown input, never default it" rule the * empty→INVALID guard already enforces in {@link file://./live-agent.ts} (empty/zero-token → `invalid`). * * This is the LOCAL port of the HOSTED adapter's `invalid-degenerate` class * (`scripts/bench/hosted/hosted-adapter.ts` `checkBoundedNumerics` / `classifyEmission`), lifted here so the * local live harness and the hosted eval adapter share ONE convention: a degenerate numeric is rejected * identically on both lanes. Pure: no clock, no RNG, no I/O. * * Two cheap, load-bearing checks: * 1. **pre-parse raw-string digit cap** — any run of >{@link MAX_NUMERIC_DIGITS} consecutive digits in the * RAW emission is a decoding loop (the 8,173-digit integer), caught BEFORE `JSON.parse` silently * coerces it to `Infinity` (which `Number.isFinite` would then reject anyway) OR — the sneakier case — * to a FINITE-but-absurd float (e.g. a 15-digit run → ~1e15) that a bare finiteness check would SCORE * as a real order. The raw cap catches BOTH before the coercion hides them. * 2. **per-field range sanity** — every action's numeric field (`order.qty` / `order.strike` / * `scheduleWake.at.minutes`) must be finite and inside {@link NUMERIC_FIELD_BOUNDS}. A `NaN`/`Infinity`/ * absurd value is degenerate. Bounds are generous — they catch garbage, not judgment. */ /** Max run of consecutive digits tolerated in a RAW emission. Any longer run is a constrained-decoding * digit loop, not a number (the 8,173-digit integer). Matches the hosted adapter's cap. */ export declare const MAX_NUMERIC_DIGITS = 12; /** * The bounded-numerics guard. Returns `{ ok: true }` when the emission carries no degenerate number; * otherwise `{ ok: false, reason }` naming the defect. A parse failure here is NOT this guard's concern * (the turn parser owns unparseable input) — an unparseable body simply passes the field check and is * rejected by the parser downstream. See the module header for the two checks. */ export declare function checkBoundedNumerics(text: string): { readonly ok: boolean; readonly reason?: string; }; //# sourceMappingURL=bounded-numerics.d.ts.map