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
TypeScript
/**
* # 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