Problem
The roadmap requires the scraper to materialize observed games into contrai_core objects before persisting, feeding supervised learning. But no serializable record of a game exists today: PlayState is a live in-memory structure full of object references, Trick holds (Player, Card) tuples, and nothing round-trips to disk. The SQLite schema for scraped games is an open question (CLAUDE.md §11).
Proposal (to design when scraper observation work opens)
Frozen dataclasses in contrai-core — e.g. BidEvent, PlayEvent, RoundRecord, GameRecord — built on Position, TeamSide, Card, Bid. The record types then are the schema:
- The SQLite table design falls out of the dataclass fields (games / rounds / bids / plays / players).
- Later they double as the web server's wire format and the supervised-learning dataset row format.
- Scraper stores raw DOM payloads / structured events first, then parses into these records (reproducibility).
Timing
Deliberately not now — bidding/play observation in the scraper are still # FUTURE LOGIC placeholders, and the right record shape depends on what is actually observable. Design this together with that work. Blocked by / benefits from: Position enum, TeamSide enum.
Acceptance criteria (when picked up)
- Records are frozen, fully typed, and round-trip to/from SQLite without loss.
- A scraped game replays through the engine's rules without contradiction (validation harness).
- Schema documented in
docs/packages/scraper/.
Problem
The roadmap requires the scraper to materialize observed games into
contrai_coreobjects before persisting, feeding supervised learning. But no serializable record of a game exists today:PlayStateis a live in-memory structure full of object references,Trickholds(Player, Card)tuples, and nothing round-trips to disk. The SQLite schema for scraped games is an open question (CLAUDE.md §11).Proposal (to design when scraper observation work opens)
Frozen dataclasses in
contrai-core— e.g.BidEvent,PlayEvent,RoundRecord,GameRecord— built onPosition,TeamSide,Card,Bid. The record types then are the schema:Timing
Deliberately not now — bidding/play observation in the scraper are still
# FUTURE LOGICplaceholders, and the right record shape depends on what is actually observable. Design this together with that work. Blocked by / benefits from:Positionenum,TeamSideenum.Acceptance criteria (when picked up)
docs/packages/scraper/.