Rebuilds the primary-capture corpus lost to .gitignore (Known Issues #200): 10 real-client requests + 12 responses captured during the post-P1 staging A/B on a real FIFA 17 client, sanitised (SID/authCode/deviceId/MAC/tokens redacted; raw pcap withheld). Documents the account/sync, empty-My-Packs 65534 sentinel, and userMassInfo contracts, incl. the finding that account/sync is coupled to Python active-profile selection (so it can't migrate standalone from the userMassInfo hybrid).
Live UTAS wire captures — 2026-08-15
Fresh sanitised FIFA 17 UTAS wire, captured during the post-P1 staging A/B on a
real FIFA 17 client (10.10.0.105) driving the isolated post-P1 candidate
backend (10.10.0.121, host bin fda40d12, Core fbb54ea). Production untouched.
This rebuilds the primary-capture corpus that was lost to .gitignore (Known Issues
#200 / "take sanitised captures on the next live FIFA run and commit them").
Files
utas-requests.sanitised.txt— 10 real client requests (----separated).utas-responses.sanitised.txt— 12 responses.
Captured with tcpdump on the container netns (UTAS is plain HTTP on :8099),
reassembled + split + sanitised by openfut-staging/extract_http.py. Redacted:
X-UT-SID/sid (<SID>), authCode (<AUTH>), deviceId (<DEV>), macAddress
(<MAC>), and any 32+char hex token (<TOKEN>). The raw .pcap is intentionally
NOT committed (it is unsanitised).
Route contracts captured (verbatim shapes)
POST /openfut/account/sync (launcher control-plane, Python-served)
Request (launcher → backend):
{"personaId":33068179,"personaName":"CAGE","level":1,"experience":0,
"experienceMax":1000,"accountFunds":0,"accountFundsCap":100000}
Response:
{"account":{"personaId":33068179,"personaName":"CAGE","clubName":"OpenFUT",
"clubAbbr":"OFC","level":1,"experience":0,"experienceMax":1000,"accountFunds":0,
"accountFundsCap":100000,"profilePath":"accounts/33068179/fifa17_profile.json",
"coins":29826776,"unopenedPacks":0},"status":"OK"}
NOTE: coins here is Python's STALE profile value (29,826,776) — Core's authoritative
balance at capture time was 29,859,876. The launcher's AccountSummary parser is
lenient and requires only {personaId,personaName,level,experience,accountFunds,coins, unopenedPacks} (clubName/clubAbbr/etc. ignored). BLOCKER for a Rust migration is NOT
the shape — it is that Python account/sync also selects the active profile the
still-Python-served userMassInfo envelope depends on, so it is coupled to the
userMassInfo hybrid and cannot migrate standalone.
GET /ut/game/fifa17/store/purchasegroup/all?ppInfo=true (empty My-Packs sentinel)
The mypacks group carries the synthetic sentinel pack when My Packs is empty:
{"assetId":65534,"displayGroup":{"priority":1,"value":"mypacks"},"id":65534,
"packType":"GOLD","packContentInfo":{"goldQuantity":0,"itemQuantity":0,...},
"state":"active","unopened":false}
Client renders empty My Packs AS Browse Packs (no crash) — the bug-6c resolver guard.
Other captured request lines
POST /ut/auth, GET user/accountinfo, GET settings, GET phishing/trusteddevice,
PUT match/reset, GET userMassInfo, PUT clientdata/userHubData,
PUT /ut/v2/game/fifa17/store/transaction/0.
See openfut-staging/p1p-live-2026-08-15/AB_VERDICT.md for the full A/B result.