{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://checkable.clickcoded.com/receipts.schema.json",
  "title": "The Checkable Standard v0.3 — manifest",
  "description": "An open standard for verifiable operations: claims with evidence, append-only corrections, permissionless validation. Formerly published as The Receipts Standard (renamed 2026-08-01; same spec, same wire format). v0.2 adds declared coverage, evidence-independence labels, evidence excerpts, and confidence/caveats. v0.3 adds an optional structured metrics object on claims, so a hand-typed money figure quoted elsewhere (e.g. on a live page) can be checked against a machine-comparable value instead of trusted from prose alone. All additive, so a v0.1 manifest remains conforming.",
  "type": "object",
  "required": ["spec", "operator", "generated", "rules", "claims"],
  "properties": {
    "spec": {"type": "string", "pattern": "^receipts-standard/0\\.[123]$"},
    "spec_url": {"type": "string", "format": "uri"},
    "coverage": {
      "type": "array", "items": {"type": "string"},
      "description": "v0.2. The claim categories this manifest declares it covers — values MUST match the claims.category enum exactly (e.g. [\"revenue\",\"delivery\",\"correction\"], not the plural form). Answers Hole 1 (cherry-picking): a manifest silent on a category it declared is non-conforming, not merely incomplete."
    },
    "operator": {
      "type": "object",
      "required": ["name", "url", "operator_type", "disclosure"],
      "properties": {
        "name": {"type": "string"},
        "url": {"type": "string", "format": "uri"},
        "operator_type": {"enum": ["ai-agent", "human", "hybrid"]},
        "persona": {"type": "string"},
        "human_principal": {"type": "string"},
        "disclosure": {"type": "string", "minLength": 1}
      }
    },
    "generated": {"type": "string", "format": "date-time", "description": "ISO-8601 timestamp"},
    "rules": {
      "type": "object",
      "description": "The operator's stated conformance rules; corrections MUST be append-only.",
      "properties": {
        "materiality": {"type": "string", "description": "v0.2. One line stating what counts as material enough to require a claim (Hole 1)."}
      }
    },
    "claims": {
      "type": "array", "minItems": 1,
      "items": {
        "type": "object",
        "required": ["id", "date", "category", "claim", "evidence", "verifiability"],
        "properties": {
          "id": {"type": "string", "pattern": "^[a-z0-9-]+$"},
          "date": {"type": "string", "format": "date"},
          "category": {"enum": ["revenue", "delivery", "send", "correction", "grant", "infrastructure", "disclosure", "challenge"]},
          "claim": {"type": "string", "minLength": 1, "description": "One sentence, checkable. A claim without evidence is not a claim. category:\"challenge\" claims log a third party's \"missing claim\" question and the operator's answer (or its still-open status) — Hole 1's public challenge mechanism, using the same append-only claims array rather than a new system."},
          "evidence": {
            "type": "object", "required": ["type", "ref"],
            "properties": {
              "type": {"enum": ["public-url", "platform-record", "ledger", "git-commit"]},
              "ref": {"type": "string", "minLength": 1},
              "independence": {
                "enum": ["third-party", "payment-processor", "own-site"],
                "description": "v0.2. Who hosts/controls this evidence, most-independent first. Answers Hole 2 (self-referential evidence): labeled honestly, not hidden. A validator can report an independence breakdown; this does not gate conformance."
              },
              "excerpt": {
                "type": "string",
                "description": "v0.2. A short exact substring the evidence page/record should contain. Answers Hole 4 (reachability ≠ meaning): a validator can confirm the ref supports the claim's substance, not just that it returns 200."
              }
            }
          },
          "verifiability": {"enum": ["public", "on-request"]},
          "corrects": {"type": "string", "description": "id of the claim this corrects; corrections are append-only, never rewrites"},
          "confidence": {
            "type": "object",
            "description": "v0.2, optional. Answers Hole 6 (overstated confidence): a true claim can still overstate certainty.",
            "required": ["level"],
            "properties": {
              "level": {"enum": ["certain", "estimated", "uncertain"]},
              "caveat": {"type": "string", "description": "What's unresolved or approximate about this claim, in plain language."}
            }
          },
          "metrics": {
            "type": "object",
            "description": "v0.3, optional. Structured numeric figures backing this claim's prose, e.g. {\"net_pool_balance\": -79.04}. Keys are free-form snake_case labels a validator can key off of; values are plain numbers, not strings. Lets a hand-typed money figure quoted on a live page be diffed against a machine-comparable source instead of trusted by prose alone (the 'ledger-number' check family).",
            "additionalProperties": {"type": "number"}
          }
        }
      }
    }
  }
}
