Bump openfut-core gitlink to 68d1065 (correctness fixes: SBC duplicate-card exploit, non-atomic economy CAS guards, season/checkin panics, sbc_submissions club_id migration 0019). Deployed to prod-core (DB migration ver 18 -> 19). Add docs/CORE_CORRECTNESS_ISSUES.md (audit + Resolution) and docs/OVERNIGHT_HANDOFF_2026-08-17.md.
11 KiB
Overnight session handoff — 2026-08-17
Autonomous session while you slept. Low-ceremony per your instruction. Everything below is verified as noted; nothing was committed or pushed (see Uncommitted work).
TL;DR
- Production promotion completed (you chose "promotion"): prod-host swapped to the
post-P1 build, content-gap imported. Then I migrated the remaining Python UTAS
routes that have a known contract to Rust: account/sync, ut/auth (SID mint),
userMassInfo (full), clientdata, club/stats/{country,league,team}, and the trivial
static acks. The client's observed FUT-hub/economy flow is now fully Rust; a
tail of lower-traffic routes without a captured wire shape (item-defs,
user-identity, watchList/marketdata, non-active
squad/<n>, draft, and mode-gated season/tournament/champion/leaderboards/sbs) still proxy to the Python oracle. - Launcher redesigned to a shareholder-grade egui UI (your headline ask). Builds clean; screenshots captured.
- New docs:
MATCH_LIFECYCLE.md(you asked),CORE_CORRECTNESS_ISSUES.md(4 known Core bugs + 1 bonus exploit, ready to fix on your go/no-go). - Nothing committed — all work is in the working tree for your review (git state is
delicate: preserved-dirty Core submodule + a concurrent
funman300actor + detached launcher branch; I didn't want to entangle that unsupervised).
What's live in production now (10.10.0.120:8099)
| Thing | State |
|---|---|
| prod-host binary | post-P1 fda40d12 + my migration rebuild (release, in target/release/openfut-utas-host) |
| prod-host pid | 3207781 (hub-managed, restart=no; retained spec points at the rebuilt binary) |
| Catalog | 9f6addaa (post-P1) |
| Core content (cards) | 136d8d68 (post-P1, +18 content-gap defs) → Core loads 1710 defs |
| Core owned | 1982 (1962 players + 17 consumables + 3 staff) |
| Coins | 29,876,776 (baseline — reset from the P1 test value when the content-gap DB was swapped in; you said data isn't precious) |
| prod-core | fixed build from canonical submodule (fbb54ea + 4 correctness fixes), DB migrated ver 18 → 19; binary now /home/alex/OpenFUT/target/release/openfut-core |
| UTAS routes (Rust) | economy, club, squad (0/active/list/PUT), account/sync, ut/auth, userMassInfo, user, clientdata, hub, settings, accountinfo, leaderboards/options, match/reset, phishing, club/stats/{year,consumables,staff,country,league,team}, watchList, static acks (store/keepalive/captcha/tfa/livemessage/activeMessage) |
| Still Python (:8199) | item-defs (item/resource, defid), club-identity (clubUser, user/list, user/club), squad/<n> (n≠0), draft, marketdata, mode-gated (season/tournament/champion/leaderboards/sbs → {} while off), and match CREATE/READY/PLAY. See docs/PRODUCTION_AUTHORITY_MATRIX.md. |
Smoke-verified live in prod (in the prod netns): all migrated routes return
owner=RUST, coins consistent, clientdata round-trips, club/stats context modes emit
distinct nation/league/team buckets. Scripts:
/home/alex/openfut-promotion/economy-2026-08-17-p2/{p2_precheck,smoke_migrated,smoke_clubstats}.py.
Changes made (all verified: builds clean, tests green)
1. Production promotion (deployed)
- Host binary
e5be8730(P1) →fda40d12(post-P1) + catalog9f6addaa. - Content-gap DB swapped in (owned 1962 → 1982). Backups in
/home/alex/openfut-promotion/economy-2026-08-17-p2/backup/+ROLLBACK.txt.
2. Route migration to Rust (deployed, rebuilt binary)
POST /ut/auth— Rust mints the SID (OPENFUT-SID-{:016X}), opens the Rust session, adopts persona from body. No Python. (+ /ut/delete/auth.)POST /openfut/account/sync— full Rust envelope; coins/unopenedPacks from Core.GET /userMassInfo— full Rust envelope (was a Python-proxy+overlay hybrid).GET/PUT /clientdata/<key>— new hostClientDataStore(JSON-persisted).GET /club/stats/{country,league,team}— madeclub_stats_bodycontext-aware (nation/league/team buckets); classify now routes allclub/stats/*to Rust.GET /squad/0— routed to the Rust active-squad projection (verified structurally identical to Pythonsquad/0: same 15 keys, players=23).GET /watchList(+ no-op add/remove) — empty list + authoritative Core credits.- Static acks (
store,match/keepalive,captcha,tfa,livemessage,activeMessage) — Rust constants (StaticAck route), byte-identical to the oracle. - Captured the remaining routes' Python wire shapes as reference fixtures for later
migration:
docs/evidence/route-shapes-2026-08-17/(user, defs, marketdata, clubUser, watchList, squad/0, season/tournament/champion/sbs, draft). - Files:
openfut-utas-host/src/{lib.rs,clientdata_store.rs(new),config.rs},openfut-adapter-fifa17/src/fut/{non_economy.rs,club_stats.rs},openfut-utas-host/tests/economy_integration.rs. - Tests:
openfut-utas-host+openfut-adapter-fifa17full suites GREEN (188 adapter + 76 host lib + all integration incl the 116s economy integration).
3. Launcher redesign + polish + live account panel (built, NOT deployed — client tool)
- Redesign: new
openfut-launcher/src/theme.rsdesign system (palette, embedded fonts, egui Visuals/Style, card/pill helpers). Branded hero header (OF monogram), left nav rail, card-based dashboard with status pills, prominent accent Launch CTA, console-style Logs. All existing launch/health/preflight/service/config logic preserved. - Polish: OpenFUT window/taskbar icon (OF monogram
IconData), Config tab rebuilt into themed cards, consistency sweep. - Live "Your Club" panel (new feature): a background
AccountMonitor(mirrorsHealthMonitor, 5s poll, non-blocking) fetches the account summary and the Dashboard shows a "Your Club" card — club name/abbr, Manager, COINS hero number, Level + XP bar, unopened packs, account funds — with clean loading/offline/error states. - Builds clean (0 warnings). Screenshots preserved (for your shareholder demo) in
/home/alex/openfut-post-p1/launcher-screenshots-2026-08-17/—launcher_account.png(the populated "Your Club" card: COINS 29,876,776, Level 12, packs 3) is the headline; plus dashboard/setup/logs/config + the offline state. All reviewed — product-quality. - Files:
openfut-launcher/src/{theme.rs(new),account_monitor.rs(new),app.rs,main.rs, account_sync.rs,config.rs}+assets/(fonts + icon). All additive; behavior preserved.
4. Core correctness fixes (deployed 2026-08-17)
All four CORE_CORRECTNESS_ISSUES.md classes fixed in the canonical openfut-core
submodule and deployed to prod-core (see that doc's "Resolution" section):
- Issue 3 (HIGH, exploit): SBC duplicate-card free-reward —
submit_sbcnow dedups ids + bounds the list (MAX_SBC_CARDS=30) →BadRequest. Regression test added. - Issue 2 (HIGH): non-atomic economy mutations — closed the concurrency-exploit
races with single-statement compare-and-swap (
spend_coinsconditional debit,open_pack/buy_listing/sell_card/checkinclaim-then-act). Multi-statement partial-failure edges (buy_pack, concurrent SBC, match/season chains) left as documented residual — need the transaction refactor, negligible for single-player. - Issue 4 (LOW):
season.rs.expect()panics → gracefulAppError; checkin index% 7→.rem_euclid(7). - Issue 1 (LOW):
sbc_submissions.club_id— migration0019(add + backfill) +submit_sbcbinds it; milestone query now correct. - Verified: Core suite 179 green + clippy clean; migration dry-run on a prod-DB copy;
post-deploy prod migration ver 19, owned 1982, coins 29,876,776, all Core + host
endpoints 200. Rollback:
backup/prod-core.preCoreFix.db(ver 18) + old binary path — seebackup/ROLLBACK_CORE_FIX.txt.
New / updated docs
docs/MATCH_LIFECYCLE.md(NEW) — consolidated FUT match loop design (CREATE→READY→ PLAY→END), contracts, reward policy, ownership split, blockers. (You asked for this.)docs/CORE_CORRECTNESS_ISSUES.md(NEW) — 4 known Core bugs + 1 bonus SBC duplicate-card exploit, each with file:line + concrete fix + severity. Needs your go/no-go (fixing bumps Core off the frozen P1 reference).docs/PRODUCTION_AUTHORITY_MATRIX.md(UPDATED) — reflects the completed migration.- Vault
06 Agent Memory/Current Priorities.md(UPDATED).
Uncommitted work — needs your review
I committed nothing (git state is delicate: openfut-core is intentionally
preserved-dirty; a concurrent funman300 actor; launcher on detached HEAD d1a71bd).
Review + commit these when you're ready:
- Superproject (mine):
openfut-utas-host/src/{lib.rs,config.rs},openfut-utas-host/src/clientdata_store.rs,openfut-utas-host/tests/{economy_integration.rs,host_test.rs},openfut-adapter-fifa17/src/fut/{club_stats.rs,non_economy.rs},docs/{PRODUCTION_AUTHORITY_MATRIX.md,MATCH_LIFECYCLE.md,CORE_CORRECTNESS_ISSUES.md,OVERNIGHT_HANDOFF_2026-08-17.md,PYTHON_RETIREMENT_PLAN.md}, and the reference fixturesdocs/evidence/route-shapes-2026-08-17/. - Launcher submodule (mine):
src/{app.rs,main.rs,theme.rs(new),account_monitor.rs(new),account_sync.rs,config.rs},assets/(fonts + icon). - Leave the pre-existing dirt alone (not mine):
CLAUDE.md,README.md,.env.example,docker-compose.yml,AGENTS.md,setup.sh,openfut-bridge,fifa17-recon/docker/...,docs/{ARCHITECTURE,ROADMAP,docker,fifa17-emulation}.md,docs/research/,scripts/utas-filter-diff.py. openfut-core(mine, this session):migrations/0019_sbc_submissions_club_id.sql(new),src/services/{sbc.rs,club.rs,pack.rs,market.rs,checkin.rs,season.rs},tests/integration_test.rs. Built + deployed to prod-core; still detached HEAD atfbb54ea(edits uncommitted, per your branch strategy).
Open decisions for you
Core correctness bugs— DONE (2026-08-17): all four classes fixed + deployed to prod-core (see "Core correctness fixes" above and the Resolution section ofdocs/CORE_CORRECTNESS_ISSUES.md). prod-core is now off the frozen P1 point, runningfbb54ea+ fixes at migration ver 19. Residual (documented): the multi-statement transaction refactor for partial-failure atomicity — negligible for single-player; do it if/when concurrency matters.- Match handshake legs (CREATE/READY/PLAY) — the only routes still on Python.
Deferred: no match has ever been played in-game, READY
itemscontract unknown,FUT_MODESoff (seedocs/MATCH_LIFECYCLE.md). Migrating them risks the economy/match/endrouting for a never-exercised path — I judged it not worth it unmonitored. - Aux service container cutover (blaze/redirector/roster → Rust) — operator-gated container change; unchanged.
Rollback (still hot)
- Python P2 image
openfut-fut-backend:p2-rollback(b1b929953f) + profile 39bb3e83 +rollback-to-python-p2.sh. - prod-host P1 binary + P1 catalog backed up in
/home/alex/openfut-promotion/economy-2026-08-17-p2/backup/(seeROLLBACK.txt). - prod state (pre-content-gap) backed up:
backup/prod-core.preB.db,prod-identity.preB.json, plus P1fifa17-production-{catalog,cards}.p1.json.