Polytraders · Milestone scope · v1 · 2026-05-16
M2 scope mapping — Real Data, Real Trades (low value)
The mock-app and the Dev Guide describe the destination. This page maps that destination to a deliverable M2, with clear in-scope / partial / deferred lines per Dev Guide section. Written so the build team can plan against it without having to read the whole guide.
The frame. The mock-app is the internal operator view. The customer-facing app is a simplified subset. When this page says "in mock" it means an operator surface; when it says "in product" it means the customer-facing UI as well. M2 ships both, but the customer-facing UI is intentionally narrower.
M2 objective
Real Data, Real Trades (low value). One strategy family, end-to-end, on real Polymarket V2 markets, with real wallets, real orders, real backtest output, real audit receipts. Politics + Crypto markets only.
Headline scope decisions
| Decision | M2 answer |
| Strategy family in M2 | Momentum only, parameterised. Other families in M3. |
| Strategy authoring | JSON/YAML parameterised templates with an in-app config editor. No scripting DSL in M2 — that is an M3 commitment. |
| Strategy score field | Generic strategy_score with a score_type tag (fair_value / confidence / expected_edge / custom). Each strategy declares its own. |
| Portfolio model | Portfolio is the unit of account. Strategies, positions, signals and risk all hang off a Portfolio. |
| Risk layers | Three: Strategy → Portfolio → Tenant. Higher layer wins. |
| Exit modes | Static TP/SL · strategy-emitted dynamic exit · portfolio-forced exit · time-based exit. Risk Manager arbitrates. |
| Backtest | Visual: price + signal markers per market, equity curve, drawdown, P&L. Operator-facing only. Never surfaced as a track record. |
| Markets | Politics + Crypto. Full-universe ingestion (watchlists are view-only). |
| Clusters | Read-only, automatic. Used by Portfolio risk and audit receipts. Not user-edited in M2. |
| Audit receipts | Reason code · builderCode · envelope ID rendered in full on every order/wallet/config/registry page. Never masked. |
Dev Guide → M2 mapping (section by section)
Discovery
| Capability | M2 | Notes |
| Market scanner (Gamma/Data) | In | Politics + Crypto. Full universe to registry. |
| Market-quality ranker | In | Consumed by Strategy entry filters. |
| Clusters (auto) | In | Used by Portfolio risk and receipts. |
| Watchlists (manual) | Partial | Read/select in mock + product; manual edit M3. |
| Cluster editing UI | Deferred | M3. |
Strategy
| Capability | M2 | Notes |
| Momentum family (parameterised) | In | Single strategy family in M2. |
| Target-portfolio selector on launch | In | Mandatory field on the launcher. |
| Market scope — cluster binding (primary) | In | Strategy binds to one or more clusters. Runs on every market currently in those clusters. See Market scope below. |
| Market scope — manual list (fallback) | In | Hand-picked list of condition IDs, capped at 50 markets per strategy. For one-off arb / single-market test launches. |
| Market scope — filter expressions (DSL) | Deferred | M3, together with the scripting DSL. |
| In-app config editor for parameters | In | JSON/YAML surface, validated. |
strategy_score + score_type contract | In | Replaces legacy "Fair Value" field. |
| Visual backtest surface | In | Per market, then expandable. |
| Scripting DSL (PineScript / Python-subset) | Deferred | M3 — syntax target chosen then. |
| AI strategy assist | Deferred | M3+, depends on scripting layer. |
| Additional strategy families (Mean-reversion, Convert-arb, etc.) | Deferred | M3. |
Risk
| Capability | M2 | Notes |
| Strategy-layer entry filters (e.g. min liquidity) | In | Lives on the strategy config. |
| Portfolio-layer guardrails | In | Sizing caps, max concurrent positions, cluster exposure, daily-loss limit. |
| Tenant-layer guardrails | In | Kill-switches, jurisdiction blocks, V2-only enforcement, builderCode pinning. |
| Layer precedence (Tenant > Portfolio > Strategy) | In | Documented; risk manager enforces. |
| Exit modes — all four | In | Static TP/SL · dynamic · portfolio-forced · time-based. |
Execution
| Capability | M2 | Notes |
| Real wallets | In | pUSD on Polygon, V2 only. |
| Real orders (CTFExchangeV2) | In | EIP-712 v2, builder attribution. |
| builderCode pinning | In | 0xb000000000000000000000000000000000000000000000000000000000003f7a, 66 chars bytes32. |
| Audit receipts | In | Reason code + builderCode + envelope ID, unmasked, on every order page. |
| Smart order router | Partial | Single-venue (Polymarket V2) for M2. Multi-venue M4+. |
Data & Ingestion
| Capability | M2 | Notes |
| Near-real-time book ingestion (WS market) | In | Auto-reconnect with backoff, staleness alerts. |
| Historical fill/price storage | In | Full universe; powers backtest. |
| RTDS (crypto/equity prices) | In | Stale-marked when feed lags. |
| WS user channel for fills | In | REST polling fallback. |
Governance & Audit
| Capability | M2 | Notes |
| Reason codes on every output | In | UPPER_SNAKE_CASE, registry-validated in CI. |
| Builder-attribution reconciliation | In | Source-of-truth for fee accounting. |
| Governance log (config change / override / reconciliation) | In | Immutable, append-only. |
| Config drift detector | In | Frozen-manifest CI check (109 bots). |
User onboarding
| Capability | M2 | Notes |
| Default settings per proficiency level | In | Customer-product side. |
| Lessons / educational materials | Partial | Starter set for M2, expanded M3. |
Technical readiness
| Capability | M2 | Notes |
| Private pre-production readiness | In | Cloudflare Access, security headers (already shipped on mock). |
| Basic SSDLC | In | Lint, CI verify, frozen-manifest, reason-code registry. |
| Load testing | In | WS + REST paths. |
| SLO / SLI / error budget / lag metrics | In | Per-bot, per-endpoint. |
| Client-data security baseline | In | Encryption at rest + in transit; key rotation. |
Explicitly not on the roadmap
- Copy-trading surfaces. Liquidity-Pulse and any similar internal model is for operators only; never exposed as a copy-trading product.
- Marketed performance claims / public track records. Backtest output stays operator-facing inside the strategy authoring surface.
- USDC.e support. pUSD only.
- V1 CLOB codepaths. V2 only;
CTFExchangeV2 only.
- Kalshi or other non-Polymarket venues. Out of scope for M2 and beyond unless re-scoped.
Shared non-negotiables
- V2 only. pUSD · CTFExchangeV2 · EIP-712 v2 · builderCode
0xb000000000000000000000000000000000000000000000000000000000003f7a.
- Audit receipts unmasked. Reason codes, builderCode and envelope IDs render in full on every receipt/wallet/config/registry page.
- INTERNAL banner on every mock-app page.
- 109 bot specs frozen. SHA-256 manifest enforces in CI.
- No copy-trading. No marketed performance claims.
Glossary deltas
The following terms were added to the glossary alongside this scope doc, so the rest of the guide can reference them: Bot (definition clarified), Backtest, Cluster, Market scope, Portfolio, Risk layers, score_type, strategy_score, Tenant, Watchlist.
Market scope — how a strategy chooses which markets to run on
A strategy binds to a Portfolio at launch. It also needs to know which markets within that portfolio's universe it should evaluate. M2 ships two modes; a third is deferred to M3.
| Mode | M2 | Behaviour | When to use it |
| Cluster binding (primary) |
In |
Strategy binds to one or more clusters. It evaluates every market currently in those clusters. As cluster membership evolves, the in-scope market set evolves with it. The Strategy Detail page shows a live count and a 10-row preview before launch. |
Default. Use this for any strategy expected to run across more than a handful of markets, including all momentum strategies in M2. |
| Manual list (fallback) |
In |
Operator hand-picks condition IDs via a searchable picker. Hard cap: 50 markets per strategy. The set is frozen at launch and only changes via an explicit edit (which writes a new audit envelope). |
One-off arbitrage, single-market test launches, narrow event coverage where the cluster is too broad. |
| Filter expressions (DSL) |
Deferred |
e.g. category = "election" AND liquidity > $50k AND days_to_resolution < 90. Strategy runs on whatever matches at evaluation time. |
M3, shipped with the scripting DSL so the syntax and lint rules are consistent. |
Audit and reason codes
- Every position the strategy opens records the market-scope mode and the resolved condition ID set at the moment of position open, on the audit envelope.
- New reason code:
STRAT_MARKET_IN_SCOPE — emitted when a market enters the strategy's evaluable set (either because it was added to a bound cluster, or because the manual list was edited).
- New reason code:
STRAT_MARKET_OUT_OF_SCOPE — emitted when a market drops out (cluster removal, manual de-selection, or market resolution).
- Existing codes (
STRAT_NO_EDGE, STRAT_EDGE_DETECTED, STRAT_PARAMETER_OUT_OF_DOMAIN) continue to apply within the in-scope set.
Backtest symmetry
Backtests apply the same scope rule retrospectively. A strategy bound to a cluster runs the backtest against the historical members of that cluster over the chosen window. A strategy on a manual list runs the backtest against exactly that list. Backtest and live evaluation must use the same scope semantics — this is a hard rule, not a convention, because it is what lets us trust a backtest as a sanity check rather than a marketing artefact.
What is explicitly out of scope for M2
- Mixed modes on a single strategy (cluster + manual override list). One mode per strategy in M2. M3 will likely allow include/exclude overrides on top of a cluster binding.
- Filter expression DSL. Ships with the scripting DSL in M3.
- Dynamic cluster authoring by operators. Clusters in M2 are read-only, automatic as stated in the headline scope above.
Open questions for the May review
- Confirm Momentum as the only strategy family in M2.
- Confirm Politics + Crypto as the only M2 market verticals.
- Confirm scripting DSL target (PineScript-style vs Python-subset) is an M3 decision, not M2.
- Confirm watchlists as view-only in M2 (no manual cluster editing).
- Confirm portfolio model as the unit of account (strategies launch into a portfolio).
Versioning. This page is the source of truth for M2 scope. Changes require a PR against generator/dev_pages.py :: render_m2_scope() and the date in the eyebrow updated.