# Get Tester Errors

- **Method:** `GET`
- **Path:** `/api/v1/runs/{run_id}/tester-errors`
- **Operation ID:** `get_tester_errors`
- **Tags:** artifact

The findings this run attributed to the persona's own action rather than to the product.

A mistyped credential, the wrong element, placeholder text read as a value: issue-shaped records that are
never issues - not in `/issues`, not in `issues_total`, not reproduced, never a ticket. Read them for why
a session stalled and for what to fix in the test setup. Empty with the run's `status` until the artifact
is assembled, like the other views; `classified` tells an artifact that never asked from one that found
none.

## Effective servers

- `https://api.saram.sh`

  Saram

## Authentication

- **HTTPBearer**: HTTP bearer

  a Saram API key (`sk_saram_<env>_...`) or a person's AuthKit access token, as `Authorization: Bearer <credential>`. Both are told apart by shape and produce the same principal.

## Path parameters

- **`run_id` (required)**: `string`

## Responses

### 200 Successful Response

**Content type:** `application/json`

schema: `TesterErrorList`, no additional properties

The run's tester errors: findings the harness attributed to its own persona, never to the product.

Issue-shaped - the same id, evidence and screenshots an issue carries - and never an issue: not in
`IssueList`, not in `issues_total`, not reproduced, never a ticket. They are served so a customer can see
why a session stalled on their own test setup (a mistyped credential, the wrong element) instead of reading
the stall as the product's.

- **`advisory` (required)**: `string`

  How to read this whole answer: harness-attributed, never a defect. What it may and may not be used
  for.
- **`classified` (required)**: `boolean`

  Whether the run's artifact sorts findings by whose failure they are at all. Empty with this false is an
  artifact from before the classification (contracts 0.5), or no artifact yet: nobody asked. Empty with this
  true is a run that asked and found none.
- **`reading` (required)**: `array`

  One entry per record, in the same order and naming its `tester_error_id`.

  **Items:**

  schema: `TesterErrorReading`, no additional properties

  How one record of `TesterErrorList.tester_errors` reads: what the persona did, and that it is never a
  ticket.
  - **`label` (required)**: `string`

    What the persona did, in the words every surface uses: the sentence the local MCP server, the GitHub PR
    comment and the dashboard all show for this kind.
  - **`tester_error_id` (required)**: `string`
  - **`may_file_ticket_alone`**: `boolean`, const: `false`, default: `false`

    False for every record in this array, by construction. Stated rather than left to be inferred from an
    absent field, because a reader that has to work it out is a reader that might not.
- **`run_id` (required)**: `string`
- **`status` (required)**: `string`

  The run's status. An empty `tester_errors` is only a result once this is terminal.
- **`subjective_fields` (required)**: `array of string`

  Fields on each record that are somebody's words rather than an observation: the persona's narration, and
  `tester_error.reason`, the harness's sentence about its own persona.
