ReviewProcess schema
Generated from the canonical schema
schemas/review-process.schema.jsonbyscripts/generate-schema-docs.mjs— do not edit this page by hand.
Frozen contract (Stage 7A, 2026-09-02; seats and claims 2026-09-02). One execution of one immutable ReviewProtocol against one subject. The process snapshots the exact protocol document and its hash, so it remains interpretable after the protocol is yanked or Campaign defaults change. It records every node's execution — every assignment on a review node (each claim of a human seat, and each hosted-agent issuance) and each reducer's exact operation, inputs, and output — and its final structured outcome. A process is finite: each review node's deadline (policy.assignment_timeout_hours from when the node opened) bounds it, and a process that cannot obtain the judgments the protocol requires by then finishes inconclusive with a reason rather than staying open. No 'current review state' is stored on the subject; anything shown about it is derived from processes.
Schema version: 0.1.1 · $id: https://tokensforprogress.org/schemas/review-process.schema.json
Fields
id
Type: string · Required: yes · Mutable: no · Pattern: ^rpr_[0-9a-z]{10,32}$
Example: "rpr_01jq7r4e1hzm"
review_protocol_id
Type: string · Required: yes · Mutable: no · Pattern: ^rpt_[0-9a-z]{10,32}$
Example: "rpt_01jq6p3c0gxk"
protocol_hash
Type: string · Required: yes · Mutable: no · Pattern: ^sha256:[0-9a-f]{64}$
content_hash of the protocol as executed; must equal the hash of protocol_snapshot.
Example: "sha256:2b3c4d5e6f708192a3b4c5d6e7f80912a3b4c5d6e7f8091a2b3c4d5e6f7081920"
protocol_snapshot
Type: object · Required: yes · Mutable: no
The exact tfp.review/v0.1 document executed (ReviewProtocol.document), frozen here.
purpose
Type: acceptance | triage | ranking | audit · Required: yes · Mutable: no
Copied from the protocol so the record reads on its own.
Example: "acceptance"
subject
Type: object · Required: yes · Mutable: no
subject.kind
Type: submission | problem_proposal | campaign_proposal · Required: yes · Mutable: —
subject.id
Type: string · Required: yes · Mutable: —
Example: "sub_01jh3mzq7d2k"
invoked_by
Type: object \| null · Required: yes · Mutable: no · Default: null
When this process settles a review stage of a VerifierContract: the run and stage. Null when review was invoked for another purpose (triage, ranking, audit) outside a verification run.
invoked_by.verification_run_id
Type: string · Required: yes · Mutable: — · Pattern: ^vrn_[0-9a-z]{10,32}$
invoked_by.stage_key
Type: string · Required: yes · Mutable: —
status
Type: queued | running | finished · Required: yes · Mutable: yes
Forward-only workflow state.
node_results
Type: array · Required: yes · Mutable: yes
One entry per node in the protocol, appended as execution proceeds.
node_results[].node_id
Type: string · Required: yes · Mutable: — · Pattern: ^[a-z][a-z0-9_]{0,39}$
node_results[].type
Type: review | reduce · Required: yes · Mutable: —
node_results[].status
Type: pending | running | completed | skipped | failed · Required: yes · Mutable: —
skipped: the node's when condition was not met. failed: the node's seats were not all completed by its deadline (human node), or no configured provider could fill it (hosted agent node).
node_results[].started_at
Type: string \| null · Required: yes · Mutable: — · Default: null
node_results[].finished_at
Type: string \| null · Required: yes · Mutable: — · Default: null
node_results[].assignment_ids
Type: array \| null · Required: yes · Mutable: — · Default: null
review nodes: every assignment on this node — each human claim (including declined and expired ones) and each hosted-agent issuance (including invalid ones). Null for reduce nodes, which have no assignments.
node_results[].reducer
Type: object \| null · Required: yes · Mutable: — · Default: null
reduce nodes: the exact operation, its inputs, and its deterministic output, so every final decision is reconstructible.
node_results[].skipped_reason
Type: string \| null · Required: yes · Mutable: — · Default: null
outcome
Type: object \| null · Required: yes · Mutable: yes · Default: null
The output node's reducer output, written once when status becomes finished. Null before then, and null when the process finished without reaching its output node (see inconclusive_reason).
outcome.control
Type: accept | reject | unresolved · Required: yes · Mutable: —
outcome.value
Type: undefined · Required: yes · Mutable: —
inconclusive_reason
Type: reviewers_unavailable | assignment_timeouts_exhausted | protocol_invalid | cancelled | null · Required: yes · Mutable: yes · Default: null
Set when the process finished without a substantive outcome. reviewers_unavailable: a review node reached its deadline with seats uncompleted, or no hosted provider could fill an agent node. protocol_invalid: the pinned protocol could not be executed. cancelled: withdrawn. assignment_timeouts_exhausted is LEGACY: emitted by the retired replacement-budget engine before the pull-based change (2026-09-02); kept so historical records validate, never emitted now.
created_at
Type: string · Required: yes · Mutable: no
started_at
Type: string \| null · Required: yes · Mutable: yes · Default: null
finished_at
Type: string \| null · Required: yes · Mutable: yes · Default: null
JSON Schema source
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tokensforprogress.org/schemas/review-process.schema.json",
"title": "ReviewProcess",
"description": "Frozen contract (Stage 7A, 2026-09-02; seats and claims 2026-09-02). One execution of one immutable ReviewProtocol against one subject. The process snapshots the exact protocol document and its hash, so it remains interpretable after the protocol is yanked or Campaign defaults change. It records every node's execution — every assignment on a review node (each claim of a human seat, and each hosted-agent issuance) and each reducer's exact operation, inputs, and output — and its final structured outcome. A process is finite: each review node's deadline (policy.assignment_timeout_hours from when the node opened) bounds it, and a process that cannot obtain the judgments the protocol requires by then finishes `inconclusive` with a reason rather than staying open. No 'current review state' is stored on the subject; anything shown about it is derived from processes.",
"x-tfp-version": "0.1.1",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"review_protocol_id",
"protocol_hash",
"protocol_snapshot",
"purpose",
"subject",
"invoked_by",
"status",
"node_results",
"outcome",
"inconclusive_reason",
"created_at",
"started_at",
"finished_at"
],
"properties": {
"id": {
"type": "string",
"pattern": "^rpr_[0-9a-z]{10,32}$",
"x-mutable": false,
"examples": [
"rpr_01jq7r4e1hzm"
]
},
"review_protocol_id": {
"type": "string",
"pattern": "^rpt_[0-9a-z]{10,32}$",
"x-mutable": false,
"examples": [
"rpt_01jq6p3c0gxk"
]
},
"protocol_hash": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$",
"x-mutable": false,
"description": "content_hash of the protocol as executed; must equal the hash of protocol_snapshot.",
"examples": [
"sha256:2b3c4d5e6f708192a3b4c5d6e7f80912a3b4c5d6e7f8091a2b3c4d5e6f7081920"
]
},
"protocol_snapshot": {
"type": "object",
"x-mutable": false,
"description": "The exact tfp.review/v0.1 document executed (ReviewProtocol.document), frozen here."
},
"purpose": {
"type": "string",
"enum": [
"acceptance",
"triage",
"ranking",
"audit"
],
"x-mutable": false,
"description": "Copied from the protocol so the record reads on its own.",
"examples": [
"acceptance"
]
},
"subject": {
"type": "object",
"additionalProperties": false,
"x-mutable": false,
"required": [
"kind",
"id"
],
"properties": {
"kind": {
"type": "string",
"enum": [
"submission",
"problem_proposal",
"campaign_proposal"
]
},
"id": {
"type": "string",
"minLength": 1,
"maxLength": 40,
"examples": [
"sub_01jh3mzq7d2k"
]
}
}
},
"invoked_by": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"x-mutable": false,
"default": null,
"required": [
"verification_run_id",
"stage_key"
],
"description": "When this process settles a `review` stage of a VerifierContract: the run and stage. Null when review was invoked for another purpose (triage, ranking, audit) outside a verification run.",
"properties": {
"verification_run_id": {
"type": "string",
"pattern": "^vrn_[0-9a-z]{10,32}$"
},
"stage_key": {
"type": "string",
"maxLength": 40
}
}
},
"status": {
"type": "string",
"enum": [
"queued",
"running",
"finished"
],
"x-mutable": true,
"description": "Forward-only workflow state."
},
"node_results": {
"type": "array",
"maxItems": 16,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"node_id",
"type",
"status",
"started_at",
"finished_at",
"assignment_ids",
"reducer",
"skipped_reason"
],
"properties": {
"node_id": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,39}$"
},
"type": {
"type": "string",
"enum": [
"review",
"reduce"
]
},
"status": {
"type": "string",
"enum": [
"pending",
"running",
"completed",
"skipped",
"failed"
],
"description": "`skipped`: the node's `when` condition was not met. `failed`: the node's seats were not all completed by its deadline (human node), or no configured provider could fill it (hosted agent node)."
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"default": null
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"default": null
},
"assignment_ids": {
"type": [
"array",
"null"
],
"default": null,
"maxItems": 100,
"items": {
"type": "string",
"pattern": "^ras_[0-9a-z]{10,32}$"
},
"description": "review nodes: every assignment on this node — each human claim (including declined and expired ones) and each hosted-agent issuance (including invalid ones). Null for reduce nodes, which have no assignments."
},
"reducer": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"default": null,
"required": [
"op",
"config",
"config_hash",
"inputs",
"output"
],
"description": "reduce nodes: the exact operation, its inputs, and its deterministic output, so every final decision is reconstructible.",
"properties": {
"op": {
"type": "string",
"enum": [
"k_of_n",
"threshold",
"coalesce"
]
},
"config": {
"type": "object",
"description": "The node's config exactly as executed, so the step is reconstructible from the process record alone."
},
"config_hash": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$",
"description": "Hash of the node's config as executed."
},
"inputs": {
"type": "array",
"maxItems": 100,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"node_id",
"assignment_id"
],
"properties": {
"node_id": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,39}$"
},
"assignment_id": {
"type": [
"string",
"null"
],
"pattern": "^ras_[0-9a-z]{10,32}$",
"description": "The completed assignment read, or null when the input is another reducer's output."
}
}
},
"description": "Exactly which responses or reducer outputs fed the operation."
},
"output": {
"type": "object",
"additionalProperties": false,
"required": [
"outcome",
"value"
],
"properties": {
"outcome": {
"type": "string",
"enum": [
"accept",
"reject",
"unresolved"
]
},
"value": {
"description": "The typed intermediate: for k_of_n the accept and reject match counts; for threshold the aggregate; for coalesce the id of the input reducer whose outcome was selected, or null."
}
}
}
}
},
"skipped_reason": {
"type": [
"string",
"null"
],
"default": null,
"maxLength": 500
}
}
},
"x-mutable": true,
"description": "One entry per node in the protocol, appended as execution proceeds."
},
"outcome": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"x-mutable": true,
"default": null,
"required": [
"control",
"value"
],
"description": "The output node's reducer output, written once when status becomes finished. Null before then, and null when the process finished without reaching its output node (see inconclusive_reason).",
"properties": {
"control": {
"type": "string",
"enum": [
"accept",
"reject",
"unresolved"
]
},
"value": {}
}
},
"inconclusive_reason": {
"type": [
"string",
"null"
],
"enum": [
"reviewers_unavailable",
"assignment_timeouts_exhausted",
"protocol_invalid",
"cancelled",
null
],
"x-mutable": true,
"default": null,
"description": "Set when the process finished without a substantive outcome. `reviewers_unavailable`: a review node reached its deadline with seats uncompleted, or no hosted provider could fill an agent node. `protocol_invalid`: the pinned protocol could not be executed. `cancelled`: withdrawn. `assignment_timeouts_exhausted` is LEGACY: emitted by the retired replacement-budget engine before the pull-based change (2026-09-02); kept so historical records validate, never emitted now."
},
"created_at": {
"type": "string",
"format": "date-time",
"x-mutable": false
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"x-mutable": true,
"default": null
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"x-mutable": true,
"default": null
}
}
}