9c3177e549
Introduces the Rust-owned core of Saved Fleets and the Reasoning Router as pure library modules, with no runtime call path yet. Everything here is parse/resolve/verify logic that later slices wire into the TUI. - `fleet_exact`: the exact Fleet schema. Routes are frozen — provider and model are literals, and the selector tokens that are legal elsewhere in CodeWhale (`auto`, `inherit`, `faster`, ...) are rejected by value, while `deny_unknown_fields` rejects `model_strength`/`loadout`/`model_class` as keys. Roles compare under one canonical key, so the `oracle`/`advisor` → `consultant` rename resolves in both directions. - `reasoning_router`: the saved Router service profile, addressable either as a named reference several Fleets can share or as a legacy inline router captured from an older file. - `fleet_reasoning`: requested → effective reasoning resolution, the Router call plan, and strict decision parsing. Parsing rejects trailing content, duplicate keys, and anything that would mutate a frozen route, so a malformed Router reply fails closed rather than silently re-routing. - `fleet_preflight`: endpoint identity and credential readiness, evaluated before any Router spend. - `fleet_snapshot`: content-addressed Fleet snapshots. Hashes are recomputed and validated on read, and no absolute path is ever captured. - `redaction`: the single chokepoint that strips secrets and absolute paths out of anything bound for a receipt. `named_fleet` gains `FleetSearchRoot`/`FleetDocument`/`load_by_name` and is committed together with the leaf modules rather than ahead of them: it imports `fleet_exact` and `fleet_snapshot`, and those import back, so the two halves do not compile apart. Two corrections to the harvested source: - `redaction` dropped a dead `arm` reset that `redact_token` overwrites before it can be read. Behavior is unchanged; the assignment only tripped `unused_assignments` under `-D warnings`. - `legacy_advisory_role_names_canonicalize_to_consultant` asserted that a lookup by the legacy spelling returns `None`, which contradicts both the module's stated contract and `member_by_role`, which canonicalizes the lookup key. The assertion now checks that both spellings land on the same member. This is a test fix, not a behavior change. Tests: 222 workflow lib tests, 16 exact_fleet_workflow integration tests.