- **`tester_errors` (required)**: `array`

  The artifact's `tester_errors[]`, each the contract's own issue object with its `tester_error` block.

  **Items:**

  schema: `Issue`, no additional properties

  A product defect the run found: what the product did wrong, where, in how many of the sessions that got there, with the evidence and the steps that reproduce it. `claim.verification.status` says what checked it, and only a `verified` issue - `reproducible: true` - may be filed as a ticket on its own. `description` is objective; `persona_rationale` is the persona's voice.
  - **`affected_sessions` (required)**: `array of string`
  - **`confidence` (required)**: `number`, minimum: `0`, maximum: `1`
  - **`description` (required)**: `string`
  - **`evidence` (required)**: `object`, schema: `Evidence1`, no additional properties

    What the issue rests on: the steps where sessions met it (`step_refs`) and, when the run kept them, screenshots, a clip of the session's video, a snapshot of the page, and the network requests and console messages around it.
    - **`step_refs` (required)**: `array`, minItems: `1`

      **Items:**

      schema: `StepRef`

      One step of one session: the session's id and the step's number within it. A finding points at the steps it rests on, and that session's step events say what happened at each.
      - **`session_id` (required)**: `string`
      - **`step_id` (required)**: `integer`
    - **`console`**: `(array of object) | null`
    - **`dom_snapshot`**: `string | null`, format: `uri`, minLength: `1`
    - **`network`**: `(array of object) | null`
    - **`screenshots`**: `array | null`

      **Items:**

      `string`, format: `uri`, minLength: `1`
    - **`video`**: `object | null`, schema: `Video`

      A clip of a session's video that shows the issue: where the video is stored (`ref`), and where the clip starts and ends, in seconds from the start of the recording.
      - **`ref`**: `string | null`
      - **`ts_end_s`**: `number | null`
      - **`ts_start_s`**: `number | null`
  - **`id` (required)**: `string`
  - **`location` (required)**: `object`, schema: `Location1`, no additional properties

    Where the defect is: the page (`route`), the element in words (`element_description`) or as a selector (`selector`), and the screen size it was seen at (`viewport`, WIDTHxHEIGHT).
    - **`route` (required)**: `string`
    - **`element_description`**: `string | null`
    - **`selector`**: `string | null`
    - **`viewport`**: `string | null`
  - **`reproducible` (required)**: `boolean`
  - **`severity` (required)**: `string`, possible values: `"low", "medium", "high", "critical"`

    Schema: `Severity`.

    How much the defect costs the people who meet it, from least to most: `low`, `medium`, `high`, `critical`. Rated by the judge from the sessions, and lowered one step when the replay did not reproduce the issue and it stands as persona-specific friction. The GitHub connector files only issues at or above its `min_severity_for_issue`.
  - **`type` (required)**: `string`

    Schema: `Type`. Known values, open (more may be added): `blocker`, `friction`, `confusion`, `bug`, `contradiction`.

    Defect classes only. A moment that worked well is an opportunity of kind `delight`, never an issue: it has no failure for reproduction to replay.
  - **`affected_count`**: `integer | null`
  - **`affected_fraction`**: `number | null`, minimum: `0`, maximum: `1`
  - **`affected_personas`**: `(array of string) | null`
  - **`baseline_status`**: `string | null`

    Schema: `BaselineStatus`. Known values, open (more may be added): `new`, `persisting`, `resolved`, `unknown`.

    How this finding compares with the run named as the baseline. `new`: the baseline reached the same page and did not have it (for an issue, only one that is `reproducible`). `persisting`: the baseline has it too. `unknown`: nothing could say - no baseline was compared, the baseline never reached the page, or an issue the baseline does not have was not verified. `resolved` is never stamped on a finding of this run: a baseline issue this run no longer has is counted in `summary.issues_resolved_vs_baseline`. More values may be added; read one you do not know as `unknown`.
  - **`claim`**: `object | null`, schema: `Claim`, no additional properties

    What this issue asserts, and what checked it. A replay matching a failure marker at a step does not say the marker was the thing the title is about, and in practice it often is not; since 0.5 that match is `verification.status: marker_matched`, and `verified` is reserved for a claim a second check (`check`) found supported by a verbatim quote from the cited steps and whose failure is the product's (`attribution`). An issue with no `claim` block, or with none of `verification`, is `unverified`: never read the absence of this object as a confirmation.
    - **`action_step`**: `object | null`, schema: `ActionStep`, no additional properties

      The step the claim is about and the replay is judged at - the action that failed, not the look that saw it or the retry after it. Written by reproduction, which picks it (`_judged_path`); absent when nothing replayed this issue.
      - **`session_id` (required)**: `string`
      - **`step_id` (required)**: `integer`
    - **`attribution`**: `string | null`

      Schema: `Attribution`. Known values, open (more may be added): `product`, `tester`, `undetermined`.

      Whose failure this is, asked before an issue is a product finding: could the persona's own action explain it? `product`: no - the failure is the product's to own. `tester`: yes - a mistyped credential, the wrong element, placeholder text read as a value; the record moves to `tester_errors[]` with a `tester_error` block, is never a ticket and never counted as an issue. `undetermined`: the harness could not tell (a persona handed stale credentials by the mission author typed exactly what it was told; an attribution call that failed), and a human must; it caps `status` at `marker_matched`. Absent means never asked - every issue before this release - and a reader treats absent as `undetermined`. A classification: nothing acts on it directly, the producer derives `status` from it, so a later member (`setup`) is additive and an older reader buckets it as `unknown`.
    - **`check`**: `object | null`, schema: `Check`, no additional properties

      The claim check: one narrow question asked of the evidence at the cited steps after a replay matched a marker - does this evidence show the product doing what the title says? Descriptive: nothing acts on it directly; the producer derives `status` from `verdict` and `attribution`. Absent when the check never ran, which is every issue before this release and every issue no marker matched.
      - **`verdict` (required)**: `string`

        Schema: `Verdict1`. Known values, open (more may be added): `supported`, `unsupported`, `ungrounded`, `skipped`.

        `supported`: the checker answered yes with a quote that gates against the ledger text of the cited steps - the only verdict that lets `status` read `verified`. `unsupported`: the checker answered no; the title claims more than the quoted line shows. `ungrounded`: the checker answered yes but its quote is not in the ledger, so the answer is discarded the way an ungrounded diary quote is and recorded in the gate ledger. `skipped`: no marker matched, or the check did not run. A classification: a later verdict is additive.
      - **`checked_by`**: `string | null`

        Schema: `CheckedBy`. Known values, open (more may be added): `judge`, `code`, `manual`.

        Which instrument answered: `judge` for the observer's checker model call under its own instructions, `code` for a mechanical rule, `manual` for a human. A classification.
      - **`quote`**: `string | null`
      - **`quote_step`**: `object | null`, schema: `QuoteStep`, no additional properties

        The step whose ledger block the quote came from.
        - **`session_id` (required)**: `string`
        - **`step_id` (required)**: `integer`
      - **`reason`**: `string | null`
    - **`expected`**: `string | null`
    - **`observed`**: `string | null`
    - **`verification`**: `object | null`, schema: `Verification`, no additional properties

      Whether the claim was checked, and by what. The two are separate questions and were conflated once already: `status` is the answer a reader acts on, `method` only says which instrument produced it. Consumers show `status`.
      - **`status` (required)**: `string`, possible values: `"verified", "marker_matched", "inconclusive", "unverified"`

        Schema: `Status`.

        Best-supported first. `verified`: a replay matched the failure marker at `action_step` AND the claim check answered `supported` with a verbatim quote from the cited steps (`check`) AND the failure is attributed to the product (`attribution`) - or `method` is `assertion` or `manual` and the same two conditions hold. This and only this may file a ticket alone, and `reproducible` is true exactly when this reads `verified`. `marker_matched` (0.5): a replay matched the failure marker at `action_step`; the claim as titled is unchecked, unsupported, or the check could not quote. The step failed again; whether it failed for the stated reason is not established, so it never files alone. `inconclusive`: a check ran and settled nothing (the marker did not appear again, the two attempts disagreed) - not a refutation. `unverified`: nothing checked it, because there was nothing to check, reproduction never ruled, or the finding is a tester error. A wrong total or a select that resets is `unverified` by construction, not disproven. Default and safe reading when the block is absent. This enum drives an action - it is the ticket-filing gate, like `issue.severity` - so it stays closed for readers too and adding a member is a breaking change: a gate must refuse a value it cannot interpret rather than guess at one, which is why `marker_matched` made 0.5 a new family.
      - **`markers`**: `(array of string) | null`
      - **`method`**: `string | null`

        Schema: `Method`. Known values, open (more may be added): `marker`, `assertion`, `manual`.

        Which check ran, when one did; absent when `status` is `unverified`. `marker`: a replay compared the failure marker at `action_step` - name it in `markers`. A marker matching is evidence the step failed again, not that it failed for the reason the title gives, so on its own it produces `marker_matched`, and `verified` only with `check.verdict: supported` and `attribution: product`. `assertion`: a state assertion checked the claim itself (reserved; not produced yet). `manual`: a human checked it. A classification: nothing acts on it - every surface shows `status` - so a reader on an older release buckets an instrument it does not know as `unknown`, and adding one is additive.
      - **`note`**: `string | null`
  - **`connector_refs`**: `object | null`

    **Additional properties:**

    `string`
  - **`contradiction`**: `object | null`, schema: `Contradiction`, no additional properties

    Populated for type=contradiction: the two statements/surfaces that conflict, each pinned to a step.
    - **`a`**: `object | null`, schema: `A`

      The first of the two statements that conflict: what the product said (`text`), and the session and step where it said it.
      - **`session_id`**: `string | null`
      - **`step_id`**: `integer | null`
      - **`text`**: `string | null`
    - **`b`**: `object | null`, schema: `B`

      The second of the two statements that conflict: what the product said (`text`), and the session and step where it said it.
      - **`session_id`**: `string | null`
      - **`step_id`**: `integer | null`
      - **`text`**: `string | null`
  - **`first_seen_step`**: `integer | null`
  - **`persona_rationale`**: `string | null`
  - **`persona_specific`**: `boolean | null`
  - **`preconditions`**: `(array of string) | null`
  - **`reached_sessions`**: `(array of string) | null`
  - **`repro_steps`**: `array | null`

    **Items:**

    schema: `ReproStep`

    One step of a replay a person or a coding agent can run without the persona, in order from an `open` of the entry page. `action` is a browser action such as `click`, `type`, `key`, `scroll`, `back`, `reload`, `upload` or `wait`; `target` is what it acts on (the address for `open`, `x,y` screen coordinates for a `click`); `value` is what it types, presses or scrolls by; `expect` is what should hold after it, such as the address the page should be on.
    - **`action` (required)**: `string`
    - **`expect`**: `string | null`
    - **`replace`**: `boolean | null`
    - **`target`**: `string | null`
    - **`value`**: `string | null`
  - **`reproduction`**: `object | null`, schema: `Reproduction1`, no additional properties

    Whether Saram replayed the issue without the persona, and what the replay showed: whether one was `attempted`, its `result`, how many `attempts` it took, and `notes` on it. A replay that saw the failure again is not on its own enough to file a ticket; `reproducible` says whether this issue may be.
    - **`attempted`**: `boolean | null`
    - **`attempts`**: `integer | null`
    - **`notes`**: `string | null`
    - **`result`**: `string | null`

      Schema: `Result1`. Known values, open (more may be added): `reproduced`, `not_reproduced`, `flaky`, `skipped`.

      What the replay showed. `reproduced`: the failure happened again. `not_reproduced`: it did not. `flaky`: the attempts disagreed. `skipped`: no replay ran. More values may be added; read one you do not know as unknown.
  - **`suggested_owner`**: `string | null`
  - **`tester_error`**: `object | null`, schema: `TesterError`, no additional properties

    What the persona did that explains this failure. Present exactly when `claim.attribution` is `tester`, and such an issue is in `tester_errors[]`, never in `issues[]`. The quote is the evidence line that shows the persona's action - the input echo, the step head with its args, a diary line, a browser line - copied exactly from the ledger and gated the same way a diary quote is; a `tester` answer whose quote does not gate falls back to `undetermined` and this block is not written.
    - **`kind` (required)**: `string`

      Schema: `Kind1`. Known values, open (more may be added): `mistyped_credential`, `mistyped_input`, `wrong_element`, `placeholder_as_value`, `ignored_instruction`, `other`.

      `mistyped_credential`: typed an email or password that differs from the one the account gave it (decided by code, comparing the typed text with the account; no secret enters a prompt or this document). `mistyped_input`: typed something other than what the brief or the screen asked for. `wrong_element`: acted on an element other than the one the title is about, or a non-interactive one. `placeholder_as_value`: read placeholder text as a pre-filled value and tried to clear or fix it. `ignored_instruction`: skipped something the screen visibly asked for first. `other`: something else the persona did that explains it. Not a tester error, by rule: a persona misreading the product's intent when a reasonable customer would misread it the same way - that is `confusion`, and it is the product's. A classification: a later kind is additive.
    - **`quote` (required)**: `string`
    - **`decided_by`**: `string | null`

      Schema: `DecidedBy`. Known values, open (more may be added): `code`, `judge`.

      `code`: a mechanical comparison decided it (the credential check). `judge`: the observer's attribution model call under its own instructions decided it. A classification.
    - **`quote_step`**: `object | null`, schema: `QuoteStep`, no additional properties

      The step whose ledger block the quote came from.

      *Schema `QuoteStep` is shown above.*
    - **`reason`**: `string | null`
  - **`title`**: `string | null`, maxLength: `120`

