0037: Validation
Status: Accepted. Extends decision 0008 (how keyframes are checked).
Context
Section 14 listed eight checks, including "a keyframe equals the state produced by replaying the events", but never said what that state is, how each line changes it, or how a keyframe is compared with it. Two validators could disagree about the same file, and a writer could not know what a validator would accept. This repository defines the format, not the tools that check it, so validation has to be defined precisely enough that any package can implement it the same way.
Writing the definition also exposed four places where the format allowed two encodings or relied on a reader inferring something: when face is written for a permanent, the order of repeated counters and goaded fields, how library positions move, and how a card comes to be on an adventure.
Decision
- Validation needs no rules engine and no card database. Every change to the state is a line, so a validator applies lines in order. A
resolvemoves nothing and adamageline changes no life total: the lines after them record those changes. - The spec defines the replay state, each line's effect on it, and how keyframes and stack snapshots are compared (spec sections 14.2 to 14.6). Clocks are not compared.
- The checks are numbered (section 14.1), so validators and conformance fixtures can name the check a file breaks. Eight new checks make explicit what earlier sections already required: source zones,
OLDvalues, mana pools, tapping, draws from the top,stacklines afterpriority,identify, the end of the game, and variations. - What validation cannot check is listed (section 14.7): completeness, correct causes, legal play, and Oracle names. A validator may check these with a rules engine, but a file that fails them is still valid.
- Incompleteness suspends the replay checks until the next keyframe, which then replaces the replayed state. Objects it does not list end.
- Canonical forms that replay needs:
faceon a permanent names a face other than its front, which is the first part of its name.castlines still always name the face or half cast.- Repeated
countersfields are in code point order of their kind, andgoadedfields are in seat order. - Library positions move by fixed rules: an object leaving or entering at a known position shifts the others counted from that end, and one at an unknown position makes the others unknown, except that draws and mills take the top card.
- The adventure and companion marks are derived from defined sequences of lines (a card cast as its second face and exiled as it resolves; a sideboard card revealed in the pregame by itself), not from card knowledge.
Rules basis
Checked against the Comprehensive Rules effective 2026-09-25.
This is mostly a format decision. The rules it relies on:
- 106.4: "Each player's mana pool empties at the end of each step and phase, and the player is said to lose this mana." Pools are empty at every step, phase, and keyframe line.
- 121.1: "A player draws a card by putting the top card of their library into their hand." 701.17a: "For a player to mill a number of cards, that player puts that many cards from the top of their library into their graveyard." So a draw or mill takes the top card.
- 400.7: an object that moves from one zone to another becomes a new object, which is why a zone change clears tapped status, counters, attachments, and links.
- 607.2q: the exception for cards exiled to pay a permanent spell's cost (decision 0034).
- 715.3d: "Instead of putting a spell that was cast as an Adventure into its owner's graveyard as it resolves, its controller exiles it. For as long as that card remains exiled, that player may play it."
Alternatives rejected
- Providing a reference validator in this repository. Rejected: this repository defines the format, and implementations live elsewhere. A precise definition plus the conformance fixtures is what packages need.
- Leaving replay to the implementer's judgment. Rejected: two validators would disagree, and "one obvious way" (
CONTRIBUTING.md) applies to checking as much as to writing. - Checking legal play. Rejected for conformance: it needs a full rules engine and card data, which would make every parser a Magic engine.
- An explicit
adventureclause on the exile move. Rejected for now: the sequence of lines already determines it without card knowledge.
Consequences
- Spec section 14 is rewritten and renamed "Validation". Sections 7.1 and 10.2 to 10.3 state the canonical
face,counters, andgoadedforms. conformance/README.mdnames the numbered check each invalid fixture breaks.