Files
OpenFUT/docs/PROJECT_STATE.md
T

10 KiB

OpenFUT — Project State

Canonical source: ../OpenFUT-Vault/06 Agent Memory/Project State.md This file is a mirror. If the two disagree, the vault wins. Update the vault first.

Factual snapshot. Prefer this over the stale root README.md/CLAUDE.md status tables (FIFA 23). Last compiled from repository evidence during context initialization.

Working

  • FIFA 17 offline FUT stack, end-to-end. Proven 2026-08-01: auth → Blaze login → device-trust → the FUT hub. Brought up by fifa17-recon/tools/openfut-fut.sh start. Evidence: FUT-RUNBOOK.md, fifa17-recon/README.md, the five responder scripts, gate-ladder troubleshooting table.
  • ProtoSSL cert-pin defeat — two live /proc/PID/mem patches (autopatch.py), VAs stable across launches. gdb-verified which gate was the wall.
  • LSX / Origin layer — crypto handshake reversed byte-exact and confirmed against the repack's own emu disassembly (docs/REPACK_INTEL.md); Origin login gates cleared.
  • Blaze redirector + Fire2/Heat2 — both hops defeated; preAuth/login/personas answered.
  • UTAS/RS4 FUT APIut/auth + boot calls + device-trust reach the hub with hand-authored JSON.
  • Persistent FIFA 17 account selection — the launcher synchronizes one configured EA persona to the Python backend before starting LSX/FIFA. LSX, Blaze, POW/EASFC, and UTAS then share that identity, while FUT coins, inventory, squads, progression, and unopened packs persist in an isolated save beneath fifa17-recon/docker/state/accounts/<persona-id>/. The POW level/XP/funds shown in FIFA's general account bar are account-scoped but remain distinct from FUT club coins. A reversible server test on 2026-08-09 verified profile switching, POW values, a 400-coin pack debit, five awarded items, and restoration of the original profile.
  • Account-scoped FUT security compatibility — launcher account synchronization initializes a persisted securityQuestion verification record in that persona's FIFA 17 profile. The UTAS PHISHING handler returns the complete CardsDLL trusted-console response (changed, exists, locked, trusted), accepts only well-formed legacy setup/validate requests under X-UT-SID, and never stores or logs the client-transformed answer. This is server-side emulation; the hook and launcher do not contain an answer or add UI automation. Automated contract coverage is in fifa17-recon/docker/ctx/tools/test_security_question.py; live first/repeat-launch acceptance is partially complete: the first launch entered FUT without a security dialog on 2026-08-09; a second fresh-process FUT entry is still required to close persistence acceptance.
  • Safe responder diagnostics — ordinary LSX logs redact challenge/session/auth-code attributes; ordinary Blaze logs redact auth/session keys and no longer emit raw Fire2 hex, decoded TDF, or config values. Forensic Blaze capture remains available only with the explicit OPENFUT_BLAZE_DUMP_FRAMES=1 opt-in. LSX and Blaze self-tests cover the new defaults.
  • OpenFUT Core — Rust FUT economy backend, feature-complete for its scope and tested: profiles, clubs, coins, packs, cards, squads, chemistry styles, SBCs, objectives, matches, market (NPC), draft, FUT Champs, seasons, statistics, achievements, events, daily check-in, division leaderboard, market trade history. 13 migrations. Integration suite (tests/integration_test.rs, 96 test fns) runs against in-memory SQLite; CI (fmt/clippy/build/test) green on openfut-core.