**Example:**

```json
{
  "run_id": "",
  "status": "",
  "classified": true,
  "tester_errors": [
    {
      "id": "",
      "type": "blocker",
      "severity": "low",
      "reproducible": true,
      "reproduction": {
        "attempted": true,
        "result": "reproduced",
        "attempts": 1,
        "notes": ""
      },
      "persona_specific": true,
      "claim": {
        "action_step": {
          "session_id": "",
          "step_id": 1
        },
        "expected": "",
        "observed": "",
        "verification": {
          "status": "verified",
          "method": "marker",
          "markers": [
            ""
          ],
          "note": ""
        },
        "attribution": "product",
        "check": {
          "verdict": "supported",
          "quote": "",
          "quote_step": {
            "session_id": "",
            "step_id": 1
          },
          "reason": "",
          "checked_by": "judge"
        }
      },
      "tester_error": {
        "kind": "mistyped_credential",
        "quote": "",
        "quote_step": {
          "session_id": "",
          "step_id": 1
        },
        "decided_by": "code",
        "reason": ""
      },
      "affected_sessions": [
        ""
      ],
      "affected_personas": [
        ""
      ],
      "affected_count": 1,
      "affected_fraction": 0,
      "reached_sessions": [
        ""
      ],
      "first_seen_step": 1,
      "location": {
        "route": "",
        "selector": "",
        "element_description": "",
        "viewport": ""
      },
      "title": "",
      "description": "",
      "persona_rationale": "",
      "contradiction": {
        "a": {
          "step_id": 1,
          "session_id": "",
          "text": ""
        },
        "b": {
          "step_id": 1,
          "session_id": "",
          "text": ""
        }
      },
      "evidence": {
        "step_refs": [
          {
            "session_id": "",
            "step_id": 1
          }
        ],
        "screenshots": [
          ""
        ],
        "video": {
          "ref": "",
          "ts_start_s": 1,
          "ts_end_s": 1
        },
        "dom_snapshot": "",
        "network": [
          {
            "additionalProperty": "anything"
          }
        ],
        "console": [
          {
            "additionalProperty": "anything"
          }
        ]
      },
      "repro_steps": [
        {
          "action": "",
          "target": "",
          "value": "",
          "replace": true,
          "expect": ""
        }
      ],
      "preconditions": [
        ""
      ],
      "baseline_status": "new",
      "confidence": 0,
      "suggested_owner": "",
      "connector_refs": {
        "additionalProperty": ""
      }
    }
  ],
  "reading": [
    {
      "tester_error_id": "",
      "label": "",
      "may_file_ticket_alone": false
    }
  ],
  "advisory": "",
  "subjective_fields": [
    ""
  ]
}
```

