TfP Docs

VerificationRun schema

Generated from the canonical schema schemas/verification-run.schema.json by scripts/generate-schema-docs.mjs — do not edit this page by hand.

Stage 6A contract with sealed-evaluation projections. The permanent record of one evaluation of one Submission under the VerifierContract pinned by its Attempt's ProblemRevision. Immutable once finished, never edited or deleted; a re-examination is a new run. A run walks the Contract's ordered stages and records one stage_result per stage attempted, so a partially-completed evaluation states how far acceptance got. It is self-contained: it records the Contract, the ProblemRevision, and the exact input artifact ids with their content hashes and sizes, and each stage records the mechanism that settled it, so the record stays interpretable after the Submission is withdrawn and the bytes are deleted. Nothing about verification is stored on the Submission; what TfP shows is derived from runs. Public reads apply the pinned revision sealing policy: protected diagnostics stay withheld until label release; final-only outcomes and scores stay withheld until score release. Stored records remain intact.

Schema version: 0.4.0 · $id: https://tokensforprogress.org/schemas/verification-run.schema.json

Fields

id

Type: string · Required: yes · Mutable: no · Pattern: ^vrn_[0-9a-z]{10,32}$

Stable opaque identifier. Canonical URL /verifications/{id} — a claim is citable as one durable link.

Example: "vrn_01jp6q3d0gyl"

submission_id

Type: string · Required: yes · Mutable: no · Pattern: ^sub_[0-9a-z]{10,32}$

The Submission examined. Who did the work and for whom comes from that Submission's Attempt and is never duplicated here.

Example: "sub_01jh3mzq7d2k"

problem_revision_id

Type: string · Required: yes · Mutable: no · Pattern: ^prv_[0-9a-z]{10,32}$

The ProblemRevision whose pin selected this Contract — the Attempt's own pinned revision, recorded so a claim states which version of the problem was answered. A later revision pinning a different Contract does not unsettle this run.

Example: "prv_01jg1h8m3n2q"

verifier_contract_id

Type: string · Required: yes · Mutable: no · Pattern: ^vct_[0-9a-z]{10,32}$

The Contract that defines what this run's result means, at the version pinned here.

Example: "vct_01jf90aa4rrc"

trigger

Type: submission | rerun | manual · Required: yes · Mutable: no

Why this run exists. submission: started automatically when the Submission was created. rerun: an explicit re-examination, typically after a corrected implementation. manual: started by an operator. Reruns are explicit and additive; registering a new implementation never re-verifies history implicitly.

Example: "submission"

inputs

Type: object · Required: yes · Mutable: no

Exactly what was examined, frozen at run time. The ids record which Artifacts and the hashes record which bytes, so a later withdrawal deletes the bytes without affecting this record. Evidence of what was checked, not a promise that the bytes remain re-checkable.

inputs.artifacts

Type: array · Required: yes · Mutable: —

The Artifacts consumed, in Contract role order. Empty when the Contract accepts a text-only answer and the Submission gave one.

inputs.summary_included

Type: boolean · Required: yes · Mutable: —

Whether the Submission's summary_md was itself an input (true for text-answer Contracts). The summary text is immutable and is never deleted, so it needs no hash here.

Example: false

stage_results

Type: array · Required: yes · Mutable: yes

One entry per Contract stage attempted, in Contract order, appended as the run progresses and frozen with the run. Stages stop at the first that does not pass, so a list shorter than the Contract's plan records where acceptance got to. Each entry pins the mechanism that settled it.

stage_results[].stage_key

Type: string · Required: yes · Mutable: —

The Contract stage this settles.

Example: "assignment_check"

stage_results[].kind

Type: sandbox | review | external · Required: yes · Mutable: —

The stage's mechanism kind, copied from the Contract so a run reads correctly on its own.

Example: "sandbox"

stage_results[].status

Type: queued | running | finished · Required: yes · Mutable: —

Execution state of this stage. Forward-only.

Example: "finished"

