147 lines
11 KiB
Markdown
147 lines
11 KiB
Markdown
# 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 API** — `ut/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
|
|
`OwnedCard`s (no FIFA wire ids — the resolver mints those at request time), idempotent,
|
|
default content untouched. Slice 5 (2026-08-11, `5276dd2`): the host sends
|
|
`X-OpenFUT-Game: fifa17` so `/club` resolves the all-mapped fifa17 profile —
|
|
**composition proven live** over HTTP (real Core+host, no FIFA client): FIFA wire query
|
|
→ real `resourceId`s (catalog) + stable/reversible wire `id`s (store); 33 renderable,
|
|
gold=22, Premier League=18, pagination page1=11/page2=7/overlap=0 (clean paging, no
|
|
drops). **The only remaining gate is the live retail FIFA A/B** (no FIFA client in the
|
|
build env; runbook `openfut-utas-host/README.md`). See the vault UTAS Endpoint Map +
|
|
Known Issues (incl. "identity resolution is NOT authorization" for later mutations).
|
|
**Slice 6 (2026-08-11): `/club` RUNTIME VALIDATED on retail FIFA 17** — operator-assisted
|
|
live A/B (`.105` client → `.120` backend via a source-scoped NAT redirect into a staged
|
|
`36abd4b` Core + `openfut-utas-host`). Every checkpoint passed on the real client:
|
|
transport, per-route Python fallback, Python-negative `/club`, Core `X-OpenFUT-Game`
|
|
scoping, real card + persistent owned-item identity (incl. the two-copy fixture),
|
|
no-filter/Gold/position/nation/league/team/combined-AND filtering, retail pagination
|
|
with no amplification, card selection, identity stability across relaunch, Python
|
|
rollback, and Rust re-enable (identity store byte-identical across the cycle, 0
|
|
reallocation). Live findings: the retail client steps `start += 10` with `count=11`
|
|
(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).
|
|
|
|
## 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.
|