### 403 the API key lacks the required scope

### 422 Validation Error

**Content type:** `application/json`

schema: `HTTPValidationError`

- **`detail`**: `array`

  **Items:**

  schema: `ValidationError`
  - **`loc` (required)**: `array of (string | integer)`
  - **`msg` (required)**: `string`
  - **`type` (required)**: `string`
  - **`ctx`**: `object`
  - **`input`**: `any`

**Example:**

```json
{
  "detail": [
    {
      "loc": [
        ""
      ],
      "msg": "",
      "type": "",
      "input": null,
      "ctx": {}
    }
  ]
}
```

## Schemas

- `A` — shown above.
- `ActionStep` — shown above.

### Attribution

**Type:** `string`

Known values, open (more may be added): `product`, `tester`, `undetermined`.

Whose failure this is, asked before an issue is a product finding: could the persona's own action explain it? `product`: no - the failure is the product's to own. `tester`: yes - a mistyped credential, the wrong element, placeholder text read as a value; the record moves to `tester_errors[]` with a `tester_error` block, is never a ticket and never counted as an issue. `undetermined`: the harness could not tell (a persona handed stale credentials by the mission author typed exactly what it was told; an attribution call that failed), and a human must; it caps `status` at `marker_matched`. Absent means never asked - every issue before this release - and a reader treats absent as `undetermined`. A classification: nothing acts on it directly, the producer derives `status` from it, so a later member (`setup`) is additive and an older reader buckets it as `unknown`.