stage_results[].result

Type: verified | refuted | inconclusive | error | null · Required: yes · Mutable: —

What this stage established, using the same four outcomes as the run: only refuted is a finding about the participant's work. Null until the stage finishes. Protected evaluation outcomes may also be null until the announced score release.

Example: "verified"

stage_results[].evidence_md

Type: string · Required: yes · Mutable: —

Human-readable account of what this stage checked and found. Protected-stage evidence is replaced with a withholding notice until label release.

Example: "Parsed 250 v-line assignments; evaluated 91/91 clauses satisfied."

stage_results[].mechanism

Type: object · Required: yes · Mutable: —

The mechanism that settled this stage. Exactly one member is non-null, matching kind. Each shape preserves what makes that kind of claim checkable later.

stage_results[].log

Type: object \| null · Required: yes · Mutable: — · Default: null

This stage's captured output, stored by TfP and served from /verifications/{id}/stages/{stage_key}/log. TfP's own record rather than a participant Artifact, so it is not withdrawable. Null when the stage produced no output.

stage_results[].started_at

Type: string \| null · Required: yes · Mutable: — · Default: null

When this stage began.

Example: "2026-09-05T10:00:04Z"

stage_results[].finished_at

Type: string \| null · Required: yes · Mutable: — · Default: null

When this stage finished.

Example: "2026-09-05T10:01:28Z"

status

Type: queued | running | finished · Required: yes · Mutable: yes

Workflow state, kept separate from the outcome: waiting on a check is a fact about the run, not a finding about the Submission. Transitions are forward-only. A run that cannot complete still reaches finished, with an error result; a run that reaches a stage TfP cannot execute finishes inconclusive rather than remaining open.

Example: "finished"

result

Type: verified | refuted | inconclusive | error | null · Required: yes · Mutable: yes

The outcome, written once when status becomes finished; null before then, or while the revision withholds the evaluation outcome until its score-release date. verified: every stage passed. refuted: a stage showed the Contract's statement does not hold. inconclusive: the evaluation could not settle the question — submission_requirements unmet, a resource limit exhausted, or a stage TfP cannot execute. error: TfP's machinery failed, which says nothing about the work. Only refuted is a statement about the participant's result. Interfaces present these as Verified / Did not satisfy the verifier / Could not determine / Verification error.

Example: "verified"

score

Type: number \| null · Required: yes · Mutable: yes · Default: null

The measured number on the Contract's declared scale, when result_kind is score and the result is verified. Null otherwise. Also null while the revision withholds evaluation scores.

Example: null

evidence_md

Type: string · Required: yes · Mutable: yes

Human-readable account of the run as a whole, written when it finishes: which stages passed, where it stopped, and why. Per-stage detail lives in stage_results. Empty while the run is unfinished. For sealed evaluations the public projection may contain a withholding notice; stored evidence is not rewritten.

Example: "Stage assignment_check verified: 91/91 clauses satisfied by the submitted assignment under implementation vfi_01jn5p2c9fxk (conformance 4/4)."

created_at

Type: string · Required: yes · Mutable: no

RFC 3339 UTC timestamp the run was created (queued).

Example: "2026-09-05T10:00:00Z"

started_at

Type: string \| null · Required: yes · Mutable: yes · Default: null

When the first stage began; null while queued.

Example: "2026-09-05T10:00:04Z"

finished_at

Type: string \| null · Required: yes · Mutable: yes · Default: null

When the run reached finished. Write-once: after it is set the run is fully immutable except for revocation and operator log redaction.

Example: "2026-09-05T10:01:28Z"

revocation

Type: object \| null · Required: yes · Mutable: yes · Default: null

Write-once retraction of the run's claim, used when the mechanism that produced it is found not to match its Contract. Additive: the run, its inputs, its stage results, and its logs remain readable, and the record states that the claim no longer stands and why. A revoked run stops contributing to the current verdict; it does not become a refutation. Null while the claim stands.

revocation.revoked_at

