{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/archstone-dev/json-schema/archstone-dev-public-verify-report-schema.json",
  "title": "PublicVerifyReport",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/archstone-dev-openapi.yaml#/components/schemas/PublicVerifyReport",
  "type": "object",
  "required": [
    "verifiedAt",
    "source",
    "api",
    "contractFingerprint",
    "summary",
    "documentNotes",
    "operations"
  ],
  "additionalProperties": false,
  "properties": {
    "verifiedAt": {
      "type": "string",
      "format": "date-time"
    },
    "source": {
      "type": "object",
      "required": [
        "url",
        "sha256",
        "unresolvedReferences"
      ],
      "additionalProperties": false,
      "properties": {
        "url": {
          "type": "string"
        },
        "sha256": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$",
          "maxLength": 64
        },
        "unresolvedReferences": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "api": {
      "type": "object",
      "required": [
        "name",
        "serverAddress"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string"
        },
        "serverAddress": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "contractFingerprint": {
      "type": "string",
      "pattern": "^sha256:[a-f0-9]{1,64}$",
      "maxLength": 71
    },
    "summary": {
      "type": "object",
      "required": [
        "operations",
        "included",
        "excludedWrites",
        "excludedIrreversible",
        "excludedOther",
        "livePassed",
        "liveFailed",
        "liveNotAttempted"
      ],
      "additionalProperties": false,
      "properties": {
        "operations": {
          "type": "integer"
        },
        "included": {
          "type": "integer"
        },
        "excludedWrites": {
          "type": "integer"
        },
        "excludedIrreversible": {
          "type": "integer"
        },
        "excludedOther": {
          "type": "integer"
        },
        "livePassed": {
          "type": "integer"
        },
        "liveFailed": {
          "type": "integer"
        },
        "liveNotAttempted": {
          "type": "integer"
        }
      }
    },
    "documentNotes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "operations": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/VerifiedOperation"
      }
    },
    "outcome": {
      "description": "Present only with `Prefer: outcome=in-body`. Added in 1.5.0.",
      "type": "string",
      "enum": [
        "verified"
      ]
    },
    "nextStep": {
      "description": "Present only with `Prefer: outcome=in-body`. The fixed next step after a verified run: a command and a sign-up address, the same for every caller. Added in 1.5.0.",
      "type": "object",
      "required": [
        "command",
        "url"
      ],
      "additionalProperties": false,
      "properties": {
        "command": {
          "type": "string",
          "pattern": "^[A-Za-z0-9@/._ -]{1,80}$",
          "maxLength": 80
        },
        "url": {
          "type": "string",
          "pattern": "^https://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]{1,200}$",
          "maxLength": 220
        }
      }
    }
  },
  "$defs": {
    "Decision": {
      "description": "Whether an operation is included in a run, and why not when it isn't. `reason` and `code` are present only when `included` is `false`; `code` only for `reason: \"not_usable\"`. Not expressed as a `oneOf` — two disjoint shapes picked apart only by a boolean would be polymorphism for its own sake, and every field below is already closed by its own enum. This schema validates field types and enum membership; it does not enforce that `reason` (or `code`) is present only when `included: false` — treat `included` as authoritative.",
      "type": "object",
      "required": [
        "included"
      ],
      "additionalProperties": false,
      "properties": {
        "included": {
          "type": "boolean"
        },
        "reason": {
          "type": "string",
          "enum": [
            "write",
            "irreversible",
            "method_hint_contradiction",
            "not_usable",
            "unclassified"
          ]
        },
        "code": {
          "type": "string",
          "description": "Present only for reason \"not_usable\" — the document-side code explaining why the operation cannot be used at all."
        }
      }
    },
    "LiveOutcome": {
      "description": "The outcome of the one live call attempted for an included, read-shaped operation. Which of `degraded`/`reachedServer`/`class`/`missing`/`reason` are present depends on `status` (and, when `status` is \"failed\", on `class`) — see each field's own description. This schema validates field types and enum membership; it does not enforce that `class` is present only when `status: \"failed\"` (or the equivalent dependency for the other fields) — treat `status` (and, for a \"failed\" outcome, `class`) as authoritative.",
      "type": "object",
      "required": [
        "status"
      ],
      "additionalProperties": false,
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "passed",
            "failed",
            "not_attempted"
          ]
        },
        "degraded": {
          "description": "Present only when status is \"passed\" and at least one field path degraded.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "reachedServer": {
          "description": "Present only when status is \"failed\".",
          "type": "boolean"
        },
        "class": {
          "description": "Present only when status is \"failed\" and reachedServer is true.",
          "type": "string",
          "enum": [
            "contract_violation",
            "server_error"
          ]
        },
        "missing": {
          "description": "Present only when class is \"contract_violation\" and fields were missing.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "reason": {
          "description": "Present only when status is \"not_attempted\".",
          "type": "string",
          "enum": [
            "needs_credential",
            "no_example_for_required_input",
            "server_address_missing",
            "call_budget_exhausted"
          ]
        }
      }
    },
    "VerifiedOperation": {
      "type": "object",
      "required": [
        "key",
        "method",
        "summary",
        "effect",
        "decision",
        "authentication",
        "requiredInputs",
        "requiredInputsWithExample",
        "live"
      ],
      "additionalProperties": false,
      "properties": {
        "key": {
          "type": "string"
        },
        "method": {
          "type": "string",
          "enum": [
            "GET",
            "PUT",
            "POST",
            "DELETE",
            "OPTIONS",
            "HEAD",
            "PATCH",
            "TRACE"
          ]
        },
        "path": {
          "description": "Absent with `Prefer: outcome=in-body`, which offers `safePath` instead.",
          "type": "string"
        },
        "summary": {
          "type": "string"
        },
        "effect": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "read",
            "write",
            "irreversible",
            null
          ]
        },
        "decision": {
          "$ref": "#/$defs/Decision"
        },
        "authentication": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "none",
            "header",
            null
          ]
        },
        "requiredInputs": {
          "type": "integer"
        },
        "requiredInputsWithExample": {
          "type": "integer"
        },
        "safePath": {
          "description": "Present only with `Prefer: outcome=in-body`. `path` when it is made only of URL-safe characters and is at most 120 characters long, otherwise `null`. Added in 1.5.0.",
          "type": [
            "string",
            "null"
          ],
          "maxLength": 120,
          "pattern": "^/[A-Za-z0-9._~!$&'()*+,;=:@%/{}-]{0,119}$"
        },
        "live": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/LiveOutcome"
            }
          ]
        }
      }
    }
  }
}