Your agent writes the order. Pilot holds it short.
Asked for a 0.0005 BTC short, Codex planned $40.11 against your $25 cap. Pilot refused it with nothing sent and named a size that fits: the 0.00031 BTC re-issue filled on dreamDEX (Somnia testnet).
maxNotionalUsd: the position this order leaves would be $40.11 notional, above the $25 cap per market
next safe action: reduce size to at most 0.00031 BTC
0x385c1486…8080 · success @ block 31576050 · filled 0.00031
refused with nothing sent: 15 rows in DEMO.md, 11 by your limits, 4 by pilot's own checks
DEMO.md · SummaryOne run, read from both sides of the stop bar.
On the left, the journal pilot wrote while Codex worked (refused 02:41:11, closed 02:41:24). On the right, the same fill as dreamDEX's own explorer shows it.
Seven ways it said no, and what to do instead.
Every refusal names its rule and a next safe action the agent can act on. These are the real rows from DEMO.md; some are scripted probes, like a made-up plan id.
the position this order leaves would be $79.80 notional, above the $25 cap per market
… close_position or a reducing order frees room
DOGE is not on the allowed list (BTC, ETH, SOL)
pick one of BTC, ETH, SOL
liquidation would sit 12.80% from mark, closer than the 15% minimum
use a smaller size (less leverage)
… is below the SOL minimum 0.1
plan at least 0.1 SOL
… plans live in this server's memory only and are one-shot
call plan_order first
… expired 2s ago (plans live 60s)
call plan_order again for fresh prices
… was already used: an earlier place_order refused it (planExpired) and sent nothing
call plan_order for a new plan
15 rows: 11 under your limits, 4 under pilot's own checks. Three of the DOGE rows also failed minQuantity; each is counted once, under your limits. The 0.0005 BTC refusal in the hero is one of the six maxNotionalUsd rows. One more refusal came from the exchange itself, with the race injected on purpose (see Honest limits). Source: DEMO.md, all times 2026-10-24 UTC.
Give an agent the SDK and it can send any order. Pilot makes it wait for clearance.
Checked twice, sent once
plan_order runs the SDK's own previews against your policy and hands back a one-shot plan_id that expires in 60 s by default. place_order re-checks your policy, re-runs the liquidation and margin previews on live state and re-derives the limit price from the live book before it sends.
The cap is on the position
With 0.2 SOL open, Claude Code planned a 0.1 SOL add, about $10 and under the cap on its own. Refused, nothing sent: the position it leaves would be $30.80.
Limits no pilot tool can edit
They live in a file no pilot tool writes; policy only reads it. They carry over between sessions, and the daily cap counts across restarts.
Closing is never blocked by your limits
close_position closes from the live on-chain size and your limits never stop it, not even an invalid policy file. When it cannot close (an empty book, the signer lock held elsewhere) it says why.
Every plan, refusal and transaction lands in an append-only journal. journal --card turns yours into a receipt to share:
What it does not do, in its own words.
“Testnet only. Nothing here has run on mainnet.”README · Honest limits
“One exchange refusal in DEMO.md is marked race injected: the limit price was lowered in the sender to make the order unfillable …”README · Honest limits
“Pilot guards its own tools, not the rest of the agent.”README · Honest limits
Is it real?
What was staged?
Are these real orders?
DEMO.md was re-read from the RPC after the run, and each order and close hash links to its fill on dreamDEX's Hideki markets explorer (brackets and cancels are checked by the RPC only). Testnet only, with a burner key.Which agents can use it?
markets, account, plan_order, place_order, close_position, bracket, cancel_all, policy, journal.Can the agent change its own limits?
What happens when an order breaks a limit?
What was scripted or staged?
DEMO.md counts. The Codex run in the hero was recorded on commit 0d18cec; since 5c81bcb pilot values a short at the top bid, so the same order would now read about $40.51.Can it always get me out?
close_position is never blocked by your limits, even by an invalid policy file. It can still stop, for example on an empty book or when another pilot server holds the signer lock, and it says why.Can I try it without a key?
PILOT_ACCOUNT names a public address; the README's Getting Started section uses the demo burner, and its second call (a $60 SOL plan) is refused by the default $25 cap with nothing sent.Set your limits once. Let the agent trade inside them.
git clone https://github.com/edycutjong/dreamdex-pilot
cd dreamdex-pilot && npm ci && npm test