Тема
TD3-B — Maker-Rebate Hook Migration & LegacyStrategy Trait Removal
Historical sprint summary — TD3-B was completed 2026-04-21 (cutover). Archived under
docs/history/sprints/as a record of the finalLegacyStrategytrait deletion. Not a living doc.
Branch: worktree-agent-a1acabb6Baseline: 004b621 (RTDS R.12) Cutover date: 2026-04-21
Summary
TD3-B finishes the multi-sprint cleanup that started with TD3-A (bucket-arb hook authoritative). With this sprint:
- Maker-rebate's discovery + placement migrated to the
Strategy::evaluate_periodichook (MakerRebateStrategy), exactly reproducing the legacyOrderManager::discover_and_place+legacy::maker_rebate::evaluatepipeline (single-side cheaper-leg parity preserved per Phase 1 limitation). - The legacy
LegacyStrategytrait,Box<dyn LegacyStrategy>dispatcher,OrderManager::discover_and_place(~1397 LOC),place_bucket_arb_group_parallelhelper, and the entirestrategies::legacy/subtree were retired — every strategy now dispatches through the newStrategy+StrategyEnginepipeline exclusively. - The
bucket_arb_hooks_emit_decisionskill-switch flag (retained for one release cycle past TD3-A) was deleted along with its 3 gate sites, 2 unit tests, the simulator's legacyevaluate_events_for_pollshim, the 586-LOCe2e_hook_parity_replayharness, and 4 dependent simulator tests. There is no longer a legacy execution arm to roll back to.
Commits
| Commit | Step | What |
|---|---|---|
b1e7f7e | TD3-B.1 | Migrate maker-rebate paired-bid logic to evaluate_periodic hook |
bf29e85 | TD3-B.3 | Delete legacy/maker_rebate.rs evaluator |
201bc96 | TD3-B.4 | Delete LegacyStrategy trait + discover_and_place + Box<dyn> selector |
62b31cf | TD3-B.5 | Delete bucket_arb_hooks_emit_decisions flag + evaluate_events_for_poll shim |
(TD3-B.2 — new MakerRebatePlacementClient trait — was unnecessary; the maker-rebate hook emits Decision::PlaceOrder which already routes through the existing OrderClient::place_limit_order.)
LOC delta
| File | Delta |
|---|---|
crates/pm-bot/src/strategies/maker_rebate.rs | +570 / -32 |
crates/pm-bot/src/strategies/legacy/maker_rebate.rs | -395 (deleted) |
crates/pm-bot/src/strategies/legacy/mod.rs | -108 (deleted) |
crates/pm-bot/src/strategies/legacy/no_op.rs | -110 (deleted) |
crates/pm-bot/src/strategies/legacy/ (directory) | gone |
crates/pm-bot/src/order_manager.rs | -1397 (discover_and_place + place_bucket_arb_group_parallel) |
crates/pm-bot/src/scanner.rs | -45 (maker_loop arg cleanup, dispatch swap) |
crates/pm-bot/src/main.rs | -25 (selector + dry-run dispatch swap) |
crates/pm-bot/src/weather/context.rs | +72 (new — migrated from legacy/) |
crates/pm-bot/src/simulator/engine.rs | -190 (evaluate_events_for_poll shim) |
crates/pm-bot/src/config.rs | -45 (flag field, env parse, 2 unit tests) |
crates/pm-bot/tests/e2e_hook_parity_replay.rs | -586 (deleted) |
crates/pm-bot/tests/{strategy_partition,sync_order_status_rest_path,ws_fill_before_insert_race,bucket_arb_no_exit_sell}.rs | -16 (flag setters) |
Net LOC: ~ -2 277 LOC removed from pm-bot.
Test count
| Phase | pm-bot lib | Total (lib + integration + doctests) |
|---|---|---|
Baseline (RTDS R.12, 004b621) | 839 | ~942 |
| After TD3-B.1 | 847 | (+8 new periodic tests) |
| After TD3-B.3 | 834 | (-13 legacy maker-rebate tests) |
| After TD3-B.4 | 831 | (-3 no-op stub name tests) |
| After TD3-B.5 | 824 | 949 |
Net library delta: -15 (added 8 new functional tests, removed 23 tests for code that no longer exists).
Files removed
crates/pm-bot/src/strategies/legacy/maker_rebate.rscrates/pm-bot/src/strategies/legacy/mod.rscrates/pm-bot/src/strategies/legacy/no_op.rscrates/pm-bot/src/strategies/legacy/directorycrates/pm-bot/tests/e2e_hook_parity_replay.rs
Files added
crates/pm-bot/src/weather/context.rs—BotMarketSnapshot+WeatherContextmigrated from the deletedlegacy/module (sole consumer isbin/backtest.rs).td3-b-cleanup-report.md(this file).
Maker-rebate functional verification
- Unit: 7 new
periodic_testscover happy path (cheaper-side emission, tie-break to YES), dedup paths (open-order skip, filled-position skip, slug mismatch), neg-risk skip, combined-too-high skip, and live-orderbook override of cachedbest_bid. All green. - Webhook + RTDS: pre-existing
webhook_tests(3) + RTDS toxic-flow tests (4) continue green — preserved verbatim. - E2E: pm-bot is configured with
BOT_STRATEGY=maker-rebateto run the engine path;MarketCache+OrderManagerRepositoryare attached unconditionally inmain.rs. The firstengine.tick_periodic()fires fromscanner::maker_loopinitial discovery (replacing the legacy initialdiscover_and_place), then on every fallback scan (fallback_scan_secs) and every 10 s basket watchdog tick (idempotent under repository dedup).
Live-test status: not validated against production CLOB in this sprint — recommended before flipping to live trading. The hook emits Decision::PlaceOrder with the same shape the previous OrderManager::clob().buy(...) call produced (Side::Buy, OrderType::Gtd, post_only=true, gtd_seconds = config.gtd_expire_secs, size = floor(budget_per_market / price) capped at min 5 shares).
Phase 1 invariants
INV-5/6/7/20/21/22/23/25/26/27 (bucket-arb basket placement invariants) are unaffected. TD3-B.4 deleted OrderManager::discover_and_place and the bucket-arb-specific place_bucket_arb_group_parallel helper, but OrderManager::place_bucket_arb_from_fsm (the canonical primitive called by OrderManagerBucketArbPlacementClient from the hook path's Decision::PostBucketArbBasket) and cancel_basket_open_orders (called by OrderManagerAbandonClient on Decision::AbandonBasket) are kept verbatim.
Build / test status
cargo build -p pm-bot --release: GREEN (3 m 15 s, 0 warnings)cargo test -p pm-bot --lib: GREEN (824 / 824)cargo test -p pm-bot(full suite incl. integration tests + doctests): GREEN (949 / 949)
pm-orchestrator has a pre-existing NEG_RISK_ADAPTER_ADDRESS import error (5 errors) unrelated to TD3-B — verified by stashing this branch's diff and re-running the workspace check on baseline. That issue belongs to the orchestrator binary's own pm-sdk upgrade work and is out of scope here.
What remains for TD4 / future sprints
- TD4 (final rebuild) — operator-facing docs + .env.example cleanup pass, removal of stale rustdoc references to
discover_and_placeandLegacyStrategy(a handful of inline comments inorder_manager.rsmention them historically). - #16 live test — recommended pre-cutover validation of the maker-rebate hook path against production CLOB on a small capital allocation.
- Two-sided maker-rebate placement — current hook preserves the Phase 1 single-side parity (one cheaper leg per market). The
RebatePairstate machine inMakerRebateStrategyis wired but not yet driven; a future sprint can land paired YES + NO emission on top of the existing structure without disturbing the TD3-B contract. pm-weather::trading— the#![cfg(any())]-gated reference source still importssuper::{BotMarketSnapshot, Signal, Strategy}(preserved as-is per the file's docstring); rewire ontopm_commontypes when WeatherEdge gets re-introduced under the unifiedDirectionalstrategy.