Partially implemented

  • FIFA 17 FUT hub depth — reaching the hub is proven, but how much of FUT is fully navigable beyond it (playing matches, pack opening, SBC submission through the game UI vs. spinner/error states) is not documented as complete. The runbook's gate ladder lists failure modes still guarded against. Treat "past the hub" as unverified.
  • Pack opening through the game UI — proven live on 2026-08-09 with the recovered CAGE test profile: purchase, reveal, item assignment/quick-sell, wallet refresh, and return from the reveal all completed. The Python transaction path also passes its 446-check contract suite. FIFA's hardcoded post-reveal mypacks return is supported by a short-lived active grace record for every opened pack; it is excluded from unopened-pack counts and retired at the next hub request.
  • FIFA 17 FUT match lifecycle — CardsDLL static analysis and isolated responder tests now cover CREATE→READY→PLAY→END. Bare /match requests carrying body matchId are classified as PLAY instead of accidentally allocating another match; READY returns the verified scalar matchId and opponentPersonaId fields; END persists W/D/L, matches played, and coin rewards per account. The implementation is deployed and test_match_lifecycle.py passes, but no football match has started or completed in FIFA yet. The READY opponent items contract and client mode-entry gate remain unresolved; FUT_MODES therefore stays off by default.
  • Core ↔ emulation integration — the two halves exist and wiring has started. First slice (2026-08-11): the My Squad owned-player search. openfut-core gained a semantic, game-independent owned-inventory query (services::inventory::{OwnedItemQuery, apply_query}
    • a Quality tier) that filters (AND) → orders deterministically → paginates, wired into GET /collection; openfut-adapter-fifa17::fut::owned_query parses the FIFA17 /club wire query and resolves numeric league/nation/team ids → semantic names (unknown id = hard error, no raw-id passthrough). Intentional fix, not parity: Python applies only league+team and ignores level/rare/position/nation/start/count (the request-amplification bug); Core applies all proven filters and paginates. rare=SP semantics UNKNOWN, unimplemented. Slice 2 (2026-08-11): openfut-utas-host — the first live UTAS host. Serves GET …/club from Core through the adapter and reverse-proxies every other UTAS route verbatim to the Python oracle (utas_server.py); plaintext HTTP/1.1 keep-alive, classify-before-execute, no python-fallback after a Core error. CoreAccess is a host-owned boundary (the adapter stays transport-agnostic). 11 host + 22 adapter tests; 10/10 mutations killed; fmt/clippy clean. Slice 3 (2026-08-11, 3ef3bc3): the real Fifa17IdentityResolver — catalog (card id → real asset id) + persistent openfut-identity store (owned instance → stable/reversible wire int) + wire-id policy, replacing all placeholders (one production path). Wire-id namespace is globally monotonic within (fifa17, owned-item), not per-account (Core owned ids are UUIDs → unambiguous reverse). Slice 4 (2026-08-11, core 36abd4b): a curated 32-card real FIFA17 dev content pack (data/games/fifa17/dev/cards.json, ids fifa17_<asset>), loaded only via opt-in Config.dev_content_games; seed-dev grants a game_id=fifa17 profile+club real OwnedCards (no FIFA wire ids — the resolver mints those at request time), idempotent, default content untouched. Remaining for a rendering retail /club: Commit 6 — the host sends X-OpenFUT-Game: fifa17 so /club queries the all-mapped fifa17 profile (no post-pagination drops), then the live retail A/B (no FIFA client in the build env). See the vault UTAS Endpoint Map + Known Issues (incl. "identity resolution is NOT authorization" for later mutations).

Stubbed / planned

  • fifa-blaze (Rust) — Milestone 1 capture stub only. Two TLS listeners that log packets; no FIFA 23 component/command handlers. Its own README says IDs are unknown. Superseded in practice by the Python FIFA 17 responders, kept as the intended FIFA 23 implementation surface.
  • openfut-launcher legacy controls — core/bridge and FIFA 23 setup controls belong to a superseded plan. The launcher now also owns the live FIFA 17 client flow: server/hook config, account synchronization, local LSX, privileged autopatch, and game launch.
  • tools/ (file-watch-diff, squad-injector, exporters) — helpers for the FLE-Lua-bridge idea in docs/direction.md. Not part of the live FIFA 17 path.
  • docs/foundational-xi-injection-test.md — a planned (not executed) test procedure for the FLE bridge route.

Stubbed / blocked (FIFA 23 lineage)

  • openfut-bridge — in-process version.dll hook on ProtoSSL. Git history: injection works but the effort hit an "architectural wall" (async event-driven gate, not a poll). Superseded first by the FLE-bridge pivot, then by the FIFA 17 route. Its CLAUDE.md task list is historical.

Unknown / requires investigation

  • Whether the FIFA 17 hub supports actually playing a FUT match offline and getting results back.
  • Whether FUT actions beyond the now-verified pack reveal/assignment flow (submit SBC, transfer market buy/sell, matches) round-trip correctly through utas_server.py.
  • The exact division of FUT state ownership once Core is wired in (who is source of truth).
  • Degree of FIFA 23 wire-format identity — asserted ("identical wire format") but the FIFA 23 client has not been re-tested against these responders in this repo's evidence.

Known technical debt / hazards

  • Root docs are stale. README.md, CLAUDE.md, openfut-bridge/CLAUDE.md all describe FIFA 23 as the target and mark FIFA 23 integration as the open item — they predate the FIFA 17 success.
  • All host state is volatile across reboot except the /etc/hosts line — re-run openfut-fut.sh start. Requires ptrace_scope=0 + root arming (security-relevant).
  • Whole stack rides on EAAC staying neutralized and game updates being off; a client update can break the memory patches (VAs) and cert bypass.
  • fifa17-recon/tools/lsx_responder_v2.py is currently modified in the working tree (uncommitted).
  • 33068179 / CAGE remains the responder fallback, but the launcher now blocks one-button launch until an explicit persona is configured and synchronized across LSX, Blaze, POW, and UTAS.