docs(route-authority): record landed Store/Market/pack handlers (unrouted)

Update cutover progress: Store BUY/pack-open/quick-sell, market
list/query/cancel/buy + move-items, durable listing/pile stores, and the
pack-content generator are implemented + tested (4d2b8b9) but NOT routed.
Remaining before the single classifier barrier: sync<->async Server wiring +
classify() routes, host<->Core writer E2E, Python differential, host
concurrency matrix, importer restart/idempotency, then the barrier + no-fallback
proofs.
This commit is contained in:
OpenFUT Agent
2026-08-13 20:48:39 +00:00
parent 4d2b8b9be3
commit 0e2ca5a7c3
+26 -6
View File
@@ -96,14 +96,34 @@ Landed (Core authority + transport + several handlers; classifier NOT yet flippe
oracle `destroy_match_body` shape).
- **Adapter policy mappers** (`181bd94`): match reward, pack price.
- All Core-backed, fail-closed (503, never Python), `FakeEconomy`-tested.
- **Store/item writers** (`4d2b8b9`, `economy_store.rs`, unrouted): `handle_store_buy`
(`purchase_items` debit+mint N → `createPackResponse`; 461 insufficient; 200 {}
cancel/unknown/owned_only), `handle_pack_open` (owned_only `redeem_entitlement`
consume-once; normal debit+mint), `handle_quick_sell{_path,_body}` (reverse-resolve
wire→Core id via `SquadWireResolver` → `sell_item`). Item wire shaping via
`fut::item::shape_item`; numeric ids via `openfut-identity`.
- **Pack-content generator** (`fut/pack_content.rs`): pure seeded
`generate_pack_contents`, gold-tier + special_chance PLACEHOLDER policy, fail-closed.
- **Market** (`market_store.rs`/`pile_store.rs`/`market.rs`, unrouted): durable sqlx
SQLite listing store (WAL+`BEGIN IMMEDIATE`, states active/reserved/sold/cancelled,
CAS reserve/complete/rollback, typed errors), durable pile metadata,
`handle_market_{list,query,cancel,buy}` (synthetic-seller buy-now = reserve→
`purchase_item`→complete_sale, race-safe two-buyer) + `handle_move_items`.
- Adapter +7 / host +43 tests incl. `two_reservers_exactly_one_wins`,
`two_buyers_exactly_one_sale_one_debit`, `state_survives_reopen`,
`move_persists_across_reopen`. clippy -D warnings + rustfmt clean.
**Not flipped:** `classify()` still routes every economy route to Python. Per the
single-writer rule the flip is one coherent barrier once ALL writers+readers are
implemented and Core is seeded — a partial flip would desync coins.
**Remaining before barrier:** Store BUY, pack-open, quick-sell (need item-wire
shaping via `club_response` shapers + `openfut-identity` numeric ids + pack-content
policy); market listing durable state + list/cancel/buy; move-items metadata;
Core-backed adapter live wiring (retire in-memory `ProfileEconomy` from prod path);
`openfut-economy-import` CLI; differential harness + concurrency + restart; then the
classifier barrier + no-Python-fallback classifier tests.
**Remaining before barrier:** (1) sync↔async **Server wiring** for the new handlers
(market/store handlers are `async` over sqlx `runtime-tokio`; the host `Server` is
sync — needs a tokio runtime bridge in dispatch) + `classify()` routes for the new
writers/readers; (2) real host↔Core **writer E2E** in `tests/economy_integration.rs`
(Store BUY/open/quick-sell/market-buy/move against a live Core + disposable DB,
extending the existing reader/match harness); (3) **Python-oracle differential**
runner (subprocess, isolated fixture, 13 ops); (4) **host-level concurrency matrix**
across the new handlers; (5) importer disposable-DB apply/restart/idempotency; then
the single **classifier barrier** + no-Python-fallback / writer-unreachable /
stale-reader proofs. Retire in-memory `ProfileEconomy` from any prod path.