# Task 9: MstConnect Pass

**Depends on:** Task 6

## Context Files
- `.dev/2026-05-28-procgen-map-core/spec/design.md` — §4.7 (Connector role), §4.5 (ConnGraph), §5 (data flow).
- `.dev/2026-05-28-procgen-map-core/README.md` — inter-pass data contract (MstConnect row).
- `reikhelm-core/src/pass.rs` — `Pass`, `GenContext` (Task 6).
- `reikhelm-core/src/region.rs` — `Region`, `RegionKind::Room`, `ConnGraph`, `Edge` (Task 5).
- `reikhelm-core/src/passes/mod.rs` — append the module declaration here.

## Files
- Create: `reikhelm-core/src/passes/connect.rs` — `ConnectConfig`, `MstConnect`.
- Modify: `reikhelm-core/src/passes/mod.rs` — append `pub mod connect;` and re-export `MstConnect`, `ConnectConfig`.

## What to Build
A connector (spec §4.7) that decides **which rooms connect**, without carving anything. It reads the real `Room` regions — those with `kind == Room` **and non-empty `cells`** (an empty-`cells` Room is an uncarved leaf; see Task 8) — builds a minimum spanning tree over their centers (edge weight = distance between centers, e.g. Manhattan), then adds a configurable fraction of extra edges between nearby rooms to create loops (so the dungeon isn't a strict tree). Each connection is pushed to `ctx.graph` as an `Edge { a, b, at: None }` — the door location is filled later by `DoorPlacer`. Operates only on `ctx.regions`/`ctx.graph`; carves no tiles.

## Interface Dependencies
- **Consumes:** `Pass`, `GenContext`, `Rng` (Task 6); `Region`, `RegionKind`, `ConnGraph` (Task 5).
- **Produces:**
  - `struct ConnectConfig { extra_edge_ratio: f64 }` (+ `Default`; `0.0` = pure MST).
  - `struct MstConnect { /* holds ConnectConfig */ }` — `new(cfg) -> Self`; `impl Pass` with `name() == "mst_connect"`.
  - **Writes to context:** MST + extra edges in `ctx.graph`, all with `at: None`.

## Tests
- Given a `GenContext` with N (≥2) Room regions, after running: the MST portion has exactly N−1 edges and connects all rooms (graph is connected — verify by union-find/BFS over edges).
- `extra_edge_ratio: 0.0` produces exactly N−1 edges; a positive ratio adds the expected extra count.
- Every edge references valid `RegionId`s of `Room` regions and has `at == None`.
- A single room (N=1) produces zero edges without panic.
- Determinism: same seed/sub-stream → identical edge set.

## Success Criteria
- [ ] `MstConnect` builds a connected MST over room centers plus configurable loop edges, all with `at: None`.
- [ ] Carves no tiles; edge endpoints are valid Room region ids.
- [ ] `pub mod connect;` appended to `passes/mod.rs`.
- [ ] Tests pass: `cargo test -p reikhelm-core connect`

## Commit
`"feat(core): MstConnect pass"`
