Тема
146: Restore maker-rebate strategy as layer
Identity
- Status: restoration design (open)
- Spawned from: F6 of ADR-024 pivot, 2026-05-13
- Original module:
crates/pm-bot/src/domain/strategies/maker_rebate.rs(~3703 LOC at archive) - Recovery:
git show 619f7f0:crates/pm-bot/src/domain/strategies/maker_rebate.rs+git show 619f7f0:crates/pm-bot/src/domain/strategies/shared/usdc.rs - Target taxonomy: split per ADR-018 —
directional::MakerRebateSingleSideprofile +binary-arb::PairedRebateprofile (per CLAUDE.md taxonomy + 4-base-algorithms memory; currently SUPERSEDED via feedback_directional_first_core; restoration would need user re-decision on whether to keep split or fuse) - Original ADR: ADR-011 (paired maker rebate emission, IMPLEMENTED → ARCHIVED-BY-024)
- Type: restoration
Context
Maker-rebate strategy emits passive maker orders to capture Polymarket's maker-rebate program. ADR-011 introduced paired YES+NO emission semantics with on-chain merge follow-up. Was production-deployed feature pre-ADR-024 pivot. Restoration must preserve paired emission semantics through ADR-025 Decision contract, without core engine modification.
Data model needs (from polymarket-data-model.md)
Market.tokens[0..2].best_bid/best_ask— both sides required for paired pathMarket.tick_size— paired orders must respect per-side tickMarket.neg_risk— informs whethermergePositions(CTF) ormergePositions(NegRiskAdapter) is target- Per-side orderbook depth for cheaper-leg single-side variant
Restoration scope
- New module:
crates/pm-bot/src/domain/strategies/maker_rebate.rs(layer crate or in-tree) - Both profiles:
MakerRebateSingleSide(cheaper-leg) ANDPairedRebate(YES+NO coordinated) - Implement
ScannerHooks+Strategytrait per ADR-025 - Shared utility: USDC arithmetic helpers (recover
shared/usdc.rsif not migrated) - Strategy config:
maker_rebate.*knobs (rebate_bps, paired_enabled, ladder rungs, etc.) - Add
StrategyType::MakerRebatevariant back + dispatcher branch - Config schema: new
crates/pm-bot/src/config/strategy/maker_rebate.rs(recover from 619f7f0)
Prerequisites
- ADR-025 ReadCtx pattern (existing).
- NEW Decision variant:
Decision::PairedPlacement { yes_order, no_order }— current Decision enum (post-F4.5) only has single-order placement; paired emission requires atomic coordination. Pre-restoration commit must add this variant + executor handler. - Merge follow-up may reuse existing
Decision::CallMergePositionsif present, else add. - pm-sdk: no new contract calls beyond existing
merge_positions/merge_positions_neg_risk. - Liveness/integration tests required: paired emission semantics regression test (was production feature; semantic regression test mandatory).
Out of scope
- Не модифицировать core engine за пределами ScannerHooks impls + new Decision variant.
- Не вводить новые traits в core layer.
- Не trash strategy isolation invariant.
Acceptance criteria
- ScannerHooks impl green per contract test pattern
- Paired emission regression test (YES + NO coordinated placement and cancellation)
- Single-side cheaper-leg integration test
- VERIFIED markers per
feedback_silent_feature_broken - ADR-011 amendment OR new ADR (post-024) confirming restoration semantics
Dependencies
- Decision::PairedPlacement variant (prereq sub-task; might be merged into this commit chain).
- Independent of #145 (maker) and #147 (merge-arb).
- Independent of #148 (bucket-arb), #149 (single-token-mm).
LOC estimate
- New strategy: ~2500-3500 LOC (originally 3703; slimmer via ReadCtx but paired logic complex)
- New strategy config: ~250 LOC
- Tests: ~600-900 LOC (paired semantics demands extensive coverage)
- Decision::PairedPlacement wiring: ~200-300 LOC
- Total: ~3500-5000 LOC
References
- ADR-024, ADR-025, ADR-011
- 619f7f0 (archive reference)
- docs/architecture/strategy-extension-points.md §8 (restoration sketches)
- CLAUDE.md taxonomy (ADR-018, 4-base-algorithms memory)