{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://thossullivan.github.io/model-eol/schema/0.1/model-eol.verification.schema.json",
  "title": "model-eol receipt verification",
  "description": "Verification report `model-eol/verification@0.1` emitted by `model-eol verify RECEIPT --json`. It names the receipt by path, schema, and the SHA-256 of its bytes, records that the receipt passed structural validation, and lists one entry per claim. A claim is verified (the supplied input reproduces the receipt's value), mismatch (it does not; expected is the receipt's value and actual is what the input produced, null when one side has no such entry), not-checked (input names the flag that would check it), or not-applicable (a no-release receipt makes no such claim). A no-release receipt checked with any release input (--commit, --version, --package) gets a released claim with status mismatch, expected false and actual true. For a feed-refresh receipt, receipt.state, receipt.checked_at, and receipt.pending_pr (exactly when state is pending, an https URL) are copied from the receipt as information; for an npm-release-result receipt, receipt.released is. They are not claims, and no other receipt kind carries them. A configured eval manifest checked with --plan and --config gets one claim per planned or recorded result identity, named results[publisher, id, via] with each part JSON-quoted; a duplicate identity is a mismatch on its own; without --plan and --config a not-checked results claim stands in for the set. Eval outcomes (status, exit_code, report, generated) are never claims: verified means the manifest is bound to the supplied inputs, not that the evals passed. Compatibility: additive changes keep this version; validators reject unknown versions. Enforced in code, not by this schema: claim names are unique; a verified claim with both expected and actual has them equal, a mismatch claim has them different, and a not-checked claim names its input; result is mismatch when any claim is mismatch, verified when every applicable claim is verified and at least one is, and partial otherwise.",
  "type": "object",
  "required": ["schema", "receipt", "structural", "claims", "result"],
  "properties": {
    "schema": { "const": "model-eol/verification@0.1" },
    "receipt": {
      "type": "object",
      "required": ["path", "schema", "sha256"],
      "properties": {
        "path": { "type": "string", "minLength": 1 },
        "schema": { "enum": ["model-eol.eval/0.1", "model-eol/feed-refresh-receipt@0.1", "model-eol/npm-release-result@0.2"] },
        "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
        "state": { "enum": ["clean", "pending"] },
        "checked_at": { "type": "string", "format": "date-time" },
        "pending_pr": { "type": "string", "format": "uri", "pattern": "^https://[^/?#@]+([/?#]|$)" },
        "released": { "type": "boolean" }
      },
      "additionalProperties": false,
      "oneOf": [
        {
          "required": ["state", "checked_at"],
          "properties": {
            "schema": { "const": "model-eol/feed-refresh-receipt@0.1" },
            "released": false
          },
          "oneOf": [
            { "required": ["pending_pr"], "properties": { "state": { "const": "pending" } } },
            { "properties": { "state": { "const": "clean" }, "pending_pr": false } }
          ]
        },
        {
          "required": ["released"],
          "properties": {
            "schema": { "const": "model-eol/npm-release-result@0.2" },
            "state": false,
            "checked_at": false,
            "pending_pr": false
          }
        },
        {
          "properties": {
            "schema": { "const": "model-eol.eval/0.1" },
            "state": false,
            "checked_at": false,
            "pending_pr": false,
            "released": false
          }
        }
      ]
    },
    "structural": { "const": "valid" },
    "claims": {
      "type": "array",
      "items": { "$ref": "#/definitions/claim" }
    },
    "result": { "enum": ["verified", "partial", "mismatch"] }
  },
  "additionalProperties": false,
  "definitions": {
    "value": { "type": ["string", "boolean", "null"] },
    "claim": {
      "type": "object",
      "required": ["claim", "status"],
      "properties": {
        "claim": { "type": "string", "minLength": 1 },
        "status": { "enum": ["verified", "mismatch", "not-checked", "not-applicable"] },
        "expected": { "$ref": "#/definitions/value" },
        "actual": { "$ref": "#/definitions/value" },
        "input": { "type": "string", "minLength": 1 }
      },
      "additionalProperties": false
    }
  }
}
