40ebf7c1e7
openfut-utas-host now classifies and owns three routes, wiring the landed adapter store_session state machine while keeping the Store economy Python's: - POST /ut/auth: proxy to Python (which mints X-UT-SID, adopts persona, refreshes save), OBSERVE the returned sid, and open a Rust session bound to peer IP + configured persona. Account/economy authority stays Python. - POST /openfut/fifa17/capability: Rust-owned, no proxy — validate + register into SessionStore (bound/pending/ignored-late); fail-closed 400 on unsupported. - GET .../store/purchasegroup: proxy to Python for the authoritative economy body, then overlay ONLY the empty-My-Packs topology from the frozen session mode — strip the 65534 sentinel for a verified clean-v1 SID, keep it otherwise. Rust never writes economy state. Session state (Arc<Mutex<SessionStore>> + monotonic clock) lives on Server; new() and from_config() initialise it (signatures unchanged). handle() gains a peer-IP variant (handle_with_ip) threaded from handle_conn. Strict never-both routing is preserved. Pure helpers (observe_sid, parse_capability_request, overlay_empty_mypacks) + classifier are unit-tested; adapter+host tests + Python A-R oracle all pass. STOP-GATE: Store BUY / coins / unopenedPackIds NOT migrated — Rust has no authoritative FIFA17 economy-mutation path (Python fut_profile.json is the source; Core's economy is separate/unwired), so moving BUY would split store authority. That cluster migration is the remaining R2 gap. No production deployment.