diff --git a/docs/PROJECT_STATE.md b/docs/PROJECT_STATE.md index 3299c51..26d03bc 100644 --- a/docs/PROJECT_STATE.md +++ b/docs/PROJECT_STATE.md @@ -104,6 +104,26 @@ Last compiled from repository evidence during context initialization. (sometimes bulk `count=100`) — Core honours `offset` and terminates; the My Club UI nests team under league; the "~1900" club counter is Python `userMassInfo`, not `/club`. Remaining is operational only (promote the staged stack to a durable deployment). +- **Slice 7 (2026-08-12): FUT squad authority (read + write) RUNTIME VALIDATED on retail FIFA 17.** + Staged operator-assisted A/B (`.105` retail client → `.120`, source-scoped utas switch + `:8099→:8199` into `openfut-utas-host` over a staged `615c5fd` Core seeded by `seed-dev` with the + dev 33-card inventory). FIFA itself consumed the Rust squad path end-to-end: FUT boot served + `RUST_OVERLAY userMassInfo` (squad overlay) and the squad screen rendered the dev XI; a controlled + in-game squad edit issued `PUT …/squad/0` → host `squad-replace` → Core → `{"id":0}`; an in-game + formation change f442→f433 persisted to Core (canonical fingerprint changed, `position_index` + remapped 0–10); a FULL FIFA relaunch cold-fetched and rendered the persisted f433 squad (no client + cache). Reversibility proven on the exact client path by log presence, not response data (both + backends coincidentally hold the same dev squad — the Python oracle `fifa17_profile.json` was + seeded from the same `squad_put_f442.json` capture): disarmed `.105:8099` reached Python (absent + from host log), re-armed reached Rust (`route=club limit=Some(9)` present); the persistent identity + store survived the cycle with 0 reallocation. Non-migrated routes (`/ut/auth`, `account/sync`, + `accountinfo`, `settings`, `hub`, store txn) correctly Python-fallback. NEW startup requirement: + the Core server loads dev card defs only for games in env `OPENFUT_DEV_CONTENT_GAMES` (comma-sep); + omitting `fifa17` makes `get_collection` silently drop every owned card (empty `/collection`, + "no squad") despite a successful seed — MUST become a deployment/preflight assertion. Preceded the + same day by a staged two-process parity gate (real Core+host over HTTP, no FIFA) confirming byte- + shape parity of `userMassInfo.squad` vs the captured oracle. Next milestone: real-data Core + import / profile strategy → production Rust UTAS. Blaze deferred. ## Stubbed / planned