afadb13de4
Q2 is LIVE-CONFIRMED (operator saw the inactive row under TRANSFER LIST with Start Price 0 and no Buy Now / Current Bid / timer, active rows still separate under LISTED ITEMS, and the state survived a full FUT exit/re-entry). Promoting from the bounded one-item probe to the real behaviour: the env gate is gone and /tradePile now enumerates the whole trade pile. Mechanism: read the pile (async), resolve each member to a shaped card (sync, because the identity/Core resolvers are not `Send`), then build the response (async). The core->wire lookup is `wire_for_owned_id`, which uses the identity store's NON-allocating `external_for` -- enumerating a pile is a READ and must never mint a wire id for an item the client has not seen. Items with no mapping, no Core record or no resolvable FIFA identity are skipped, never faked. Includes a bug the DIFFERENTIAL caught and unit tests did not: a pile row OUTLIVES its auction, so after a sale the seller's `trade` row is stale, and filtering only on ACTIVE listings re-advertised a SOLD card as an owned unlisted item. Suppression is now by listing state via `blocking_core_items()` -- active (real auction shown instead), reserved (sale in flight) and sold (card gone) -- while `cancelled` is deliberately NOT suppressed, because a cancelled listing means the card came back to the pile. New test covers all three plus the store-level rule. counts semantics deliberately unchanged: `count`/`selling` still track auctions only. 341 tests pass, 0 failed, clippy clean. Deployed: the 6 previously stranded pile items now render, alongside the 1 active listing, with Ronaldo correctly in /club and out of the pile. Body preserved as phase-c-full-pile-exposed.json.