{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/garyyang-finchip/acd-framework/assets/erc-acdf/schemas/result-receipt.schema.json",
  "title": "ACDF Result Receipt (off-chain carrier of a registry record)",
  "description": "A portable description of what ACDFRegistry.getResult(issueId) and getIssue(issueId) return, for indexers and off-chain consumers. The receipt is a CARRIER of the registry record, never a substitute for it: the registry instance named in `registry` is the normative source, and a receipt proves nothing about another chain. Three dimensions are reported separately: procedure state, outcome type, and (per consumer and effect) enactment status.",
  "type": "object",
  "required": ["chainId", "registry", "policyRegistry", "issueId", "policyId", "state", "outcomeType", "roundCount"],
  "additionalProperties": false,
  "properties": {
    "chainId": { "type": "integer", "minimum": 1 },
    "registry": { "$ref": "#/$defs/address", "description": "ACDFRegistry instance that holds the record." },
    "policyRegistry": { "$ref": "#/$defs/address", "description": "Co-deployed ACDFPolicyRegistry the issue's policy lives in." },
    "issueId": { "$ref": "#/$defs/bytes32" },
    "policyId": { "$ref": "#/$defs/bytes32", "description": "Policy version the issue is bound to (frozen at filing)." },
    "state": { "type": "string", "enum": ["Filed", "Deciding", "Provisional", "Final", "Withdrawn"], "description": "Procedure state." },
    "outcomeType": { "type": "string", "enum": ["None", "Decided", "NoDecision"], "description": "Outcome type. Meaningful once state is Final; 'None' before." },
    "outcomeYes": { "type": "boolean", "description": "For Decided results: true = the issue's yes effect applies." },
    "reason": { "type": "string", "enum": ["NONE", "QUORUM_NOT_MET", "SUBMITTER_SILENT", "VETOED", "NO_CLEARANCE", "NOT_REACHED", "TOTAL_TIMEOUT", "NO_ACCEPTANCE"] },
    "decidedAt": { "$ref": "#/$defs/uint64", "description": "Instant the adopted result became determined (not the settlement call)." },
    "finalAt": { "$ref": "#/$defs/uint64" },
    "roundCount": { "type": "integer", "minimum": 0, "description": "Rounds run, including appeal rounds." },
    "sourceRound": { "type": "integer", "minimum": 0, "description": "1-based round whose decision was adopted. Under PRESERVE_UNLESS_OVERTURNED it may be smaller than roundCount when an appeal round ended in NoDecision and the earlier decision was kept." },
    "adoptedFromEarlierRound": { "type": "boolean", "description": "True when a Decided result was taken from a round before the last one (finality by adoption after a NoDecision appeal round), false when the last round decided itself." },
    "effectClass": { "type": "string", "enum": ["Advisory", "Binding"] },
    "consumer": { "$ref": "#/$defs/address", "description": "Bound consumer (zero for Advisory issues)." },
    "effectYes": { "$ref": "#/$defs/bytes32" },
    "effectNo": { "$ref": "#/$defs/bytes32" },
    "disposition": { "$ref": "#/$defs/bytes32", "description": "Opaque reference to the consumer's committed NoDecision disposition." },
    "obligationId": { "$ref": "#/$defs/bytes32", "description": "Consumer-committed obligation scope; exclusivity of unfinished Binding issues is keyed on (consumer, obligationId, question). Zero for Advisory issues." },
    "subject": {
      "type": "object",
      "required": ["chainId", "target", "id", "dataHash"],
      "properties": {
        "chainId": { "type": "integer" },
        "target": { "$ref": "#/$defs/address" },
        "id": { "type": ["integer", "string"] },
        "dataHash": { "$ref": "#/$defs/bytes32" }
      }
    },
    "question": { "$ref": "#/$defs/bytes32" },
    "enactments": {
      "type": "array",
      "description": "Informative enactment log entries as recorded by the bound consumer. Authoritative execution state lives at the consumer.",
      "items": {
        "type": "object",
        "required": ["consumer", "effectId", "status"],
        "properties": {
          "consumer": { "$ref": "#/$defs/address" },
          "effectId": { "$ref": "#/$defs/bytes32" },
          "status": { "type": "string", "enum": ["NotEnacted", "Enacted", "Failed"] },
          "reporter": { "$ref": "#/$defs/address" },
          "ref": { "$ref": "#/$defs/bytes32" },
          "at": { "$ref": "#/$defs/uint64" }
        }
      }
    },
    "chainFinality": {
      "type": "object",
      "description": "Optional. Procedural finality (state = Final) is not chain finality; a carrier may state the block and confirmation depth it observed the record at.",
      "properties": { "blockNumber": { "type": "integer" }, "blockHash": { "$ref": "#/$defs/bytes32" }, "confirmations": { "type": "integer" } }
    }
  },
  "$defs": {
    "bytes32": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" },
    "address": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
    "uint64": { "type": ["integer", "string"], "minimum": 0 }
  }
}