**Example:**

```json
"product"
```

**Example:**

```json
"tester"
```

**Example:**

```json
"undetermined"
```

- `B` — shown above.

### BaselineStatus

**Type:** `string`

Known values, open (more may be added): `new`, `persisting`, `resolved`, `unknown`.

How this finding compares with the run named as the baseline. `new`: the baseline reached the same page and did not have it (for an issue, only one that is `reproducible`). `persisting`: the baseline has it too. `unknown`: nothing could say - no baseline was compared, the baseline never reached the page, or an issue the baseline does not have was not verified. `resolved` is never stamped on a finding of this run: a baseline issue this run no longer has is counted in `summary.issues_resolved_vs_baseline`. More values may be added; read one you do not know as `unknown`.

**Example:**

```json
"new"
```

**Example:**

```json
"persisting"
```

**Example:**

```json
"resolved"
```

**Example:**

```json
"unknown"
```

- `Check` — shown above.

### CheckedBy

**Type:** `string`

Known values, open (more may be added): `judge`, `code`, `manual`.

Which instrument answered: `judge` for the observer's checker model call under its own instructions, `code` for a mechanical rule, `manual` for a human. A classification.

**Example:**

```json
"judge"
```

**Example:**

```json
"code"
```

**Example:**

```json
"manual"
```

