{
  "openapi": "3.1.0",
  "info": {
    "title": "FORM Agent Decision API",
    "version": "1.5.0",
    "description": "Read-only sports and prediction-market decision packets. FORM returns a qualified bet, watch, or explicit no-play and never accepts credentials or submits orders."
  },
  "servers": [{ "url": "https://form.market" }],
  "paths": {
    "/api/mcp": {
      "post": {
        "operationId": "callFormMcp",
        "summary": "Connect an AI agent to FORM's read-only MCP tools",
        "description": "Streamable HTTP JSON-RPC endpoint supporting current stateless MCP (2026-07-28) and handshake-era clients through 2025-03-26. Tools cover token-efficient compact cross-venue discovery, targeted verified tape, and one-market PASS, WATCH, or BET evaluation. BET requires a clearing live price plus a caller-owned research packet with confirmed rules and supporting and opposing evidence across independent hosts; FORM validates structure and provenance, not source truth. No execution or order tool is exposed.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "required": ["jsonrpc", "method"], "properties": { "jsonrpc": { "const": "2.0" }, "id": {}, "method": { "type": "string" }, "params": { "type": "object" } } } } }
        },
        "responses": {
          "200": { "description": "A JSON-RPC initialize, tools/list, or tools/call response" },
          "202": { "description": "Notification accepted with no response body" },
          "403": { "description": "Browser origin rejected" },
          "405": { "description": "No server-initiated SSE stream is offered" }
        }
      }
    },
    "/api/market-network": {
      "get": {
        "operationId": "discoverMultiVenuePredictionMarkets",
        "summary": "Browse open Kalshi and Polymarket markets",
        "description": "Returns normalized venue-scoped market pages with separate provenance, price semantics, and cursors, plus a researchQueue ranked only by observable open status, displayed price, spread tightness, and reported activity. Researchability is not a probability estimate, edge claim, recommendation, or fillability claim. Similar titles are not assumed equivalent. No credentials or execution authority.",
        "parameters": [
          { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } },
          { "name": "kalshiCursor", "in": "query", "required": false, "schema": { "type": "string", "pattern": "^[A-Za-z0-9._~=-]{1,1024}$" }, "description": "Opaque Kalshi next-page cursor" },
          { "name": "polymarketCursor", "in": "query", "required": false, "schema": { "type": "string", "pattern": "^[A-Za-z0-9._~=-]{1,1024}$" }, "description": "Opaque Polymarket keyset cursor" }
        ],
        "responses": {
          "200": { "description": "A multi-venue discovery page; may be explicitly partial when one provider is unavailable" },
          "400": { "description": "Invalid or unsupported pagination input" },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "Every configured public market provider is unavailable" }
        }
      }
    },
    "/api/agent-research-candidate": {
      "get": {
        "operationId": "startPredictionMarketResearch",
        "summary": "Get one ranked candidate with fresh exact tape",
        "description": "Searches up to three live pages for optional filters, tries up to three eligible candidates, reports exact search coverage and remaining cursors, and returns the first fresh synchronized two-sided Kalshi or Polymarket book. Research starting point only: no probability, edge, recommendation, fill guarantee, credentials, or execution authority.",
        "parameters": [
          { "name": "venue", "in": "query", "required": false, "schema": { "type": "string", "enum": ["all", "kalshi", "polymarket"], "default": "all" } },
          { "name": "category", "in": "query", "required": false, "schema": { "type": "string", "maxLength": 60 } },
          { "name": "query", "in": "query", "required": false, "schema": { "type": "string", "maxLength": 80 } },
          { "name": "closesWithinHours", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 8760 }, "description": "Only consider markets whose provider close time is within this many hours" },
          { "name": "detail", "in": "query", "required": false, "schema": { "type": "string", "enum": ["compact", "full"], "default": "compact" }, "description": "Compact keeps top-of-book and summarized near-touch depth; full includes every returned level" }
        ],
        "responses": {
          "200": { "description": "A ready research starting point or explicit no-fresh-candidate result with a deterministic next action" },
          "400": { "description": "Invalid or unsupported filter" },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "The market network could not be retrieved" }
        }
      }
    },
    "/api/agent-research-candidate-verify": {
      "post": {
        "operationId": "verifyResearchStartingPointReceipt",
        "summary": "Verify a research-packet reproducibility checksum",
        "description": "Checks whether the complete filters, candidate, tape, failover attempts, next step, and boundaries still match their SHA-256 checksum. This is not a digital signature, source-truth verification, or external timestamp.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object" } } } },
        "responses": {
          "200": { "description": "Integrity result with authentic=false" },
          "400": { "description": "A complete JSON object was not supplied" },
          "405": { "description": "Only POST is accepted" }
        }
      }
    },
    "/api/market-universe": {
      "get": {
        "operationId": "discoverPredictionMarkets",
        "summary": "Browse open prediction markets across venue categories",
        "description": "Returns one explicit provider page of live public markets and a cursor for the next page. Discovery only: no fair value, ranking, recommendation, fillability claim, credentials, or execution authority.",
        "parameters": [
          { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } },
          { "name": "cursor", "in": "query", "required": false, "schema": { "type": "string", "pattern": "^[A-Za-z0-9._~=-]{1,512}$" }, "description": "Opaque next-page cursor returned by the previous response" }
        ],
        "responses": {
          "200": { "description": "A paginated cross-category market-discovery page" },
          "400": { "description": "Invalid or unsupported pagination input" },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "A fresh public market page could not be retrieved" }
        }
      }
    },
    "/api/polymarket-tape": {
      "get": {
        "operationId": "getExactPolymarketTape",
        "summary": "Get exact YES and NO books for one Polymarket condition",
        "description": "Resolves one venue-scoped condition ID and returns side-aware CLOB books, timestamps, hashes, displayed depth, and a hard expiration. Market facts only: no fair value, recommendation, fill guarantee, credentials, or execution authority.",
        "parameters": [
          { "name": "marketId", "in": "query", "required": true, "schema": { "type": "string", "pattern": "^polymarket:0x[a-f0-9]{64}$" }, "description": "Exact stable FORM Polymarket condition ID" }
        ],
        "responses": {
          "200": { "description": "Fresh exact-market YES and NO order books with quality gates and expiration" },
          "400": { "description": "Missing or invalid stable Polymarket market ID" },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "The exact market or synchronized public books could not be validated" }
        }
      }
    },
    "/api/kalshi-tape": {
      "get": {
        "operationId": "getExactKalshiTape",
        "summary": "Get exact YES and NO books for one Kalshi market",
        "description": "Resolves one venue-scoped ticker and returns side-aware books, timestamps, displayed depth, provenance, and a hard expiration. YES and NO asks are derived exactly from the opposing displayed bids. Market facts only: no fair value, recommendation, fill guarantee, credentials, or execution authority.",
        "parameters": [
          { "name": "marketId", "in": "query", "required": true, "schema": { "type": "string", "pattern": "^kalshi:[A-Z0-9-]+$" }, "description": "Exact stable FORM Kalshi market ID" }
        ],
        "responses": {
          "200": { "description": "Fresh exact-market YES and NO order books with quality gates and expiration" },
          "400": { "description": "Missing or invalid stable Kalshi market ID" },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "The exact market or synchronized public books could not be validated" }
        }
      }
    },
    "/api/agent-tape": {
      "get": {
        "operationId": "getVerifiedTape",
        "summary": "Get FORM's current normalized public market tape",
        "parameters": [
          { "name": "competition", "in": "query", "required": false, "schema": { "type": "string", "pattern": "^[a-z][a-z0-9_]{0,59}$" }, "description": "Exact FORM competition id" },
          { "name": "marketId", "in": "query", "required": false, "schema": { "type": "string", "pattern": "^kalshi:[A-Z0-9-]+$" }, "description": "Exact stable FORM market id" },
          { "name": "maxSpreadCents", "in": "query", "required": false, "schema": { "type": "number", "minimum": 0, "maximum": 20 }, "description": "Maximum observed bid-ask spread" },
          { "name": "minTouchSize", "in": "query", "required": false, "schema": { "type": "number", "minimum": 0, "maximum": 1000000000 }, "description": "Minimum size on the weaker displayed touch" },
          { "name": "resolvesBefore", "in": "query", "required": false, "schema": { "type": "string", "format": "date-time" }, "description": "Latest contract resolution time" },
          { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 20, "default": 20 } }
        ],
        "responses": {
          "200": {
            "description": "A 60-second market-facts envelope with stable identity, two-sided quotes, displayed depth, quality, and provenance",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifiedTape" } } }
          },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "A fresh public tape could not be validated" }
        }
      }
    },
    "/api/agent-pricing": {
      "post": {
        "operationId": "priceAgentScenario",
        "summary": "Stress a probability estimate and calculate price and loss limits",
        "description": "Uses a calling-agent-owned estimate. It does not create a FORM forecast, qualify a bet, or authorize execution.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPricingRequest" } } }
        },
        "responses": {
          "200": { "description": "Maximum entry price and maximum-loss-capped size", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentPricingResponse" } } } },
          "400": { "description": "Invalid or incomplete assumptions" },
          "405": { "description": "Only POST is accepted" }
        }
      }
    },
    "/api/agent-evaluation": {
      "post": {
        "operationId": "evaluateLiveAgentMarket",
        "summary": "Evaluate one fresh market against a calling agent's estimate and risk rules",
        "description": "Fetches the current verified ask for a stable market ID and returns WATCH when it clears the caller-owned stressed price and size limits, otherwise PASS. It never creates a FORM forecast, qualifies a BET, or authorizes execution.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentEvaluationRequest" } } }
        },
        "responses": {
          "200": { "description": "A short-lived WATCH or PASS result with live quote, maximum price, and capped size", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentEvaluationResponse" } } } },
          "400": { "description": "Invalid or incomplete assumptions" },
          "404": { "description": "Stable market ID is not in the fresh verified tape" },
          "405": { "description": "Only POST is accepted" },
          "503": { "description": "A fresh verified evaluation could not be produced" }
        }
      }
    },
    "/api/agent-evaluation-verify": {
      "post": {
        "operationId": "verifyAgentMarketEvaluationChecksum",
        "summary": "Check a market evaluation against its reproducibility checksum",
        "description": "Returns whether the supplied packet still matches its SHA-256 checksum. A valid result is not a FORM signature, source-truth verification, or external timestamp.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentEvaluationResponse" } } } },
        "responses": {
          "200": { "description": "Checksum consistency result with explicit authenticity limitations" },
          "400": { "description": "A complete evaluation packet was not supplied" },
          "405": { "description": "Only POST is accepted" }
        }
      }
    },
    "/api/agent-ranking": {
      "post": {
        "operationId": "rankAgentForecastSlate",
        "summary": "Rank 1–20 caller-owned forecasts across fresh Kalshi and Polymarket tapes",
        "description": "Fetches exact venue tapes and returns ranked WATCH checkpoints plus every PASS and unavailable identity under displayed-touch, market, correlation-group, and portfolio-loss caps. Displayed size is not a fill guarantee. It does not infer contract equivalence, create forecasts, qualify bets, verify correlations, or authorize execution.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentRankingRequest" } } }
        },
        "responses": {
          "200": { "description": "A short-lived ranked slate with WATCH, PASS, and unavailable counts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentRankingResponse" } } } },
          "400": { "description": "Invalid, duplicate, incomplete, or oversized forecast slate" },
          "405": { "description": "Only POST is accepted" },
          "503": { "description": "A synchronized fresh ranking could not be produced" }
        }
      }
    },
    "/api/agent-ranking-verify": {
      "post": {
        "operationId": "verifyAgentForecastSlateChecksum",
        "summary": "Check a ranked slate against its reproducibility checksum",
        "description": "Returns whether the supplied packet matches its SHA-256 checksum. A valid result is not a FORM signature, proof of origin, or external timestamp.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentRankingResponse" } } } },
        "responses": {
          "200": { "description": "Checksum consistency result with an explicit authenticity limitation" },
          "400": { "description": "A complete object was not supplied" },
          "405": { "description": "Only POST is accepted" }
        }
      }
    },
    "/api/agent-decision": {
      "get": {
        "operationId": "getCurrentAgentDecision",
        "summary": "Get FORM's current short-lived decision packet",
        "responses": {
          "200": {
            "description": "A 60-second qualified-bet, watch, or no-play envelope",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentDecisionResponse" } } }
          },
          "405": { "description": "Only GET is accepted" }
        }
      }
    },
    "/api/agent-reputation": {
      "get": {
        "operationId": "getAgentReputation",
        "summary": "Get FORM's proof-backed model reputation record",
        "responses": {
          "200": {
            "description": "An unrated, provisional, or rated record derived from verified forecast and settlement ledgers",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentReputationRecord" } } }
          },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "The complete proof chain could not be verified" }
        }
      }
    },
    "/api/settlement-readiness": {
      "get": {
        "operationId": "getSettlementReadiness",
        "summary": "Check every unresolved sealed forecast against its official result source",
        "responses": {
          "200": {
            "description": "Verified ledger state plus upcoming, awaiting-final, final-ready, review, and unavailable counts",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SettlementReadiness" } } }
          },
          "405": { "description": "Only GET is accepted" },
          "503": { "description": "The proof chain or official result checks could not be verified" }
        }
      }
    },
    "/api/agent-learning-review": {
      "post": {
        "operationId": "reviewAgentLearningLoop",
        "summary": "Grade a sealed agent iteration and enforce promotion gates",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentLearningReviewRequest" } } } },
        "responses": {
          "200": { "description": "A HOLD_IN_SHADOW or PROMOTION_ELIGIBLE improvement brief; no model mutation or execution authority" },
          "400": { "description": "Invalid or unbounded settled forecast cohort" },
          "405": { "description": "Only POST is accepted" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AgentLearningReviewRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["agentId", "iterationId"],
        "anyOf": [{ "required": ["records"] }, { "required": ["trades"] }],
        "properties": {
          "agentId": { "type": "string", "minLength": 1, "maxLength": 80 },
          "iterationId": { "type": "string", "minLength": 1, "maxLength": 80 },
          "records": { "type": "array", "maxItems": 500, "items": { "type": "object" } },
          "trades": { "type": "array", "maxItems": 500, "items": { "type": "object", "required": ["id", "marketId", "side", "entryPriceCents", "riskPct", "pnlUsd", "settledAt"] } }
        }
      },
      "AgentLearningProfile": {
        "type": "object",
        "additionalProperties": false,
        "required": ["schemaVersion", "agentId", "sourceIterationId", "sourceResolvedCount", "sourceTradeCount", "minimumUncertaintyPts", "minimumEdgePts", "maximumRiskPct"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "agentId": { "type": "string", "minLength": 1, "maxLength": 80 },
          "sourceIterationId": { "type": "string", "minLength": 1, "maxLength": 80 },
          "sourceResolvedCount": { "type": "integer", "minimum": 0, "maximum": 500 },
          "sourceTradeCount": { "type": "integer", "minimum": 0, "maximum": 500 },
          "minimumUncertaintyPts": { "type": "number", "minimum": 0, "maximum": 20 },
          "minimumEdgePts": { "type": "number", "minimum": 0, "maximum": 20 },
          "maximumRiskPct": { "type": "number", "minimum": 0.1, "maximum": 5 }
        }
      },
      "AgentRankingRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["forecasts", "bankrollUsd", "maxRiskPct", "maxGroupRiskPct", "maxPortfolioRiskPct"],
        "properties": {
          "forecasts": { "type": "array", "minItems": 1, "maxItems": 20, "items": { "$ref": "#/components/schemas/AgentForecast" } },
          "bankrollUsd": { "type": "number", "minimum": 1, "maximum": 10000000 },
          "maxRiskPct": { "type": "number", "minimum": 0.1, "maximum": 5 },
          "maxGroupRiskPct": { "type": "number", "minimum": 0.1, "maximum": 20 },
          "maxPortfolioRiskPct": { "type": "number", "minimum": 0.1, "maximum": 20 }
        }
      },
      "AgentForecast": {
        "type": "object",
        "additionalProperties": false,
        "required": ["marketId", "estimatePct", "side", "feeAndSlippageCents", "uncertaintyPts", "minimumEdgePts", "correlationGroup"],
        "properties": {
          "marketId": { "type": "string", "pattern": "^(?:kalshi:[A-Z0-9-]+|polymarket:0x[a-f0-9]{64})$" },
          "estimatePct": { "type": "number", "minimum": 1, "maximum": 99 },
          "side": { "type": "string", "enum": ["yes", "no"] },
          "feeAndSlippageCents": { "type": "number", "minimum": 0, "maximum": 10 },
          "uncertaintyPts": { "type": "number", "minimum": 0, "maximum": 20 },
          "minimumEdgePts": { "type": "number", "minimum": 0, "maximum": 20 },
          "correlationGroup": { "type": "string", "pattern": "^[a-z0-9][a-z0-9:_-]{0,59}$", "description": "Caller-declared shared game, event, or thesis exposure group" }
        }
      },
      "AgentRankingResponse": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "validUntil", "summary", "bankroll", "groups", "evaluations", "unavailable", "qualification", "execution", "warning", "receipt"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM agent slate ranking" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "validUntil": { "type": "string", "format": "date-time" },
          "summary": { "type": "object" },
          "bankroll": { "type": "object" },
          "groups": { "type": "array", "items": { "type": "object" } },
          "evaluations": { "type": "array", "items": { "$ref": "#/components/schemas/AgentEvaluationResponse" } },
          "unavailable": { "type": "array", "items": { "type": "object" } },
          "qualification": { "type": "object", "properties": { "betQualified": { "const": false } } },
          "execution": { "type": "object", "properties": { "authorized": { "const": false }, "credentialsAccepted": { "const": false }, "orderSubmissionAvailable": { "const": false } } },
          "warning": { "type": "string" },
          "receipt": { "type": "object", "required": ["schemaVersion", "kind", "purpose", "authenticity", "request", "integrity"], "properties": { "schemaVersion": { "const": 1 }, "kind": { "const": "FORM agent slate receipt" }, "purpose": { "const": "reproducibility-checksum" }, "authenticity": { "const": "not-provided" }, "request": { "$ref": "#/components/schemas/AgentRankingRequest" }, "integrity": { "type": "object", "required": ["algorithm", "scope", "digest"], "properties": { "algorithm": { "const": "SHA-256" }, "scope": { "const": "agent-slate-ranking-v1" }, "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" } } } } }
        }
      },
      "AgentEvaluationRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["marketId", "estimatePct", "side", "feeAndSlippageCents", "uncertaintyPts", "minimumEdgePts", "bankrollUsd", "maxRiskPct"],
        "properties": {
          "marketId": { "type": "string", "pattern": "^(?:kalshi:[A-Z0-9-]+|polymarket:0x[a-f0-9]{64})$" },
          "estimatePct": { "type": "number", "minimum": 1, "maximum": 99 },
          "side": { "enum": ["yes", "no"] },
          "feeAndSlippageCents": { "type": "number", "minimum": 0, "maximum": 10 },
          "uncertaintyPts": { "type": "number", "minimum": 0, "maximum": 20 },
          "minimumEdgePts": { "type": "number", "minimum": 0, "maximum": 20 },
          "bankrollUsd": { "type": "number", "minimum": 1, "maximum": 10000000 },
          "maxRiskPct": { "type": "number", "minimum": 0.1, "maximum": 5 },
          "learningProfile": { "$ref": "#/components/schemas/AgentLearningProfile" },
          "settledHistory": { "$ref": "#/components/schemas/AgentLearningReviewRequest" }
        }
      },
      "AgentEvaluationResponse": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "validUntil", "action", "reason", "market", "pricing", "risk", "qualification", "execution", "warning"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM live market evaluation" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "validUntil": { "type": "string", "format": "date-time" },
          "action": { "enum": ["WATCH", "PASS"] },
          "market": { "type": "object", "required": ["marketId", "venue", "title", "observedAt", "resolvesAt", "side", "offeredPriceCents", "spreadCents", "weakerTouchSize", "resolutionReview", "provenance"] },
          "pricing": { "type": "object", "required": ["estimateOwner", "estimatePct", "stressedProbabilityPct", "maximumEntryPriceCents", "offeredPriceGapCents", "allInOfferedPriceCents", "clearsLimit"] },
          "risk": { "type": "object" },
          "qualification": { "type": "object", "properties": { "betQualified": { "const": false } } },
          "execution": { "type": "object", "properties": { "authorized": { "const": false }, "credentialsAccepted": { "const": false }, "orderSubmissionAvailable": { "const": false } } }
        }
      },
      "AgentPricingRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["estimatePct", "side", "offeredPriceCents", "feeAndSlippageCents", "uncertaintyPts", "minimumEdgePts", "bankrollUsd", "maxRiskPct"],
        "properties": {
          "estimatePct": { "type": "number", "minimum": 1, "maximum": 99 },
          "side": { "enum": ["yes", "no"] },
          "offeredPriceCents": { "type": "number", "minimum": 1, "maximum": 99 },
          "feeAndSlippageCents": { "type": "number", "minimum": 0, "maximum": 10 },
          "uncertaintyPts": { "type": "number", "minimum": 0, "maximum": 20 },
          "minimumEdgePts": { "type": "number", "minimum": 0, "maximum": 20 },
          "bankrollUsd": { "type": "number", "minimum": 1, "maximum": 10000000 },
          "maxRiskPct": { "type": "number", "minimum": 0.1, "maximum": 5 }
        }
      },
      "AgentPricingResponse": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "action", "assumptions", "price", "risk", "qualification", "execution", "warning"],
        "properties": {
          "kind": { "const": "FORM agent pricing response" },
          "action": { "enum": ["price-clears", "price-too-high-or-size-zero", "no-valid-entry"] },
          "price": { "type": "object" },
          "risk": { "type": "object" },
          "qualification": { "type": "object", "properties": { "betQualified": { "const": false } } },
          "execution": { "type": "object", "properties": { "authorized": { "const": false }, "credentialsAccepted": { "const": false }, "orderSubmissionAvailable": { "const": false } } }
        }
      },
      "VerifiedTape": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "validUntil", "venue", "coverage", "markets", "boundary"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM verified market tape" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "validUntil": { "type": "string", "format": "date-time" },
          "venue": { "type": "object", "required": ["id", "name", "access"] },
          "coverage": { "type": "object", "required": ["sourcePublishedMarkets", "publishedMarkets", "availableCompetitions"], "properties": { "sourcePublishedMarkets": { "type": "integer" }, "publishedMarkets": { "type": "integer" }, "availableCompetitions": { "type": "array", "items": { "type": "object", "required": ["id", "marketCount", "nextResolvesAt"] } } } },
          "markets": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["marketId", "venueTicker", "eventId", "title", "observedAt", "resolvesAt", "quote", "quality", "provenance"]
            }
          },
          "boundary": {
            "type": "object",
            "properties": {
              "edgeInferred": { "const": false },
              "recommendation": { "const": false },
              "executionAuthorized": { "const": false },
              "credentialsAccepted": { "const": false }
            }
          }
        }
      },
      "AgentDecisionResponse": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "validUntil", "decision", "execution", "services", "links"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM agent decision response" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "validUntil": { "type": "string", "format": "date-time" },
          "decision": {
            "type": "object",
            "required": ["schemaVersion", "kind", "createdAt", "action", "marketId", "label", "dataCoverage", "sources", "thesis", "countercase", "invalidation", "blockers"],
            "properties": {
              "action": { "enum": ["qualified-bet", "watch", "no-play"] },
              "marketId": { "type": "string" },
              "label": { "type": "string" },
              "dataCoverage": { "type": "object" },
              "sources": { "type": "array" },
              "blockers": { "type": "array", "items": { "type": "string" } }
            }
          },
          "execution": {
            "type": "object",
            "properties": {
              "authorized": { "const": false },
              "credentialsAccepted": { "const": false },
              "orderSubmissionAvailable": { "const": false }
            }
          },
          "services": { "type": "object" },
          "links": { "type": "object" }
        }
      },
      "AgentReputationRecord": {
        "type": "object",
        "required": ["schemaVersion", "kind", "generatedAt", "subject", "status", "eligibility", "sample", "metrics", "gates", "proof", "boundary"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM agent reputation record" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "subject": { "type": "object", "required": ["type", "id", "stage"] },
          "status": { "enum": ["unrated", "provisional", "rated"] },
          "eligibility": {
            "type": "object",
            "properties": {
              "productionRecommendations": { "type": "boolean" },
              "agentOpinionMarket": { "const": false }
            }
          },
          "sample": { "type": "object", "required": ["sealed", "resolved", "minimumRequired", "remaining"] },
          "metrics": {
            "type": "object",
            "description": "Performance values remain null until official live settlements exist."
          },
          "gates": { "type": "object" },
          "proof": { "type": "object", "required": ["algorithm", "forecastLedgerRoot", "settlementLedgerRoot", "forecastLedger", "settlementLedger", "modelStatus"] },
          "boundary": { "type": "string" }
        }
      },
      "SettlementReadiness": {
        "type": "object",
        "required": ["schemaVersion", "kind", "checkedAt", "modelId", "ledger", "counts", "nextEventAt", "results", "scheduler", "persistence"],
        "properties": {
          "schemaVersion": { "const": 1 },
          "kind": { "const": "FORM settlement readiness monitor" },
          "checkedAt": { "type": "string", "format": "date-time" },
          "modelId": { "type": "string" },
          "ledger": { "type": "object" },
          "counts": { "type": "object" },
          "nextEventAt": { "type": ["string", "null"], "format": "date-time" },
          "results": { "type": "array" },
          "scheduler": { "type": "object" },
          "persistence": { "type": "object" }
        }
      }
    }
  }
}
