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.

49 lines (42 loc) 3.37 kB
# The support partition is written once; sign policy is a named view at the read seam A run's expected-$ honesty question — *"is this cash REAL?"* — has two honest answers, because it is really two questions. **Sign policy is a property of the question asked of the run, never of the run itself.** (Owner, 2026-07-12; kestrel-dpy.) The forcing case is the fill model as *experimental assumption*. Grading one tape under `strict-cross` (the floor) and `maker-fair` (the offline ceiling — fills at `@fair`) is a deliberate bracket, and the ceiling's cells are `extrapolated` *by construction*. Any blanket refusal of extrapolated expected-$ zeroes the ceiling run's upside and makes the floor↔ceiling bracket unreadable — yet that same refusal is exactly right the moment a number is banked, ranked, or attested. Both consumers are legitimate; they are asking different questions: - **Raw expected-$***"what does this run claim under its own fill model?"* The experiment/comparison view: the config grids and fill-model brackets (kestrel-5zl) compare raw, support-labeled numbers on one tape. The Grade's honesty obligation here is to **label**, never to censor — the fill model is the stated assumption. - **Bankable expected-$***"what may be banked, ranked, sold?"* Calibrated cells in full, plus extrapolated **losses**; extrapolated **gains are refused**. The asymmetry is deliberate and conservative: a strategy can neither hill-climb into an uncalibrated corner nor park its losses there. Leaderboards, seasons, and any attested receipt read this view and only this view. Mechanically: the engine (the single writer, ADR-0011) records per-fill `pFill` + `support` on the bus; the Blotter's `fill_claim` carries a **four-cell partition**`calibrated`/`extrapolated` × gain/loss — **preserved as data, never collapsed at write time**. Every policy, present and future, is a pure function over the partition, and all of it lives in **one support module** (`FillSupport`, the partition, the named views) consumed by the fill engine, the projector, and the grader alike. This fixes a live inconsistency: today `bankableEv` (src/grade) keeps extrapolated losses while the Blotter's `fill_claim` partitions *unsigned* expected-$ — so a consumer that "subtracts the extrapolated slice" would erase extrapolated losses, flattering exactly the strategy the doctrine exists to punish. With the signed partition on the record, the two can no longer disagree. Considered and rejected: **symmetric exclusion** (drop extrapolated both ways — simpler, but lets losses hide in uncalibrated corners) and **policy at write time** (bake one view into the Blotter — collapses the partition, forecloses the bracket use-case, and makes the sign policy unauditable after the fact). Consequences: `fill_claim` gains signed sub-slices (a `bus_schema`/Blotter-shape bump on the same one-time regeneration discipline as ADR-0011); raw and bankable render side by side wherever a Grade renders, each labeled with its view name and the fill-model support counts; the platform's attestation path (KM: sell the attested receipt) binds to **bankable** by construction. Note the deliberate rhyme: raw vs bankable is the same shape as certification vs attestation — the open number anyone can recompute vs the number someone will vouch for.