Type: string · Required: yes · Mutable: —

When the claim was retracted.

Example: "2026-10-02T14:00:00Z"

revocation.revoked_by_user_id

Type: string · Required: yes · Mutable: — · Pattern: ^usr_[0-9a-z]{10,32}$

Who retracted it — accountability for a retraction is part of the record.

Example: "usr_01jf90aa4rrc"

revocation.reason_md

Type: string · Required: yes · Mutable: —

Why the claim no longer stands, stated plainly.

Example: "Implementation v2 accepted assignments mentioning variables outside the instance, which the Contract rejects; all runs it produced are revoked pending re-examination under v3."

JSON Schema source

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tokensforprogress.org/schemas/verification-run.schema.json",
  "title": "VerificationRun",
  "description": "Stage 6A contract with sealed-evaluation projections. The permanent record of one evaluation of one Submission under the VerifierContract pinned by its Attempt's ProblemRevision. Immutable once finished, never edited or deleted; a re-examination is a new run. A run walks the Contract's ordered stages and records one stage_result per stage attempted, so a partially-completed evaluation states how far acceptance got. It is self-contained: it records the Contract, the ProblemRevision, and the exact input artifact ids with their content hashes and sizes, and each stage records the mechanism that settled it, so the record stays interpretable after the Submission is withdrawn and the bytes are deleted. Nothing about verification is stored on the Submission; what TfP shows is derived from runs. Public reads apply the pinned revision sealing policy: protected diagnostics stay withheld until label release; final-only outcomes and scores stay withheld until score release. Stored records remain intact.",
  "x-tfp-version": "0.4.0",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "submission_id",
    "problem_revision_id",
    "verifier_contract_id",
    "trigger",
    "inputs",
    "stage_results",
    "status",
    "result",
    "score",
    "evidence_md",
    "created_at",
    "started_at",
    "finished_at",
    "revocation"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^vrn_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "Stable opaque identifier. Canonical URL /verifications/{id} — a claim is citable as one durable link.",
      "examples": [
        "vrn_01jp6q3d0gyl"
      ]
    },
    "submission_id": {
      "type": "string",
      "pattern": "^sub_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "The Submission examined. Who did the work and for whom comes from that Submission's Attempt and is never duplicated here.",
      "examples": [
        "sub_01jh3mzq7d2k"
      ]
    },
    "problem_revision_id": {
      "type": "string",
      "pattern": "^prv_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "The ProblemRevision whose pin selected this Contract — the Attempt's own pinned revision, recorded so a claim states which version of the problem was answered. A later revision pinning a different Contract does not unsettle this run.",
      "examples": [
        "prv_01jg1h8m3n2q"
      ]
    },
    "verifier_contract_id": {
      "type": "string",
      "pattern": "^vct_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "The Contract that defines what this run's result means, at the version pinned here.",
      "examples": [
        "vct_01jf90aa4rrc"
      ]
    },
    "trigger": {
      "type": "string",
      "enum": [
        "submission",
        "rerun",
        "manual"
      ],
      "x-mutable": false,
      "description": "Why this run exists. `submission`: started automatically when the Submission was created. `rerun`: an explicit re-examination, typically after a corrected implementation. `manual`: started by an operator. Reruns are explicit and additive; registering a new implementation never re-verifies history implicitly.",
      "examples": [
        "submission"
      ]
    },
    "inputs": {
      "type": "object",
      "additionalProperties": false,
      "x-mutable": false,
      "required": [
        "artifacts",
        "summary_included"
      ],
      "description": "Exactly what was examined, frozen at run time. The ids record which Artifacts and the hashes record which bytes, so a later withdrawal deletes the bytes without affecting this record. Evidence of what was checked, not a promise that the bytes remain re-checkable.",
      "properties": {
        "artifacts": {
          "type": "array",
          "maxItems": 20,
          "description": "The Artifacts consumed, in Contract role order. Empty when the Contract accepts a text-only answer and the Submission gave one.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "role",
              "artifact_id",
              "content_hash",
              "size_bytes"
            ],
            "properties": {
              "role": {
                "type": "string",
                "maxLength": 40,
                "description": "The Contract role this Artifact filled.",
                "examples": [
                  "assignment"
                ]
              },
              "artifact_id": {
                "type": "string",
                "pattern": "^art_[0-9a-z]{10,32}$",
                "description": "The Artifact consumed.",
                "examples": [
                  "art_01jh3mp2c9fx"
                ]
              },
              "content_hash": {
                "type": "string",
                "pattern": "^sha256:[0-9a-f]{64}$",
                "description": "The server-computed hash of the exact bytes examined — carried into this record so the claim names the bytes even after they are deleted.",
                "examples": [
                  "sha256:3f786850e387550fdab836ed7e6dc881de23001b3f786850e387550fdab836ed"
                ]
              },
              "size_bytes": {
                "type": "integer",
                "minimum": 0,
                "description": "Size of the bytes examined.",
                "examples": [
                  4096
                ]
              }
            }
          }
        },
        "summary_included": {
          "type": "boolean",
          "description": "Whether the Submission's summary_md was itself an input (true for text-answer Contracts). The summary text is immutable and is never deleted, so it needs no hash here.",
          "examples": [
            false
          ]
        }
      }
    },
    "stage_results": {
      "type": "array",
      "maxItems": 10,
      "x-mutable": true,
      "description": "One entry per Contract stage attempted, in Contract order, appended as the run progresses and frozen with the run. Stages stop at the first that does not pass, so a list shorter than the Contract's plan records where acceptance got to. Each entry pins the mechanism that settled it.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "stage_key",
          "kind",
          "status",
          "result",
          "evidence_md",
          "mechanism",
          "log",
          "started_at",
          "finished_at"
        ],
        "properties": {
          "stage_key": {
            "type": "string",
            "maxLength": 40,
            "description": "The Contract stage this settles.",
            "examples": [
              "assignment_check"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "sandbox",
              "review",
              "external"
            ],
            "description": "The stage's mechanism kind, copied from the Contract so a run reads correctly on its own.",
            "examples": [
              "sandbox"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "finished"
            ],
            "description": "Execution state of this stage. Forward-only.",
            "examples": [
              "finished"
            ]
          },
          "result": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "verified",
              "refuted",
              "inconclusive",
              "error",
              null
            ],
            "description": "What this stage established, using the same four outcomes as the run: only `refuted` is a finding about the participant's work. Null until the stage finishes. Protected evaluation outcomes may also be null until the announced score release.",
            "examples": [
              "verified"
            ]
          },
          "evidence_md": {
            "type": "string",
            "maxLength": 20000,
            "description": "Human-readable account of what this stage checked and found. Protected-stage evidence is replaced with a withholding notice until label release.",
            "examples": [
              "Parsed 250 v-line assignments; evaluated 91/91 clauses satisfied."
            ]
          },
          "mechanism": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "sandbox",
              "review",
              "external"
            ],
            "description": "The mechanism that settled this stage. Exactly one member is non-null, matching `kind`. Each shape preserves what makes that kind of claim checkable later.",
            "properties": {
              "sandbox": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "default": null,
                "required": [
                  "verifier_implementation_id",
                  "implementation_content_hash",
                  "runtime_image_digest",
                  "backend",
                  "exit_code",
                  "duration_ms",
                  "evidence_hash"
                ],
                "description": "For `sandbox` stages: the executed mechanism, pinned by id and by hash, plus the backend that ran it and the digest of the evidence it produced.",
                "properties": {
                  "verifier_implementation_id": {
                    "type": "string",
                    "pattern": "^vfi_[0-9a-z]{10,32}$",
                    "description": "The conforming implementation executed. Only an implementation whose conformance has passed produces an authoritative run.",
                    "examples": [
                      "vfi_01jn5p2c9fxk"
                    ]
                  },
                  "implementation_content_hash": {
                    "type": "string",
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "description": "That implementation's content_hash at execution time.",
                    "examples": [
                      "sha256:1a2b3c4d5e6f708192a3b4c5d6e7f80912a3b4c5d6e7f8091a2b3c4d5e6f70819"
                    ]
                  },
                  "runtime_image_digest": {
                    "type": "string",
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "description": "Digest of the image actually executed — never a tag, which can move.",
                    "examples": [
                      "sha256:9f2b7c1e4a8d6035b1c2ee74d0f39a4b5c6d7e8f90123456789abcdef0123456"
                    ]
                  },
                  "exit_code": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Process exit code; null when the process was killed by a limit.",
                    "examples": [
                      0
                    ]
                  },
                  "duration_ms": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0,
                    "description": "Wall-clock execution time, so a near-timeout result is visible as such. Null for the tfp-builtin backend: it runs inside the Worker, whose clock does not advance during synchronous execution, so no honest measurement exists.",
                    "examples": [
                      84120
                    ]
                  },
                  "backend": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "The execution backend TfP selected for this run. Recorded here, never on the implementation, so verification claims do not depend on which provider ran them.",
                    "examples": [
                      "cloudflare-sandbox"
                    ]
                  },
                  "evidence_hash": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "default": null,
                    "description": "Deterministic tree digest of everything the implementation wrote under /output/evidence/, when anything was written.",
                    "examples": [
                      null
                    ]
                  }
                }
              },
              "review": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "default": null,
                "required": [
                  "review_process_id",
                  "review_protocol_id",
                  "protocol_hash"
                ],
                "description": "For `review` stages: the ReviewProcess that adjudicated it, the ReviewProtocol it executed, and the hash of the exact protocol snapshot. The process record carries the full evidence — assignments, reviewer identities or agent configurations, structured responses, rationale, citations, and every reducer step.",
                "properties": {
                  "review_process_id": {
                    "type": "string",
                    "pattern": "^rpr_[0-9a-z]{10,32}$",
                    "description": "The ReviewProcess that adjudicated this stage.",
                    "examples": [
                      "rpr_01jq7r4e1hzm"
                    ]
                  },
                  "protocol_hash": {
                    "type": "string",
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "description": "Hash of the frozen Review Protocol snapshot, so the process is reconstructible even after Campaign settings change.",
                    "examples": [
                      "sha256:2b3c4d5e6f708192a3b4c5d6e7f80912a3b4c5d6e7f8091a2b3c4d5e6f7081920"
                    ]
                  },
                  "review_protocol_id": {
                    "type": "string",
                    "pattern": "^rpt_[0-9a-z]{10,32}$",
                    "description": "The immutable ReviewProtocol the process executed.",
                    "examples": [
                      "rpt_01jq6p3c0gxk"
                    ]
                  }
                }
              },
              "external": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "default": null,
                "required": [
                  "system",
                  "reference",
                  "rule_owner",
                  "evidence_hash",
                  "attested_by_user_id",
                  "attested_at"
                ],
                "description": "For `external` stages: the external system that settled it, the durable reference by which the claim can be traced back, and who owned the rule. Execution adapters come later; the record shape is fixed now.",
                "properties": {
                  "system": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The external institution, instrument, or resolution source.",
                    "examples": [
                      "Open Reaction Database"
                    ]
                  },
                  "reference": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "description": "Their durable identifier for the acceptance, assay, or resolution.",
                    "examples": [
                      "ord-dataset-9c1f2a"
                    ]
                  },
                  "evidence_hash": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "default": null,
                    "description": "Hash of any evidence document TfP stored for this stage.",
                    "examples": [
                      null
                    ]
                  },
                  "attested_by_user_id": {
                    "type": "string",
                    "pattern": "^usr_[0-9a-z]{10,32}$",
                    "description": "The User who recorded this external outcome. External stages depend on a person's attestation; naming them is what makes it accountable.",
                    "examples": [
                      "usr_01jf90aa4rrc"
                    ]
                  },
                  "attested_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "When the outcome was recorded in TfP, which may be much later than when it occurred externally.",
                    "examples": [
                      "2026-11-14T09:00:00Z"
                    ]
                  },
                  "rule_owner": {
                    "type": "string",
                    "enum": [
                      "contract",
                      "partner"
                    ],
                    "description": "Copied from the Contract stage: whether TfP applied the Contract's own acceptance rule to the returned evidence, or the external party's judgment was the result.",
                    "examples": [
                      "contract"
                    ]
                  }
                }
              }
            }
          },
          "log": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": false,
            "default": null,
            "required": [
              "content_hash",
              "size_bytes",
              "truncated",
              "redaction"
            ],
            "description": "This stage's captured output, stored by TfP and served from /verifications/{id}/stages/{stage_key}/log. TfP's own record rather than a participant Artifact, so it is not withdrawable. Null when the stage produced no output.",
            "properties": {
              "content_hash": {
                "type": "string",
                "pattern": "^sha256:[0-9a-f]{64}$",
                "description": "Hash of the stored log bytes.",
                "examples": [
                  "sha256:0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9"
                ]
              },
              "size_bytes": {
                "type": "integer",
                "minimum": 0,
                "description": "Size of the stored log.",
                "examples": [
                  18422
                ]
              },
              "truncated": {
                "type": "boolean",
                "description": "Whether output exceeded the capture ceiling and was cut. Recorded rather than hidden, so nobody mistakes a truncated log for the whole story.",
                "examples": [
                  false
                ]
              },
              "redaction": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "default": null,
                "required": [
                  "redacted_at",
                  "redacted_by_user_id",
                  "reason",
                  "original_content_hash",
                  "original_size_bytes"
                ],
                "description": "Operator-only removal of log content, for a credential or personal data captured in verifier output. Participants cannot invoke it. Append-only and audited: the actor, time, reason, and the original content hash and length are retained, so the record states that a log of that hash and length existed and was redacted, without retaining the content. A run's inputs, artifact hashes, stage results, result, and evidence_md are never redactable.",
                "properties": {
                  "redacted_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "When the log content was removed.",
                    "examples": [
                      "2026-10-02T14:00:00Z"
                    ]
                  },
                  "redacted_by_user_id": {
                    "type": "string",
                    "pattern": "^usr_[0-9a-z]{10,32}$",
                    "description": "The operator responsible.",
                    "examples": [
                      "usr_01jf90aa4rrc"
                    ]
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "secret_material",
                      "personal_data",
                      "legal_requirement"
                    ],
                    "description": "Why, from a closed list.",
                    "examples": [
                      "secret_material"
                    ]
                  },
                  "original_content_hash": {
                    "type": "string",
                    "pattern": "^sha256:[0-9a-f]{64}$",
                    "description": "Hash of the log content as it stood before redaction. Retained so the record can state that a log with this hash and length existed, without retaining the content itself.",
                    "examples": [
                      "sha256:0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9"
                    ]
                  },
                  "original_size_bytes": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Length of the log content before redaction.",
                    "examples": [
                      18422
                    ]
                  }
                }
              },
              "resource_uri": {
                "type": "string",
                "pattern": "^tfp://verifications/vrn_[0-9a-z]+/stages/[a-z0-9_]+/log$",
                "description": "MCP Resource serving the log bytes (read-only; same visibility as the run).",
                "examples": [
                  "tfp://verifications/vrn_01hxyz/stages/assignment_check/log"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Web URL serving the same bytes.",
                "examples": [
                  "https://tokensforprogress.org/verifications/vrn_01hxyz/stages/assignment_check/log"
                ]
              }
            }
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "default": null,
            "description": "When this stage began.",
            "examples": [
              "2026-09-05T10:00:04Z"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "default": null,
            "description": "When this stage finished.",
            "examples": [
              "2026-09-05T10:01:28Z"
            ]
          }
        }
      }
    },
    "status": {
      "type": "string",
      "enum": [
        "queued",
        "running",
        "finished"
      ],
      "x-mutable": true,
      "description": "Workflow state, kept separate from the outcome: waiting on a check is a fact about the run, not a finding about the Submission. Transitions are forward-only. A run that cannot complete still reaches `finished`, with an `error` result; a run that reaches a stage TfP cannot execute finishes `inconclusive` rather than remaining open.",
      "examples": [
        "finished"
      ]
    },
    "result": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "verified",
        "refuted",
        "inconclusive",
        "error",
        null
      ],
      "x-mutable": true,
      "description": "The outcome, written once when status becomes `finished`; null before then, or while the revision withholds the evaluation outcome until its score-release date. `verified`: every stage passed. `refuted`: a stage showed the Contract's statement does not hold. `inconclusive`: the evaluation could not settle the question — submission_requirements unmet, a resource limit exhausted, or a stage TfP cannot execute. `error`: TfP's machinery failed, which says nothing about the work. Only `refuted` is a statement about the participant's result. Interfaces present these as Verified / Did not satisfy the verifier / Could not determine / Verification error.",
      "examples": [
        "verified"
      ]
    },
    "score": {
      "type": [
        "number",
        "null"
      ],
      "x-mutable": true,
      "default": null,
      "description": "The measured number on the Contract's declared scale, when result_kind is `score` and the result is `verified`. Null otherwise. Also null while the revision withholds evaluation scores.",
      "examples": [
        null
      ]
    },
    "evidence_md": {
      "type": "string",
      "maxLength": 20000,
      "x-mutable": true,
      "description": "Human-readable account of the run as a whole, written when it finishes: which stages passed, where it stopped, and why. Per-stage detail lives in stage_results. Empty while the run is unfinished. For sealed evaluations the public projection may contain a withholding notice; stored evidence is not rewritten.",
      "examples": [
        "Stage `assignment_check` verified: 91/91 clauses satisfied by the submitted assignment under implementation vfi_01jn5p2c9fxk (conformance 4/4)."
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "x-mutable": false,
      "description": "RFC 3339 UTC timestamp the run was created (queued).",
      "examples": [
        "2026-09-05T10:00:00Z"
      ]
    },
    "started_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "x-mutable": true,
      "default": null,
      "description": "When the first stage began; null while queued.",
      "examples": [
        "2026-09-05T10:00:04Z"
      ]
    },
    "finished_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "x-mutable": true,
      "default": null,
      "description": "When the run reached `finished`. Write-once: after it is set the run is fully immutable except for revocation and operator log redaction.",
      "examples": [
        "2026-09-05T10:01:28Z"
      ]
    },
    "revocation": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": false,
      "x-mutable": true,
      "default": null,
      "required": [
        "revoked_at",
        "revoked_by_user_id",
        "reason_md"
      ],
      "description": "Write-once retraction of the run's claim, used when the mechanism that produced it is found not to match its Contract. Additive: the run, its inputs, its stage results, and its logs remain readable, and the record states that the claim no longer stands and why. A revoked run stops contributing to the current verdict; it does not become a refutation. Null while the claim stands.",
      "properties": {
        "revoked_at": {
          "type": "string",
          "format": "date-time",
          "description": "When the claim was retracted.",
          "examples": [
            "2026-10-02T14:00:00Z"
          ]
        },
        "revoked_by_user_id": {
          "type": "string",
          "pattern": "^usr_[0-9a-z]{10,32}$",
          "description": "Who retracted it — accountability for a retraction is part of the record.",
          "examples": [
            "usr_01jf90aa4rrc"
          ]
        },
        "reason_md": {
          "type": "string",
          "minLength": 1,
          "maxLength": 10000,
          "description": "Why the claim no longer stands, stated plainly.",
          "examples": [
            "Implementation v2 accepted assignments mentioning variables outside the instance, which the Contract rejects; all runs it produced are revoked pending re-examination under v3."
          ]
        }
      }
    }
  }
}