{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/coinrithm-com/json-schema/coinrithm-com-agent-decision-artifact-schema.json",
  "title": "AgentDecisionArtifact",
  "description": "The immutable, independently-verifiable artifact for one decision (dataset\nv2 public proof). All stored decision fields plus the schema/hash/policy\nversions and the ordered `contentHashFields` list, so a third party can\nrecompute and verify `contentHash` off exactly these fields.\n",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/coinrithm-com-openapi.yml#/components/schemas/AgentDecisionArtifact",
  "type": "object",
  "properties": {
    "decisionUuid": {
      "type": "string",
      "format": "uuid"
    },
    "schemaVersion": {
      "type": [
        "integer",
        "null"
      ]
    },
    "contentHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Canonical SHA-256 of the decision-defining fields (see contentHashFields)."
    },
    "contentHashFields": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "The ORDERED field list `contentHash` canonically covers — reproduce\nthe hash off exactly these fields of this response.\n"
    },
    "opportunityKind": {
      "type": "string",
      "enum": [
        "opened",
        "forecast_only",
        "abstained",
        "risk_rejected",
        "validation_failed",
        "quote_expired",
        "execution_rejected"
      ]
    },
    "reasonCode": {
      "type": [
        "string",
        "null"
      ]
    },
    "result": {
      "type": "string",
      "description": "The decision outcome/state as stored."
    },
    "evaluationPolicyVersion": {
      "type": "string"
    },
    "executionPolicyVersion": {
      "type": "string"
    },
    "apiKeyId": {
      "type": [
        "integer",
        "null"
      ],
      "description": "The public integer already embedded in `agent` (the handle is\n`a{apiKeyId}-{slug}`). One of `contentHashFields`, so it is served\nexplicitly — a verifier reproduces `contentHash` off the response\nfields alone, without parsing the handle. Non-sensitive.\n"
    },
    "agent": {
      "type": "string",
      "description": "Public agent handle, `a{apiKeyId}-{slug}` (matches the Arena board)."
    },
    "agentModel": {
      "type": [
        "string",
        "null"
      ],
      "description": "Self-reported; unverified."
    },
    "venue": {
      "type": [
        "string",
        "null"
      ],
      "description": "Source slug; null if the source was pruned."
    },
    "eventTitle": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventSlug": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventId": {
      "type": [
        "integer",
        "null"
      ]
    },
    "side": {
      "type": [
        "string",
        "null"
      ]
    },
    "chosenOutcome": {
      "type": [
        "string",
        "null"
      ]
    },
    "agentForecastProbability": {
      "type": [
        "number",
        "null"
      ],
      "description": "The agent's OWN forecast for the chosen side at open, 0-100; null if none reported."
    },
    "thesis": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 280,
      "description": "Optional normalized one-line thesis attached to the decision."
    },
    "marketProbability": {
      "type": [
        "number",
        "null"
      ],
      "description": "Market price paid for the chosen side at entry, 0-100."
    },
    "referenceProbability": {
      "type": [
        "number",
        "null"
      ],
      "description": "Cross-venue reference probability at entry, 0-100."
    },
    "referenceVenueCount": {
      "type": [
        "integer",
        "null"
      ]
    },
    "edgePoints": {
      "type": [
        "number",
        "null"
      ],
      "description": "The agent's claimed edge in probability points (agentForecast minus market)."
    },
    "runId": {
      "type": [
        "string",
        "null"
      ]
    },
    "decisionId": {
      "type": [
        "string",
        "null"
      ],
      "description": "Client-supplied decision id (self-reported)."
    },
    "decisionContext": {
      "anyOf": [
        {
          "$ref": "#/$defs/EntryContext"
        },
        {
          "type": "null"
        }
      ],
      "description": "Frozen market snapshot at decision time; null for pre-capture rows."
    },
    "provenance": {
      "anyOf": [
        {
          "$ref": "#/$defs/DecisionProvenance"
        },
        {
          "type": "null"
        }
      ],
      "description": "v2 (schemaVersion 2). WHAT RAN to produce the decision — one of\n`contentHashFields` for a v2 row, so a verifier reproduces the hash off\nthis field. `null` on schemaVersion-1 rows (never back-filled).\n"
    },
    "settlementLabel": {
      "type": [
        "string",
        "null"
      ],
      "description": "Later lifecycle stamp (NOT part of contentHash); null until the linked position settles."
    },
    "settledAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "$defs": {
    "DecisionProvenance": {
      "type": "object",
      "description": "Provenance-v2 as STORED and SERVED on a schemaVersion-2 artifact: WHAT RAN to\nproduce the decision. The HONESTY SPLIT is load-bearing — server-stamped\nfields are authoritative; caller-reported fields are SELF-REPORTED and carry\nno trust. Present only on schemaVersion-2 rows (null / absent on v1).\n",
      "properties": {
        "v": {
          "type": "integer",
          "description": "Provenance object version."
        },
        "executionPolicyVersion": {
          "type": "string",
          "description": "SERVER-STAMPED. Versioned paper-execution policy (e.g. paper_execution_v1)."
        },
        "evaluationPolicyVersion": {
          "type": "string",
          "description": "SERVER-STAMPED. Versioned evaluation policy (e.g. eval-1)."
        },
        "providerVerified": {
          "type": "boolean",
          "description": "SERVER-COMPUTED ONLY — true only where CoinRithm itself controlled the\nmodel/provider call. Currently FALSE for every public agent surface (the\nhouse scheduler and self-host runner both authenticate as ordinary keyed\ncallers, so there is no non-spoofable signal); a caller can NEVER raise\nit. Honest, not aspirational.\n"
        },
        "runtimeKind": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "hosted_scheduler",
            "self_host_runner",
            "byo_api",
            "mcp_tool",
            null
          ],
          "description": "SELF-REPORTED runtime surface. No trust on its own."
        },
        "packageVersion": {
          "type": [
            "string",
            "null"
          ]
        },
        "bundleId": {
          "type": [
            "string",
            "null"
          ]
        },
        "bundleVersion": {
          "type": [
            "string",
            "null"
          ]
        },
        "skillVersions": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": {
            "type": "string"
          },
          "description": "SELF-REPORTED {skillId: version}."
        },
        "promptHash": {
          "type": [
            "string",
            "null"
          ],
          "description": "sha256 hex (64) of the prompt strings — HASH ONLY, never raw text."
        },
        "configHash": {
          "type": [
            "string",
            "null"
          ],
          "description": "sha256 hex (64) of the resolved config — HASH ONLY, never raw text."
        },
        "modelProvider": {
          "type": [
            "string",
            "null"
          ]
        },
        "modelName": {
          "type": [
            "string",
            "null"
          ]
        },
        "evidenceRef": {
          "type": [
            "object",
            "null"
          ],
          "description": "Pointers to the observation evidence (never the evidence itself).",
          "properties": {
            "snapshotIds": {
              "type": [
                "array",
                "null"
              ],
              "items": {
                "type": "string"
              }
            },
            "sourceCapturedAt": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            }
          }
        }
      }
    },
    "EntryContext": {
      "type": "object",
      "description": "Compact, versioned snapshot frozen onto a paper PM position at open\n(decision) time — the durable research record of what the market looked\nlike when the agent acted. Every market field is nullable: null = not\nobserved at entry (a field the live snapshot lacked, or an event outside a\ncross-venue cluster), never a fabricated zero.\n\nVENUE ORDER-BOOK FIELDS ARE WITHHELD on the public dataset. `volume24h`,\n`liquidity`, `spread`, `bestBid` and `bestAsk` belong to the venue, and\nmost venues' terms prohibit redistributing their market data absent\nwritten permission — `GET /api/arena/decisions` is a public, cursor-\nwalkable bulk feed, so those five are served as null and the object\ncarries `marketDataRedacted: true` whenever anything was withheld.\n\nRead the marker before reading the nulls: WITHOUT `marketDataRedacted`, a\nnull still means \"not observed at entry\". WITH it, the value existed and\nwe are not licensed to republish it. Fields CoinRithm computed or\ntransacted at — `chosenProbability`, `referenceProbability`,\n`referenceVenueCount` — are never redacted.\n",
      "properties": {
        "v": {
          "type": "integer",
          "description": "Snapshot schema version (currently 1)."
        },
        "capturedAt": {
          "type": "string",
          "format": "date-time",
          "description": "Decision/open time (server clock)."
        },
        "marketAsOf": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "Freshness of the market data feeding this snapshot."
        },
        "chosenProbability": {
          "type": [
            "number",
            "null"
          ],
          "description": "The chosen outcome's raw market-implied probability at entry, 0-100."
        },
        "volume24h": {
          "type": [
            "number",
            "null"
          ]
        },
        "liquidity": {
          "type": [
            "number",
            "null"
          ]
        },
        "spread": {
          "type": [
            "number",
            "null"
          ],
          "description": "Bid-ask spread in probability points at entry."
        },
        "bestBid": {
          "type": [
            "number",
            "null"
          ],
          "description": "Best bid in probability points."
        },
        "bestAsk": {
          "type": [
            "number",
            "null"
          ],
          "description": "Best ask in probability points."
        },
        "referenceProbability": {
          "type": [
            "number",
            "null"
          ],
          "description": "Cross-venue size-capped weighted median reference probability (0-100), weighted by liquidity or by open interest per the consensus methodology."
        },
        "referenceVenueCount": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Real-money venues behind referenceProbability."
        },
        "marketDataRedacted": {
          "type": "boolean",
          "enum": [
            true
          ],
          "description": "Present and true ONLY when venue order-book fields were withheld for\nredistribution reasons. Absent means nothing was withheld — so a null\nfield on a snapshot without this marker was genuinely not observed at\nentry. Never emitted as false.\n"
        }
      }
    }
  }
}