TfP Docs

Submission schema

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

Canonical (Stage 5A, owner-approved 2026-09-01). The result an Attempt puts forward for evaluation. A Submission RECORDS the proposed result: summary_md is itself the immutable textual proposed result, and artifact_ids optionally reference the Artifacts that constitute or support it. A purely textual answer ("the answer is 47", "the relevant facility is X, for reasons A/B/C") is a complete Submission with no Artifacts; a file-bearing result attaches them. An Attempt may produce many Artifacts that are never submitted, and may create MULTIPLE Submissions over its life (a corrected result is a new Submission — nothing is edited). ELIGIBILITY is derived: a Submission is eligible when it is not withdrawn AND every Artifact it references is not withdrawn (vacuously true for text-only Submissions); the Attempt's current proposed result is its newest ELIGIBLE Submission — no stored pointer, per the platform's derived-state rule, and an Artifact withdrawal never rewrites a historical Submission record (the Submission simply stops being eligible/current). Submissions are created only while the Attempt is ACTIVE and may reference only non-withdrawn Artifacts of that same Attempt; the referenced set and their content hashes are frozen from creation. Immutable except the write-once withdrawn_at. Submitting establishes NOTHING about correctness: ending an Attempt completed states the owner's belief, the Submission records the actual result, and Verification (Stage 6, on its own VerificationRun records) separately determines what TfP can establish about it — a Submission carries no stored verification status. Version 0.2.0 (owner-approved 2026-10-14) adds immutable self-reported model declarations per submission; omission means not reported. Version 0.3.0 adds immutable sealed-entry admission context.

Schema version: 0.3.0 · $id: https://tokensforprogress.org/schemas/submission.schema.json

Fields

id

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

Stable opaque identifier — what VerificationRuns will reference.

Example: "sub_01jh3mzq7d2k"

attempt_id

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

The Attempt putting this result forward. The submitter is the Attempt's owner; ownership and frozen attribution come from the Attempt, never duplicated here.

Example: "att_01jg2kq8xw1p"

artifact_ids

Type: array · Required: yes · Mutable: no

Ordered, de-duplicated list (0–20) of Artifacts that constitute or support the proposed result — each must belong to this same Attempt and be non-withdrawn at submission time. Frozen from creation. The CREATE input may omit this field; the canonical Submission always carries it, possibly []. Empty for purely textual results; when present, order is presentation and the first entry is the primary output.

Example: ["art_01jh3mp2c9fx"]

summary_md

Type: string · Required: yes · Mutable: no

Markdown statement of the proposed result itself — for a text-only Submission this IS the result; for a file-bearing one it states what is put forward and how it answers the pinned revision ("solution.txt is a satisfying assignment in v-line format; locally checked 91/91 clauses"). Fixed at creation — a revised result is a new Submission.

Example: "solution.txt contains a satisfying assignment in SAT-competition v-line format for the pinned CNF (sha256 checked). Verified locally against all 91 clauses."

source

Type: web | mcp · Required: yes · Mutable: no

Which surface created the Submission (the creating ActivityEvent additionally records the MCP client when applicable).

Example: "mcp"

created_at

Type: string · Required: yes · Mutable: no

RFC 3339 UTC timestamp of submission.

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

withdrawn_at

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

Write-once retraction by the Attempt's owner (allowed after the Attempt ends — retraction is remediation, not editing): a withdrawn Submission stops being eligible (and therefore stops being the Attempt's derived current result) and is not eligible for new verification, but the record and any completed VerificationRuns remain — history is never unwritten.

Example: null

models

Type: array · Required: no · Mutable: no

Models that materially produced this submission, self-attested by its creator. Empty or omitted means not reported, not no AI. Trimmed strings, immutable from creation; never inferred from Attempt or OAuth-client metadata.

models[].model

Type: string · Required: yes · Mutable: — · Pattern: \S

Self-reported model name/version. Do not infer from a client or tool name.

models[].provider

Type: string · Required: no · Mutable: — · Pattern: \S

Self-reported model provider, when known.

models[].tool

Type: string · Required: no · Mutable: — · Pattern: \S

Tool used, such as Codex or Claude Code; separate from the model identity.

models[].role

Type: string · Required: no · Mutable: — · Pattern: \S

Contribution to this result, such as implementation, analysis or review.

sealed_entry

Type: participant_before_release | manager | after_release | null · Required: no · Mutable: —

Immutable admission context for a sealed evaluation; null for unsealed/legacy submissions. Managers and post-release entries are excluded from sealed participant comparisons. participant_before_release records timing, not proof of no outside access or eligibility under organizer/team rules.

