{
  "contract": "fact-list",
  "version": 2,
  "templates": [
    {
      "id": "fact-policy-holds",
      "title": "the readable-facts list is complete and has no duplicate pair",
      "type": "general",
      "expand": "once",
      "test": {
        "type": "general",
        "scope": "{{inputs:scope}}",
        "holds": "the readable-facts list has at least one row; every fact the Fixed prose promises the player can read appears in at least one row; no two rows name the same fact citation and the same channel",
        "diagnostics": [
          "{{instance}}-fact-list-completeness"
        ]
      },
      "text": "Audit class: observer-judged. Across the supplied scope, the readable-facts list has at least one row, every fact the Fixed prose promises the player can read appears in at least one row, and no two rows name the same fact citation and the same channel.",
      "inputs": {
        "scope": {
          "default": "all Fixed prose that promises the player can read a fact, and every readable-facts row"
        }
      }
    },
    {
      "id": "color-and-audio-policy-holds",
      "title": "the promised color and audio policies hold throughout play",
      "type": "general",
      "expand": "once",
      "bindings": {
        "color-result": {
          "flag": "color-alone",
          "map": {
            "never": "every fact the game shows remains readable after all hue differences are removed",
            "player-recolorable": "any fact the game shows that otherwise relies on hue alone becomes readable after the player changes every color carrying it, and the changed presentation is observed before readability is judged"
          }
        },
        "audio-result": {
          "flag": "audio-alone",
          "map": {
            "never": "every promised fact remains readable with audio muted and has at least one row whose channel is text, symbol-or-shape, place-or-size, animation, outline-or-contrast, or haptic",
            "allowed": "no promised fact becomes unreadable with audio muted except in the play situations its Fixed citation identifies as audio-only"
          }
        }
      },
      "test": {
        "type": "general",
        "scope": "every fact the game's Fixed prose says the player can tell, including facts with no readable-facts row, across the play situations that prose names",
        "holds": "{{bind:color-result}}; {{bind:audio-result}}",
        "diagnostics": [
          "{{instance}}-fact-observer-results",
          "{{instance}}-color-and-audio-state"
        ]
      },
      "text": "Audit class: observer-judged. Across every fact the game's Fixed prose says the player can tell, including facts with no readable-facts row, and the play situations that prose names, {{bind:color-result}}; {{bind:audio-result}}."
    },
    {
      "id": "presentation-control-visible",
      "title": "the promised presentation setting changes a fact in play",
      "type": "general",
      "expand": "once",
      "when": {
        "flag": {
          "presentation-control": [
            "player-configurable"
          ]
        }
      },
      "test": {
        "type": "general",
        "scope": "{{inputs:scope}}",
        "holds": "at least one player-facing setting changes or can disable a channel named by a readable-facts row; every row names every setting that changes or can disable its channel and states the result at each supported end; each declaration matches the running game in every applicable play situation named by the row's fact citation; when a setting can disable the row's channel, the row names another channel row for the same fact that remains readable or states that the fact becomes unreadable, and any unreadable result obeys the selected color and audio policies",
        "diagnostics": [
          "{{instance}}-presentation-settings",
          "{{instance}}-presentation-observer-results"
        ]
      },
      "text": "Audit class: observer-judged. Across the supplied scope, at least one player-facing setting changes or can disable a channel named by a readable-facts row. Every row names each setting that affects its channel and the result at every supported end, and the running game matches that declaration in every applicable cited situation. A row whose channel a setting can disable names another readable row for the same fact, or states that the fact becomes unreadable. An unreadable result obeys the selected color and audio policies.",
      "inputs": {
        "scope": {
          "default": "every player-facing presentation setting that affects a promised fact, across all applicable play situations named by that fact's Fixed citation"
        }
      }
    },
    {
      "id": "presentation-setting-effect-holds",
      "title": "the setting declaration for {{row.id}} matches play",
      "type": "scenario",
      "expand": "per-row",
      "collection": "readable-facts",
      "test": {
        "type": "scenario",
        "given": "the channel at {{row.fact}}; this row declares: {{row.presentation-settings}}",
        "when": [
          "every named setting is observed at both ends of its supported range in every applicable play situation named at {{row.fact}}"
        ],
        "then": [
          "the channel changes or is disabled exactly as declared",
          "if the channel is disabled, another declared row keeps the fact readable or this row states that the fact becomes unreadable, and that result obeys the selected color and audio policies"
        ],
        "diagnostics": [
          "{{instance}}-{{row.id}}-presentation-setting-result"
        ]
      },
      "text": "Audit class: observer-judged. For {{row.id}}, observe every named setting at both ends of its supported range in every applicable situation named at {{row.fact}}. The channel changes or is disabled exactly as declared. If the channel is disabled, another row keeps the fact readable or this row states that the fact becomes unreadable, and that result obeys the selected color and audio policies. This row declares: {{row.presentation-settings}}"
    },
    {
      "id": "audio-off-result-holds",
      "title": "the audio-off result for {{row.id}} matches play",
      "type": "scenario",
      "expand": "per-row",
      "collection": "readable-facts",
      "when": {
        "row": {
          "channel": [
            "audio-cue",
            "spatial-audio",
            "narration",
            "audio-description"
          ]
        }
      },
      "test": {
        "type": "scenario",
        "given": "the audio channel at {{row.fact}} and this row's audio-off declaration: {{row.without-audio}}",
        "when": [
          "audio is turned off in every play situation named at {{row.fact}}"
        ],
        "then": [
          "the player receives the declared non-audio route or the fact becomes unreadable exactly as declared",
          "an unreadable result occurs only when the selected audio policy allows it"
        ],
        "diagnostics": [
          "{{instance}}-{{row.id}}-audio-off-result"
        ]
      },
      "text": "Audit class: observer-judged. With audio off in every situation named at {{row.fact}}, the row promises: {{row.without-audio}} If that declaration says the fact becomes unreadable, the selected audio policy must allow it."
    },
    {
      "id": "fact-readable-by-channel",
      "title": "the fact defined at {{row.fact}} is readable through {{bind:channel-route}} alone",
      "type": "scenario",
      "expand": "per-row",
      "collection": "readable-facts",
      "bindings": {
        "channel-route": {
          "row_field": "channel",
          "map": {
            "text": "words or numbers shown to the player",
            "symbol-or-shape": "a pictorial symbol, distinct shape, or pattern",
            "place-or-size": "where something sits or how large or full it is",
            "animation": "movement over time",
            "outline-or-contrast": "an outline or light-dark contrast",
            "audio-cue": "a non-spatial audio cue",
            "spatial-audio": "the direction or position of a sound",
            "narration": "spoken interface or screen narration",
            "audio-description": "spoken description of visual action or presentation",
            "haptic": "vibration or another touch pattern"
          }
        }
      },
      "test": {
        "type": "scenario",
        "given": "the fact defined at {{row.fact}}, checked separately in every play situation named there; every other route to the fact, declared or not, is removed or made identical across the states that the observer must distinguish, so that {{bind:channel-route}} is the only thing that changes with the fact; developer instrumentation that the game does not present to the player, such as an audit pane, a debug overlay, or a save file, is not a route",
        "when": [
          "within each named play situation, an observer using {{bind:channel-route}} meets each state the cited prose names at least once, in an order the observer does not know, with no prior knowledge of which state is present"
        ],
        "then": [
          "in each named play situation, the observer correctly names the state every time from {{bind:channel-route}} alone"
        ],
        "diagnostics": [
          "{{instance}}-{{row.id}}-observer-result"
        ]
      },
      "text": "Audit class: observer-judged. The check repeats in every play situation named at {{row.fact}}. Every other route to the fact, declared or not, is removed or made identical across the states that the observer must distinguish. Then the only thing that changes with the fact is {{bind:channel-route}}. Developer instrumentation that the game does not present to the player, such as an audit pane, a debug overlay, or a save file, is not a route. Within each named play situation, an observer meets each state the cited prose names at least once, in an order that the observer does not know, and correctly names the state every time from {{bind:channel-route}} alone."
    }
  ]
}
