diff --git a/docs/FIFA17_CONTENT_COMPLETENESS.md b/docs/FIFA17_CONTENT_COMPLETENESS.md new file mode 100644 index 0000000..53f2eb3 --- /dev/null +++ b/docs/FIFA17_CONTENT_COMPLETENESS.md @@ -0,0 +1,66 @@ +# FIFA17 Content Completeness (33-record gap) + +Evidence: ContentGapMap scout vs import-input.json (persona 33068179, 1995 items), +fifa17-recon/data/tables, manifest/fifa17-import-manifest.json (OBSERVED). + +## Summary +| Category | Expected | Resolvable | Unrecoverable | +|---|---|---|---| +| Legend players | 13 instances (10 defs) | 0 | 13 (need .105 Legends locale names) | +| Consumables | 17 | 17 | 0 | +| Staff | 3 | 3 | 0 | + +## Consumables (17/17 RESOLVABLE — carddbid present in fcc tables; semantics from cardsubtypeid) +| wire_id | resourceId | subtype | kind | table | +|---|---|---|---|---| +| 100000239 | 5003012 | 54 | gk_training | fcc_trainingcards | +| 100000249 | 5003011 | 54 | gk_training | fcc_trainingcards | +| 100000260 | 5003004 | 52 | gk_training | fcc_trainingcards | +| 100000272 | 5003059 | 91 | position/playstyle mod | fcc_trainingcards | +| 100000250 | 5003060 | 92 | position/playstyle mod | fcc_trainingcards | +| 100000327 | 5003065 | 97 | position/playstyle mod | fcc_trainingcards | +| 100000238 | 5003066 | 98 | position/playstyle mod | fcc_trainingcards | +| 100000261 | 5003068 | 100 | position/playstyle mod | fcc_trainingcards | +| 100000316 | 5003068 | 100 | position/playstyle mod | fcc_trainingcards | +| 100000293 | 5003103 | 258 | player_playstyle | fcc_trainingcards | +| 100000326 | 5003112 | 267 | player_playstyle | fcc_trainingcards | +| 100000283 | 5003116 | 271 | gk_playstyle | fcc_trainingcards | +| 100000294 | 5001004 | 201 | player_contract | fcc_contractcards | +| 100000304 | 5001008 | 202 | manager_contract | fcc_contractcards | +| 100000305 | 5001009 | 202 | manager_contract | fcc_contractcards | +| 100000315 | 5002027 | 217 | healing | fcc_healingcards | +| 100000426 | 5002013 | 213 | healing | fcc_healingcards | + +## Staff (3/3 RESOLVABLE) +| wire_id | resourceId | subtype | role | table | +|---|---|---|---|---| +| 100000271 | 3000083 | 8 | fitnesscoach | fitnesscoachcards | +| 100000427 | 3000083 | 8 | fitnesscoach | fitnesscoachcards | +| 100000282 | 9000081 | 6 | gkcoach | gkcoachcards | + +## Legends (13 instances / 10 defs — UNRECOVERABLE from .120) +All defer via NoName gate (openfut-import-fifa17/src/lib.rs:476-478). 6 assets absent +from players.json; 236250/236253/236257 resolve only to placeholder nameid 24313='171918'. +dcplayernames.json/editedplayernames.json EMPTY in .120 dump. Version formula holds for all +(resourceId == (version<<24)|assetId) — so they auto-promote the instant a .105-derived +name row exists; NO code change needed, only name data. + +| asset | resourceId(ver) | rareflag/rating/pos | wire copies | +|---|---|---|---| +| 169193 | 169193(v0) | 1/r87/CDM | 100000057,100000083,100000146,100000157 | +| 211029 | 211029(v0) | 1/r73/CB | 100000165 | +| 224512 | 224512(v0) | 1/r67/LB | 100000170 | +| 227403 | 227403(v0) | 1/r64/ST | 100000160 | +| 236743 | 236743(v0) | 1/r60/LB | 100000163 | +| 237510 | 237510(v0) | 1/r59/CB | 100000162 | +| 236250 | 17013466(v1) | 3/r78/ST | 100001102 | +| 236253 | 17013469(v1) | 3/r77/CAM | 100001932 | +| 236253 | 100899549(v6) | 21/r77/CAM | 100001472 | +| 236257 | 117676769(v7) | 22/r78/LM | 100001043 | + +## Implementation +- Consumables+staff: NEW emit path in openfut-import-fifa17 (classify already buckets; + plan_definitions only ingests PlayerCard). Add definition builders + Core CardDefinition + rows to fifa17-production-cards.json + owned instances in apply.rs. Data 100% present. +- Legends: attempt read-only .105 Legends locale research; if names recoverable add roster + rows (auto-promote). Otherwise document as unrecoverable (do NOT fabricate names). diff --git a/docs/PRODUCTION_AUTHORITY_MATRIX.md b/docs/PRODUCTION_AUTHORITY_MATRIX.md new file mode 100644 index 0000000..8879d2b --- /dev/null +++ b/docs/PRODUCTION_AUTHORITY_MATRIX.md @@ -0,0 +1,104 @@ +# Production Authority Matrix (post-P1) + +Definitive inventory of every production-reachable FIFA17 route/service and its +current owner. Derived from the live `prod-host` dispatch log (owner= labels, +real Client A session 2026-08-14), `openfut-utas-host/ROUTE_AUTHORITY.md`, and the +prod container config (`OPENFUT_SERVERS="blaze roster pow"`). + +Evidence labels: OBSERVED (live log/db), PROVEN (test), INFERRED, HYPOTHESIS. + +Legend: owner R = Rust/Core, P = Python oracle (:8199 proxied via PYTHON_FALLBACK). + +## UTAS HTTP (front door: openfut-utas-host :8099) + +### ECONOMY — already Rust (Python economy hits = 0, OBSERVED) +| Method/path (tail) | Prod owner | Writes state | Rust handler | Py proxy | +|---|---|---|---|---| +| GET /user/credits | R | no | handle_credits | NO | +| GET /store/purchasegroup[/all] | R | no | handle_purchasegroup | NO | +| PUT /store/transaction[/] | R | coins,inv,pile | handle_store_buy | NO | +| POST /purchased[/items] | R | coins,inv,ent,pile | handle_pack_open | NO | +| GET /purchased[/items] | R | no | shape_purchased_reveal | NO | +| DELETE /item/ | R | coins,inv | handle_quick_sell_path | NO | +| POST /ut/delete/../item | R | coins,inv | handle_quick_sell_body | NO | +| PUT /item | R | inv,pile | handle_move_items | NO | +| POST /ut/delete/../match | R | coins | handle_match_end | NO | +| POST /auctionhouse,/transfermarket | R | listings | handle_market_list | NO | +| GET /tradePile[/counts] | R | no | handle_market_query | NO | +| /trade/ (POST/PUT/GET) | R | coins,inv,listings | handle_market_buy | NO | +| DELETE /ut/delete/../trade/ | R | listings | handle_market_cancel | NO | + +### NON-ECONOMY — Rust-owned +| Route | Owner | Notes | +|---|---|---| +| POST /ut/auth | R (OBSERVE) | session_opened; envelope currently Python-generated, Rust observes — auth boundary TBD | +| capability (/openfut/fifa17/capability) | R | -> Bound (CleanV1) | +| GET /userMassInfo | R (OVERLAY) | Rust overlays economy fields + squad onto Python envelope (hybrid) | +| GET /club, /club/* readers | R | Core-backed collection | +| squad-active, /squad/* | R | Core squad tx (SquadReplace) | + +### NON-ECONOMY — still Python (PYTHON_FALLBACK, OBSERVED live) +| Method/path | Owner | Response (observed) | Stateful | Migration target | +|---|---|---|---|---| +| POST /openfut/account/sync | P | account envelope | selects profile | R (candidate) | +| GET /user/accountinfo | P | {} | no (static) | R (trivial) | +| GET /settings | P | {"configs":[]} | no (static) | R (trivial) | +| GET /phishing/trusteddevice | P | trusted-device/security-question | first-entry state | R (security-question priority) | +| PUT /match/reset | P | {} | maybe | R (trivial/small) | +| GET /hub | P | tile counts (clubPlayers/auction/tradePile) | reads inventory+listings | R (reads Core) | +| GET /club/stats/year | P | stat[] (players/gold/...) | reads inventory | R (reads Core) | +| GET /club/stats/consumables | P | stat[] | reads inventory | R (reads Core) | +| GET /club/stats/staff | P | {} | no | R (trivial/reads Core) | +| GET /leaderboards/options | P | {} | no (static) | R (trivial) | +| PUT /clientdata/userHubData | P | {} | stores blob | R (small stateful) | + +## AUXILIARY SERVICES (prod container OPENFUT_SERVERS="blaze roster pow") +All aux services are **Python in production today** (container `entrypoint.sh` runs +`blaze_responder_v3b.py`/`roster_server.py`/`pow_server.py`). Rust equivalents exist +outside Docker; deploying them is operator-gated (production deployment forbidden here). + +| Service | Rust crate | Completeness | Prod owner | Reachable | Blocker to candidate | +|---|---|---|---|---|---| +| Blaze (:42130) | openfut-blaze-host + openfut-protocol-blaze + adapter::blaze | COMPLETE, gate-proven to real FUT (Gate 10: 3 logins, 10 pack opens, 448/448 py suite) | Python | yes | ERRC error-reply placement unresolved; wire into candidate bring-up | +| Redirector (:42127 TLS) | openfut-redirector-host + openfut-tls (OpenSSL vendored) | COMPLETE, 1 live handshake 2026-08-11 (TLSv1.2/AES256-GCM-SHA384) | Python | yes | never full-path gated; cert consistency | +| Roster (:8081) | openfut-roster-host | COMPLETE, oracle-parity + lifecycle tests, unit-only | Python | yes | never live-gated | +| POW (:8094 + :8080) | NONE (only pow_server.py) | no Rust host; 58 templates, bodies placeholder | Python | yes | LARGEST: no crate + bodies un-reversed | +| Nucleus (:42131) | none (advertised string only) | n/a | Python stub (advertised, unused) | NO (0 live hits) | DEAD in current flow — keep advertising URL, no migration | + +RETIRED/out-of-scope: fifa-blaze (FIFA23 capture stub), openfut-bridge (FIFA23). Not in FIFA17 flow. + +## NON-ECONOMY UTAS TARGET OWNER (confirmed via scouts) +Core already exposes GET/PUT /settings, GET /club|/collection|/statistics|/profile, /squad/*. +New Rust arm = Route variant + classify() arm (lib.rs:118-140) + owner-labelled handler. + +| Route | Port complexity | Target | Notes | +|---|---|---|---| +| user/accountinfo | trivial-static ({}) | R | host constant | +| settings | trivial-static ({"configs":[]}) | R | host constant / Core /settings | +| leaderboards/options | trivial-static | R | host constant | +| match/reset | trivial-static ({}) | R | host constant ack | +| phishing/trusteddevice | small (validate hex + constant) | R | security-question: stateless ack, always verified/trusted | +| clientdata/userHubData | small stateful | R | Core PUT /settings upsert keyed userHubData | +| hub | medium (derived counts) | R | Core collection + market counts | +| club/stats/year | medium (rating-tier aggregation) | R | Core /collection + /statistics | +| club/stats/consumables | medium | R | BLOCKED on 17-consumable import | +| club/stats/staff | trivial ({}) or derived | R | BLOCKED on 3-staff import | +| account/sync | small-medium (persona select + save) | R | hardest: no direct Core route; host session/persona logic | +| ut/auth envelope | small (SID mint) | R (currently OBSERVE) | Python still mints envelope; boundary decision | + +## MIGRATION PRIORITY ORDER (Phase 12) +1. Content gap consumable+staff emit (unblocks club/stats/{consumables,staff}) — import crate. +2. Trivial-static host routes: accountinfo, settings, leaderboards/options, match/reset, phishing/trusteddevice. +3. clientdata/userHubData (Core settings upsert). +4. hub + club/stats/year (Core-derived aggregation). +5. userMassInfo full ownership (envelope scaffold; econ+squad already Rust). +6. account/sync + ut/auth envelope (account/session boundary). +7. Aux candidate wiring (blaze/roster/redirector already built) + POW (blocked) + Nucleus (dead). + +## ECONOMY EXPECTATION +Python economy hits = 0 (OBSERVED live + PROVEN by NEVER-BOTH/no-fallback tests). +Any nonzero Python economy hit = P1 regression, priority zero. + +## STATUS +Baseline + economy + Rust-owned non-economy rows: OBSERVED/PROVEN. +Aux + non-economy target owners: confirmed via HostSourceMap/PythonContractMap/AuxServiceMap/ContentGapMap scouts.