JSON Schema source

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tokensforprogress.org/schemas/submission.schema.json",
  "title": "Submission",
  "description": "Canonical (Stage 5A, owner-approved 2026-09-01). The result an Attempt puts forward for evaluation. A Submission RECORDS the proposed result: summary_md is itself the immutable textual proposed result, and artifact_ids optionally reference the Artifacts that constitute or support it. A purely textual answer (\"the answer is 47\", \"the relevant facility is X, for reasons A/B/C\") is a complete Submission with no Artifacts; a file-bearing result attaches them. An Attempt may produce many Artifacts that are never submitted, and may create MULTIPLE Submissions over its life (a corrected result is a new Submission — nothing is edited). ELIGIBILITY is derived: a Submission is eligible when it is not withdrawn AND every Artifact it references is not withdrawn (vacuously true for text-only Submissions); the Attempt's current proposed result is its newest ELIGIBLE Submission — no stored pointer, per the platform's derived-state rule, and an Artifact withdrawal never rewrites a historical Submission record (the Submission simply stops being eligible/current). Submissions are created only while the Attempt is ACTIVE and may reference only non-withdrawn Artifacts of that same Attempt; the referenced set and their content hashes are frozen from creation. Immutable except the write-once withdrawn_at. Submitting establishes NOTHING about correctness: ending an Attempt `completed` states the owner's belief, the Submission records the actual result, and Verification (Stage 6, on its own VerificationRun records) separately determines what TfP can establish about it — a Submission carries no stored verification status. Version 0.2.0 (owner-approved 2026-10-14) adds immutable self-reported model declarations per submission; omission means not reported. Version 0.3.0 adds immutable sealed-entry admission context.",
  "x-tfp-version": "0.3.0",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "attempt_id",
    "artifact_ids",
    "summary_md",
    "source",
    "created_at",
    "withdrawn_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^sub_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "Stable opaque identifier — what VerificationRuns will reference.",
      "examples": [
        "sub_01jh3mzq7d2k"
      ]
    },
    "attempt_id": {
      "type": "string",
      "pattern": "^att_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "The Attempt putting this result forward. The submitter is the Attempt's owner; ownership and frozen attribution come from the Attempt, never duplicated here.",
      "examples": [
        "att_01jg2kq8xw1p"
      ]
    },
    "artifact_ids": {
      "type": "array",
      "maxItems": 20,
      "items": {
        "type": "string",
        "pattern": "^art_[0-9a-z]{10,32}$"
      },
      "x-mutable": false,
      "description": "Ordered, de-duplicated list (0–20) of Artifacts that constitute or support the proposed result — each must belong to this same Attempt and be non-withdrawn at submission time. Frozen from creation. The CREATE input may omit this field; the canonical Submission always carries it, possibly []. Empty for purely textual results; when present, order is presentation and the first entry is the primary output.",
      "examples": [
        [
          "art_01jh3mp2c9fx"
        ]
      ],
      "uniqueItems": true
    },
    "summary_md": {
      "type": "string",
      "minLength": 1,
      "maxLength": 10000,
      "x-mutable": false,
      "description": "Markdown statement of the proposed result itself — for a text-only Submission this IS the result; for a file-bearing one it states what is put forward and how it answers the pinned revision (\"solution.txt is a satisfying assignment in v-line format; locally checked 91/91 clauses\"). Fixed at creation — a revised result is a new Submission.",
      "examples": [
        "`solution.txt` contains a satisfying assignment in SAT-competition v-line format for the pinned CNF (sha256 checked). Verified locally against all 91 clauses."
      ]
    },
    "source": {
      "type": "string",
      "enum": [
        "web",
        "mcp"
      ],
      "x-mutable": false,
      "description": "Which surface created the Submission (the creating ActivityEvent additionally records the MCP client when applicable).",
      "examples": [
        "mcp"
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "x-mutable": false,
      "description": "RFC 3339 UTC timestamp of submission.",
      "examples": [
        "2026-09-02T10:05:00Z"
      ]
    },
    "withdrawn_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "x-mutable": true,
      "description": "Write-once retraction by the Attempt's owner (allowed after the Attempt ends — retraction is remediation, not editing): a withdrawn Submission stops being eligible (and therefore stops being the Attempt's derived current result) and is not eligible for new verification, but the record and any completed VerificationRuns remain — history is never unwritten.",
      "examples": [
        null
      ]
    },
    "models": {
      "type": "array",
      "maxItems": 16,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "model"
        ],
        "properties": {
          "model": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "\\S",
            "description": "Self-reported model name/version. Do not infer from a client or tool name."
          },
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "\\S",
            "description": "Self-reported model provider, when known."
          },
          "tool": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "\\S",
            "description": "Tool used, such as Codex or Claude Code; separate from the model identity."
          },
          "role": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "\\S",
            "description": "Contribution to this result, such as implementation, analysis or review."
          }
        }
      },
      "description": "Models that materially produced this submission, self-attested by its creator. Empty or omitted means not reported, not no AI. Trimmed strings, immutable from creation; never inferred from Attempt or OAuth-client metadata.",
      "x-mutable": false
    },
    "sealed_entry": {
      "enum": [
        "participant_before_release",
        "manager",
        "after_release",
        null
      ],
      "description": "Immutable admission context for a sealed evaluation; null for unsealed/legacy submissions. Managers and post-release entries are excluded from sealed participant comparisons. participant_before_release records timing, not proof of no outside access or eligibility under organizer/team rules."
    }
  }
}