{
  "$defs": {
    "AdversarialOutcome": {
      "description": "The outcome of an adversarial run's canonical match, from the **submission's**\nperspective.",
      "oneOf": [
        {
          "const": "win",
          "description": "The submission won the match.",
          "type": "string"
        },
        {
          "const": "loss",
          "description": "The submission lost the match.",
          "type": "string"
        },
        {
          "const": "draw",
          "description": "The match was a draw.",
          "type": "string"
        },
        {
          "const": "forfeit",
          "description": "The submission forfeited (it failed to build, did not export the contract\nentry, trapped, exhausted its fuel/memory, or returned an invalid action).",
          "type": "string"
        }
      ]
    },
    "AdversarialReplay": {
      "description": "One auto-generated proof replay: the submission played head-to-head against a\nsingle reference opponent. A finished adversarial run records one of these per\nopponent in [`AdversarialResult::replays`] — programmatic, reproducible\nevidence the implementation actually plays, which is what *replaces*\nproof-of-implementation for adversarial cases.",
      "properties": {
        "blueScore": {
          "description": "The opponent's (Blue's) banked score at the end of the match.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "ended": {
          "description": "How the match ended (`swept`, `time_limit`, or `forfeit`).",
          "type": "string"
        },
        "opponent": {
          "description": "The id of the opponent the submission was matched against (Blue).",
          "type": "string"
        },
        "outcome": {
          "$ref": "#/$defs/AdversarialOutcome",
          "description": "The outcome from the submission's perspective."
        },
        "redScore": {
          "description": "The submission's (Red's) banked score at the end of the match.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "replayJson": {
          "description": "Run-root-relative path to the published, browser-playable replay.",
          "type": "string"
        },
        "scored": {
          "description": "Whether this match's outcome counts as recorded evidence. `false` for an\nexhibition opponent (e.g. `random`, a trivial bar): its replay is kept so a\nreviewer can watch it, but the outcome is informational only.",
          "type": "boolean"
        },
        "ticks": {
          "description": "How many ticks the match ran for.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "winner": {
          "anyOf": [
            {
              "$ref": "#/$defs/AdversarialTeam"
            },
            {
              "type": "null"
            }
          ],
          "description": "The winning side, or `None` for a draw. `red` is the submission."
        }
      },
      "required": [
        "opponent",
        "replayJson",
        "redScore",
        "blueScore",
        "ended",
        "ticks",
        "outcome",
        "scored"
      ],
      "type": "object"
    },
    "AdversarialResult": {
      "description": "The result of scoring an adversarial run.\n\nAn adversarial run's authoritative output is its compiled wasm controller. The\nvalidator (see `crate::adversarial_validator::AdversarialValidator`) loads it\nas Red and plays it against the case's committed reference opponents (Blue),\neach through the shared [Foray host](foray_host), writing one published replay\nper opponent into the run's asset directory (see [`Self::replays`]). The\ntop-level fields mirror the **canonical** opponent's match (`border-soldier`),\nwhich scoring and the leaderboard read. A submission that fails to build, does\nnot export the entry, or forfeits is recorded as a loss/forfeit — never a\ncrash. Present only on an adversarial run's [`ValidationSummary`].",
      "properties": {
        "blueScore": {
          "description": "The opponent's (Blue's) banked score at the end of the match.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "controllerModule": {
          "default": "",
          "description": "Run-root-relative path to the produced controller wasm module (the case's\n`build.module`), or empty when the build emitted none. Lets the push flow\nupload the controller to the backend (so a pushed run is selectable in the\narena) without re-resolving the case manifest.",
          "type": "string"
        },
        "detail": {
          "default": null,
          "description": "Detail about a submission that could not be matched (for example a missing\nor unloadable module), or `None` when the match ran.",
          "type": ["string", "null"]
        },
        "ended": {
          "description": "How the match ended (the replay's `ended`: `swept`, `time_limit`, or\n`forfeit`).",
          "type": "string"
        },
        "opponent": {
          "description": "The id of the canonical opponent the submission was scored against (Blue).",
          "type": "string"
        },
        "outcome": {
          "$ref": "#/$defs/AdversarialOutcome",
          "description": "The outcome from the submission's perspective."
        },
        "redScore": {
          "description": "The submission's (Red's) banked score at the end of the match.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "replayJson": {
          "description": "Run-root-relative path to the canonical published replay (`replay.json`) —\nthe scored artifact mirrored by the top-level fields below. Also the first\nentry of [`Self::replays`].",
          "type": "string"
        },
        "replays": {
          "default": [],
          "description": "One proof replay per reference opponent the run was auto-replayed against\n(canonical opponent first). These are the run's evidence of play. Empty\nonly when the submission never presented a loadable controller (a forfeit\nbefore any match could run).",
          "items": {
            "$ref": "#/$defs/AdversarialReplay"
          },
          "type": "array"
        },
        "submissionTeam": {
          "$ref": "#/$defs/AdversarialTeam",
          "description": "Which side the submission played (always [`AdversarialTeam::Red`] for the\ncanonical match; recorded so a consumer never has to assume it)."
        },
        "ticks": {
          "description": "How many ticks the match ran for.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "winner": {
          "anyOf": [
            {
              "$ref": "#/$defs/AdversarialTeam"
            },
            {
              "type": "null"
            }
          ],
          "description": "The winning side, or `None` for a draw. `red` is the submission."
        }
      },
      "required": [
        "replayJson",
        "opponent",
        "submissionTeam",
        "redScore",
        "blueScore",
        "ended",
        "ticks",
        "outcome"
      ],
      "type": "object"
    },
    "AdversarialTeam": {
      "description": "Which side a match outcome is reported from, for an adversarial run.\n\nThe validator always runs the submission as Red against the committed baseline\nopponent as Blue (lead decision 4), so [`AdversarialResult::outcome`] is from\nthe submission's perspective and this records that the submission was Red.",
      "oneOf": [
        {
          "const": "red",
          "description": "The west colony — the submission, in the canonical match.",
          "type": "string"
        },
        {
          "const": "blue",
          "description": "The east colony — the baseline opponent, in the canonical match.",
          "type": "string"
        }
      ]
    },
    "AnimationSpec": {
      "description": "A model **animation** — one unified type across the whole pipeline. On the\n*required* contract it is a declaration: its [`Self::joints`] set is fixed and\n[`Self::tracks`] is empty; the declaration is seeded into `rig.json` from t=0. On\nthe *produced* rig the model fills [`Self::tracks`] with the authored F-curve\nmotion. An animation is either an [`Self::auto_play`] decorative idle (played\ncontinuously by default) or a named playable a game triggers.",
      "properties": {
        "autoPlay": {
          "description": "Whether the animation plays continuously by default (a decorative idle) or is\na named playable a game triggers.",
          "type": "boolean"
        },
        "joints": {
          "description": "The joints the animation is **required** to drive. Present on both the\ndeclaration and the produced animation.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "looping": {
          "description": "Whether the animation loops (true) or plays once and holds the last pose.",
          "type": "boolean"
        },
        "name": {
          "description": "Stable, unique name a game plays this animation by (for example `walk`).",
          "type": "string"
        },
        "periodMs": {
          "description": "The period in milliseconds — one full loop across every track.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "tracks": {
          "description": "The authored F-curve tracks, one per driven joint. Empty for a pure required\ndeclaration; filled on the produced rig.",
          "items": {
            "$ref": "#/$defs/AnimationTrackSpec"
          },
          "type": "array"
        }
      },
      "required": ["name", "periodMs", "looping", "autoPlay", "joints"],
      "type": "object"
    },
    "AnimationTrackSpec": {
      "description": "One track of an [`AnimationSpec`]: the F-curve keyframes that drive a single\njoint over the animation's timeline.",
      "properties": {
        "joint": {
          "description": "The joint this track drives (a declared [`JointSpec::name`]).",
          "type": "string"
        },
        "keyframes": {
          "description": "The keyframes, in time order, sampled over the animation's period.",
          "items": {
            "$ref": "#/$defs/KeyframeSpec"
          },
          "type": "array"
        }
      },
      "required": ["joint", "keyframes"],
      "type": "object"
    },
    "Assertion": {
      "description": "One assertion a validation script checked on its way to an [`AutoVerdict`] — a\nsingle mechanical fact, recorded pass or fail, exactly like one `assert` in a\ncode test framework. Both the passing and the failing assertions are kept, so the\nreviewer sees the full proof of what the script observed, not just the outcome.",
      "properties": {
        "actual": {
          "description": "For a comparison assertion, the value actually observed. Paired with\n[`expected`](Self::expected); `None` for a bare boolean fact.",
          "type": ["string", "null"]
        },
        "expected": {
          "description": "For a comparison assertion (`expectEq`, `expectClose`, …), the value the\ncheck required — what it *should* have been. A reviewer sees this beside the\n[`actual`](Self::actual) on a failing assertion, so the mismatch is legible\nwithout the label having to bake the number in. `None` for a bare boolean\nfact (`expectOk`), which has no value pair to show.",
          "type": ["string", "null"]
        },
        "label": {
          "description": "A short human-readable statement of what was checked, phrased so it reads\ntrue when it passes — e.g. \"the ball reflects and stays on the near side\".",
          "type": "string"
        },
        "pass": {
          "description": "Whether this individual check held.",
          "type": "boolean"
        }
      },
      "required": ["label", "pass"],
      "type": "object"
    },
    "AssetFrameResult": {
      "description": "The regenerate result for one frame of an asset-generation run.\n\nFor a single sprite this is the whole run's one frame (index 0); for a sprite\nsheet there is one per declared frame, each a completely separate file. One\nsignal comes out of each, recorded rather than gated (the same stance as\nend-to-end [checks](CheckResult)): the [divergence](Self::cheat_divergence)\nbetween the regenerated image and the pixels the model left on disk — a high\ndivergence means the model drew outside the tool. There is no target image and\nno fidelity score; the regenerated image is reviewed against the brief.",
      "properties": {
        "actionsLog": {
          "description": "Run-root-relative path to this frame's recorded action log.",
          "type": "string"
        },
        "cheatDivergence": {
          "default": null,
          "description": "Divergence between the regenerated frame and the model's on-disk preview,\nin `0.0..=1.0` (0.0 is identical). High divergence flags drawing outside\nthe tool. `None` when the model left no readable preview to compare.",
          "format": "double",
          "type": ["number", "null"]
        },
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated for this frame.",
          "type": ["string", "null"]
        },
        "index": {
          "description": "The frame index this result records under: `0` for a single sprite, the\ndeclared `[[sheet.frame]]` index for a sprite sheet.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "operationCount": {
          "description": "How many operations this frame's log recorded.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "previewImage": {
          "description": "Run-root-relative path to the pixels the model left on disk (this frame's\n`preview`), kept for the side-by-side comparison and the divergence signal.",
          "type": "string"
        },
        "regeneratedImage": {
          "description": "Run-root-relative path to the image regenerated from this frame's action\nlog — the scored output for this frame.",
          "type": "string"
        }
      },
      "required": [
        "index",
        "regeneratedImage",
        "previewImage",
        "actionsLog",
        "operationCount"
      ],
      "type": "object"
    },
    "AssetGenResult": {
      "description": "The result of regenerating an asset-generation run.\n\nAn asset-generation run's authoritative output is its recorded action log(s);\nthe validator replays each through the same drawing logic the binary used (see\n`crate::validator::AssetGenValidator`) to produce the **regenerated** image(s),\nwhich are the output a human reviews against the brief. A single sprite\nproduces one [frame](AssetFrameResult); a sprite sheet produces one per\ndeclared frame, each its own separate file. There is no target image and no\nautomated fidelity score. Present only on an asset-generation run's\n[`ValidationSummary`].",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated at the run level, or\n`None`. Per-frame detail lives on each [`AssetFrameResult`].",
          "type": ["string", "null"]
        },
        "frames": {
          "description": "The per-frame results: exactly one for a single sprite (frame index 0), one\nper declared frame for a sprite sheet, in declared order.",
          "items": {
            "$ref": "#/$defs/AssetFrameResult"
          },
          "type": "array"
        },
        "sheet": {
          "anyOf": [
            {
              "$ref": "#/$defs/AssetSheet"
            },
            {
              "type": "null"
            }
          ],
          "description": "The sprite-sheet frame dimensions and named sequences, when the case draws a\nsprite sheet (`asset_kind = \"sprite-sheet\"`). Carried into the run record so\nthe review UI can play the named animations from the per-frame images,\nwithout a separate catalog lookup. `None` for a single-sprite case."
        }
      },
      "required": ["frames"],
      "type": "object"
    },
    "AssetSheet": {
      "description": "The resolved `[sheet]` of a sprite-sheet case: the frames the model draws —\neach a separate file the size of one [`CanvasSpec`] — and the named sequences a\nreviewer plays back. The frame dimensions are the canvas dimensions; the\ndeclared frame indices and the sequences that reference them drive per-frame\nscoring and animated playback.",
      "properties": {
        "frameHeight": {
          "description": "Height of one frame in pixels (the canvas height).",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "frameWidth": {
          "description": "Width of one frame in pixels (the canvas width).",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "frames": {
          "description": "The declared frame indices, in declared order. At least one is present and\nall are unique.",
          "items": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "type": "array"
        },
        "sequences": {
          "description": "The named animation sequences, in declared order. At least one is present.",
          "items": {
            "$ref": "#/$defs/AssetSheetSequence"
          },
          "type": "array"
        }
      },
      "required": ["frameWidth", "frameHeight", "frames", "sequences"],
      "type": "object"
    },
    "AssetSheetSequence": {
      "description": "A resolved named animation sequence within a [`SheetSpec`]: an ordered list of\nrow-major frame indices played at [`Self::fps`].",
      "properties": {
        "fps": {
          "description": "Playback rate in frames per second. Always greater than zero.",
          "format": "double",
          "type": "number"
        },
        "frames": {
          "description": "The ordered row-major frame indices this sequence plays. Non-empty, every\nindex a valid cell.",
          "items": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "type": "array"
        },
        "name": {
          "description": "Human-readable display name, surfaced in the review UI.",
          "type": "string"
        },
        "slug": {
          "description": "Stable slug naming this sequence (for example `walk-right`).",
          "type": "string"
        }
      },
      "required": ["slug", "name", "frames", "fps"],
      "type": "object"
    },
    "AudioGenResult": {
      "description": "The validation result of an audio asset-generation run — the decoded PCM\n`clip.wav` (and, for `music`, the portable `clip.mid`). The validator decodes the\n`.wav`, confirms it is well-formed, within the `[audio]` format, no longer than\nthe cap, and not silent. Present only on an audio run's [`ValidationSummary`].",
      "properties": {
        "channels": {
          "description": "The decoded channel count (1 = mono, 2 = stereo).",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "clip": {
          "description": "Run-root-relative path to the emitted PCM `clip.wav` — the clip a game plays\nand the reviewer hears.",
          "type": "string"
        },
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated (a missing or malformed\n`.wav`, a format mismatch, an over-cap or silent clip), or `None`.",
          "type": ["string", "null"]
        },
        "durationMs": {
          "description": "The decoded clip length in milliseconds.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "midi": {
          "description": "Run-root-relative path to the portable `clip.mid` score, for a `music` run.\n`None` for the two SFX kinds (and when a `music` run emitted none).",
          "type": ["string", "null"]
        },
        "preview": {
          "description": "Run-root-relative path to the rendered waveform/spectrogram preview PNG, or\n`None` when the model rendered none.",
          "type": ["string", "null"]
        },
        "sampleRate": {
          "description": "The decoded sample rate in Hz.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": ["clip", "sampleRate", "channels", "durationMs"],
      "type": "object"
    },
    "AuthMode": {
      "description": "The authentication mode a run used, recorded so a published run is\nself-describing about how its cost should be interpreted.",
      "oneOf": [
        {
          "const": "apiKey",
          "description": "A provider API key, injected into the run container as an environment\nvariable. Billing is charged directly against that key.",
          "type": "string"
        },
        {
          "const": "subscription",
          "description": "A harness account subscription, supplied as credential files copied into\nthe run container. There is no per-run provider charge.",
          "type": "string"
        }
      ]
    },
    "AutoVerdict": {
      "description": "One auto-decided checklist verdict produced by a [`DebugScriptResult`].\n\nAuto verdicts are strictly binary — an objective mechanic either fired or it did\nnot — so this carries a plain [`pass`](Self::pass) rather than the graded\n`VerdictStatus` a human review uses. The reviewer UI pre-fills the checklist from\nthese (shown desaturated to mark them auto-set) and the reviewer may override any.\n\nThe verdict is decided by a list of [`Assertion`]s — the individual mechanical\nfacts the script checked, each recorded pass or fail exactly as a code test\nframework reports every `assert`. The verdict [`pass`](Self::pass)es iff every\nassertion passed. The assertions are the machine-readable *proof* of the verdict:\nthey show a reviewer precisely what was checked and which parts held, rather than\na single opaque pass/fail.",
      "properties": {
        "assertions": {
          "default": [],
          "description": "The individual assertions the script checked to reach this verdict — the\nproof, both the parts that held and the parts that failed. Empty only for a\nlegacy script that reported a bare pass with no assertions.",
          "items": {
            "$ref": "#/$defs/Assertion"
          },
          "type": "array"
        },
        "id": {
          "description": "The verdict id this decides — the [review item](crate::test_case::ReviewItem)'s\nown id, or the composite `<item>.<sub-item>` id for a sub-item.",
          "type": "string"
        },
        "pass": {
          "description": "Whether the mechanic passed. `true` earns the item (or sub-item) its weight.\nSet by the script from its assertions — true iff every [`Assertion`] passed.",
          "type": "boolean"
        }
      },
      "required": ["id", "pass"],
      "type": "object"
    },
    "AxisSpec": {
      "description": "A principal axis a [`JointSpec`] acts about or along.",
      "oneOf": [
        {
          "const": "x",
          "description": "The x axis.",
          "type": "string"
        },
        {
          "const": "y",
          "description": "The y (up) axis.",
          "type": "string"
        },
        {
          "const": "z",
          "description": "The z axis.",
          "type": "string"
        }
      ]
    },
    "CheckResult": {
      "description": "The result of a single opt-in validation check.",
      "properties": {
        "detail": {
          "description": "Detail about a check that could not be completed.",
          "type": ["string", "null"]
        },
        "name": {
          "description": "Human-readable display name for the check, carried through from the\ndeclared [`Check`](crate::test_case::Check).",
          "type": "string"
        },
        "reached": {
          "description": "Whether the check could drive the implementation into the view and\ncapture it for comparison. When false, [`Self::similarity`] is `0.0` and\n[`Self::detail`] explains why.",
          "type": "boolean"
        },
        "similarity": {
          "description": "Similarity signal in the range `0.0..=1.0` against the reference\nbaseline. This is a signal, not a strict match requirement.",
          "format": "double",
          "type": "number"
        },
        "view": {
          "description": "The view the check records under.",
          "type": "string"
        }
      },
      "required": ["view", "name", "reached", "similarity"],
      "type": "object"
    },
    "CostMetrics": {
      "description": "Cost of a run, recorded two ways.\n\nEach figure is optional: `None` means the cost is **unknown** — typically\nbecause the model's per-token prices could not be resolved (the model is\nabsent from OpenRouter's catalog, or OpenRouter lists a nonsensical price).\nThis is distinct from `Some(0.0)`, a genuinely free run. Keeping the two\napart avoids presenting an unknown cost as `$0.00`.",
      "properties": {
        "actual": {
          "description": "The amount actually charged for the run, recorded for reference. Equal\nto the comparable figure unless the harness reports its own exact cost.\n`None` when the cost is unknown.",
          "format": "double",
          "type": ["number", "null"]
        },
        "comparable": {
          "description": "The canonical figure shown on the site, stable across providers. It is\nderived from token classes and OpenRouter's listed prices, except for\nharnesses that drive a single provider directly and report their own\nexact cost (such as Claude Code), where that reported cost — itself\nprovider-stable — is used instead. `None` when the cost is unknown.",
          "format": "double",
          "type": ["number", "null"]
        }
      },
      "type": "object"
    },
    "DebugScriptOutput": {
      "description": "A single media artifact a [`DebugScriptResult`] declares and produces.\n\nThe *actual* media (from the model's build) is synthesized per run and recorded\nhere by presence. Its *baseline* counterpart — the same output driven from the\ncase's reference implementation — is a fixed property of the case *version*,\nsynthesized once at publish-reference time and served case-scoped (keyed by\nslug/version/variant/item/output), so it is **not** recorded per run: the reviewer\nUI resolves the baseline from the catalog, not the run tree. The actual bytes live\nin the collected implementation tree and are addressed through the run's\nvalidation-media route; this records only presence and the metadata a UI needs to\nlay the pair out.",
      "properties": {
        "actualPresent": {
          "description": "Whether the model's build produced this output (the *actual* media).",
          "type": "boolean"
        },
        "id": {
          "description": "The output id, unique within its script — the media file's stem.",
          "type": "string"
        },
        "kind": {
          "$ref": "#/$defs/MediaKind",
          "description": "Whether this output is an image or a video clip."
        },
        "name": {
          "description": "Human-readable display name, carried through from the declared output.",
          "type": "string"
        }
      },
      "required": ["id", "name", "kind", "actualPresent"],
      "type": "object"
    },
    "DebugScriptResult": {
      "description": "The outcome of driving one review item's **debug script** against the build's\n[instrumentation](https://…/testing/end-to-end/instrumentation/) — the reporter-side\nautomation a case authors to decide an objective review item without a human.\n\nThe script drives the build's declared debug-API handle (see\n[`crate::test_case::Instrumentation`]) to set up a scenario, step the real\nsimulation forward, and read the outcome back, producing (a) an auto **verdict**\nper verdict id the item covers and (b) the declared media **outputs** — captured\ntwice, once from the model's build (the *actual*) and once from the case's\nreference implementation (the *baseline*), for the reviewer's side-by-side.\n\nA script that could be run but did not complete against a conformant build (a\nmissing handle, a thrown call, a malformed return, or a declared output the build\nnever produced) is recorded with [`ran`](Self::ran) `false`. That **fails the\nchecklist point the script backs** — a failed [`verdicts`](Self::verdicts) entry\nis synthesized for it, pre-filled into the review like any auto verdict and\noverridable by the reviewer — rather than failing the whole run: a build with a\nbroken debug API is still reviewed, and is scored down by exactly the points its\nchecks could not answer. A script the host could not run *at all* (no browser) is\nnot recorded here — that degrades like a [check](CheckResult).",
      "properties": {
        "categoryTitle": {
          "default": "",
          "description": "The backing category/item's title, so the script list can group each result\nunder its category. Equal to [`Self::title`] for a whole-item driver.",
          "type": "string"
        },
        "detail": {
          "default": null,
          "description": "Detail about a failed or degraded script (the handle was missing, a call\nthrew, an output was not produced), or `None` when it ran clean.",
          "type": ["string", "null"]
        },
        "gates": {
          "default": true,
          "description": "Whether a failed drive of this script **gates** the run. `true` for every\nordinary scripted point; `false` only when the backing review point is excluded\nfrom scoring for the version (an [`Erratum`](crate::test_case::Erratum) with\n[`exclude_from_score`](crate::test_case::Erratum::exclude_from_score) links its\nverdict id). An excluded point is still driven and its media captured, but it\nis not scored, so a `ran == false` on it costs nothing. Defaults to `true` so a\nresult recorded before the field existed still counts.",
          "type": "boolean"
        },
        "itemId": {
          "description": "The id of the [review item](crate::test_case::ReviewItem) this script backs.",
          "type": "string"
        },
        "outputs": {
          "default": [],
          "description": "The media outputs the script declares, each captured from the model's build\n(the *actual*). The matching *baseline* media is a case property served\ncase-scoped, not recorded per run. Empty when the script declares none.",
          "items": {
            "$ref": "#/$defs/DebugScriptOutput"
          },
          "type": "array"
        },
        "preconditionUnmet": {
          "default": false,
          "description": "Whether a `false` [`ran`](Self::ran) records an UNMET PRECONDITION rather than\na debug-API contract failure.\n\nA script's `arrange` often searches the model's own world for a spot to pose\nits scenario — a blind corner in an invented maze, a legal build tile. That\nsearch can come up empty against a fully conformant build: every call was\nanswered correctly, there was simply no such spot. That is INCONCLUSIVE about\nthe model, so it is held apart from a genuine contract failure: no failed\nverdict is synthesized for it and the point is left for the reviewer to decide\nby hand. Only ever `true` alongside `ran == false`.",
          "type": "boolean"
        },
        "ran": {
          "description": "Whether the script executed to completion against a **conformant** build:\nthe handle was installed, every call returned, the return value was\nwell-formed, and every declared output was produced. `false` records a\ndebug-API contract failure, which fails the checklist point this script backs\n(unless it was only a [precondition](Self::precondition_unmet) that went\nunmet).",
          "type": "boolean"
        },
        "script": {
          "description": "The reporter-side script path that was run (relative to the case version\nfolder), for display — e.g. `validation/ball-spin.mjs`.",
          "type": "string"
        },
        "subItemId": {
          "default": null,
          "description": "The id of the sub-item this script backs when it is a per-sub-item driver, or\n`None` when the whole item is validated. Together with [`Self::item_id`] it forms\nthe verdict id (`<item>.<sub>` or `<item>`) that keys this result's auto verdict\n(see [`AutoVerdict::id`]) and its media (see [`crate::validation_media_name`]).",
          "type": ["string", "null"]
        },
        "title": {
          "description": "The verdict unit's own title, carried through for display in the script list —\nthe sub-item's title for a per-sub-item driver, or the review item's title when\nthe whole item is validated. Carries no category prefix.",
          "type": "string"
        },
        "verdicts": {
          "default": [],
          "description": "The auto verdicts the script decided. A per-unit driver decides its one verdict\n(this result's verdict id), so this normally carries a single entry; it is kept a\nlist because a script returns a `verdicts` map and the driver preserves whatever\nids it emits. Empty when the script did not run.",
          "items": {
            "$ref": "#/$defs/AutoVerdict"
          },
          "type": "array"
        }
      },
      "required": ["itemId", "title", "script", "ran"],
      "type": "object"
    },
    "DriveKindSpec": {
      "description": "Who drives a [`JointSpec`].",
      "oneOf": [
        {
          "const": "caller",
          "description": "A consuming game supplies the joint's value at runtime.",
          "type": "string"
        },
        {
          "const": "auto",
          "description": "The joint is driven only by the model's [`AnimationSpec`] tracks, holding at\n`rest` until one overlays it.",
          "type": "string"
        }
      ]
    },
    "HarnessSlug": {
      "description": "A stable slug identifying a supported agent harness.\n\nSerializes to the snake/kebab-case slugs used throughout run records and the\nsite (all eight happen to be single-word lowercase tokens).",
      "oneOf": [
        {
          "const": "claude",
          "description": "Anthropic Claude Code (`claude`).",
          "type": "string"
        },
        {
          "const": "codex",
          "description": "OpenAI Codex (`codex`).",
          "type": "string"
        },
        {
          "const": "cline",
          "description": "Cline (`cline`).",
          "type": "string"
        },
        {
          "const": "antigravity",
          "description": "Google Antigravity (`antigravity`).",
          "type": "string"
        },
        {
          "const": "goose",
          "description": "Goose (`goose`).",
          "type": "string"
        },
        {
          "const": "kilo",
          "description": "Kilo Code (`kilo`).",
          "type": "string"
        },
        {
          "const": "opencode",
          "description": "OpenCode (`opencode`).",
          "type": "string"
        },
        {
          "const": "pi",
          "description": "Pi (`pi`).",
          "type": "string"
        }
      ]
    },
    "InterpSpec": {
      "description": "How an [`AnimationSpec`] F-curve segment interpolates between two keyframes —\nthe graph-editor curve real 3D tools use, so motion carries weight and snap\ninstead of sliding linearly. Set per keyframe on the segment **leaving** it.",
      "oneOf": [
        {
          "const": "constant",
          "description": "Hold the value until the next key (a step).",
          "type": "string"
        },
        {
          "const": "linear",
          "description": "A straight line to the next key.",
          "type": "string"
        },
        {
          "const": "bezier",
          "description": "A smooth cubic Bézier shaped by tangent handles (auto tangents when omitted).",
          "type": "string"
        },
        {
          "const": "ease-in",
          "description": "Preset Bézier: start slow and accelerate into the next key.",
          "type": "string"
        },
        {
          "const": "ease-out",
          "description": "Preset Bézier: start fast and decelerate into the next key.",
          "type": "string"
        },
        {
          "const": "ease-in-out",
          "description": "Preset Bézier: ease both ends.",
          "type": "string"
        }
      ]
    },
    "JointKindSpec": {
      "description": "Whether a [`JointSpec`] rotates or translates its part.",
      "oneOf": [
        {
          "const": "rotation",
          "description": "Rotate the part about [`JointSpec::axis`] through [`JointSpec::pivot`].",
          "type": "string"
        },
        {
          "const": "translation",
          "description": "Translate the part along [`JointSpec::axis`].",
          "type": "string"
        }
      ]
    },
    "JointSpec": {
      "description": "A resolved joint of a [`ModelSpec`]: one named degree of freedom on a part.\n\nA joint is either **caller-driven** (a consuming game supplies its value at\nruntime, e.g. `turret_yaw`) or **`auto`** (driven only by the model's\n[`AnimationSpec`] tracks, holding at `rest` until one overlays it). Rotations\nare in radians about [`Self::axis`] through [`Self::pivot`]; translations are in\nvoxel units along the axis.",
      "properties": {
        "axis": {
          "$ref": "#/$defs/AxisSpec",
          "description": "The axis the joint acts about (rotation) or along (translation)."
        },
        "drive": {
          "$ref": "#/$defs/DriveKindSpec",
          "description": "Who drives this joint: a caller (a game) or the model's animations."
        },
        "kind": {
          "$ref": "#/$defs/JointKindSpec",
          "description": "Whether this joint rotates or translates the part."
        },
        "max": {
          "description": "Maximum value.",
          "format": "double",
          "type": "number"
        },
        "min": {
          "description": "Minimum value: radians for a rotation, voxel units for a translation.",
          "format": "double",
          "type": "number"
        },
        "name": {
          "description": "Stable name of this joint; the parameter a game addresses (for example\n`turret_yaw`).",
          "type": "string"
        },
        "offset": {
          "description": "A fixed mount translation `[x, y, z]` (in voxels) this joint applies to the\npart in addition to its driven motion — the translation half of a compound\nattach. Absent (or all-zero) means no offset.",
          "items": {
            "format": "double",
            "type": "number"
          },
          "maxItems": 3,
          "minItems": 3,
          "type": ["array", "null"]
        },
        "orient": {
          "description": "A fixed mount rotation `[x, y, z]` (radians, applied as Euler X→Y→Z about\n[`Self::pivot`]) this joint applies in addition to its driven motion — the\nrotation half of a compound attach. Absent (or all-zero) means no rotation.",
          "items": {
            "format": "double",
            "type": "number"
          },
          "maxItems": 3,
          "minItems": 3,
          "type": ["array", "null"]
        },
        "part": {
          "description": "The part this joint moves (a declared [`PartSpec::name`]).",
          "type": "string"
        },
        "pivot": {
          "description": "The joint origin in the part's local voxel coordinates (`[x, y, z]`).",
          "items": {
            "format": "int64",
            "type": "integer"
          },
          "maxItems": 3,
          "minItems": 3,
          "type": "array"
        },
        "rest": {
          "description": "The rest/default value, within `[min, max]`.",
          "format": "double",
          "type": "number"
        }
      },
      "required": [
        "name",
        "part",
        "kind",
        "axis",
        "pivot",
        "min",
        "max",
        "rest",
        "drive"
      ],
      "type": "object"
    },
    "KeyframeSpec": {
      "description": "A resolved keyframe within an [`AnimationTrackSpec`] F-curve: a joint value at a\ntime offset, plus how the curve leaves this key.",
      "properties": {
        "inHandle": {
          "description": "Bézier in-handle on this key as `[dt_ms, dvalue]` offset from the key; `None`\n= auto tangent.",
          "items": {
            "format": "double",
            "type": "number"
          },
          "maxItems": 2,
          "minItems": 2,
          "type": ["array", "null"]
        },
        "interp": {
          "$ref": "#/$defs/InterpSpec",
          "description": "Interpolation of the segment **leaving** this key."
        },
        "outHandle": {
          "description": "Bézier out-handle on this key as `[dt_ms, dvalue]` offset from the key;\n`None` = auto tangent.",
          "items": {
            "format": "double",
            "type": "number"
          },
          "maxItems": 2,
          "minItems": 2,
          "type": ["array", "null"]
        },
        "tMs": {
          "description": "Time offset from the start of the animation, in milliseconds\n(`0..=period_ms`).",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "value": {
          "description": "The joint value at this time.",
          "format": "double",
          "type": "number"
        }
      },
      "required": ["tMs", "value", "interp"],
      "type": "object"
    },
    "MaterialGenResult": {
      "description": "The validation result of a `material` asset-generation run — the emitted per-map\nPNGs plus the parsed `material.json`. Like `ui`, a `material` run is **not**\nregenerated: the validator decodes each declared map and parses `material.json`.\nPresent only on a `material` run's [`ValidationSummary`].",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated at the run level (a missing\nor malformed `material.json`, an absent `base-color`), or `None`.",
          "type": ["string", "null"]
        },
        "maps": {
          "description": "The per-map results, in declared order. Always includes `base-color`.",
          "items": {
            "$ref": "#/$defs/MaterialMapResult"
          },
          "type": "array"
        },
        "size": {
          "description": "The maps' square resolution in pixels (the declared `[material].size`).",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "tiling": {
          "description": "The suggested world-space tiling scale carried in `material.json`, when\npresent. `None` when `material.json` declares none.",
          "format": "double",
          "type": ["number", "null"]
        }
      },
      "required": ["maps", "size"],
      "type": "object"
    },
    "MaterialMapResult": {
      "description": "The validation result for one map channel of a `material` run: its emitted PNG\nand the color space it is tagged with.",
      "properties": {
        "colorSpace": {
          "description": "The color space this map is tagged with in `material.json` (`srgb` for\n`base-color`/`emissive`, `linear` for the data maps).",
          "type": "string"
        },
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated for this map (a missing PNG,\na size mismatch), or `None`.",
          "type": ["string", "null"]
        },
        "image": {
          "description": "Run-root-relative path to this map's emitted PNG.",
          "type": "string"
        },
        "name": {
          "description": "The map channel this result records under (`base-color`, `normal`, …).",
          "type": "string"
        }
      },
      "required": ["name", "image", "colorSpace"],
      "type": "object"
    },
    "MediaKind": {
      "description": "The kind of a piece of media — used for both reference media and proof\nartifacts so a UI knows whether to render an `<img>` or a `<video>`.",
      "oneOf": [
        {
          "const": "image",
          "description": "A still image (`png`, `jpg`, `jpeg`, `webp`, `gif`).",
          "type": "string"
        },
        {
          "const": "video",
          "description": "A video clip (`webm`, `mp4`). A run captures its clip as the `.webm`\nPlaywright records natively; the public snapshot transcodes it to `.mp4`\nfor universal (incl. iOS/Safari) playback.",
          "type": "string"
        }
      ]
    },
    "ModelSpec": {
      "description": "The resolved `[model]` of a voxel-animation case: the rig the model must\nproduce — named parts in a parent/child hierarchy and the named joints a\nconsuming game (or an auto-play clip) drives. This is the **required** contract\n(the scoring targets and the stable, game-facing joint interface); at run time\nthe model may add further parts and joints of its own, which are recorded in\nthe produced `rig.json` but are not required here. Carried into the run record\n(see [`crate::validation::VoxelGenResult`]) so the review and viewer UIs know\nthe joint interface without a separate catalog lookup.",
      "properties": {
        "animations": {
          "description": "The model's **animations** — one unified type across the pipeline. On the\n*required* contract each is a declaration (its `joints` set, `tracks` empty),\nseeded into `rig.json` from t=0; on the *produced* rig each additionally\ncarries the model-authored F-curve `tracks`. Empty when the case declares\nnone.",
          "items": {
            "$ref": "#/$defs/AnimationSpec"
          },
          "type": "array"
        },
        "joints": {
          "description": "The declared joints, in declared order. Each names a declared part.",
          "items": {
            "$ref": "#/$defs/JointSpec"
          },
          "type": "array"
        },
        "parts": {
          "description": "The declared parts, in declared order. The first is the root (its `parent`\nis `None`); every other part names a declared parent.",
          "items": {
            "$ref": "#/$defs/PartSpec"
          },
          "type": "array"
        }
      },
      "required": ["parts", "joints"],
      "type": "object"
    },
    "NineSlice": {
      "description": "The resolved fixed nine-slice insets of a UI element (or as read back from\n`ui.json`): the stretchable border margins in pixels.",
      "properties": {
        "bottom": {
          "description": "Bottom inset in pixels.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "left": {
          "description": "Left inset in pixels.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "right": {
          "description": "Right inset in pixels.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "top": {
          "description": "Top inset in pixels.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": ["left", "right", "top", "bottom"],
      "type": "object"
    },
    "PartSpec": {
      "description": "A resolved part of a [`ModelSpec`]: one named voxel component of the rig.",
      "properties": {
        "name": {
          "description": "Stable name of this part (for example `chassis`, `turret`). The `voxel-anim`\nbinary targets a part's voxel operations with `--part <name>`.",
          "type": "string"
        },
        "parent": {
          "description": "The parent part this one is attached to, or `None` for the root part. A\npart inherits its parent's world transform, so posing a parent moves it too.",
          "type": ["string", "null"]
        },
        "pivot": {
          "description": "The attachment point of this part in the parent's local voxel coordinates\n(`[x, y, z]`). For the root part this is its origin in world space.",
          "items": {
            "format": "int64",
            "type": "integer"
          },
          "maxItems": 3,
          "minItems": 3,
          "type": "array"
        }
      },
      "required": ["name", "pivot"],
      "type": "object"
    },
    "ParticleGenResult": {
      "description": "The validation result of a particle asset-generation run — the parsed\n`system.json` (the authored emitter/force/curve definition) and the rendered\npreview. A particle run is **not** regenerated and there is no bake: the validator\nparses `system.json`, confirms it is well-formed and non-empty (it actually emits\nparticles), and takes the preview as the reviewer sees it. Present only on a\nparticle run's [`ValidationSummary`].",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated (a missing or malformed\n`system.json`, or a system that emits nothing), or `None`.",
          "type": ["string", "null"]
        },
        "emitterCount": {
          "description": "How many emitters the authored system declares.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "preview": {
          "description": "Run-root-relative path to the rendered preview animation (`effect.gif`) the\nreviewer plays, or `None` when the model rendered none.",
          "type": ["string", "null"]
        },
        "system": {
          "description": "Run-root-relative path to the emitted `system.json` — the authored definition\nevery consumer simulates live.",
          "type": "string"
        }
      },
      "required": ["system", "emitterCount"],
      "type": "object"
    },
    "PerformanceCaseKind": {
      "description": "Which phase of the held-out scored set a case belongs to.\n\nA performance run's scored set is run in two phases. **Smoke** cases are a cheap\ncorrectness pre-flight — tiny scenarios that each exercise one behaviour in\nisolation (a belt, a side-load, a splitter, an inserter, an assembler). Every\nsmoke case must reproduce the oracle before any **stress** case runs; if one\nfails, the stress cases are skipped and counted as failed, so a broken engine is\ncaught in milliseconds rather than after burning through the large scenarios.\nSmoke cases are graded on **correctness alone** — their fuel is not metered into\nthe score. **Stress** cases are the large held-out scenarios whose consumed fuel,\nsummed, is the comparable performance result.",
      "oneOf": [
        {
          "const": "smoke",
          "description": "A correctness pre-flight case: it gates the stress cases and its fuel is not\nscored.",
          "type": "string"
        },
        {
          "const": "stress",
          "description": "A scored stress case: its consumed fuel counts toward the run's total. The\ndefault, so records and manifests written before smoke tests existed read as\nstress cases.",
          "type": "string"
        }
      ]
    },
    "PerformanceCaseResult": {
      "description": "The result of scoring one held-out input case of a performance run.",
      "properties": {
        "correct": {
          "description": "Whether this case **passed**: the oracle's exact answer produced *within*\nthe fuel ceiling. An answer that is correct but over the ceiling is not a\npass — see [`Self::over_ceiling`].",
          "type": "boolean"
        },
        "detail": {
          "default": null,
          "description": "Detail about an incorrect or unrunnable case, or `None` when correct.",
          "type": ["string", "null"]
        },
        "firstMismatchTick": {
          "description": "The tick of the first snapshot whose answer diverged from the oracle, when\nthe engine is incorrect for that reason. `None` when correct, or when the\nfailure was structural rather than a checksum mismatch.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "fuel": {
          "description": "The fuel the engine consumed on this case. `Some` whenever the engine ran to\ncompletion — including an over-ceiling run, whose consumed fuel is exactly\nthe overshoot to display; `None` when the engine could not be run or\nexhausted even its runway (there is no finished total to report).",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "input": {
          "description": "The case-relative path of the input instance this result records under, so a\nreviewer can tie the result back to its case.",
          "type": "string"
        },
        "kind": {
          "$ref": "#/$defs/PerformanceCaseKind",
          "default": "stress",
          "description": "Which phase this case belongs to: a correctness pre-flight [smoke\ntest](PerformanceCaseKind::Smoke) or a scored [stress\ncase](PerformanceCaseKind::Stress). Defaults to `Stress` for records written\nbefore smoke tests existed."
        },
        "overCeiling": {
          "description": "The engine produced the oracle's exact answer but consumed **more fuel than\nthe ceiling** (it finished only because the case granted a\n[runway](crate::test_case::PerformanceCase)). The answer is right, so it is\nnot \"incorrect\", but it does not pass — the point of recording it is to show\n*how far* over the ceiling the engine ran, with playback still available.\nMutually exclusive with [`Self::correct`]. `false` for a passing, wrong, or\nunrunnable case.",
          "type": "boolean"
        },
        "scenarioJson": {
          "default": null,
          "description": "Run-root-relative path to the published, browser-playable scenario, or\n`None` when the case's input could not be read.\n\nBrowser playback loads the run's own engine module (see\n[`PerformanceResult::module_wasm`]) and steps it over this scenario to\nreconstruct the factory the submission actually computed — a run records only\na handful of scheduled snapshots, thousands of ticks apart, so there is\nnothing to interpolate between. Publishing the scenario alongside the result\nis what feeds that playback, exactly as an adversarial run publishes its\n[`replay_json`](AdversarialReplay::replay_json).",
          "type": ["string", "null"]
        },
        "skipped": {
          "default": false,
          "description": "The case was **not run** because a smoke test failed first, so the stress\ncases were skipped to save the fuel and wall-clock of running them. It counts\nas a failure (the run is incorrect), but is distinct from an engine that ran\nand produced the wrong answer — the engine never saw this case. Only ever\n`true` for a [stress](PerformanceCaseKind::Stress) case; defaults to `false`.",
          "type": "boolean"
        },
        "snapshots": {
          "default": [],
          "description": "The per-snapshot checksums the submission actually produced, in schedule\norder. Empty when the engine could not be run at all.\n\nRecorded so [browser playback](crate::validation) can *prove* what it is\ndrawing: playback loads the run's **own** engine module and steps it, and at\neach scheduled snapshot tick can compare the module's checksum against the one\nrecorded here — a cheap assertion that the wasm it is animating is the engine\nthe run graded, not a stand-in.\n\n`#[serde(default)]` because run records written before this field existed\nmust still load.",
          "items": {
            "$ref": "#/$defs/PerformanceSnapshotCheck"
          },
          "type": "array"
        }
      },
      "required": ["input", "correct", "overCeiling"],
      "type": "object"
    },
    "PerformanceResult": {
      "description": "The result of scoring a performance run.\n\nA performance run's authoritative output is its compiled wasm engine. The\nvalidator (see `crate::performance_validator::PerformanceValidator`) loads it,\nruns it once per held-out input case through the shared [Lattice\nhost](lattice_host) under the manifest's per-case fuel/memory limits, and\nchecks each case's output against the reference oracle. A run is **correct**\nonly when every case is, and its [`total_fuel`](Self::total_fuel) — the fuel a\ncorrect engine consumes — is the comparable performance result. A built-but-\nwrong engine still loaded (it presented an engine); its correctness gate lives\nhere, mirroring how an adversarial run records its outcome separately from the\nload signal. Present only on a performance run's [`ValidationSummary`].",
      "properties": {
        "cases": {
          "description": "The per-case results, in the case's declared order.",
          "items": {
            "$ref": "#/$defs/PerformanceCaseResult"
          },
          "type": "array"
        },
        "correct": {
          "description": "Whether **every** scored input case passed — the oracle's exact answer\nproduced *within* the fuel ceiling.",
          "type": "boolean"
        },
        "detail": {
          "default": null,
          "description": "Detail about a run that could not be scored at all (for example a missing or\nunloadable module), or `None` when every case ran.",
          "type": ["string", "null"]
        },
        "fuelLimit": {
          "description": "The per-scenario fuel **pass line** (`[sandbox].fuel_limit`), so a viewer\ncan render a case's overshoot (\"26% over the ceiling\") without the manifest.\nA case may run past it on its [runway](crate::test_case::PerformanceCase)\nand still record its fuel; the pass line is what that fuel is judged against.\n`None` on a run that could not be scored at all.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "moduleWasm": {
          "description": "Run-root-relative path to the published **engine module** — the submission's\nown `engine.wasm`, the one artifact a performance run authoritatively\nproduces — or `None` when the build emitted no module.\n\nPublished so browser playback can load and step the **run's own engine** over\neach case's [scenario](PerformanceCaseResult::scenario_json), reconstructing\nthe factory the submission actually computed (divergences and all) rather than\nre-simulating with the reference engine. There is one module per run — every\ncase's playback drives the same wasm — so it is recorded here at the run\nlevel, not per case. The module built by the buildkit exports the tick-at-a-\ntime playback ABI the renderer drives, alongside the scored `simulate` entry.",
          "type": ["string", "null"]
        },
        "totalFuel": {
          "description": "The total fuel consumed across all cases — the comparable performance\nresult. `Some` only when [`Self::correct`]; `None` for an incorrect run,\nwhere the fuel is meaningless.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        }
      },
      "required": ["correct", "cases"],
      "type": "object"
    },
    "PerformanceSnapshotCheck": {
      "description": "One scored snapshot: the tick it was taken at and the checksum the submission\nproduced there. The checksum is the canonical\n[`Snapshot::checksum`](lattice_core::state::Snapshot) — the validator's whole\ncomparison key — so a recorded run carries the same evidence the grader used.",
      "properties": {
        "checksum": {
          "description": "The checksum the submission produced, formatted `fnv1a64:%016x`.",
          "type": "string"
        },
        "tick": {
          "description": "The tick this snapshot was taken at.",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": ["tick", "checksum"],
      "type": "object"
    },
    "PriorGameJamEntry": {
      "description": "One earlier game-jam run's gameplay README, as served back to a new run of the\nsame jam by the same model (under any harness) so the new run can build something\ndistinct from what came before.\n\nOne type serves both ends of that trip: it is what the backend returns from\n`GET /game-jams/{slug}/prior-readmes` and the driver threads into seeding and the\nprompt, *and* what the new run records in\n[`RunRecord::game_jam_prior_entries`](RunRecord::game_jam_prior_entries) as the\ninputs it was given. The `readme` is the prior run's captured\n[`RunRecord::game_jam_readme`].",
      "properties": {
        "finishedAt": {
          "description": "RFC 3339 timestamp of when the prior run finished, used to order and label\nthe entries (oldest first) when they are seeded.",
          "type": "string"
        },
        "readme": {
          "description": "The gameplay README the prior run produced.",
          "type": "string"
        },
        "runId": {
          "description": "The prior run's id, carried so an entry can be traced back to its run.",
          "type": "string"
        }
      },
      "required": ["runId", "finishedAt", "readme"],
      "type": "object"
    },
    "ProofResult": {
      "description": "The presence result for a single declared proof-of-implementation artifact.\n\nA test case can ask the agent to write evidence (a screenshot or short clip)\nto a known path; validation records whether each declared proof turned up in\nthe produced tree. This is **informational** — a missing proof never gates the\nrun's status; it is surfaced so a reviewer sees the gap.",
      "properties": {
        "dest": {
          "description": "The run-root-relative path the proof was expected at, carried through from\nthe declared proof. Locates the produced file for publishing and tells a UI\nwhere it lives.",
          "type": "string"
        },
        "detail": {
          "description": "Detail about a missing or unreadable proof, or `None` when present.",
          "type": ["string", "null"]
        },
        "id": {
          "description": "The proof id this result records under (matches a declared\n[`ProofFile`]).",
          "type": "string"
        },
        "kind": {
          "$ref": "#/$defs/MediaKind",
          "description": "Whether the proof media is an image or a video."
        },
        "name": {
          "description": "Human-readable display name, carried through from the declared proof.",
          "type": "string"
        },
        "present": {
          "description": "Whether the agent produced the proof at its declared `dest`.",
          "type": "boolean"
        }
      },
      "required": ["id", "name", "kind", "dest", "present"],
      "type": "object"
    },
    "RunEnvironment": {
      "description": "The container environment a run executed in.\n\nThese values are captured from inside the run container — not the host — so\nthey describe the environment the harness actually built in. The harness\nversion is not duplicated here; it lives in [`RunSubject::harness_version`].",
      "properties": {
        "authMode": {
          "$ref": "#/$defs/AuthMode",
          "description": "Which authentication mode the run used. This is how the run's cost should\nbe read: an API-key run is billed against that key, while a subscription\nrun carries no per-run provider charge (a harness that still reports an\nexact charge — Claude Code does even on a subscription — is recorded\nas-is; one that reports none falls back to OpenRouter comparable pricing)."
        },
        "containerImage": {
          "description": "The run-container image the run executed in: the single shared base image,\nthe same for every harness. The full, pullable reference pulled by digest\nfrom the registry (for example,\n`ghcr.io/theclockwyrks/test-cabinet-base@sha256:…`), or the local-build\nfallback tag for an offline run.",
          "type": "string"
        },
        "nodeVersion": {
          "description": "The Node.js version reported by `node --version` inside the container\n(for example, `v22.11.0`), or `None` when it could not be determined.",
          "type": ["string", "null"]
        },
        "os": {
          "description": "The container OS, taken from `/etc/os-release`'s `PRETTY_NAME` (for\nexample, `Debian GNU/Linux 12 (bookworm)`). `unknown` when the probe\ncould not determine it.",
          "type": "string"
        }
      },
      "required": ["os", "containerImage", "authMode"],
      "type": "object"
    },
    "RunLinks": {
      "description": "Links to a run's published outputs.",
      "properties": {
        "playableBuild": {
          "description": "The playable build, when one has been published.",
          "type": ["string", "null"]
        },
        "sourceRepo": {
          "description": "The public repository holding the run's generated source, when released.",
          "type": ["string", "null"]
        }
      },
      "type": "object"
    },
    "RunMetrics": {
      "description": "The full metrics block recorded in a [`crate::run_record::RunRecord`].",
      "properties": {
        "cost": {
          "$ref": "#/$defs/CostMetrics",
          "description": "Cost, recorded as comparable and actual."
        },
        "runTimeSeconds": {
          "description": "End-to-end wall-clock time of the run, in seconds.",
          "format": "double",
          "type": "number"
        },
        "tokens": {
          "$ref": "#/$defs/TokenMetrics",
          "description": "Normalized token usage."
        }
      },
      "required": ["runTimeSeconds", "tokens", "cost"],
      "type": "object"
    },
    "RunState": {
      "description": "The terminal state of a run — the single axis that decides publishability and\nhow a run scores. Classified objectively at the point a run ends: a clean\nharness exit splits into [`Completed`](RunState::Completed) and\n[`Catastrophic`](RunState::Catastrophic) (nothing to evaluate — the output\nnever built or loaded);\na harness that exits **non-zero** is a\n[`HarnessError`](RunState::HarnessError) and one that stops responding\naltogether is [`Hung`](RunState::Hung); a run stopped before the harness\nfinished is [`TimedOut`](RunState::TimedOut) (the runtime cap) or\n[`Infrastructure`](RunState::Infrastructure) (everything else).",
      "oneOf": [
        {
          "const": "completed",
          "description": "The harness exited cleanly and the run produced a usable, evaluable\nimplementation. Published through the review gate and scored on the\nreviewer checklist.",
          "type": "string"
        },
        {
          "const": "catastrophic",
          "description": "The harness exited cleanly — the model claimed completion — but the produced\noutput did not build/load, so there is nothing to evaluate and **no playable\nbuild**. The *model* is the reason: a catastrophic failure is real signal at\nthe benchmark's edge, so it is publishable (carrying its broken source), but\nit has no review checklist to score and is reported as a separate\ncatastrophic-failure statistic.\n\nReserved for a total failure to produce a runnable artifact. An output that\nbuilds and loads is reviewable however badly it behaves: a missing or\nnon-conformant debug API fails the individual checklist points its validation\nscripts back (see\n[`DebugScriptResult`](crate::validation::DebugScriptResult)), scoring the run\ndown rather than removing it from review.",
          "type": "string"
        },
        {
          "const": "timed_out",
          "description": "The run hit its maximum runtime and was stopped before the harness finished\n— the model never converged (a small model can legitimately loop on a hard\ntask). A distinct, publishable tier from [`Catastrophic`](RunState::Catastrophic);\nlikewise unscored and reported as its own timeout statistic.",
          "type": "string"
        },
        {
          "const": "harness_error",
          "description": "The agent harness (or the orchestrator runner driving it) exited **non-zero**\n— the model drove the harness to exit early, a real and reportable signal\nabout that model. Publishable **without** a review (recorded only as a\nper-model harness-error statistic on the model page), but — unlike the other\nfailure tiers — it releases **no** source repo and no playable build: a\nharness-error run produced no evaluable output worth releasing.\n\nPublishing is never automatic: a subscription auth-token refresh also\nsurfaces here as a non-zero exit and must **not** be reported, so a human\ndecides per run (through the same publish-failures affordance the other\ntiers use) which harness errors to record.",
          "type": "string"
        },
        {
          "const": "hung",
          "description": "The agent harness stopped producing output entirely and was killed as hung\n— it neither finished nor failed, it stalled (a provider request that never\nreturns, a subagent that never reports back).\n\nTreated exactly like a [`HarnessError`](RunState::HarnessError): publishable\n**without** a review as a per-model statistic, releasing no source repo and\nno playable build, and never published automatically. It is a distinct state\nbecause the cause is distinct — nothing exited, so there is no exit code to\nreport — and because a hung run is the one failure the Test Cabinet ends on\nits own timer rather than observing.",
          "type": "string"
        },
        {
          "const": "infrastructure",
          "description": "The Test Cabinet's own infrastructure failed: the container would not start\nor pull, a pod was OOM-killed, or seeding / the case's init step failed. Not\nthe model's fault — retained with a diagnostic [`RunStatus::detail`] for\ndebugging, but **never** publishable and excluded from every model statistic.\nA harness that merely exited non-zero is a\n[`HarnessError`](RunState::HarnessError), not this.",
          "type": "string"
        }
      ]
    },
    "RunStatus": {
      "description": "A run's status, with enough detail to understand a failure.",
      "properties": {
        "detail": {
          "description": "Optional human-readable detail, required in practice for failures.",
          "type": ["string", "null"]
        },
        "state": {
          "$ref": "#/$defs/RunState",
          "description": "The run's terminal state."
        }
      },
      "required": ["state"],
      "type": "object"
    },
    "RunSubject": {
      "description": "The subject of a run: what was run, with what, against which model.",
      "properties": {
        "harnessSlug": {
          "$ref": "#/$defs/HarnessSlug",
          "description": "The agent harness slug."
        },
        "harnessVersion": {
          "description": "The harness version, where it could be determined.",
          "type": ["string", "null"]
        },
        "modelId": {
          "description": "The model ID passed to the harness, treated as an opaque string.",
          "type": "string"
        },
        "orchestratorSlug": {
          "default": "one-shot",
          "description": "The resolved slug of the orchestrator that conducted the harness sessions\n(for example `one-shot` or `ralph`). For an external `--orchestrator-dir`\nthis is the directory's own manifest slug, not the request's. Defaults to\n`one-shot` so records written before orchestrator selection existed — and\nhand-written fixtures — still deserialize. See\n[orchestrators](crate::OrchestratorCatalog).",
          "type": "string"
        },
        "testCaseSlug": {
          "description": "The test case slug.",
          "type": "string"
        },
        "testCaseVersion": {
          "description": "The exact, immutable test case version.",
          "type": "string"
        },
        "testType": {
          "$ref": "#/$defs/TestType",
          "default": "end-to-end",
          "description": "The test type this case belongs to. Defaults to\n[`TestType::EndToEnd`](crate::TestType) so records written before the\ndiscriminator existed (all end-to-end) still deserialize. The UI branches\non this to choose how to present a run's result."
        },
        "variant": {
          "description": "The variant of the test case that was run (for example `base`).",
          "type": "string"
        }
      },
      "required": [
        "testCaseSlug",
        "testCaseVersion",
        "variant",
        "harnessSlug",
        "modelId"
      ],
      "type": "object"
    },
    "RunTooling": {
      "description": "Provenance for the Test Cabinet build that orchestrated a run.\n\nDistinct from [`RunSubject::harness_version`], which describes the agent\nharness: this identifies the build of the Test Cabinet orchestrator itself,\nso a run can be traced back to the exact code that produced it.",
      "properties": {
        "testCabinetCommit": {
          "description": "The Test Cabinet commit the run's binary was built from, suffixed with\n`-dirty` when built from a modified working tree. `None` when the build\ncould not determine it (for example, a build with no git repository).",
          "type": ["string", "null"]
        }
      },
      "type": "object"
    },
    "RunValidation": {
      "description": "The validation summary embedded in a [`crate::run_record::RunRecord`].",
      "properties": {
        "adversarial": {
          "anyOf": [
            {
              "$ref": "#/$defs/AdversarialResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The canonical-match result of an adversarial run. `None` for any other\ntype, so a non-adversarial summary serializes with no new field at all and\nits shape is unchanged."
        },
        "asset": {
          "anyOf": [
            {
              "$ref": "#/$defs/AssetGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The regenerate-and-score result of an asset-generation run. `None` for an\nend-to-end run, so an end-to-end summary serializes with no new field at\nall and its shape is unchanged."
        },
        "audio": {
          "anyOf": [
            {
              "$ref": "#/$defs/AudioGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The validation result of an audio asset-generation run. `None` for every\nother kind/type."
        },
        "build": {
          "anyOf": [
            {
              "$ref": "#/$defs/StepResult"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Outcome of the required static-build step, or `None` if it was never\nreached (the install failed, or there was no `package.json`)."
        },
        "checks": {
          "description": "Per-check results for the validation checks the test case declares.",
          "items": {
            "$ref": "#/$defs/CheckResult"
          },
          "type": "array"
        },
        "debugScripts": {
          "description": "Per-verdict-unit debug-script results (one per validated whole item or\nsub-item), for an end-to-end run whose case mandates\n[instrumentation](DebugScriptResult) and whose items opt into automated\nvalidation. Empty when the case declares no auto-validated units\n(so an unchanged case serializes with no new field at all). Unlike the\ninformational proofs, a script that did not run costs the run the checklist\npoint it backs: see [`DebugScriptResult`].",
          "items": {
            "$ref": "#/$defs/DebugScriptResult"
          },
          "type": "array"
        },
        "detail": {
          "description": "Detail about a fatal load failure (build failure, uncaught runtime error,\nor a missing browser that prevented capture).",
          "type": ["string", "null"]
        },
        "install": {
          "anyOf": [
            {
              "$ref": "#/$defs/StepResult"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Outcome of the required dependency-install step, or `None` if the build\nnever reached it (for example, no `package.json` was found)."
        },
        "loaded": {
          "description": "Whether the implementation built, served, and rendered without a fatal\nerror. This is the clearest possible signal about a run.",
          "type": "boolean"
        },
        "material": {
          "anyOf": [
            {
              "$ref": "#/$defs/MaterialGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The validation result of a `material` asset-generation run. `None` for every\nother kind/type."
        },
        "particle": {
          "anyOf": [
            {
              "$ref": "#/$defs/ParticleGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The validation result of a particle asset-generation run. `None` for every\nother kind/type."
        },
        "performance": {
          "anyOf": [
            {
              "$ref": "#/$defs/PerformanceResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The correctness-and-fuel result of a performance run. `None` for any other\ntype, so a non-performance summary serializes with no new field at all and\nits shape is unchanged."
        },
        "proofs": {
          "default": [],
          "description": "Per-proof presence results for the proof-of-implementation artifacts the\ntest case requests. Empty when the case declares none. Informational: a\nmissing proof does not change [`Self::loaded`].",
          "items": {
            "$ref": "#/$defs/ProofResult"
          },
          "type": "array"
        },
        "ui": {
          "anyOf": [
            {
              "$ref": "#/$defs/UiGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The validation result of a `ui` asset-generation run. `None` for every other\nkind/type."
        },
        "voxel": {
          "anyOf": [
            {
              "$ref": "#/$defs/VoxelGenResult"
            },
            {
              "type": "null"
            }
          ],
          "description": "The regenerate result of a voxel asset-generation run — also carries the\n**skinned** kinds (with [`VoxelGenResult::skinned`] set). `None` for every\nother type (and for the 2D sprite kinds, which use [`Self::asset`]), so a\nnon-voxel summary serializes with no new field at all."
        }
      },
      "required": ["loaded", "checks"],
      "type": "object"
    },
    "StepResult": {
      "description": "The outcome of a single **required** build step — dependency install or the\nstatic build — that every run performs before the load check.\n\nBuilding an implementation is not a single opaque step: the install and the\nbuild each run a manifest-declared command and each can fail on its own, so\neach is reported in the [`ValidationSummary`] in its own right rather than\nbeing folded silently into the load signal. See `docs/validation.md`.",
      "properties": {
        "command": {
          "description": "The command that was run (the manifest's `install` or `build` command).",
          "type": "string"
        },
        "detail": {
          "description": "Detail about a failure (a tail of the command's stderr), or `None` when\nthe step succeeded.",
          "type": ["string", "null"]
        },
        "succeeded": {
          "description": "Whether the command exited successfully.",
          "type": "boolean"
        }
      },
      "required": ["command", "succeeded"],
      "type": "object"
    },
    "TestType": {
      "description": "The type of a test case: which class of capability it measures and which\nmanifest tables it declares.\n\nToday five types exist in code: the original [`Self::EndToEnd`] (build a\nworking program), [`Self::FullStack`] (build a working program *and* produce\nits own assets with the asset-generation binaries, which are on `PATH` in the\nfull-stack run image), [`Self::AssetGeneration`] (drive a drawing tool toward a\ntarget image), [`Self::Adversarial`] (write a wasm controller pitted\nhead-to-head against a baseline), and [`Self::Performance`] (write a wasm\nengine scored on correctness plus the fuel it burns). The type is the explicit\ndiscriminator everything branches on\n— resolution, validation, the run record, and the UI — rather than being\ninferred from which tables a manifest happens to declare. It defaults to\n[`Self::EndToEnd`] so manifests that predate the discriminator keep resolving.",
      "oneOf": [
        {
          "const": "end-to-end",
          "description": "Build a working program judged by running it (the only type until now).",
          "type": "string"
        },
        {
          "const": "full-stack",
          "description": "Build a working program that must also **produce its own assets** during the\nrun, using the asset-generation binaries (`draw`, `draw-sheet`, `particle-2d`,\n`sfx-synth`, `sfx-sample`, `music`, …) baked onto `PATH` in the full-stack run\nimage. Behaves like [`Self::EndToEnd`] in every other respect — it releases a\nsource repo, has a `[build]` table, may declare `packages`, and is judged by\nrunning the built program — but selects the full-stack image instead of the\nbare base image. See `docs/testing/full-stack/`.",
          "type": "string"
        },
        {
          "const": "game-jam",
          "description": "Build an **entire game of any genre from a theme alone** — no spec, no\nreference mockups — that must be *playable* and *enjoyable*. Like\n[`Self::FullStack`] the model also **produces its own assets** during the\nrun (it selects the same full-stack run image), releases a source repo, has\na `[build]` table, and may declare `packages`; unlike it, a game jam seeds\nno `[[spec]]`/`[[reference]]` and is reviewed on a **graded** scale over\ngeneral categories (see [`crate::review::VerdictStatus::GRADES`]) rather\nthan pass/fail against a spec. See `docs/testing/game-jam/`.",
          "type": "string"
        },
        {
          "const": "asset-generation",
          "description": "Produce a graphical asset by driving a drawing tool one operation at a\ntime; the recorded operations are the authoritative output.",
          "type": "string"
        },
        {
          "const": "adversarial",
          "description": "Write a controller compiled to wasm that drives one side of a head-to-head\ngame; the controller is run repeatedly against a baseline opponent and the\nmatch outcome is the authoritative result. See\n`docs/testing/adversarial/`.",
          "type": "string"
        },
        {
          "const": "performance",
          "description": "Write an engine compiled to wasm that simulates a deterministic world; the\nengine's output is checked for correctness against a reference oracle and,\nwhen correct, scored by the fuel it consumes. The contract entry is invoked\n**once per input case** (not per tick), so the whole simulation runs in one\ncall. See `docs/testing/performance/`.",
          "type": "string"
        }
      ]
    },
    "TokenMetrics": {
      "description": "The four normalized token classes recorded for every run.\n\nThe [`crate::harness`] layer is responsible for translating each harness's\nraw reporting into these classes. In particular:\n\n- cached reads must be subtracted from input so [`Self::uncached_input`]\n  excludes them, and\n- reasoning tokens must be subtracted from output so [`Self::output`]\n  excludes them.\n\nEach class is optional: `None` means the harness does **not** report that\nclass at all (the value could not be determined), which is distinct from\n`Some(0)` (the harness reports the class and it was zero). Keeping the two\napart matters for any consumer that aggregates across classes — a total that\nfolds in an unknown class would be misleading, so such totals are themselves\nreported as unknown rather than silently treating the gap as zero.",
      "properties": {
        "cachedInput": {
          "description": "Input tokens served from the provider's cache (billed at a lower rate), or\n`None` when the harness does not break cached reads out.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "output": {
          "description": "Non-reasoning output tokens, or `None` when the harness does not report\noutput usage.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "reasoning": {
          "description": "Internal reasoning tokens (billed as output, tracked separately), or `None`\nwhen the harness does not break reasoning out — note that a harness which\nfolds reasoning into `output` reports `None` here, not `Some(0)`.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        },
        "uncachedInput": {
          "description": "Input tokens that were **not** served from the provider's cache, or `None`\nwhen the harness does not report input usage.",
          "format": "uint64",
          "minimum": 0,
          "type": ["integer", "null"]
        }
      },
      "type": "object"
    },
    "UiElementResult": {
      "description": "The validation result for one element of a `ui` run: its emitted flattened PNG,\nits decoded dimensions, and any authored nine-slice.",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated for this element (a missing\nPNG, a size mismatch, an out-of-bounds nine-slice), or `None`.",
          "type": ["string", "null"]
        },
        "height": {
          "description": "The decoded pixel height of the emitted PNG.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "image": {
          "description": "Run-root-relative path to this element's emitted flattened RGBA PNG — the\nreviewed image.",
          "type": "string"
        },
        "name": {
          "description": "The element name this result records under (`canvas` for a single-image case,\nthe declared `[[ui.element]]` name for a kit).",
          "type": "string"
        },
        "nineSlice": {
          "anyOf": [
            {
              "$ref": "#/$defs/NineSlice"
            },
            {
              "type": "null"
            }
          ],
          "description": "The nine-slice insets carried in `ui.json`, when the model authored them.\n`None` when the element declares no stretchable region."
        },
        "width": {
          "description": "The decoded pixel width of the emitted PNG.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": ["name", "image", "width", "height"],
      "type": "object"
    },
    "UiGenResult": {
      "description": "The validation result of a `ui` asset-generation run — the emitted flattened\nPNG(s) plus the parsed `ui.json`. A `ui` run is **not** regenerated: its output\nis the image data the `paint`/`ui` binaries emit, which the validator decodes and\nwell-formedness-checks. Present only on a `ui` run's [`ValidationSummary`].",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated at the run level (for\nexample a missing or malformed `ui.json`), or `None`.",
          "type": ["string", "null"]
        },
        "elements": {
          "description": "The per-element results: one for a single-image case, one per declared\nelement for a kit, in declared order.",
          "items": {
            "$ref": "#/$defs/UiElementResult"
          },
          "type": "array"
        }
      },
      "required": ["elements"],
      "type": "object"
    },
    "VoxelGenResult": {
      "description": "The regenerate result of a voxel asset-generation run — the 3D analog of\n[`AssetGenResult`].\n\nA static model ([`crate::test_case::AssetKind::VoxelModel`]) produces one\n[part](VoxelPartResult) (the whole model); an animated model\n([`crate::test_case::AssetKind::VoxelAnimation`]) produces one per declared\npart. There is no target model and no automated fidelity score; the regenerated\nmodel is reviewed against the brief. Present only on a voxel run's\n[`ValidationSummary`].",
      "properties": {
        "blender": {
          "default": false,
          "description": "Whether this is a **Blender** run (`blender-character`/`blender-prop`/\n`blender-mechanism`): the emitted mesh is a self-contained **native glTF** whose\nrig and animations (if any) are baked into the file itself (glTF skin + animation\nchannels), not authored as a `rig.json`. The marker tells the 3D viewer to load\nthe glTF with a native glTF player (skeleton and/or baked clips) rather than\nposing the mesh from an inline rig. A `blender-character` is additionally\n`skinned`; a `blender-prop` (static) and `blender-mechanism` (rigid node-hierarchy\nanimations) are **not**. `false` for every non-Blender run.",
          "type": "boolean"
        },
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated at the run level, or\n`None`. Per-part detail lives on each [`VoxelPartResult`].",
          "type": ["string", "null"]
        },
        "model": {
          "anyOf": [
            {
              "$ref": "#/$defs/ModelSpec"
            },
            {
              "type": "null"
            }
          ],
          "description": "The **required** rig (parts + joints) the case declared, for an animated\nmodel. The stable, game-facing joint interface reviewers score against.\n`None` for a static model."
        },
        "parts": {
          "description": "The per-part results: exactly one for a static model (named `model`), one per\ndeclared part for an animated model, in declared order.",
          "items": {
            "$ref": "#/$defs/VoxelPartResult"
          },
          "type": "array"
        },
        "rig": {
          "anyOf": [
            {
              "$ref": "#/$defs/ModelSpec"
            },
            {
              "type": "null"
            }
          ],
          "description": "The **full** rig the model actually produced (`rig.json`) — the required\nparts and joints plus any the model added of its own. This is what the\nviewer poses and a consuming game drives. `None` for a static model."
        },
        "skinned": {
          "default": false,
          "description": "Whether this is a **skinned** run (`mc-skinned`/`sn-skinned`/`dc-skinned`):\none continuous mesh bound to the rig and deformed by linear-blend skinning,\nrather than the rigid per-part posing of the other voxel-family kinds. The\nmarker tells the 3D viewer to skin the single mesh rather than pose per-part\nmeshes. `false` for every non-skinned voxel-family run.",
          "type": "boolean"
        }
      },
      "required": ["parts"],
      "type": "object"
    },
    "VoxelPartResult": {
      "description": "The regenerate result for one part of a voxel-generation run.\n\nFor a static model this is the whole model's one part; for an animated model\nthere is one per declared part. Cheat detection is retired for the voxel family:\nthe scored artifact is the emitted geometry (the `PartMesh`-shaped `.glb`\nevery voxel-family binary emits) plus reviewer judgment of the model's own\nrendered preview, so — unlike the sprite [`AssetFrameResult`] — a voxel part\ncarries no regenerated image and no cheat divergence.",
      "properties": {
        "detail": {
          "default": null,
          "description": "Detail about anything that could not be evaluated for this part.",
          "type": ["string", "null"]
        },
        "mesh": {
          "description": "Run-root-relative path to the `PartMesh`-shaped `.glb` this part's binary\nemitted — **what the client renders in 3D** for every voxel-family kind (both\nthe cube kinds and the six surface-meshed kinds emit it). `mesh.glb` for a\nstatic kind, `meshes/<part>.glb` per part for an animated one.",
          "type": "string"
        },
        "name": {
          "description": "The part name this result records under: `model` for a static model, the\ndeclared `[[model.part]]` name for an animated model.",
          "type": "string"
        },
        "operationCount": {
          "description": "How many operations this part's log recorded.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "opsLog": {
          "description": "Run-root-relative path to this part's recorded operation log.",
          "type": "string"
        },
        "previewImage": {
          "description": "Run-root-relative path to the isometric PNG the model rendered for this part\n(its `preview`) — the reviewed image for this part.",
          "type": "string"
        },
        "voxelCount": {
          "description": "How many occupied voxels the regenerated part contains.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name",
        "mesh",
        "previewImage",
        "opsLog",
        "operationCount",
        "voxelCount"
      ],
      "type": "object"
    }
  },
  "$id": "https://docs.testcabinet.ai/schema/core/run-record.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "The complete run record emitted by every run.\n\nThis is the contract consumed by the site and published with each run. Its\nshape is deliberately fixed; the `packages/run-record` bindings and the\npublished JSON Schema are generated from it (see the module docs).",
  "properties": {
    "environment": {
      "$ref": "#/$defs/RunEnvironment",
      "description": "The container environment the run executed in."
    },
    "finishedAt": {
      "description": "RFC 3339 timestamp for when the run finished.",
      "type": "string"
    },
    "gameJamPriorEntries": {
      "description": "The earlier entries this **game-jam** run was seeded with and briefed to build\nsomething distinct from: every prior run of the same jam by the same model whose\ngameplay README was written into the run's `previous-entries/` folder, oldest\nfirst — README body included, exactly as this run was shown it.\n\nEmpty for a jam's first run by a model (and for every other test type). Unlike\n[`game_jam_readme`](Self::game_jam_readme) these *are* meant to be shown: they\nare inputs to the run, the only ones not shared with every other run of the jam,\nand the Inputs tab renders each README inline beside the jam's prompt and specs.\nThe bodies are carried here rather than looked up from the runs that produced\nthem, because that is what makes them readable as inputs — a prior run may never\nbe published, and a record has to stand on its own. Defaulted and omitted when\nempty so records written before the field existed still deserialize.",
      "items": {
        "$ref": "#/$defs/PriorGameJamEntry"
      },
      "type": "array"
    },
    "gameJamReadme": {
      "description": "The gameplay `README.md` a **game-jam** run produced, captured verbatim from\nthe produced tree at run finish (trimmed to a sane cap). `None` for every\nother test type, and for a game-jam run that shipped no README.\n\nThis is what makes a later jam run aware of what earlier runs already built:\nthe backend serves the prior runs' READMEs (matched on the same jam and model,\nacross harnesses) back to a new run, which seeds them and is asked to build\nsomething distinct. Kept out of a run's other surfaces — it exists to brief the\n*next* run, not to be displayed. Defaulted and omitted when absent so records\nwritten before the field existed still deserialize and non-jam records stay\nslim.",
      "type": ["string", "null"]
    },
    "id": {
      "description": "A unique run ID.",
      "type": "string"
    },
    "links": {
      "$ref": "#/$defs/RunLinks",
      "description": "Links to published outputs."
    },
    "metrics": {
      "$ref": "#/$defs/RunMetrics",
      "description": "Resource metrics for the run."
    },
    "startedAt": {
      "description": "RFC 3339 timestamp for when the run started.",
      "type": "string"
    },
    "status": {
      "$ref": "#/$defs/RunStatus",
      "description": "Terminal status."
    },
    "subject": {
      "$ref": "#/$defs/RunSubject",
      "description": "What was run."
    },
    "tooling": {
      "$ref": "#/$defs/RunTooling",
      "description": "Provenance for the Test Cabinet build that orchestrated the run."
    },
    "validation": {
      "$ref": "#/$defs/RunValidation",
      "description": "Summary of the validation pass."
    }
  },
  "required": [
    "id",
    "startedAt",
    "finishedAt",
    "subject",
    "tooling",
    "environment",
    "metrics",
    "validation",
    "links",
    "status"
  ],
  "title": "RunRecord",
  "type": "object"
}
