Bot Framework Architecture

Module architecture for the bot framework in the Rust `rusty-marvin` project. Uses a **strategy framework** with hand analysis, modular strategy composition, and advanced cash-game bots — while keeping proprietary bot logic in a separate private crate.

---

## Goals

1. **Public/Private separation** — Advanced bots live in a private crate excludable from public mirrors
2. **Framework in `holdem_core`** — Traits, helpers, analysis tools remain public and reusable
3. **Idiomatic Rust** — Traits instead of interfaces, enums instead of inheritance, `Option` instead of null
4. **Minimal disruption** — Existing bots and engine code continue to work unchanged

---

## Workspace Structure

```
rusty-marvin/
├── Cargo.toml                    # workspace root
├── holdem_core/                  # PUBLIC crate — framework + simple bots
│   └── src/
│       ├── card.rs, deck.rs, board.rs, hand.rs, hole_cards.rs
│       ├── evaluator/            # 3-tier: Supersonic → Cactus Kev → Algorithmic
│       └── game/
│           ├── player.rs         # HoldemPlayer trait + Seat
│           ├── bot_factory.rs    # Plugin-style registration
│           ├── bots/             # CallBot, FoldBot, RaiseBot, RandomBot, FlockBot, ChumpBot, StrategyBot
│           └── strategy/         # Strategy trait, ModularStrategy, Context, Analyzer, Helper, Recorder
├── holdem_bots/                  # PRIVATE crate — advanced bots
│   └── src/
│       ├── lib.rs                # register_bots()
│       └── cash/                 # BigStackBot, ShortStackBot, PostFlopStrategy
├── holdem_sim/                   # simulation runner
└── docs/
```

---

## Key Traits and Relationships

### Strategy Trait
```rust
pub trait Strategy: Send + Sync {
    fn is_applicable(&self, context: &StrategyContext) -> bool;
    fn act(&self, context: &StrategyContext) -> Action;
}
```

### VotingMode Enum
```rust
pub enum VotingMode {
    FirstApplicable,  // First applicable wins
    Democratic,       // Majority vote
    Random,           // Weighted random
}
```

### ModularStrategy (Composite Pattern)
Contains `Vec<Box<dyn Strategy>>` + `VotingMode`. Implements `Strategy` trait.

### StrategyBot (Adapter)
Bridges `Strategy` trait → `HoldemPlayer` trait. Manages per-hand state (hole cards, action recorder).

### StrategyContext
Aggregated decision state: `GameInfo`, `HoleCards`, `ActionRecorder`, `aggressor_id`, `num_raises`, `num_callers`.

---

## Java → Rust Idiom Mapping

| Java | Rust | Notes |
|---|---|---|
| `interface Strategy` | `trait Strategy` | `Send + Sync` bounds |
| `ModularStrategy extends Strategy` | Struct implementing trait | Composition over inheritance |
| `BigStackStrategy extends ModularStrategy` | `BigStackBot` implementing `Strategy` directly | Flat delegation |
| `ModularStrategy implements HoldemPlayer` | `StrategyBot` wraps `Strategy` | Adapter pattern |
| `HandAnalyzer` singleton | `HandAnalyzer` with `Arc<Evaluator>` | `OnceLock` singleton |
| `null` | `Option<T>` | Idiomatic |

---

## Bot Factory: Plugin Registration Pattern

1. `holdem_core` handles built-in bots directly in `create_bot()` — zero overhead
2. `holdem_bots` exports `register_bots()` calling `register_bot_type()` for custom bots
3. `holdem_sim` calls `holdem_bots::register_bots()` behind `#[cfg(feature = "advanced-bots")]`

Dependency flows correctly: `holdem_sim` → `holdem_bots` → `holdem_core`

---

## Public vs Private Separation

**Public (holdem_core):** All traits, analysis tools, ModularStrategy, ActionRecorder, StrategyContext, StrategyBot, simple test bots, evaluator

**Private (holdem_bots):** BigStackBot, ShortStackBot, preflop strategy tables, PostFlopStrategy, future proprietary bots

Conditional compilation via `#[cfg(feature = "advanced-bots")]` in holdem_sim.

---

## Design Decisions

- **Strategy separate from HoldemPlayer:** Strategy is a decision interface; HoldemPlayer is a lifecycle interface. Allows composition and isolated testing.
- **StrategyBot adapter over ModularStrategy implementing HoldemPlayer:** Keeps strategy framework pure, manages per-hand state in one place.
- **Plugin registry over hardcoded match:** Allows holdem_bots to register without holdem_core knowing about it.
- **OnceLock over Lazy:** Already in std::sync, no extra dependency needed.

id: 659da65d964344fc89e6b4eafac0098c
parent_id: 2c8da247905946c3aa19eb4936e16323
created_time: 2026-05-31T10:37:02.827Z
updated_time: 2026-05-31T10:37:02.827Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1780223822827
user_created_time: 2026-05-31T10:37:02.827Z
user_updated_time: 2026-05-31T10:37:02.827Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
type_: 1