← Blog

Worst Case, in Dollars: How Bounded Risk Is Enforced Below the Agent

Bounded risk is a type in Kestrel, and the L0 risk envelope is the runtime layer that clamps or vetoes every actor, including the agent, and may never open risk.

Answer card

Bounded risk in Kestrel is a type, not a policy you hope holds. Every PLAN carries a budget <n>R and bracket, so its maximum loss is known before a single order routes. Below the agent, the risk envelope (L0) can clamp or veto any actor, including the agent, and may never open risk, only tighten it. The proof a human sees: a term-sheet approval URL stating worst case in dollars, with sliders that can only make it smaller.

The two questions risk should answer

A trading system should be able to answer two questions at all times: how much can this lose, and who can change that number. Most agent stacks answer neither cleanly. The model calls a place_order tool, the tool does what it's told, and the blast radius is whatever the model decided, checked (maybe) by a prompt that says "be careful" and a rate limit somewhere. The loss bound lives in the agent's intentions. That is exactly the wrong place for it.

Kestrel moves the bound out of intention and into the type system, then enforces it in a layer the agent cannot reach past. This is the same discipline as the agent is never in the hot path: the thing that matters most for safety does not depend on the model behaving.

DimensionTypical agent stackKestrel
Where the loss bound livesThe model's intentionsThe PLAN type (budget <n>R + bracket)
When worst case is knownAfter the fact, in the post-mortemAt author time, in dollars, before the first order
Who enforces itA prompt and a rate limitThe risk envelope (L0), below the agent
Can the enforcing layer open risk?N/A: there is no distinct layerNo: L0 may only clamp, veto, or tighten
Path to real moneyWhatever the tool allowsHuman-signed scope; LIVE is a platform-enforced singleton

Bounded risk is a type

In Kestrel a PLAN is a standing, bounded-risk contingent program: trigger, actions, bracket, invalidation, TTL. The word bounded is load-bearing. A plan without a stated budget and bracket does not typecheck as a plan; it is not a thing the runtime will arm.

IMPORT { fade-ladder } FROM "./armory/reversion.kestrel"
USING signal SPX exec SPY 0dte

PLAN spx-fade budget 3R ttl +45m regime {intraday: chop}
  WHEN spot crosses above HOD AND velocity(5m) >= p95 held 120s
  DO buy 1 atm P @ lean(bid, fair, 0.5) cap fair
  RELOAD WHEN spot crosses above HOD band 8bp buy 1 +1 P @ fair-3c
  TP 2x frac 0.5 @ fair
  EXIT filled held 20m @ bid
  INVALIDATE spot > HOD held 120s

budget 3R is not documentation. It is the maximum this plan may lose, expressed in R (the pod's risk unit), and the runtime holds it as a hard ceiling: the bracket, the reload, and the TTL are all bounded so the sum cannot exceed 3R. You do not get to arm a plan whose worst case is unknown. The worst case is computed, in dollars, at author time, before the agent, the human, or anyone else says go.

This is why a backtest is never flattering and the chart is in text have a sibling here: worst case, in dollars. The number exists before the trade, not in the post-mortem.

The risk envelope (L0): clamp, veto, never open

Above the type sits enforcement. Kestrel's org model is a recursive POD tree: a PM pod allocates risk envelopes to child Books and Traders, and those may allocate further down. The risk envelope (L0) is the lowest, most privileged layer. Three properties define it:

  1. It can clamp. If a plan asks for 3R but the envelope it runs under has 2R of headroom left, the plan is clamped to 2R. The agent's request is an upper bound on what it gets, never a floor.
  2. It can veto. L0 can refuse an action outright: a trade outside the envelope's scope, a size past the ceiling, an order after expiry. Veto beats intent. It applies to everyone, including the agent that authored the plan and the human who funded the pod.
  3. It may never open risk. This is the invariant that makes the other two trustworthy. No actor can use L0 to increase an allowance: not the agent, not a child pod, not a slider in a UI. Authority only narrows as it flows downward. L0 is a one-way ratchet toward less risk.

That third property is the whole game. A safety layer that can also grant risk is just another actor in the blast radius. Because L0 can only tighten, the maximum loss computed at the top of the tree is a true ceiling for everything beneath it; nothing below can vote itself a bigger number.

Budgets nest; authority narrows downward

Risk in the POD tree behaves like a set of nested envelopes, each strictly inside its parent.

PM pod            budget 100R   (funded ceiling)
 └─ Book: reversion   budget 30R   (<= parent headroom)
     └─ Trader: spx-fade  budget 8R   (<= book headroom)
         └─ PLAN spx-fade   budget 3R   (clamped to trader headroom)

A child can never hold more than its parent grants, and the runtime enforces the inequality at every hop. When a Scan fires and a PM authors a new leaf (a Book plus Coverage plus thesis plus budget), that leaf is born inside the parent's envelope, not beside it. The recursion is what lets a desk delegate to many agents and still state one number for the whole book's worst case. Names are data; budgets are structure.

The proof a human actually sees

On kestrel.markets, the commercial platform, bounded risk surfaces as the envelope, the one authorization primitive: {scope, budget, ceiling, expiry, revocation}. The moment authority is granted, a term-sheet approval URL shows worst case in dollars for the scope being authorized. And the controls obey the same L0 rule: sliders may only tighten. You can drag the budget down; you cannot drag it past the ceiling you were granted. One-tap revocation and mandatory expiry are part of the same primitive.

The envelope is also two-signer. A wallet may sign commerce-only scopes (data, sim, paper), but a human must sign any legal, broker, or LIVE scope. LIVE is a platform-enforced singleton: at most one live authority per pod lineage. So the worst-case-in-dollars you approve is the worst case the runtime will honor, and the path to real money always crosses a human signature.

Where this is not the right fit

Bounded-risk-as-a-type is honest about its edges:

  • Unbounded discretion. If your intent is "let the model trade freely and see what happens," Kestrel will fight you at author time: every plan needs a budget and bracket. That friction is the point, but it is friction.
  • Strategies whose risk genuinely can't be pre-stated. Some books (certain naked-short or path-dependent exposures) have a worst case that isn't cleanly expressible as nR with a bracket. Kestrel makes you encode a bound anyway; if the honest bound is "very large," it will say so rather than hide it.
  • Today's maturity. The type-level bound and the POD tree are core to the language. As of mid-2026: anonymous trial sims, certified Grades, shareable proof URLs, and 402 Offers with Stripe settlement are live; always-on paper presence and the human-signed live path are in build. The free tier needs no signup. The full two-signer envelope, term-sheet URL, and LIVE singleton are platform surfaces still in build. We would rather say that than imply it all ships today.

Illustrative throughout: the plan above is how an agent could express a fade, not a recommendation. Deploy a template into your pod and you arm it. This is not investment advice.

Why put the bound below the agent at all

Because intelligence is getting cheaper and capital is not. Host the scarcity, rent the genius. The scarce, dangerous thing is trading authority over real money, so the bound on that authority belongs in the layer that stays constant while models come and go, not in the model's reasoning that changes with every release. An agent can be brilliant or broken; L0 clamps both to the same dollar ceiling. That is what it means for risk to be a type rather than a promise.


Bounded risk is a type, not a promise: L0 can clamp or veto anyone including the agent, and it may never open risk, so the worst case is knowable in dollars before the first order.