Тема
Production-Readiness Sweep — 2026-05-03
Snapshot of pm-bot production-readiness status as of commit
fe880bc(post-X2.4 WebUI configurator), refreshed by the X2.5 final-closure sweep on 2026-05-03.Purpose: single artefact an operator (or future agent) can read to answer "is the binary ready for live operation, what are the open known limitations, and where do I look next." Companion to the per-section
production-readiness-checklist.md(operator pre-flight) andtech-debt-backlog.md(per-row history). This document is the summary; the other two are the operator manual and the engineering log.
1. Verdict
READY for sustained 24/7 production on any of the 5 active strategies (bucket-arb, directional, maker, maker-rebate, merge-arb), single- or multi-wallet, single- or multi-strategy-via- process-restart. All correctness invariants are test-covered, the operator tooling is feature-complete, and the open backlog is empty (deferred-roadmap rows excepted — those are gated on empirical production signals rather than further implementation).
Tier upgrade (X2.5, this sweep). The two-tier "MVP-capable" vs "full operator-tooling" framing introduced by the 2026-05-03 user-decision sweep is collapsed: the upper tier shipped end-to-end across X1 (TD-27 dashboard rebuild) → X2 (FE-1 multi-wallet + FE-2 SQLite strategy config + FE-5 budget predicate + X2.4 WebUI configurator) → X3 (TD-2/TD-3/TD-4 strategy bug-fix bundle) → X4 (TD-5 stress-test re-port) → X5 (TD-7 paired maker-rebate emission) → X6 (cleanup batch — Headless MetricsTick / OrderClient struct migration / //! docs full coverage). The original lower-tier scope (single-strategy / single-wallet via .env, TUI primary, dashboard wallet-explorer + /local route as observability) is still fully supported as the legacy path — the new selector env vars (BOT_WALLET_LABEL, BOT_STRATEGY_LABEL) are semantic-Optional and unset ⇒ trading hot path bit-identical to pre-X2 behaviour.
| Tier | Scope | Status |
|---|---|---|
| Sustained production-ready (collapsed from prior two tiers) | Single- or multi-wallet, single- or multi-strategy-via-process-restart, TUI + Vue 3 SPA dashboard with cancel UI / risk widgets / configurator, encrypted wallets store + plaintext strategy-config store, FE-5 budget predicate, paired maker-rebate emission, alerts engine, journal retention | READY 2026-05-03 (X2.5) |
Open items list — empty. The implementation queue in tech-debt-backlog.md holds zero rows for the first time since the file was created. The active backlog reduces to the deferred-to-roadmap set (FE-3 multi-strategy per process, FE-4 declarative Condition rule engine, FE-5 reinvestment toggle) — each gated on empirical signals from a production cycle rather than further design or implementation work.
History trace (rows that stood open before X2.5 and shipped during the X1+X2+X3+X4+X5+X6 chain):
- TD-2 / TD-3 / TD-4 — RESOLVED 2026-05-03 (X3 strategy bug-fix bundle, commit
02a6fb0). - TD-5 — RESOLVED 2026-05-03 (X4 stress-test re-port, commit
f6e5fa9; +14 lib tests, 966 → 980). - TD-7 — RESOLVED 2026-05-03 (X5.1..X5.4 paired maker-rebate emission; ADR-011 + paired runbook + sprint summary; +33 lib tests, 980 → 1014).
- TD-27 — RESOLVED 2026-05-03 (X1.0..X1.5b dashboard rebuild + X2.4 configurator surface; ADRs 012/013/014/015 §D8/D9; 12 → 28 pm-dashboard integration tests).
- FE-1 / FE-2 / FE-5 — RESOLVED 2026-05-03 (X2.2..X2.3 multi-wallet store + SQLite strategy config + budget predicate; ADR-015; +57 lib tests, 1014 → 1071; +27 pm-cli integration tests).
- Headless MetricsTick ingest / Phase 5.6.2 OrderClient struct migration /
//!docs full coverage — RESOLVED 2026-05-03 (X6 cleanup batch, commita611c35; supplemented by N5/N6 polish ine53b73b).
The deferred-to-roadmap rows remain unchanged from the user-decision sweep:
- FE-3 multi-strategy per process — picks up after operators exercise FE-1/FE-2/FE-5 in production for one cycle. Architecture ADR will draw on the archived pm-orchestrator design (multi-strategy execution shape).
- FE-4 declarative
Conditionrule engine — picks up after FE-2 + WebUI configurator are battle-tested. Pre-existing implementation in archived pm-orchestrator; salvage path is port + operator validation pass, no design work needed up-front. - FE-5 reinvestment toggle — backlog only; defer until empirical data from base FE-5 in production for at least one cycle.
The 2026-05-03 user-decision sweep removed never-requested items (TD-15 / TD-16 / TD-25 / TD-26 / testnet row / Telegram + SMTP backends — earlier cleanup commit 9fe2e5f) and bundled four Tier-3 polish rows under TD-27 (closed in X1). Nothing in the deferred-to-roadmap set blocks production.
2. Build / test status
Workspace at commit fe880bc (X2.4 — WebUI configurator):
| Check | Status | Notes |
|---|---|---|
cargo check --workspace | green (cached) | 6 crates: pm-common, pm-cli, pm-sdk, pm-bot, pm-bot-events, pm-dashboard |
cargo build --workspace --release | green | release binary ~19 MB |
cargo clippy -p pm-bot -p pm-sdk -p pm-bot-events --lib | 0 warnings | TD-23 swept the prior 43-warning batch in N4 polish; preserved through X1+X2+X3+X4+X5+X6 |
cargo test -p pm-bot --lib | 1071 passed / 0 failed / 1 ignored | X2.5 baseline (899 → 1071: +14 X4 + +33 X5 + +57 X2.2 + +68 across X3/X6/N4..N7) |
cargo test -p pm-cli --tests | 27 passed / 0 failed | X2.3 introduced the suite covering all 7 pm-cli strategy subcommands + audit invariants |
cargo test -p pm-dashboard --tests | 28 passed / 0 failed | X2.4 grew the suite from 12 to 28 (FE-1 + FE-2 REST endpoints + FE-5 422 reject path coverage) |
cargo test -p pm-sdk --lib | 18 passed / 0 failed | unchanged across the X-chain |
cargo test -p pm-bot --tests | 1066+ passed / 0 failed / 16 ignored | load tests + smoke harnesses (counts unchanged from N7 baseline) |
cargo doc --workspace --no-deps | clean | TD-24 fixed rtds_probe.rs HTML-tag rustdoc warning in N5; the //! docs full-coverage row in X6 closed remaining gaps |
The 1 ignored lib test is intentional (slow / network-bound); the 16 ignored integration tests are smoke harnesses gated behind operator flags (--smoke-rtds, --smoke-webhook).
Workspace test total: 1144 (1071 pm-bot lib + 27 pm-cli + 28 pm-dashboard + 18 pm-sdk lib), all green; 0 clippy warnings; trading hot path bit-identical to pre-X2 (every test added in X2.2..X2.4 is additive against the new multi-wallet / config-store / configurator surface; the env path itself touches no production code on the hot path — confirmed by the 1014 → 1071 baseline preservation).
3. Operator handbook (entry-point)
| Need | Doc |
|---|---|
| Pre-flight checklist | production-readiness-checklist.md |
| Strategy / RTDS smoke procedure | smoke-test-runbook.md |
| Dashboard smoke procedure (UI widgets, X1.5b) | dashboard-smoke-runbook-2026-05-03.md |
| Multi-wallet smoke procedure (configurator surface, X2.5) | multi-wallet-smoke-runbook-2026-05-03.md |
Multi-wallet migration runbook (.env → SQLite, X2.5) | multi-wallet-migration-runbook-2026-05-03.md |
| RTDS toxic-flow activation | rtds-cutover-runbook.md |
| Local-Bot dashboard mode | local-dashboard-runbook.md |
| Paired maker-rebate activation (TD-7) | paired-maker-rebate-runbook-2026-05-03.md |
| Alerts engine + custom rules / sinks (TD-12) | alerts-2026-05-03.md |
| Journal retention / GC (TD-11) | journal-retention-2026-05-03.md |
| DB / journal clean rewrite | db-clean-rewrite-2026-05-03.md |
| Env var reference | env-reference.md |
| Rate limits (CLOB, Gamma) | rate-limits.md |
| Replay parity methodology | replay-parity-methodology.md |
| Backlog triage / next item | backlog-triage-2026-05-03.md |
| Per-row TD history | tech-debt-backlog.md |
| Worktree cleanup helper | scripts/cleanup-worktrees.sh (TD-8 RESOLVED 2026-05-03) |
ADR set:
| ADR | Topic |
|---|---|
adr-006-archive-extraction.md | Archived crate set (12 → 6) |
adr-007-pm-bot-modular-restructure.md | Domain / application / IO split |
adr-008-config-split-per-strategy.md | Per-strategy config modules |
adr-016-timezone-handling-policy.md | Midnight-to-midnight time policy |
adr-010-order-client-trait-unified.md | Order placement trait + dry-run adapter |
adr-011-paired-maker-rebate-emission.md | TD-7 paired maker-rebate emission (Accepted 2026-05-03 X5.1; shipped X5.2..X5.4) |
adr-012-pm-dashboard-redesign.md | TD-27 pm-dashboard redesign (backend + Vue 3 SPA split, finalized 2026-05-03 X1.0) |
adr-013-dashboard-cancel-ui-invariants.md | Dashboard cancel UI invariants (X1.5a — soft-delete + paranoid bulk gate) |
adr-014-dashboard-risk-metrics.md | Dashboard risk metrics lock-in (X1.5b — Sharpe / Sortino / max drawdown) |
adr-015-multi-wallet-and-strategy-config.md | Multi-wallet (FE-1) + SQLite strategy config (FE-2) + budget predicate (FE-5) + WebUI configurator surface (X2.4); Accepted 2026-05-03 X2.1 |
merge-arb-strategy.md | merge-arb v2 design + on-chain merge |
phase-5-scanner-fsm-extraction.md | Scanner / FSM extraction |
pm-bot-dashboard-integration.md | ADR-005 Local-Bot Mode |
rtds-integration.md | RTDS integration + 12-question resolution |
strategy-isolation-design.md | Strategy trait + Decision pipeline |
webhook-signal-source.md | ADR-003 webhook signal source |
4. Deployment
Native cargo (recommended)
Production binary path:
sh
cargo build --workspace --release
target/release/pm-bot --strategy <bucket-arb|directional|maker|maker-rebate|merge-arb> \
--env env/.env.<preset>Companion processes (optional):
sh
target/release/pm-dashboard # web UI on :31337
target/release/pm-cli <subcommand> # init / wrap / approve / redeem / cancel-all / sell-allDocker
docker-compose.yml and docker-compose.prod.yml exist for the historical multi-service deployment, but the current 6-crate workspace does not require external services for trading. pm-bot runs as a single self-contained binary: SQLite for journal, no Valkey, no trading-api, no market-data daemon (those crates were archived 2026-05-02 — see ADR-006). Use Docker only if the operator wants the dashboard in a container.
5. Required env vars (fail-fast)
BotConfig::validate_required_env_or_panic enforces that every [REQUIRED] line in env/.env.example (112 lines) is set. Missing values abort startup with a single panic listing every missing key.
Strategy-conditional blocks are surfaced lazily after BOT_STRATEGY parses, so operators may need a second dry-run pass after picking a strategy:
| Block | Activated by |
|---|---|
BUCKET_ARB_* | BOT_STRATEGY=bucket-arb |
MAKER_REBATE_* | BOT_STRATEGY=maker-rebate |
DIRECTIONAL_* | BOT_STRATEGY=directional |
MAKER_* | BOT_STRATEGY=maker |
MERGE_ARB_* | BOT_STRATEGY=merge-arb |
WEBHOOK_* | WEBHOOK_ENABLED=true |
RTDS_* | always required |
BOT_LOCAL_API_* | BOT_LOCAL_API_ENABLED=true (other 3 vars apply defaults rather than fail-fast — see ADR-005) |
Public optional defaults (NOT in fail-fast list):
WEATHER_API_KEY— built-in public Weather Underground free-tier keyBUCKET_ARB_AUTOSELL,BOT_TOTAL_BUDGET,POLYGON_RPC_URL,WEBHOOK_IP_ALLOWLIST,MARKET_*_FILTER— semantic-Optional,Nonemeans feature offBOT_LOCAL_API_*(Local-Bot Mode, ADR-005) — opt-in observability layer;BOT_LOCAL_API_ENABLED=false(default) ⇒ trading hot path bit-identical to pre-integrationBOT_WALLET_LABEL/BOT_STRATEGY_LABEL(multi-wallet selectors, ADR-015) — opt-in. Unset ⇒ legacy.envpath bit-identical. WhenBOT_WALLET_LABELis set,WALLETS_MASTER_PASSPHRASEMUST be set and non-empty (fail-fast atcrates/pm-bot/src/main.rs:112-116). When BOTH selectors are set, INV-3 enforces that the strategy row'swallet_labelequalsBOT_WALLET_LABEL(fail-fast atcrates/pm-bot/src/main.rs:210-228).BOT_WALLETS_DB_PATH/BOT_CONFIG_DB_PATH(multi-wallet store paths, ADR-015) — semantic-Optional. Default./wallets.db/./config.dbresolve relative to pm-bot's working directory. Recommended deployment override:/etc/pm-bot/wallets.db(mode 0600) and/etc/pm-bot/config.db(mode 0644).MAKER_REBATE_PAIRED_ENABLED(TD-7 paired emission, ADR-011) — defaultfalsepreserves Phase 1 single-side parity bit-for-bit. Activation runbook:paired-maker-rebate-runbook-2026-05-03.md.
6. Open known limitations
The implementation queue is empty as of X2.5 (2026-05-03). The active backlog reduces to the deferred-to-roadmap rows below — each gated on empirical signals from a production cycle, not on further design or implementation work.
Implementation queued — empty
The X1+X2+X3+X4+X5+X6 sprint chain shipped every previously-queued row. History trace lives in tech-debt-backlog.md "Resolved / obsolete (kept for traceability)" table — TD-2 / TD-3 / TD-4 / TD-5 / TD-7 / TD-27 / FE-1 / FE-2 / FE-5 / Headless MetricsTick / OrderClient struct migration / //! docs full coverage all carry RESOLVED rows with commit hashes.
Production-critical resolved within prior sweeps
- TD-11 auto-prune retention — RESOLVED 2026-05-03. Auto-prune scheduler +
pm-cli journal gcprimitive shipped; seejournal-retention-2026-05-03.md. - TD-12 alerts — RESOLVED 2026-05-03. Engine +
LogSinkbaseline shipped; seealerts-2026-05-03.md. - TD-18 metrics_loop wiring — RESOLVED 2026-05-03;
tokio::spawnnext tolocal_api::serveconfirmed live SSE 1Hz cadence. - TD-21 RTDS observability, TD-23 clippy sweep, TD-24 rustdoc HTML-tag — all RESOLVED in N3..N5 polish batch.
- TD-7 paired maker-rebate emission — RESOLVED 2026-05-03 in X5.1..X5.4. ADR-011 + paired runbook (
paired-maker-rebate-runbook-2026-05-03.md). DefaultMAKER_REBATE_PAIRED_ENABLED=falsepreserves single-side parity bit-for-bit. - TD-27 dashboard UI redesign — RESOLVED 2026-05-03 in X1.0..X1.5b + X2.4. ADRs 012 / 013 / 014 + ADR-015 §D8/D9. 28 pm-dashboard integration tests (was 12 pre-X2.4). Dashboard smoke runbook (
dashboard-smoke-runbook-2026-05-03.md) for trading widgets and multi-wallet smoke runbook (multi-wallet-smoke-runbook-2026-05-03.md) for the configurator surface. - FE-1 / FE-2 / FE-5 — RESOLVED 2026-05-03 in X2.2..X2.3. ADR-015. Migration runbook (
multi-wallet-migration-runbook-2026-05-03.md) documents the.env→wallets.db+config.dbpath. 27 pm-cli integration tests.
Deferred to roadmap with documented architecture
- FE-3 multi-strategy per process — gated on operators exercising FE-1 + FE-2 + WebUI configurator in production for one cycle. Architecture: parent strategy manager + per-strategy child processes
- wallet selection. Salvage path documented from archived pm-orchestrator.
- FE-4 declarative
Conditionrule engine — gated on FE-2 SQLite config + WebUI configurator being battle-tested. Pre-existing implementation in archived pm-orchestrator (25+ leaf-condition enum); salvage path is port + operator validation pass, no design work needed up-front. - FE-5 reinvestment toggle — backlog only; base FE-5 budget-limit predicate shipped. Defer until empirical data from base FE-5 in production for at least one cycle.
Removed in cleanup (never user-scoped)
TD-15 (CSV / Parquet export), TD-16 (multi-wallet aggregation as separate feature — subsumed by FE-1, now RESOLVED), TD-25 (Telegram backend), TD-26 (SMTP backend), testnet validation row, Telegram / SMTP backends — all deleted in cleanup commit 9fe2e5f. Listed here for completeness only.
7. Operator escalation procedure
The alert engine (TD-12) provides structured tracing lines for critical events via LogSink. Escalation flow:
- Soft alert (P&L drift, fill-rate degradation): operator monitors pm-dashboard
/localroute (whenBOT_LOCAL_API_ENABLED=true) or the TUI directly. Thedrawdown_thresholdandposts_err_spikerules surface aswarn!log lines when their thresholds trip. - Hard alert (emergency stop, repeated rejection cluster): the
emergency_stoprule emits anerror!log line; theMetricsTickSSE stream emitsis_emergency=true(Phase 7c schema). Operator polls or watches the/api/local/streamendpoint. - On-chain alert (wallet drained, suspicious tx): out-of-band — block explorer / RPC monitoring.
The AlertSink trait is public; an operator who needs to fan alerts into an external system (e.g. log aggregator with paging) can implement it in a side crate / fork — see alerts-2026-05-03.md "Custom rules + sinks".
8. Rollback procedure
Trading is fully reversible via env restart — no schema migration, no on-chain state to roll back.
- Kill switch:
pkill pm-bot(or systemd / supervisor stop). - Cancel open orders:
cargo run -p pm-cli -- cancel-all --private-key $KEY. - Sell open positions (if needed):
cargo run -p pm-cli -- sell-all --private-key $KEY(FOK at best bid). - Redeem resolved positions:
cargo run -p pm-cli -- redeem --all --private-key $KEY --rpc-url $RPC. - Restart with safe defaults: re-launch with
BUCKET_ARB_IMMEDIATE_FILL_ENABLED=false,RTDS_TOXIC_FLOW_ACTIVE_CANCEL_ENABLED=false,RTDS_TOXIC_FLOW_LOG_ONLY=true,WEBHOOK_ENABLED=false,BOT_BUDGET_PER_MARKET=5.
The journal SQLite (pm-bot.sqlite) is forward-compat across sessions — a restart creates a new bot_sessions row but does not disturb prior state. Hard reset: stop the binary + delete the SQLite file (operator-conscious — destroys session history).
9. Sign-off (X2.5 — final closure)
- [x] Build green (
cargo check --workspace). - [x] Tests baseline preserved and grown additively: 1071 pm-bot lib (1 ignored) + 27 pm-cli integration + 28 pm-dashboard integration + 18 pm-sdk lib = 1144 tests workspace-wide, all green. Trading hot path bit-identical (the
1014 → 1071lib delta is purely additive against the new multi-wallet / config-store / configurator surface). - [x] Clippy clean (0 warnings on pm-bot, pm-sdk, pm-bot-events).
- [x] Tier 1 sweep landed (TD-1 + TD-17 OBSOLETE marks; TD-6 + TD-8 RESOLVED;
scripts/cleanup-worktrees.shshipped + smoke-tested). - [x] Tier 2 documentation landed (FSD bucket-arbitrage immediate-fill block extended with TD-2 / TD-3 / TD-4 operator-facing limitations; production-readiness checklist refreshed with current numbers).
- [x] Tier 5 sweep doc (this file) created.
- [x] Cleanup pass (post-Tier-3): never-requested rows removed (TD-15 / TD-16 / TD-25 / TD-26); TD-12 marked fully RESOLVED.
- [x] Post-user-decision sweep (2026-05-03) — 5 rounds of
AskUserQuestionconsolidating every open and deferred row. Outcome- sprint sequencing recorded; coding unblocked.
- [x] TD-27 X1.0 — ADR-012 landed (585 LOC, Accepted). Scope finalized via 4 AskUserQuestion rounds.
- [x] X1 dashboard rebuild — RESOLVED 2026-05-03. X1.1 frontend scaffold (
9d8ddc9) → X1.2 backend REST (b76c1a2) → X1.3 Pinia + SSE (cabe6c9) → X1.4a darkPreset + PnL chart + WalletView (4db95fb) → X1.4b chunks + Compare + persist + events + retire (47bb95a) → X1.5a cancel UI hardening + ADR-013 (305cd75) → X1.5b risk widgets + ADR-014 (21a853d). - [x] X2 multi-wallet + SQLite config — RESOLVED 2026-05-03. X2.1 ADR-015 (
94bbbf5) → X2.2 FE-1 encrypted multi-wallet store (0f2978f) → X2.3 FE-2 SQLite strategy config + FE-5 budget predicate (33b0402) → X2.4 WebUI configurator (fe880bc) → X2.5 final closure docs (this revision). - [x] X3 strategy bug-fix bundle — RESOLVED 2026-05-03. TD-2 + TD-3
- TD-4 shipped as a single bundle (
02a6fb0).
- TD-4 shipped as a single bundle (
- [x] X4 stress-test re-port — RESOLVED 2026-05-03. TD-5 14 ST-0* invariants re-authored against
BucketArbStrategy::on_ws_bookhookMockRepository(f6e5fa9).
- [x] X5 paired maker-rebate emission — RESOLVED 2026-05-03. TD-7 ADR-011 + pure evaluator + state machine + runbook (
4185085→184257c→32cc2a6→af105b3). - [x] X6 cleanup batch — RESOLVED 2026-05-03. Headless MetricsTick ingest + Phase 5.6.2 OrderClient struct migration +
//!docs full coverage (a611c35+ N4..N6 polish frome53b73b). - [x] X2.5 final closure docs (this revision):
multi-wallet-migration-runbook-2026-05-03.md(537 LOC) +multi-wallet-smoke-runbook-2026-05-03.md(28-probe smoke) + tech-debt-backlog rows for FE-1/FE-2/FE-5/ TD-7/TD-27 closed in the resolved table + this verdict block upgraded to READY for sustained 24/7 production. - [x] Implementation queue empty. First time since the file was created. Active backlog reduces to deferred-to-roadmap rows (FE-3 / FE-4 / FE-5 reinvestment toggle), each gated on empirical production signals.
End of sweep — workspace is production-ready.