- `Claim` — shown above.
- `Contradiction` — shown above.

### DecidedBy

**Type:** `string`

Known values, open (more may be added): `code`, `judge`.

`code`: a mechanical comparison decided it (the credential check). `judge`: the observer's attribution model call under its own instructions decided it. A classification.

**Example:**

```json
"code"
```

**Example:**

```json
"judge"
```

- `Evidence1` — shown above.
- `HTTPValidationError` — shown above.
- `Issue` — shown above.

### Kind1

**Type:** `string`

Known values, open (more may be added): `mistyped_credential`, `mistyped_input`, `wrong_element`, `placeholder_as_value`, `ignored_instruction`, `other`.

`mistyped_credential`: typed an email or password that differs from the one the account gave it (decided by code, comparing the typed text with the account; no secret enters a prompt or this document). `mistyped_input`: typed something other than what the brief or the screen asked for. `wrong_element`: acted on an element other than the one the title is about, or a non-interactive one. `placeholder_as_value`: read placeholder text as a pre-filled value and tried to clear or fix it. `ignored_instruction`: skipped something the screen visibly asked for first. `other`: something else the persona did that explains it. Not a tester error, by rule: a persona misreading the product's intent when a reasonable customer would misread it the same way - that is `confusion`, and it is the product's. A classification: a later kind is additive.

**Example:**

```json
"mistyped_credential"
```

**Example:**

```json
"mistyped_input"
```

**Example:**

```json
"wrong_element"
```

**Example:**

```json
"placeholder_as_value"
```

**Example:**

```json
"ignored_instruction"
```

**Example:**

```json
"other"
```

- `Location1` — shown above.

### Method

**Type:** `string`

Known values, open (more may be added): `marker`, `assertion`, `manual`.

Which check ran, when one did; absent when `status` is `unverified`. `marker`: a replay compared the failure marker at `action_step` - name it in `markers`. A marker matching is evidence the step failed again, not that it failed for the reason the title gives, so on its own it produces `marker_matched`, and `verified` only with `check.verdict: supported` and `attribution: product`. `assertion`: a state assertion checked the claim itself (reserved; not produced yet). `manual`: a human checked it. A classification: nothing acts on it - every surface shows `status` - so a reader on an older release buckets an instrument it does not know as `unknown`, and adding one is additive.

