Start here
You are building a non-custodial platform for other people's trading bots. Users author the bots. We supply the guardrails that make running them safe, and an AI layer that helps users decide, place, and monitor. The 109 specs in this guide are the rails underneath that — not the product. Read what you are building first, then work the PR path below.
The product model, in four sentences
Most of this guide reads like a manual for a 109-bot system we own end to end. That describes your first month of code; it does not describe the product. Somebody else's bot is the thing that trades. Our bots exist to constrain it, inform it, and explain it — which is why user code is sandboxed, why guardrails are a chain rather than a class, and why an LLM response can never become an order on its own.
See where this work lands in the product
A high-fidelity re-skin of the eight live operator pages (Dashboard, Strategies, Risks, Bots, Decisions, Orders, Portfolios, Wallets) plus a new Pipeline page, showing exactly how the four-state promotion ladder, reason codes, envelope viewer, and V2-only rails surface to the operator. Each page is annotated with what changes vs. today.
The first eight PRs, in order.
Each step is one reviewable PR. Do not skip ahead. Do not start a strategy PR before the rails it depends on are merged. PRs 1–5 are the shared rails and are largely shipped. PRs 6–8 are what turn those rails into the actual product — they are the ones currently missing, and they are the reason the earlier five exist.
- PR 1 — Contracts. Land
MarketSnapshot,OrderBookSnapshot,OrderIntent,ReportEnvelope, and theReasonCoderegistry as TypeScript types inpackages/contracts. No bot code yet. See typed schemas → - PR 2 — First risk bot. Implement
risk.killswitchagainst the contracts from PR 1. KillSwitch is the smallest, most important bot. Use the Risk template. Add afixtures/risk.killswitch/{normal,warning,hard,failure}.jsonpack. See KillSwitch spec → - PR 3 — Fixture pack format. Land the four-file fixture-pack convention used by
verify.js. Document it in Test pack. From this PR forward, every bot PR ships its fixtures in the same shape. - PR 4 — Reporting envelope. Wire
ReportEnvelopeinto the runner so everydecide()emit lands a structured event. Free-textconsole.logis forbidden after this PR. See envelope spec → - PR 5 — Demo wiring. Add the bot to
wired_bots.jsonand to the synthetic browser demo. The synthetic feed is the only feed; production data does not exist yet. Open the demo → - PR 6 — RiskGate, as the single write path. Collapse every route to the venue into one function that no other code can bypass. Move the guardrail chain behind it in a fixed order, make the hard guardrails non-disableable in config, and make the exposure reserve atomic over
filled + pending + partial. Done when a grep for venue-client imports outside the gate returns nothing, and a test that tries to submit around the gate fails to compile. RiskGate standard → - PR 7 —
rules.yamlparser and the user sandbox. Land the Tier-1 schema, the bounds check that clamps user risk values to the platform floor (loudly, never silently), and signal-name resolution against the registry at save time. Then the isolate with its CPU, memory, and rate budgets, and the strike-to-quarantine path. Done when a user bot can be authored, backtested, shadowed, and paused without any of its code holding a key, a client, or a socket. User-bot standard → - PR 8 — AI suggestion envelope. Land
TradeSuggestionwith mandatory evidence and registry-validated market ids, and route accepted suggestions through the same RiskGate as any bot proposal. Start with surface C (monitoring) — it is read-only, it is the highest-value surface for users, and it cannot lose money if it is wrong. Done when there is no code path from a model response to a signature. AI-assist standard →
How to implement a bot
The same 7 steps for every bot, every class. Do not invent a different shape.
- Pick the class. Discovery, Strategy, Risk, Execution, Governance. The class determines authority, mode ladder, and which template you copy. By Class →
- Copy the template. The five class templates under
/templates/<class>/are the only approved starting point. Do not start from scratch. Templates → - Paste the spec into your README. Open the bot's spec page. Paste it into the bot package's README so any spec change is reviewable in the same PR as the code change.
- Implement
decide(ctx, intent). Everything else — interface,emit,explain,health— is already wired by the template. Your work is the decision function. - Write the fixture pack. Four files:
normal.json,warning.json,hard.json,failure.json. Copy expected outputs from the spec's wire-examples section — do not hand-write them. - Run
npm test. All four packages must stay green:contracts,synthdata,backtest,bots. The bots package runsverify.js: factory shape,decide()determinism, fixture-pack presence. - Open the PR. The promotion-gate checklist is the PR template. Mark the readiness state honestly: a bot with a passing fixture pack is
shadow-ready, notproduction-live.
The seven questions, in case you forgot one
- What do I build first? — Read the Plan. Phases 1–3 ship the shared rails; Phase 4 the risk gate; Phase 5 the execution rails; Phase 6 the first strategy. Skipping a phase means rebuilding it later under pressure.
- Which class does my bot belong to? — Pick the class. Class determines authority, modes, and template.
- Which template do I copy? — The five class templates. The single approved starting point.
- Which schemas must I import? — All inputs and outputs come from the typed schemas. If the object isn't there, it isn't real yet.
- Which test fixtures must pass? — Every fixture pack ships
{normal,warning,hard,failure}.json. Yourdecide()must reproduce the expected outputs deterministically. - What counts as done? —
demo-wiredrequires 27/27 on the per-bot documentation checklist (section 29) and a passing fixture pack and a clean run ofverify.js. That is documentation completeness plus reference implementation — it is not readiness to trade. Promotion toproduction-liverequires shadow mode, runtime envelopes, and change control. - How do I promote it? — Through the readiness ladder:
docs-complete → demo-wired → shadow-ready → runtime-live → production-live. Never skip a state.
What you must never do
These are not style preferences. Each one, if broken, breaks the product's core promise, and each one is easy to break with a change that looks like an improvement.
| Never | How it usually gets broken | What breaks |
|---|---|---|
| Add a second path to the venue. | A "quick" admin cancel endpoint, a migration script, a test helper that ships. | The guardrail chain becomes decorative. RiskGate |
| Give user code a key, a venue client, or network access. | A convenience helper injected into the sandbox context "just for reading prices". | Non-custodial and the sandbox both. User bots |
| Let a guardrail fail open. | A catch-all that returns ALLOW, merged as a resilience fix. | The system trades hardest exactly when it understands least. Failing closed |
| Let a user loosen a hard cap. | A config override that is read after the platform floor is applied. | The floor. Order of application matters. RiskGate |
| Act on model output automatically. | A monitoring loop that de-risks on its own "for the user's benefit". | Advisory-only. That is Trade authority in a monitoring costume. AI assist |
| Widen a session-key method whitelist. | Adding transfer to unblock a withdrawal feature. |
Custody. There is no bounded version of this. Signing model |
| Flatten a user's positions without authority. | A revoke handler that "safely" closes everything out. | Custody, in the one moment the user was asserting they did not grant it. |
What does NOT belong on your machine
- Production wallet keys. Use the staging signer; production keys live only in the signing service.
- The live Polymarket API. Tests use the recorded CLOB v2 fixture set.
- Free-text logging. Use the ReportEnvelope.
- Hard-coded market IDs or contract addresses. They live in
BotConfig.
If you only read one other page
Read what you are building. It is the page that makes every other page in this guide mean the right thing. After that, bot-interface is the most important contract for the bots we supply, and RiskGate is the most important one for the platform.