Each turn is a fresh prompt holding the game so far as JSON: every labelled scene, the submissions and verdicts, and the budget. The model reasons, then answers with one compact JSON action: build a scene, or submit a rule in the DSL. The last action object in the reply is played; a broken one is charged, never repaired. Local models can decode under a grammar that admits exactly the legal actions. A submitted rule goes straight to the grader, so no LLM touches the reward.
{"action":"experiment","scene":[{"color":"BLUE","shape":"WEDGE","size":"SMALL","orientation":"UP"}]}
{"action":"submit","rule":"(exists x0 (= (color x0) BLUE))"}