{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id":     "docs/runtime/admin-control-plane-service/approval_store_schema.json",
  "title":   "Admin Approval Store · Phase 2b",
  "description": "JSON-Schema for docs/runtime/admin-control-plane-service/approval_examples.json (A-owned · file-backed · read-only scaffold). Row shape mirrors docs/runtime/admin-control-plane/approval_queue_model.json#queue_shape.item_fields — any divergence is a bug. Phase 2c will persist the same shape in Postgres.",
  "type": "object",
  "required": ["schema_version", "baseline", "owner", "approvals"],
  "properties": {
    "schema_version": { "type": "string" },
    "baseline":       { "type": "string" },
    "phase":          { "type": "string" },
    "updated_at":     { "type": "string", "format": "date" },
    "owner":          { "type": "string" },
    "honest_note":    { "type": "string" },
    "store_policy":   { "type": "string" },
    "approvals": {
      "type": "array",
      "items": { "$ref": "#/definitions/approval_row" }
    }
  },
  "definitions": {
    "approval_row": {
      "type": "object",
      "required": [
        "approval_id", "matrix_row", "target_type", "target_id",
        "submitted_by", "submitter_role",
        "required_signer_roles", "required_signer_count",
        "current_signers", "sensitive_flag",
        "state", "sla_band", "sla_due_at", "opened_at"
      ],
      "properties": {
        "approval_id": {
          "type": "string",
          "pattern": "^APP-\\d{6}-[A-Za-z0-9]{4,}$",
          "description": "Stable id · pattern APP-YYMMDD-XXXX"
        },
        "queue_id": {
          "type": "string",
          "description": "Optional · queue-{matrix_row_id} convention from queue_id_pattern"
        },
        "matrix_row": {
          "type": "string",
          "description": "FK to approval_matrix.matrix_rows[].id · e.g. row-sensitive-override"
        },
        "target_type": {
          "type": "string",
          "enum": ["case", "asset", "flag_transition", "tenant_publish", "wizard_bundle", "canonical_promote"]
        },
        "target_id": { "type": "string" },
        "target_snapshot_ref": { "type": ["string", "null"] },
        "submitted_by": { "type": "string" },
        "submitter_role": { "type": "string" },
        "required_signer_roles": {
          "type": "array",
          "items": { "type": "string" },
          "minItems": 1
        },
        "required_signer_count": {
          "type": "integer",
          "enum": [1, 2]
        },
        "current_signers": {
          "type": "array",
          "items": { "$ref": "#/definitions/signer_row" }
        },
        "sensitive_flag": { "type": "boolean" },
        "state": {
          "type": "string",
          "enum": [
            "pending", "in_review", "signed_partial", "signed_full",
            "rejected", "sent_back", "withdrawn", "expired"
          ]
        },
        "sla_band": {
          "type": "string",
          "description": "References docs/kb/data/sla_model.json band ids · e.g. routine-4h / priority-1h / critical-15m · not verified against B file in this scaffold"
        },
        "sla_due_at": {
          "type": "string",
          "format": "date-time",
          "description": "ISO-8601 · DOUBLES AS TTL deadline · ttl_remaining = max(0, sla_due_at - now)"
        },
        "opened_at": { "type": "string", "format": "date-time" },
        "closed_at": { "type": ["string", "null"], "format": "date-time" },
        "audit_event_refs": {
          "type": "array",
          "items": { "type": "string" },
          "description": "IDs from audit store · DISPLAY-ONLY in Phase 2b · not verified"
        },
        "rationale": { "type": "string" },
        "source":    {
          "type": "string",
          "enum": ["manual", "api", "migration", "demo-seed"]
        }
      },
      "allOf": [
        {
          "description": "Dual-approval rows must declare required_signer_count=2 · single=1",
          "if":   { "properties": { "required_signer_count": { "const": 2 } } },
          "then": { "properties": { "required_signer_roles": { "minItems": 2 } } }
        },
        {
          "description": "Closed states MUST carry closed_at",
          "if":   { "properties": { "state": { "enum": ["signed_full","rejected","withdrawn","expired"] } } },
          "then": { "required": ["closed_at"] }
        }
      ]
    },
    "signer_row": {
      "type": "object",
      "required": ["user_id", "role", "decision", "signed_at"],
      "properties": {
        "user_id":   { "type": "string" },
        "role":      { "type": "string" },
        "decision":  { "type": "string", "enum": ["approve", "reject", "sent_back"] },
        "signed_at": { "type": "string", "format": "date-time" },
        "rationale": { "type": "string" },
        "signed_jwt_hash": { "type": "string", "description": "SHA-256 of the JWT present at sign time · display-only in Phase 2b" }
      }
    }
  }
}
