market: emit FIFA 17's own forSale itemState, not the oracle's listFS
Single-field protocol-correctness fix, deployed as a candidate for a live A/B. `itemData.itemState: "listFS"` on the seller's own auction rows is not a FIFA 17 token at all: zero occurrences in `CardsDLL_Win64_retail.dll` (md5 4de3493131d7d2ff7f8b360c5ac9b655), zero in 4.26 GiB of live client memory, and it decodes to -1 through `FUN_180166660` — so the client was handed an unrecognised `CARD_OFFERSTATE`. FIFA 17's value for an item offered for sale is `forSale` (5), from the 12-row table at 0x180229cc0. Changed only where the invalid token was emitted: `handle_market_query` (GET …/tradePile) and `handle_market_status` (GET …/trade/status). The market search path already emitted `forSale` and is untouched — which is also why the risk here was lower than it looked: the client has been decoding `forSale` on a live route all along, and only the seller's own pile carried the bad value. Wire A/B on the same expired row: EXACTLY one field differs. tradeId, tradeState, expires, startingBid, buyNowPrice, currentBid, bidState, sellerName, sellerEstablished, watched, coinsProcessed, the twelve-atom count and the whole itemData card are byte-identical; coins unchanged at 29,843,976; Fix A's zero `inactive` rows intact. The differential asserted PARITY on this field and therefore passed while BOTH sides were wrong — the exact mechanism by which the defect survived every run. `market query tradePile` is now DIFFERENT-BY-DESIGN, pinning oracle == "listFS" and rust == "forSale" so the divergence cannot silently close again. Where the FIFA 17 binary contradicts the Python oracle, the binary wins. Gates: 126 host tests, 214 adapter tests, fmt clean, clippy clean. NOT claimed: that this preserves the list -> expire -> Return-to-Club lifecycle. That needs an operator FIFA 17 session and has NOT been observed yet. Also not claimed: anything about the Flash action gate — `CARD_OFFERSTATE` is one of three still-confounded candidates and this change does not test it. Revert is one line if the live test fails.
This commit is contained in:
@@ -642,10 +642,43 @@ live on our listed row. FIFA 17's value for a listed item is `forSale` (5), from
|
||||
so does the Python oracle (`utas_server.py:3921`) — which is exactly why the
|
||||
differential never caught it: **oracle parity is necessary but not sufficient.**
|
||||
|
||||
Deliberately NOT fixed in the same change: `CARD_OFFERSTATE` (itemState) is one of the
|
||||
three unresolved gate candidates, and every actionable row observed so far carried
|
||||
`itemState = −1`. Flipping it to `forSale` could perturb the one flow that currently
|
||||
works (expired → Return to Club), so it ships alone and gets its own live A/B.
|
||||
### Fix B — `forSale` CANDIDATE DEPLOYED, live A/B outstanding (2026-08-17)
|
||||
|
||||
Shipped as a code+deploy change, deliberately alone, and **not yet live-confirmed**.
|
||||
|
||||
| Claim | Status |
|
||||
|---|---|
|
||||
| `listFS` is not a FIFA 17 token and decodes to −1 | **CONFIRMED** (binary + 4.26 GiB process scan + live row) |
|
||||
| `forSale` is FIFA 17-native, value 5 | **CONFIRMED** (12-row table at `0x180229cc0`) |
|
||||
| Emitting `forSale` preserves the list → expire → Return-to-Club lifecycle | **NOT YET OBSERVED** — needs an operator FIFA 17 session |
|
||||
| `CARD_OFFERSTATE` is the Flash action-gate term | **STILL UNPROVEN** — this change does not test it |
|
||||
|
||||
Wire A/B (`docs/evidence/market-lifecycle-2026-08-17/itemstate-forsale-ab.json`): on the
|
||||
same expired row, **exactly one field changed** — `itemState` `listFS` → `forSale`.
|
||||
`tradeId`, `tradeState`, `expires`, `startingBid`, `buyNowPrice`, `currentBid`,
|
||||
`bidState`, `sellerName`, `sellerEstablished`, `watched`, `coinsProcessed`, the atom
|
||||
count (12), and the whole `itemData` card are byte-identical; coins unchanged; Fix A's
|
||||
zero `inactive` rows intact.
|
||||
|
||||
Risk was lower than it first appeared, for a reason worth recording: the market SEARCH
|
||||
route (`/transfermarket`) **already** emitted `forSale`, so the client has been decoding
|
||||
`forSale` (5) on a live path all along — only the seller's own pile carried the invalid
|
||||
token.
|
||||
|
||||
Differential consequence: `market query tradePile` moves from `PARITY` to
|
||||
`DIFFERENT-BY-DESIGN`, pinning `oracle == "listFS"` and `rust == "forSale"` so the
|
||||
divergence stays visible. That assertion previously demanded parity and passed while
|
||||
**both** sides were wrong — the mechanism by which this defect survived every
|
||||
differential run. **Where the FIFA 17 binary contradicts the Python oracle, the binary
|
||||
wins.**
|
||||
|
||||
Revert is one line if the live A/B fails: both `auction_record_as(l, "forSale")` calls in
|
||||
`market.rs` back to `"listFS"`, rebuild, restart `prod-host`. On failure the rule is to
|
||||
revert and go to the AVM1 gate work — NOT to compensate with another field change.
|
||||
|
||||
**Claim boundary:** this is protocol correctness of one token. It is not evidence about
|
||||
the Flash decision tree; `STATE`, `CARD_OFFERSTATE` and `RESERVEDPRICE`/`MAX_CREDITS`
|
||||
remain confounded.
|
||||
|
||||
### Proving the gate (not yet done)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user