# Issue #1097 — Bannerlord M5 Sovereign Victory: Implementation

**Date:** 2026-03-23
**Status:** Python stack implemented — game infrastructure pending

## Summary

Issue #1097 is the final milestone of Project Bannerlord (#1091): Timmy holds
the title of King with majority territory control through pure local strategy.

This PR implements the Python-side sovereign victory stack (`src/bannerlord/`).
The game-side infrastructure (Windows VM, GABS C# mod) remains external to this
repository, consistent with the scope decision on M4 (#1096).

## What was implemented

### `src/bannerlord/` package

| Module | Purpose |
|--------|---------|
| `models.py` | Pydantic data contracts — KingSubgoal, SubgoalMessage, TaskMessage, ResultMessage, StateUpdateMessage, reward functions, VictoryCondition |
| `gabs_client.py` | Async TCP JSON-RPC client for Bannerlord.GABS (port 4825), graceful degradation when game server is offline |
| `ledger.py` | SQLite-backed asset ledger — treasury, fiefs, vassal budgets, campaign tick log |
| `agents/king.py` | King agent — Qwen3:32b, 1× per campaign day, sovereign campaign loop, victory detection, subgoal broadcast |
| `agents/vassals.py` | War / Economy / Diplomacy vassals — Qwen3:14b, domain reward functions, primitive dispatch |
| `agents/companions.py` | Logistics / Caravan / Scout companions — event-driven, primitive execution against GABS |

### `tests/unit/test_bannerlord/` — 56 unit tests

- `test_models.py` — Pydantic validation, reward math, victory condition logic
- `test_gabs_client.py` — Connection lifecycle, RPC dispatch, error handling, graceful degradation
- `test_agents.py` — King campaign loop, vassal subgoal routing, companion primitive execution

All 56 tests pass.

## Architecture

```
KingAgent (Qwen3:32b, 1×/day)
  └── KingSubgoal → SubgoalQueue
        ├── WarVassal (Qwen3:14b, 4×/day)
        │     └── TaskMessage → LogisticsCompanion
        │           └── GABS: move_party, recruit_troops, upgrade_troops
        ├── EconomyVassal (Qwen3:14b, 4×/day)
        │     └── TaskMessage → CaravanCompanion
        │           └── GABS: assess_prices, buy_goods, establish_caravan
        └── DiplomacyVassal (Qwen3:14b, 4×/day)
              └── TaskMessage → ScoutCompanion
                    └── GABS: track_lord, assess_garrison, report_intel
```

## Subgoal vocabulary

| Token | Vassal | Meaning |
|-------|--------|---------|
| `EXPAND_TERRITORY` | War | Take or secure a fief |
| `RAID_ECONOMY` | War | Raid enemy villages for denars |
| `TRAIN` | War | Level troops via auto-resolve |
| `FORTIFY` | Economy | Upgrade or repair a settlement |
| `CONSOLIDATE` | Economy | Hold territory, no expansion |
| `TRADE` | Economy | Execute profitable trade route |
| `ALLY` | Diplomacy | Pursue non-aggression / alliance |
| `RECRUIT` | Logistics | Fill party to capacity |
| `HEAL` | Logistics | Rest party until wounds recovered |
| `SPY` | Scout | Gain information on target faction |

## Victory condition

```python
VictoryCondition(
    holds_king_title=True,           # player_title == "King" from GABS
    territory_control_pct=55.0,      # > 51% of Calradia fiefs
)
```

## Graceful degradation

When GABS is offline (game not running), `GABSClient` logs a warning and raises
`GABSUnavailable`. The King agent catches this and runs with an empty game state
(falls back to RECRUIT subgoal). No part of the dashboard crashes.

## Remaining prerequisites

Before M5 can run live:

1. **M1-M3** — Passive observer, basic campaign actions, full campaign strategy
   (currently open; their Python stubs can build on this `src/bannerlord/` package)
2. **M4** — Formation Commander (#1096) — declined as out-of-scope; M5 works
   around M4 by using Bannerlord's Tactics auto-resolve path
3. **Windows VM** — Mount & Blade II: Bannerlord + GABS mod (BUTR/Bannerlord.GABS)
4. **OBS streaming** — Cinematic Camera pipeline (Step 3 of M5) — external to repo
5. **BattleLink** — Alex co-op integration (Step 4 of M5) — requires dedicated server

## Design references

- Ahilan & Dayan (2019): Feudal Multi-Agent Hierarchies — manager/worker hierarchy
- Wang et al. (2023): Voyager — LLM lifelong learning pattern
- Feudal hierarchy design doc: `docs/research/bannerlord-feudal-hierarchy-design.md`

Fixes #1097