**Example:**

```json
"marker"
```

**Example:**

```json
"assertion"
```

**Example:**

```json
"manual"
```

- `QuoteStep` — shown above.
- `ReproStep` — shown above.
- `Reproduction1` — shown above.

### Result1

**Type:** `string`

Known values, open (more may be added): `reproduced`, `not_reproduced`, `flaky`, `skipped`.

What the replay showed. `reproduced`: the failure happened again. `not_reproduced`: it did not. `flaky`: the attempts disagreed. `skipped`: no replay ran. More values may be added; read one you do not know as unknown.

**Example:**

```json
"reproduced"
```

**Example:**

```json
"not_reproduced"
```

**Example:**

```json
"flaky"
```

**Example:**

```json
"skipped"
```

### Severity

**Type:** `string`, possible values: `"low", "medium", "high", "critical"`

How much the defect costs the people who meet it, from least to most: `low`, `medium`, `high`, `critical`. Rated by the judge from the sessions, and lowered one step when the replay did not reproduce the issue and it stands as persona-specific friction. The GitHub connector files only issues at or above its `min_severity_for_issue`.

### Status

**Type:** `string`, possible values: `"verified", "marker_matched", "inconclusive", "unverified"`

Best-supported first. `verified`: a replay matched the failure marker at `action_step` AND the claim check answered `supported` with a verbatim quote from the cited steps (`check`) AND the failure is attributed to the product (`attribution`) - or `method` is `assertion` or `manual` and the same two conditions hold. This and only this may file a ticket alone, and `reproducible` is true exactly when this reads `verified`. `marker_matched` (0.5): a replay matched the failure marker at `action_step`; the claim as titled is unchecked, unsupported, or the check could not quote. The step failed again; whether it failed for the stated reason is not established, so it never files alone. `inconclusive`: a check ran and settled nothing (the marker did not appear again, the two attempts disagreed) - not a refutation. `unverified`: nothing checked it, because there was nothing to check, reproduction never ruled, or the finding is a tester error. A wrong total or a select that resets is `unverified` by construction, not disproven. Default and safe reading when the block is absent. This enum drives an action - it is the ticket-filing gate, like `issue.severity` - so it stays closed for readers too and adding a member is a breaking change: a gate must refuse a value it cannot interpret rather than guess at one, which is why `marker_matched` made 0.5 a new family.

- `StepRef` — shown above.
- `TesterError` — shown above.
- `TesterErrorList` — shown above.
- `TesterErrorReading` — shown above.

### Type

**Type:** `string`

Known values, open (more may be added): `blocker`, `friction`, `confusion`, `bug`, `contradiction`.

Defect classes only. A moment that worked well is an opportunity of kind `delight`, never an issue: it has no failure for reproduction to replay.

**Example:**

```json
"blocker"
```

**Example:**

```json
"friction"
```

**Example:**

```json
"confusion"
```

**Example:**

```json
"bug"
```

**Example:**

```json
"contradiction"
```

- `ValidationError` — shown above.

### Verdict1

**Type:** `string`

Known values, open (more may be added): `supported`, `unsupported`, `ungrounded`, `skipped`.

`supported`: the checker answered yes with a quote that gates against the ledger text of the cited steps - the only verdict that lets `status` read `verified`. `unsupported`: the checker answered no; the title claims more than the quoted line shows. `ungrounded`: the checker answered yes but its quote is not in the ledger, so the answer is discarded the way an ungrounded diary quote is and recorded in the gate ledger. `skipped`: no marker matched, or the check did not run. A classification: a later verdict is additive.

**Example:**

```json
"supported"
```

**Example:**

```json
"unsupported"
```

**Example:**

```json
"ungrounded"
```

**Example:**

```json
"skipped"
```

- `Verification` — shown above.
- `Video` — shown above.
