Handbook
Games LCDL layer
The thick layer parses and validates LLM outputs after the engine has supplied finite legal_moves. Engines stay authoritative; LCDL tasks must not invent move_id values.
Data flow
| Step | Owner | Artefact |
|---|---|---|
| 1 | Engine | PlayerView, tuple[Move, ...] |
| 2 | Adapter / orchestrator | Task payload: player_view, legal_moves lists (often via schemas.move_to_candidate_dict) |
| 3 | Governed task | run_task("game_move_*", "v1", …) (runner.run_task) |
| 4 | game_lcdl.validate |
Subset checks, confidence ranges, heuristic key coverage |
Mapping table
| Engine field | Typical task JSON key |
|---|---|
PlayerView dataclass |
player_view: object mirroring game_id, player_id, public, private, metadata |
Move.move_id, Move.actor, … |
Each row under legal_moves |
| Chosen identifier | selected_move_id (explain), or status + ids (parse/rank) |
HTTP-shaped helpers
forge_lcdl.games.adapters.web_json builds canonical JSON envelopes without binding to a web framework (state_response, legal_moves_response, apply_move_request, error_response).
Contracts
Formal markdown lives under src/forge_lcdl/contracts/game_move_*/v1/; summarized in GAMES-LCDL-TASKS.md.