Pam Production Readiness Brief - 2026-05-24
Executive readout
Pam is not ready for autonomous live trading.
The repository still contains a cross-venue Kalshi/Polymarket arbitrage path, but the current production-safe landing point is an observe, journal, alert, and manual-review system. Automated execution should remain disabled until exchange clients, order semantics, capital accounting, partial-fill handling, and deployment topology are corrected and verified against live canary tests.
Remediation pass - 2026-05-24
Code-level blockers unblocked:
- Kalshi client now uses the documented V2 balance, orderbook, order-status, positions, and event-order endpoints.
- Kalshi signed REST request support was added for
KALSHI_API_KEYplusKALSHI_PRIVATE_KEY_PATHorKALSHI_PRIVATE_KEY. get_market_orderbook()was added, unblocking overlap/liquidity evaluation.- Kalshi balance accounting now has explicit cents and dollars methods, and report callers use dollars directly.
- Polymarket dashboard pagination was added with public Gamma reads, so market discovery does not require trading auth.
- Polymarket account balance no longer returns a fake placeholder balance.
- Cross-venue live execution is gated behind
ALLOW_LIVE_ARBITRAGE_EXECUTION=1. - Production dashboard startup now requires explicit
SECRET_KEY,ADMIN_USERNAME, andADMIN_PASSWORD; Render no longer hardcodes the admin password. - Added
tools/production_canary.py, a reusable read-only canary for safety toggles, Kalshi balance/market/orderbook reads, Polymarket market/orderbook/collateral reads, and cross-venue capital split. - Local
.envdry-run safety was set toFORCE_DRY_RUN=1. render.yamlnow defines a separateunicorn-land-workerservice runningpython3 main.py run --dry-run, withFORCE_DRY_RUN=1and live arbitrage execution disabled.
Current post-fix verification:
- Full test suite: 222 passed.
python3 tools/production_canary.pywith.envloaded andFORCE_DRY_RUN=1: passed.tools/overlap_report.pyno longer has broken evaluation from a missing Kalshi orderbook method.- Latest overlap report still found 0 ranked candidates and 0 tradeable exact pairs.
- Capital split is currently Kalshi 100% / Polymarket 0%, so rebalancing remains an operational blocker before any cross-venue execution.
- Journaled opportunity scan refreshed the stale-scan blocker; candidate review currently has 2 deployable non-arbitrage review-gated candidates and 0 stale scan blockers.
- Scanner output now prefers Kalshi
ticker_nameover UUID market ids, and candidate review de-duplicates old UUID rows behind the executable ticker row for the same market title. - Deployment gating now blocks UUID-like exchange tickers with
exchange_ticker_is_uuid. - Added
tools/manual_trade_packet.pyto live-check one exact Kalshi ticker before any manual order discussion; it reports title, contract date, close/expiration, stale candidate status, and derived YES/NO bid/ask.
Where the arbitrage strategy stands
Pam is still looking at arbitrage between Kalshi and Polymarket in code:
main.pystill wiresrun_arbitrage_scan()toCryptoArbitrageScanner.scheduler.pystill has a recurring arbitrage scanning job.arbitrage/crypto_scanner.pystill implements inventory-backed Kalshi/Polymarket matching and near-pair review.tools/overlap_report.pystill evaluates cross-venue overlap.
The current live evidence does not support production auto-execution:
- Cross-venue inventory scan found 65 Kalshi and 24 Polymarket contracts in scope, matched 0 equivalent executable contracts, and found no arbitrage opportunities.
tools/overlap_report.pyfound one loose matched pair, but evaluation failed because the Kalshi client lacksget_market_orderbook. The pair also had weak equivalence and a large expiry mismatch, so it was not execution-grade.- Kalshi-only ladder scanning ran successfully against live data: 15 series, 24 events, 1,756 rungs, 0 monotone violations, 0 bucket violations.
- Research/candidate review is functioning as a gate. The latest review showed 0 deployable candidates and 2 review-only candidates blocked by stale scan age.
Practical landing point: keep cross-venue arbitrage as a research and discovery track, keep Kalshi ladder arbitrage as an alert-only scanner, and make Pam’s near-term production surface a monitored candidate-review system with no auto-execution.
Production blockers
-
Exchange API contracts are stale or incomplete. - Kalshi balance is currently requested from
/account/, but current Kalshi docs showGET /trade-api/v2/portfolio/balance. - Kalshi event-market order creation now usesPOST /trade-api/v2/portfolio/events/orderswith V2 fields such asticker,side,count,price, andtime_in_force. - Kalshi orderbook docs showGET /trade-api/v2/markets/{ticker}/orderbook; Pam’s overlap/liquidity code expects aget_market_orderbookmethod that does not exist inexecution/kalshi_api.py. - Polymarket discovery and trading are partly coupled to private-key CLOB auth. Public market/orderbook reads should not fail because trading credentials are absent or invalid. -
Live execution is not atomic enough for arbitrage. -
arbitrage/arbitrage_executor.pyhas a placeholder branch for real order placement in_place_order_with_retry. - Two-leg execution is sequential and partial-fill recovery is not a real hedge/unwind workflow. - Polymarketplace_order()returnspending, while the executor checks forfilled, so live status semantics are inconsistent. -
Capital and balance checks are not production-grade. - Kalshi balance lookup failed with a 404 during the sweep. - Polymarket account balance returns a placeholder value. - The overlap report could not compute a reliable capital split.
-
Journaling and review freshness need tightening. - A fresh
trade-candidates --no-journalscan produced current rows in output, but candidate review still read stale journaled rows and blocked them withscan_age_sec>900. - Production candidate review needs a single source of truth for scan freshness. -
Deployment is web-only. -
render.yamlstartsgunicorn app:app. - There is no separate production worker service for schedulers, research loops, overlap watchers, or ladder daemons. -
Dashboard and secrets need hardening. -
app.pystill has fallback admin credentials and a fallback secret key. -render.yamlsets a static admin username/password. - Dashboard code references Polymarket methods that do not exist on the current client. -
Dry-run/live separation needs cleaner accounting. - Status and dry-run flows can create arbitrage trade records, so headline counts do not clearly separate simulated, review, paper, and live executions.
Recommended production shape
Phase 1 should be production monitoring, not trading:
- Run the web dashboard and a separate worker process.
- Force dry-run globally with
FORCE_DRY_RUN=1. - Journal every opportunity scan, ladder scan, near-pair review, and candidate-review decision.
- Send Telegram alerts only for reviewable or structurally interesting opportunities.
- Add canary tests for Kalshi balance, orderbook, create-order dry validation if available, and Polymarket public reads/private order signing.
- Add explicit mode/status fields for
scan,paper,manual_review,live_attempted, andlive_filled.
Phase 2 can add manual approvals:
- Correct exchange clients to current official endpoints.
- Implement real balance/allowance checks.
- Add fill-or-kill or immediate-or-cancel semantics where supported.
- Add real partial-fill handling and automated cancellation/unwind logic.
- Require a human approval token before any order reaches an exchange.
Phase 3 is automated execution, only after live canaries and manual approvals have run cleanly for a sustained period.
Verification performed
python3 -m pytest: 217 passed.python3 main.py status: app configured with live trading enabled, test mode enabled, real API disabled, arbitrage enabled.python3 main.py research-status: research gate confident, candidate review gate ready, 0 deployable candidates.python3 main.py opportunity-scan --limit 2 --no-journal: 2 review/watch candidates, no deployable trade.python3 main.py trade-candidates --limit 2 --no-journal --recent-runs 6 --max-per-state 3: 0 deployable, 2 review-only, both stale by scan-age gate.python3 main.py arbitrage scan --max-resolution-days 30 --near-pair-limit 3: no arbitrage opportunities found.python3 -m arbitrage.kalshi_ladder_scanner: 0 ladder violations found.python3 tools/overlap_report.py: 1 loose pair, 0 ranked candidates, broken evaluation due missing Kalshi orderbook method.
Primary source checks
- Kalshi API environments: https://docs.kalshi.com/getting_started/api_environments
- Kalshi balance endpoint: https://docs.kalshi.com/api-reference/portfolio/get-balance
- Kalshi orderbook endpoint: https://docs.kalshi.com/api-reference/market/get-market-orderbook
- Kalshi V2 event order endpoint: https://docs.kalshi.com/api-reference/orders/create-order-v2
- Polymarket CLOB overview: https://docs.polymarket.com/developers/CLOB/trades/trades-data-api
- Polymarket create order docs: https://docs.polymarket.com/developers/CLOB/orders/create-order
- Polymarket fees: https://docs.polymarket.com/polymarket-learn/trading/fees