forge-lcdl

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.