{
  "openapi": "3.0.3",
  "info": {
    "title": "Drokio Public API",
    "version": "1.1.0",
    "description": "Machine-readable contract for the public Drokio API (v1).\n\nTwo authentication models are used:\n- **`bearerApiKey`** — most routes require `Authorization: Bearer <api_key>` (a Drokio license key). The per-key limit is 100 requests/minute.\n- **public** — a handful of routes (status, public trust state, badge SVG, license verification, trial enrollment, checkout, and the corroborated threat feed) are callable without a key; they authenticate by request body or by a gated server flag instead.\n\nAuthenticated routes wrap success as `{ \"success\": true, \"data\": ... }` and errors as `{ \"success\": false, \"error\": { \"code\", \"message\" } }`. The license/trial/checkout routes intentionally return a flat (non-enveloped) shape for backwards compatibility with the Drako WordPress plugin — this is documented per-operation. All responses carry `X-Drokio-Version` and `X-RateLimit-Remaining` headers.\n\nOnly routes an external integrator may actually call are documented; first-party dashboard, admin, internal and Stripe-webhook routes are deliberately omitted.",
    "contact": {
      "name": "Drokio Support",
      "email": "soporte@drokio.com",
      "url": "https://drokio.com/docs"
    },
    "license": {
      "name": "Proprietary — Drokio",
      "url": "https://drokio.com"
    }
  },
  "servers": [
    {
      "url": "https://drokio.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Platform",
      "description": "Service status and account verification."
    },
    {
      "name": "Licensing",
      "description": "License verification, trial enrollment and checkout."
    },
    {
      "name": "Telemetry",
      "description": "Plugin/agent telemetry and attack-event ingestion."
    },
    {
      "name": "Signals",
      "description": "Privacy-safe posture-signal ingestion across verticals."
    },
    {
      "name": "Threat Intelligence",
      "description": "Corroborated, identity-free threat feed and breach signals."
    },
    {
      "name": "Scanning",
      "description": "Remote scan triggers and vulnerability mirror."
    },
    {
      "name": "Risk",
      "description": "Defensive exploitability-risk scoring."
    },
    {
      "name": "Trust",
      "description": "Public TrustOS verification state, evidence and badges."
    },
    {
      "name": "Certification",
      "description": "Drokio Certify — issue, publicly verify and revoke signed credentials."
    }
  ],
  "paths": {
    "/api/v1/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Service status",
        "description": "Public health endpoint used by the status page and external uptime checks. Reports overall status, API version, Brain (AI) availability and process uptime. Does not consume rate limit.",
        "tags": [
          "Platform"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Current service status.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/StatusResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/verify": {
      "post": {
        "operationId": "verifyApiKey",
        "summary": "Verify an API key",
        "description": "Confirms an API key is valid and returns its plan, site quota and expiry. Useful for an integration to self-check on startup.",
        "tags": [
          "Platform"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Key is valid; account status returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ApiKeyStatus"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Authed self-info (who am I, what can I call)",
        "description": "Returns the calling key's OWN effective contract: plan, license status, the effective module set (including per-license overrides), the per-key rate-limit policy the auth layer enforces, whether the key is bound to a registered domain, and the trial end date when the license is in trial. The response NEVER echoes the API key, the owner email, or any secret. Also rate-limited per IP pre-auth (30/min, own bucket).",
        "tags": [
          "Platform"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "The caller's own contract summary.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MeResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "414": {
            "description": "Request URL exceeds the 8 KiB cap (`URI_TOO_LONG`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/license/verify": {
      "post": {
        "operationId": "verifyLicense",
        "summary": "Verify a license (Drako plugin)",
        "description": "Called by the Drako WordPress plugin (~daily) to confirm a license is still valid and learn which modules are allowed. The key travels either as `Authorization: Bearer <key>` (preferred for programmatic clients; `domain` becomes optional) or as `api_key` in the body (legacy plugin contract; `domain` required). NEVER by query string. **Returns a flat shape** (not the `{success,data}` envelope) for plugin backwards compatibility. Always returns HTTP 200 for a well-formed request — an invalid/expired/mismatched license is signalled by `valid: false` + a `free`-plan downgrade, never by a 4xx. The ONE disclosed invalid state is `reason: \"suspended\"` (payment problem). Valid responses additionally carry `status`, `modules` (alias of `modules_allowed`), `domain_bound` and `trial_ends_at` (additive fields).",
        "tags": [
          "Licensing"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LicenseVerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License resolution (valid, suspended or downgraded).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseVerifyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed body. Still returns the flat shape with `valid: false`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseVerifyResponse"
                }
              }
            }
          },
          "413": {
            "description": "Body exceeds the 8 KiB cap. Returns the flat shape with `valid: false`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseVerifyResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-IP pre-auth rate limit exceeded. Includes a `Retry-After` header.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            }
          }
        }
      }
    },
    "/api/v1/license/trial": {
      "post": {
        "operationId": "startTrial",
        "summary": "Start a 14-day trial",
        "description": "Enrolls a WordPress domain into a 14-day trial. Requires a card via Stripe SetupIntent (mock when `STRIPE_SECRET_KEY` is unset). Anti-fraud: one trial per domain, one per installation hash, max three per email. **Returns a flat shape** for plugin compatibility.",
        "tags": [
          "Licensing"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TrialRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Trial created; license key + SetupIntent client secret returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrialResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlatError"
                }
              }
            }
          },
          "409": {
            "description": "Not eligible (anti-fraud rule hit).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlatError"
                }
              }
            }
          },
          "429": {
            "description": "Per-IP pre-auth rate limit exceeded. Includes a `Retry-After` header.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            }
          },
          "502": {
            "description": "Stripe SetupIntent creation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlatError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/checkout": {
      "post": {
        "operationId": "createCheckout",
        "summary": "Create a checkout session",
        "description": "Creates a Stripe Checkout session for a monthly subscription of catalog items. Prices are resolved server-side from the catalog; any `price_*` sent by the client is ignored. When Stripe is not configured a mock checkout URL is returned (`mock: true`). **Returns a flat shape** for plugin compatibility.",
        "tags": [
          "Licensing"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session created (real or mock).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or unknown catalog slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlatError"
                }
              }
            }
          },
          "429": {
            "description": "Per-IP pre-auth rate limit exceeded. Includes a `Retry-After` header.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            }
          },
          "502": {
            "description": "Stripe error while creating the session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlatError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/telemetry": {
      "post": {
        "operationId": "ingestTelemetry",
        "summary": "Ingest telemetry (heartbeat or attack events)",
        "description": "Accepts one of two body shapes, discriminated server-side:\n1. **Heartbeat** — `{ site_url, license_key, drako_version, ..., stats, events }` from the Drako plugin. The `license_key` in the body must equal the Bearer key.\n2. **Attack events** — `{ site_uuid, domain, events: [{ type: \"attack_blocked\", ... }] }` for the live attack globe.\n\nDomain binding is enforced: a productive license must report from its registered domain. Max 100 events per request.",
        "tags": [
          "Telemetry"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TelemetryHeartbeat"
                  },
                  {
                    "$ref": "#/components/schemas/TelemetryAttackEvents"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Telemetry accepted. Shape depends on the body kind.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/TelemetryHeartbeatAck"
                            },
                            {
                              "$ref": "#/components/schemas/TelemetryAttackAck"
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload (error code `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/metrics": {
      "post": {
        "operationId": "getTenantAnalyticsMetrics",
        "summary": "Tenant-scoped analytics snapshot (your own metrics)",
        "description": "Returns the caller's OWN aggregate security metrics derived from the telemetry its plugins reported — per-site summaries/details, 30-day severity buckets, per-site security scores and the Brain verdict tally. Tenant scoping is exact-by-construction: the snapshot key is derived server-side from the Bearer credential; the body can never name another tenant. The optional `sections` filter selects data sections; an empty/omitted body serves the full snapshot; an explicit `sections: []` serves only the counters envelope. Every 200 attests `crossTenantDataServed: false`. Max 8 KiB.",
        "tags": [
          "Telemetry"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsMetricsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The caller's tenant-scoped analytics snapshot (honest zeros when empty).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AnalyticsMetricsResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Unreadable body / malformed JSON (`INVALID_PAYLOAD`) or invalid filter (`ANALYTICS_INVALID_PAYLOAD` / `ANALYTICS_UNKNOWN_FIELD` / `ANALYTICS_INVALID_QUERY` / `ANALYTICS_UNKNOWN_SECTION` / `ANALYTICS_QUERY_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/digital-immunity/signal": {
      "post": {
        "operationId": "ingestDigitalImmunitySignal",
        "summary": "Ingest a Digital Immunity posture signal (WordPress)",
        "description": "Opt-in, privacy-safe per-module coverage signal from the Drako plugin. The validator rejects PII / secrets / content; `piiIncluded`, `contentIncluded` and `secretsIncluded` must be the literal `false`. The aggregation identity (`siteIdHash`) is derived server-side from the authenticated key. Write-only (no GET). Max 32 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostureSignal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted; persistence posture reported.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Schema/privacy rejection (`INVALID_SIGNAL_SCHEMA` / `WRITE_REJECTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/saas/signal": {
      "post": {
        "operationId": "ingestSaasSignal",
        "summary": "Ingest a SaaS posture signal",
        "description": "Opt-in SaaS posture signal from an enrolled connector. Same privacy contract as the WordPress signal plus connector binding: the connector's `licenseIdHash` must match the one derived from the authenticated key. Write-only. Max 32 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostureSignal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted; persistence + binding posture reported.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Schema/binding rejection (`INVALID_SAAS_SIGNAL_SCHEMA` / `SAAS_BINDING_*`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/server-guard/signal": {
      "post": {
        "operationId": "ingestServerGuardSignal",
        "summary": "Ingest a Server Guard posture signal",
        "description": "Readiness ingest for the Server Guard agent. Privacy contract rejects usernames, passwords, tokens, raw logs, IPs and file contents at any depth. Write-only. Max 16 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostureSignal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted; persistence posture reported.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Schema/privacy rejection (`SERVER_GUARD_*`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/pc-guard/signal": {
      "post": {
        "operationId": "ingestPcGuardSignal",
        "summary": "Ingest a PC Guard posture signal",
        "description": "Readiness ingest for the PC/endpoint Guard agent. Privacy contract additionally forbids screenshots, keystrokes, clipboard, browser history, cookies, biometric data and personal files. Write-only. Max 16 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostureSignal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted; persistence posture reported.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Schema/privacy rejection (`PC_GUARD_*`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/cloud-immunity/signal": {
      "post": {
        "operationId": "ingestCloudImmunitySignal",
        "summary": "Ingest a Cloud Immunity posture signal",
        "description": "Opt-in posture signal from a modern-stack app (counts and ratios only — never a secret, source code, env value or PII). The `appIdHash` aggregation identity is derived server-side from the authenticated key (replace-on-write). Write-only. Max 16 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPostureSignal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted; persistence posture reported.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Schema/privacy rejection (`INVALID_SIGNAL_SCHEMA` / `WRITE_REJECTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llave/signal": {
      "post": {
        "operationId": "ingestLlaveSignal",
        "summary": "Ingest a Llave key-hygiene inventory snapshot",
        "description": "Drokio Llave (access-key hygiene). The caller reports an ANONYMIZED, fully-bucketed snapshot of its key/secret inventory METADATA (kind / age bucket / rotation policy / scope breadth / last-use bucket / storage class / public-exposure flag — enum buckets, booleans and small counts ONLY). NO SECRET EVER CROSSES THIS ENDPOINT: the wire schema has no free-text per-key field, and a pre-validation scan hard-400s any secret-smelling key name or value shape (`CREDENTIAL_MATERIAL_REJECTED`). The contributing `licenseIdHash` is derived server-side from the Bearer key (any body value is overridden). Returns the 0-100 fleet hygiene-risk score + recommend-only remediation. Write-only (no GET). Max 8 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LlaveSignalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Snapshot scored + aggregate posture recorded (replace-on-write per site).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/LlaveSignalAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Credential material detected (`CREDENTIAL_MATERIAL_REJECTED`), invalid snapshot (`INVALID_LLAVE_SIGNAL`) or malformed JSON (`INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fenix/assess": {
      "post": {
        "operationId": "assessFenixRestoreSafety",
        "summary": "Assess restore safety of a backup candidate (Fénix)",
        "description": "Drokio Fénix (post-incident clean restore). The caller reports ONE ANONYMIZED, fully-bucketed restore-candidate signal (backup age bucket / integrity-check state / known-infected overlap class / clean-suspicious-infected FILE-CLASS COUNTS — enum buckets and small counts ONLY) and receives a 0-100 restore-safety score, a 5-band verdict and an ordered RECOMMEND-ONLY restore plan. ASSESSMENT, NOT EXECUTION: Drokio never restores, quarantines, deletes or fetches a backup — every 200 attests `restoreExecuted: false`. NO PATH / NO CONTENT EVER CROSSES THIS ENDPOINT: a pre-engine scan hard-400s any path/content-smelling key name or value shape (`RESTORE_CONTENT_REJECTED`). The contributing `licenseIdHash` is derived server-side from the Bearer key (any body value is overridden); the aggregate assessment is stored replace-on-write per (license, site). On top of the per-IP and per-key limits, a per-LICENSE daily volume cap (server-derived license hash, own bucket) returns a hard 429 when exhausted. Write-only (no GET). Max 8 KiB.",
        "tags": [
          "Signals"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FenixAssessRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Candidate scored; aggregate assessment recorded (replace-on-write per license+site).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FenixAssessAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Path/content material detected (`RESTORE_CONTENT_REJECTED`), invalid bucketed signal (`INVALID_FENIX_SIGNAL`) or malformed JSON (`INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/canary/trip": {
      "post": {
        "operationId": "reportCanaryTrip",
        "summary": "Report a Vault Tripwire (decoy) trip",
        "description": "Reports an ANONYMIZED behavioral trip when a Drokio Bóveda decoy is touched — a ~100% confidence breach signal. The validator hard-rejects raw payload, secret/ credential value, exfiltrated data, cookie, token, email, geolocation and headers; IP/User-Agent are accepted-and-discarded. The sybil-resistance `licenseIdHash` is derived server-side from the key. Write-only. Max 32 KiB.",
        "tags": [
          "Threat Intelligence"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CanaryTrip"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Trip accepted; identity-free fingerprint receipt returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/CanaryTripAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid trip (`INVALID_CANARY_TRIP` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threat-feed": {
      "get": {
        "operationId": "getThreatFeed",
        "summary": "Corroborated threat feed (Colmena)",
        "description": "The identity-free Colmena threat feed the Drako plugin polls (~15 min) to pre-block attacker techniques corroborated across the fleet.\n\nGated: when `DROKIO_COLMENA_FEED_ENABLED` is not `1` the route returns an empty `DISABLED` feed (HTTP 200) **without** requiring auth. When enabled it requires a valid license key (Bearer). Supports `If-None-Match` for a 304. Carries only fingerprint match-tokens + attack_type + severity + corroboration count — no site/license identity, no IP, no payload.",
        "tags": [
          "Threat Intelligence"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {}
        ],
        "parameters": [
          {
            "name": "If-None-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Per-epoch ETag from a previous response; yields 304 when unchanged."
          }
        ],
        "responses": {
          "200": {
            "description": "The corroborated (or empty DISABLED) feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThreatFeed"
                }
              }
            }
          },
          "304": {
            "description": "Feed unchanged since the supplied ETag."
          },
          "401": {
            "description": "Feed enabled but no/invalid license key supplied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-IP pre-auth rate limit exceeded. Includes a `Retry-After` header.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            }
          }
        }
      }
    },
    "/api/v1/atlas/report": {
      "post": {
        "operationId": "ingestAtlasReport",
        "summary": "Ingest one edge-anonymized Colmena report (Atlas)",
        "description": "The write side of the Colmena fleet threat-feed. A fleet node submits ONE edge-anonymized behavioral report (attack type + behavior class + opaque payload hash + hashed site/license identity — never IP, never UA, never raw payload, never PII). Hard-forbidden raw-payload/PII keys are rejected 400; legacy `ip`/`userAgent` fields are silently stripped; `siteIdHash` / `licenseIdHash` must be opaque hash tokens (`[A-Za-z0-9_-]{1,128}`). On top of the per-IP and per-key limits, a per-LICENSE daily volume cap (server-derived license hash) returns a hard 429 when exhausted. The 200 echoes ONLY the opaque `fingerprintKey` — never any identity. Write-only. Max 8 KiB.",
        "tags": [
          "Threat Intelligence"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AtlasReportRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Report accepted into the corroboration ledger.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AtlasReportAck"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Privacy/shape rejection (`ATLAS_INVALID_REPORT` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Report store transiently unavailable (`ATLAS_STORE_UNAVAILABLE`); the report was NOT recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/atlas/stack-match": {
      "post": {
        "operationId": "matchAtlasStack",
        "summary": "Filtered Colmena corroboration match (Atlas)",
        "description": "Asks which of the caller's LOCALLY-derived fingerprint keys (`attackType|payloadHash|behaviorClass`) and/or attack types are fleet-corroborated right now — without pulling the full feed. An EMPTY query returns zero matches (never the whole feed) plus the identity-free corroboration summary. Gated like the feed reader: when `DROKIO_COLMENA_FEED_ENABLED` is not `1` the feed mode is `DISABLED` and matches are honestly empty. Matches carry ONLY {fingerprintKey, attackType, severity, distinctSites}. Max 8 KiB.",
        "tags": [
          "Threat Intelligence"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AtlasStackMatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Matches for the queried keys/types (possibly empty).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AtlasStackMatchResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query (`ATLAS_INVALID_PAYLOAD` / `ATLAS_UNKNOWN_FIELD` / `ATLAS_INVALID_QUERY` / `ATLAS_QUERY_TOO_LARGE` / `ATLAS_INVALID_FINGERPRINT_KEY` / `ATLAS_UNKNOWN_ATTACK_TYPE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/boveda/summary": {
      "get": {
        "operationId": "getBovedaVaultSummary",
        "summary": "Bóveda vault deterrence posture (identity-free)",
        "description": "Licensed read surface over the Vault Tripwire engine: fleet deterrence score + band, per-surface roll-ups (counts only), corroborated attacker patterns (identity-free fingerprint composites + counts), the static decoy-coverage catalog and the persistence posture. EVERY identity axis is stripped — the response declares `scope.tenantScoping: \"CAPABILITY_NOT_SCOPED\"` and a leak guard runs before every 200. No body / query input is read. The write side is POST /api/v1/canary/trip.",
        "tags": [
          "Threat Intelligence"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "The sanitized, identity-free vault posture.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/BovedaVaultPosture"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "414": {
            "description": "Request URL exceeds the 8 KiB cap (`URI_TOO_LONG`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Posture failed the identity-free guard (`BOVEDA_POSTURE_GUARD`) — fails closed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Vault posture temporarily unavailable (`BOVEDA_SUMMARY_UNAVAILABLE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scan": {
      "post": {
        "operationId": "triggerScan",
        "summary": "Trigger a remote scan",
        "description": "Queues a remote scan for a site and returns a `scan_id`. The result is delivered out-of-band in a later phase. Responds 202 Accepted.",
        "tags": [
          "Scanning"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScanRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Scan queued.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ScanResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload (`INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scanner": {
      "post": {
        "operationId": "runVulnerabilityScan",
        "summary": "Run the vulnerability scanner (mirror)",
        "description": "Returns a vulnerability scan result for a site. Plan-gated: `starter` may only run `quick`; `pro`+ may run `full`; `enterprise` may run `deep`. NOTE: this endpoint currently returns pre-computed/synthetic findings from the mock vulnerability database — the production CVE correlation is a future phase.",
        "tags": [
          "Scanning"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScannerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Scan result.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ScannerResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload (`INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/velo/scan": {
      "post": {
        "operationId": "runVeloPiiScan",
        "summary": "Scan a text sample for PII exposure (Velo)",
        "description": "Authorized, customer-driven PII-exposure scan. The caller submits a BOUNDED TEXT SAMPLE from its OWN system (a log line, an API response, an error body). The sample is classified in-memory (email / phone / card / national-id / health) and is NEVER stored, logged or echoed — the response carries only per-class match counts, coarse positions ({piiClass, startOffset, length}) and remediation recommendations, plus must-be-false privacy attestations. A counts-only ledger row may persist best-effort (the scan never depends on it). Max 8 KiB body; `sample` capped at 6000 chars.",
        "tags": [
          "Scanning"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VeloScanRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Classification counts + remediation (never the sample or a matched value).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/VeloScanResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid envelope (`INVALID_VELO_SCAN` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exploitability-risk/score": {
      "post": {
        "operationId": "scoreExploitabilityRisk",
        "summary": "Score exploitability risk (defensive)",
        "description": "Authorized defensive risk scoring. Accepts declarative metadata ONLY — no target URLs/IPs, no exploit code, no payloads, no scan results, no credentials. The denylist scan rejects forbidden fields to depth 4. Every response asserts `offensiveOutputGenerated: false` and `payloadGenerated: false`. Max 8 KiB.",
        "tags": [
          "Risk"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExploitabilityRiskInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Risk score, band, rationale and defensive mitigations.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ExploitabilityRiskResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation/denylist rejection (`EXPLOITABILITY_RISK_*`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/gladiador/assess": {
      "post": {
        "operationId": "assessGladiadorReadiness",
        "summary": "Score defensive adversarial readiness (Gladiador)",
        "description": "DEFENSIVE adversarial-readiness scoring. The caller submits an anonymized CONTROL-COVERAGE record — an object whose keys come EXCLUSIVELY from the frozen Gladiador technique-id catalog and whose values are coverage flags ({controlPresent, controlTested, daysSinceLastValidation?}). Unknown keys are rejected (nothing free-form can smuggle a target/finding in). An empty object is valid (scored as the honest worst case, 0). Pure compute — the route never executes, simulates or dispatches anything; every response attests `offensiveOutputGenerated: false` and `attackExecuted: false`. Max 8 KiB.",
        "tags": [
          "Risk"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GladiadorCoverageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Readiness score, band, component breakdown and prioritized gaps.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GladiadorAssessment"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid coverage record (`GLADIADOR_UNKNOWN_TECHNIQUE_ID` / `GLADIADOR_INVALID_COVERAGE` / `GLADIADOR_INVALID_PAYLOAD` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/guardian-sesion/assess": {
      "post": {
        "operationId": "assessSessionHijackRisk",
        "summary": "Score session-hijack risk from bucketed signals (Guardián de Sesión)",
        "description": "DEFENSIVE session-hijack-risk scoring over pre-bucketed, ANONYMIZED per-session signals plus a single OPAQUE pre-hashed session reference. Any raw identity / telemetry field (email, ip, userId, geo, token, cookie, fingerprint, …) at any depth is rejected 400. Returns a 0-100 hijack-risk score, its band and RECOMMENDED defensive step-up actions (MFA / re-auth / terminate / notify) — the endpoint only recommends, it NEVER enforces. Pure compute, nothing persisted. Max 8 KiB.",
        "tags": [
          "Risk"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GuardianSesionSignals"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hijack-risk score, band, contributing signals and recommend-only actions.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GuardianSesionAssessment"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation/PII rejection (`GUARDIAN_SESION_*`, e.g. `GUARDIAN_SESION_FORBIDDEN_PII_FIELD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/argos/incidents": {
      "post": {
        "operationId": "attributeArgosIncident",
        "summary": "Forensic attribution from anonymized signals (ARGOS)",
        "description": "DEFENSIVE forensic-attribution endpoint. The caller submits ALREADY-COMPUTED, anonymized detector signals (the ForensicSignals envelope — counts, buckets and booleans only; no raw payload / IP / geo / secret field exists in the shape) and receives an ordered attribution timeline, a ranked BEHAVIORAL actor-cohort hypothesis (never a named actor / nation / person), an overall confidence (0-100) and an anonymized non-reversible fingerprint. Pure compute, nothing persisted, no outbound network. Max 8 KiB.",
        "tags": [
          "Risk"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArgosForensicSignals"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attribution timeline + behavioral cohort hypotheses + confidence.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ArgosAttribution"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid signals envelope (`ARGOS_*`, e.g. `ARGOS_INVALID_SURFACE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/certify/issue": {
      "post": {
        "operationId": "issueCertifyCredential",
        "summary": "Issue a signed Drokio Certify credential",
        "description": "Mints a tamper-evident credential for one of the caller's OWN subjects — \"Drokio certified subject X for kind K, valid until E\" — signs its content hash with Ed25519 (graceful `unsigned-no-key` when no signing key is configured) and records it. The `subject_ref_hash` is derived SERVER-SIDE from the authenticated key (+ optional opaque `subjectLabel` fan-out); the client can never choose the credential id, epochs or signature. Verify later via the public `GET /api/v1/certify/verify/{id}`. Max 16 KiB.",
        "tags": [
          "Certification"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CertifyIssueRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Credential minted, signed (when a key is configured) and recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/CertifyIssueResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid issue request (`INVALID_CREDENTIAL_KIND` / `INVALID_SUBJECT_LABEL` / `SUBJECT_LABEL_TOO_LONG` / `INVALID_VALIDITY` / `INVALID_SCORE` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Durable-write failure (`CERTIFY_STORE_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/certify/verify/{id}": {
      "get": {
        "operationId": "verifyCertifyCredential",
        "summary": "Publicly verify a Certify credential",
        "description": "PUBLIC (no auth) verification of a Drokio Certify credential by its opaque id. Reports an honest verdict: existence, internal consistency, Ed25519 signature validity (using ONLY the public key embedded in the stored envelope), revocation and expiry. `overallValid` is true only when ALL checks pass — a revoked or expired credential whose signature still verifies reports `overallValid: false` with explicit reasons. An unknown id is an honest 404, never a fake `valid`. The full signature envelope is returned so a third party can re-verify entirely offline.",
        "tags": [
          "Certification"
        ],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "The opaque credential id returned at issue time."
          }
        ],
        "responses": {
          "200": {
            "description": "Verification verdict (valid or not — always honest).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertifyVerifyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing/malformed credential id (`invalid_credential_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertifyPublicError"
                }
              }
            }
          },
          "404": {
            "description": "No credential with this id (`credential_not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertifyPublicError"
                }
              }
            }
          },
          "429": {
            "description": "Per-IP pre-auth rate limit exceeded. Includes a `Retry-After` header.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            }
          },
          "503": {
            "description": "Verification temporarily unavailable (`verify_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertifyPublicError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/certify/revoke": {
      "post": {
        "operationId": "revokeCertifyCredential",
        "summary": "Revoke one of your own Certify credentials",
        "description": "Revokes a credential the authenticated key issued. Ownership is enforced WITHOUT trusting the body: the stored `subject_ref_hash` must be reproducible from THIS key under the supplied `subjectLabel` (defaults to the no-label subject). Unknown id or ownership mismatch returns 404 — the endpoint never reveals that an id exists under a different owner. After revocation the public verify endpoint reports `overallValid: false` with reason `REVOKED`. Max 8 KiB.",
        "tags": [
          "Certification"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CertifyRevokeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Revocation recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/CertifyRevokeResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid body (`INVALID_CREDENTIAL_ID` / `INVALID_SUBJECT_LABEL` / `INVALID_PAYLOAD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid `Authorization: Bearer <api_key>` header, or unknown key (error codes `UNAUTHORIZED` / `INVALID_KEY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "API key expired (error code `EXPIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Unknown id or not owned by this key (`CREDENTIAL_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Payload exceeds the size cap (`PAYLOAD_TOO_LARGE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded — 100 requests/minute. Includes a `Retry-After` header (error code `RATE_LIMITED`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Store failure (`CERTIFY_STORE_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trust/{slug}": {
      "get": {
        "operationId": "getTrustState",
        "summary": "Public TrustOS verification state",
        "description": "Public (no auth) current TrustOS state for a verified site, including a signed attestation (Ed25519) when a signing key is configured. Returns 404 for an unknown slug (never a fake `verified`) and 403 for a private verification.",
        "tags": [
          "Trust"
        ],
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The site's public verification slug."
          }
        ],
        "responses": {
          "200": {
            "description": "Public trust state + attestation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustStateResponse"
                }
              }
            }
          },
          "403": {
            "description": "Verification is private.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustError"
                }
              }
            }
          },
          "404": {
            "description": "No site verified at this slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trust/{slug}/evidence/{ref}": {
      "get": {
        "operationId": "getTrustEvidence",
        "summary": "Public TrustOS evidence metadata",
        "description": "Public (no auth) auditable metadata for an evidence reference appearing in a site's sub-scores or trust events. NEVER exposes raw artifact content — hash + metadata + description only. `ref` is URL-encoded (e.g. `sha256:...`).",
        "tags": [
          "Trust"
        ],
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The site's public verification slug."
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded evidence reference."
          }
        ],
        "responses": {
          "200": {
            "description": "Evidence metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustEvidenceResponse"
                }
              }
            }
          },
          "404": {
            "description": "Site not found or private.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/badge/{slug}": {
      "get": {
        "operationId": "getTrustBadge",
        "summary": "Trust badge (SVG)",
        "description": "Public (no auth) dynamic SVG badge showing the current TrustOS state, for embedding in a customer site footer. Returns a neutral grey badge (never a fake green) for unknown/private sites or at-risk/suspended states. Always HTTP 200 with `image/svg+xml`.",
        "tags": [
          "Trust"
        ],
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The site's public verification slug."
          }
        ],
        "responses": {
          "200": {
            "description": "An SVG badge.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Drokio license key",
        "description": "A Drokio license API key, sent as `Authorization: Bearer <api_key>`. Limited to 100 requests/minute per key."
      }
    },
    "schemas": {
      "SuccessEnvelope": {
        "type": "object",
        "required": [
          "success",
          "data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "description": "Operation-specific payload."
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "INVALID_PAYLOAD"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "FlatError": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message (flat shape)."
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "required": [
          "status",
          "version",
          "brain_available",
          "uptime"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down"
            ]
          },
          "version": {
            "type": "string",
            "example": "1.0.0"
          },
          "brain_available": {
            "type": "boolean"
          },
          "uptime": {
            "type": "string",
            "example": "1d 4h 12m 9s"
          }
        }
      },
      "ApiKeyStatus": {
        "type": "object",
        "required": [
          "valid",
          "plan",
          "sites_allowed",
          "sites_used",
          "expires_at"
        ],
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "plan": {
            "type": "string",
            "enum": [
              "starter",
              "pro",
              "enterprise"
            ]
          },
          "sites_allowed": {
            "type": "integer"
          },
          "sites_used": {
            "type": "integer"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MeResponse": {
        "type": "object",
        "description": "The calling key's own contract summary. NEVER carries the API key, the owner email, or any secret.",
        "required": [
          "plan",
          "status",
          "modules",
          "rateLimitPolicy",
          "domainBound"
        ],
        "properties": {
          "plan": {
            "type": "string",
            "description": "Effective plan: the product license's plan (`free`/`pro`/`business`/`enterprise`) when the key is also a product license, otherwise the REST quota plan (`starter`/`pro`/`enterprise`)."
          },
          "status": {
            "type": "string",
            "description": "License status (`active`/`trial`/...). A pure REST quota key reports `active`."
          },
          "modules": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Effective module set (per-license overrides included)."
          },
          "rateLimitPolicy": {
            "type": "object",
            "required": [
              "label",
              "limit",
              "windowSeconds",
              "scope"
            ],
            "properties": {
              "label": {
                "type": "string",
                "example": "api:per-key-60s"
              },
              "limit": {
                "type": "integer",
                "example": 100
              },
              "windowSeconds": {
                "type": "integer",
                "example": 60
              },
              "scope": {
                "type": "string",
                "enum": [
                  "per-api-key"
                ]
              }
            },
            "description": "The per-key policy the auth layer actually enforces."
          },
          "domainBound": {
            "type": "boolean",
            "description": "true ⇔ the key is bound to a registered domain (product licenses always are). REST quota keys are multi-site and report false."
          },
          "trialEndsAt": {
            "type": "string",
            "nullable": true,
            "description": "Present ONLY when status is `trial` (ISO date or null)."
          }
        }
      },
      "LicenseVerifyRequest": {
        "type": "object",
        "description": "Conditional requirements the validator enforces: when the key travels in the body (legacy plugin contract) BOTH `api_key` and `domain` are required; when it travels as `Authorization: Bearer <key>` both become optional (a body `api_key` that differs from the Bearer key yields the generic invalid shape).",
        "properties": {
          "api_key": {
            "type": "string",
            "description": "Drokio license key (dk_test_* / dk_live_*). Required unless the key is sent as Bearer."
          },
          "domain": {
            "type": "string",
            "description": "Required when the key travels in the body; optional with Bearer."
          },
          "plugin_version": {
            "type": "string"
          },
          "wp_version": {
            "type": "string"
          },
          "php_version": {
            "type": "string"
          },
          "installation_hash": {
            "type": "string"
          },
          "modules_active": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "LicenseVerifyResponse": {
        "type": "object",
        "required": [
          "valid",
          "plan",
          "modules_allowed",
          "modules",
          "trial_active",
          "trial_days_remaining",
          "next_billing",
          "message"
        ],
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "plan": {
            "type": "string",
            "enum": [
              "free",
              "pro",
              "business",
              "enterprise"
            ]
          },
          "status": {
            "type": "string",
            "description": "License status (`active`/`trial`/...). Present only in valid responses."
          },
          "modules_allowed": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Legacy name the Drako plugin reads."
          },
          "modules": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Additive alias of `modules_allowed`."
          },
          "domain_bound": {
            "type": "boolean",
            "description": "true ⇔ THIS call verified the key↔domain binding (a `domain` was sent and matched). Present only in valid responses."
          },
          "trial_active": {
            "type": "boolean"
          },
          "trial_days_remaining": {
            "type": "integer"
          },
          "trial_ends_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Trial end (ISO) when status is `trial`; null otherwise. Present only in valid responses."
          },
          "next_billing": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "reason": {
            "type": "string",
            "enum": [
              "suspended"
            ],
            "description": "The ONLY disclosed invalid state: a payment problem (chargeback/dispute). Every other invalid case is byte-identical and undisclosed."
          },
          "message": {
            "type": "string"
          }
        }
      },
      "TrialRequest": {
        "type": "object",
        "required": [
          "email",
          "domain",
          "plan",
          "installation_hash"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "domain": {
            "type": "string"
          },
          "plan": {
            "type": "string",
            "enum": [
              "pro",
              "business",
              "enterprise"
            ],
            "description": "`free` is rejected."
          },
          "installation_hash": {
            "type": "string",
            "minLength": 8
          },
          "plugin_version": {
            "type": "string"
          },
          "wp_version": {
            "type": "string"
          },
          "php_version": {
            "type": "string"
          }
        }
      },
      "TrialResponse": {
        "type": "object",
        "required": [
          "success",
          "api_key",
          "plan",
          "trial_days",
          "trial_end",
          "modules_allowed",
          "setup_intent_client_secret",
          "mock"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "api_key": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "trial_days": {
            "type": "integer",
            "example": 14
          },
          "trial_end": {
            "type": "string",
            "format": "date-time"
          },
          "modules_allowed": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "setup_intent_client_secret": {
            "type": "string"
          },
          "mock": {
            "type": "boolean"
          }
        }
      },
      "CheckoutRequest": {
        "type": "object",
        "required": [
          "items",
          "domain",
          "email"
        ],
        "properties": {
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 30,
            "items": {
              "type": "object",
              "required": [
                "type",
                "slug"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "module",
                    "pack",
                    "plan"
                  ]
                },
                "slug": {
                  "type": "string",
                  "pattern": "^[a-z0-9_-]{1,40}$"
                }
              }
            }
          },
          "domain": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "trial_days": {
            "type": "integer",
            "minimum": 0,
            "maximum": 90
          }
        }
      },
      "CheckoutResponse": {
        "type": "object",
        "required": [
          "success",
          "checkout_url"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "checkout_url": {
            "type": "string",
            "format": "uri"
          },
          "mock": {
            "type": "boolean",
            "description": "Present and true when Stripe is not configured."
          }
        }
      },
      "TelemetryStats": {
        "type": "object",
        "required": [
          "files_monitored",
          "hardening_rules_active",
          "events_last_24h",
          "files_modified",
          "last_scan",
          "brain_available"
        ],
        "properties": {
          "files_monitored": {
            "type": "integer"
          },
          "hardening_rules_active": {
            "type": "integer"
          },
          "events_last_24h": {
            "type": "integer"
          },
          "files_modified": {
            "type": "integer"
          },
          "last_scan": {
            "type": "string",
            "format": "date-time"
          },
          "brain_available": {
            "type": "boolean"
          }
        }
      },
      "TelemetryHeartbeat": {
        "type": "object",
        "required": [
          "site_url",
          "license_key",
          "drako_version",
          "wordpress_version",
          "php_version",
          "modules_active",
          "stats",
          "events"
        ],
        "properties": {
          "site_url": {
            "type": "string",
            "format": "uri"
          },
          "license_key": {
            "type": "string",
            "description": "Must equal the Bearer key."
          },
          "drako_version": {
            "type": "string"
          },
          "wordpress_version": {
            "type": "string"
          },
          "php_version": {
            "type": "string"
          },
          "modules_active": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "stats": {
            "$ref": "#/components/schemas/TelemetryStats"
          },
          "events": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "object",
              "required": [
                "type",
                "severity",
                "title",
                "description",
                "timestamp",
                "metadata"
              ],
              "properties": {
                "type": {
                  "type": "string"
                },
                "severity": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                },
                "metadata": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "TelemetryAttackEvents": {
        "type": "object",
        "required": [
          "site_uuid",
          "domain",
          "events"
        ],
        "properties": {
          "site_uuid": {
            "type": "string",
            "minLength": 8
          },
          "domain": {
            "type": "string",
            "minLength": 3
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "object",
              "required": [
                "type",
                "attack_type",
                "source_ip",
                "module",
                "severity",
                "blocked",
                "timestamp"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "attack_blocked"
                  ]
                },
                "attack_type": {
                  "type": "string",
                  "enum": [
                    "sqli",
                    "bruteforce",
                    "scanner",
                    "xss",
                    "malware",
                    "rce",
                    "lfi",
                    "other"
                  ]
                },
                "source_ip": {
                  "type": "string",
                  "minLength": 7
                },
                "source_country": {
                  "type": "string"
                },
                "target_path": {
                  "type": "string"
                },
                "module": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "critical",
                    "high",
                    "medium",
                    "low"
                  ]
                },
                "blocked": {
                  "type": "boolean"
                },
                "details": {
                  "type": "string",
                  "description": "Sanitized at the boundary; control chars stripped."
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "TelemetryHeartbeatAck": {
        "type": "object",
        "required": [
          "received",
          "events_count"
        ],
        "properties": {
          "received": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "events_count": {
            "type": "integer"
          }
        }
      },
      "TelemetryAttackAck": {
        "type": "object",
        "required": [
          "success",
          "received"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "received": {
            "type": "integer"
          }
        }
      },
      "PostureSignal": {
        "type": "object",
        "description": "A privacy-safe posture signal (per-vertical shape). The validator accepts only allow-listed fields and requires the must-be-false privacy literals (`piiIncluded`/`contentIncluded`/`secretsIncluded`, etc.) to be the literal `false`. Identity hashes are derived server-side from the authenticated key.",
        "additionalProperties": true,
        "properties": {
          "piiIncluded": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "contentIncluded": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "secretsIncluded": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "CloudPostureSignal": {
        "type": "object",
        "description": "Counts-and-ratios posture signal for a modern-stack app. No secret, source, env value or PII. `appIdHash` is overridden server-side.",
        "additionalProperties": true,
        "properties": {
          "piiIncluded": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "secretsIncluded": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "SignalAck": {
        "type": "object",
        "required": [
          "accepted",
          "receivedAt",
          "persistenceMode",
          "persistedToDatabase"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "retentionExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "persistenceMode": {
            "type": "string",
            "description": "Active storage mode (e.g. in-memory until the operator enables Postgres)."
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "adapterLabel": {
            "type": "string",
            "enum": [
              "in-memory",
              "postgres",
              "disabled"
            ]
          },
          "bindingMode": {
            "type": "string",
            "description": "Connector/site binding posture (may be NOT_ENFORCED_YET)."
          }
        }
      },
      "CanaryTrip": {
        "type": "object",
        "description": "An anonymized decoy trip. Raw payload / secret / credential / exfil / cookie / token / email / geolocation / headers are HARD-rejected; the must-be-false privacy flags must be the literal `false`. `licenseIdHash` is overridden server-side.",
        "additionalProperties": true,
        "properties": {
          "siteIdHash": {
            "type": "string"
          },
          "tripwireType": {
            "type": "string"
          },
          "surface": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "high",
              "medium",
              "low"
            ]
          }
        }
      },
      "CanaryTripAck": {
        "type": "object",
        "required": [
          "accepted",
          "fingerprintKey",
          "receivedAt",
          "persistenceMode",
          "persistedToDatabase"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "fingerprintKey": {
            "type": "string",
            "description": "Identity-free composite fingerprint key."
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "retentionExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "persistenceMode": {
            "type": "string"
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "adapterLabel": {
            "type": "string",
            "enum": [
              "in-memory",
              "postgres",
              "disabled"
            ]
          }
        }
      },
      "ThreatFeed": {
        "type": "object",
        "required": [
          "feedMode",
          "epoch",
          "ttlSeconds",
          "fingerprints"
        ],
        "properties": {
          "feedMode": {
            "type": "string",
            "enum": [
              "WATCH",
              "ENFORCE",
              "DISABLED"
            ]
          },
          "epoch": {
            "type": "string",
            "description": "Per-15-min epoch bucket id (or `disabled`)."
          },
          "ttlSeconds": {
            "type": "integer"
          },
          "fingerprints": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "matchToken": {
                  "type": "string",
                  "description": "Identity-free fingerprint match token."
                },
                "attackType": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "critical",
                    "high",
                    "medium",
                    "low"
                  ]
                },
                "corroborationCount": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ScanRequest": {
        "type": "object",
        "required": [
          "site_url",
          "scan_type"
        ],
        "properties": {
          "site_url": {
            "type": "string",
            "format": "uri"
          },
          "scan_type": {
            "type": "string",
            "enum": [
              "integrity",
              "pii",
              "full"
            ]
          }
        }
      },
      "ScanResponse": {
        "type": "object",
        "required": [
          "scan_id",
          "status",
          "estimated_time"
        ],
        "properties": {
          "scan_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ]
          },
          "estimated_time": {
            "type": "string",
            "example": "30s"
          }
        }
      },
      "ScannerRequest": {
        "type": "object",
        "required": [
          "site_url",
          "scan_type"
        ],
        "properties": {
          "site_url": {
            "type": "string",
            "format": "uri"
          },
          "scan_type": {
            "type": "string",
            "enum": [
              "quick",
              "full",
              "deep"
            ]
          }
        }
      },
      "VulnerabilityFinding": {
        "type": "object",
        "required": [
          "id",
          "component_type",
          "component_name",
          "installed_version",
          "title",
          "severity",
          "cve_id",
          "description",
          "affected_versions",
          "fixed_in",
          "recommended_action",
          "reference_url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "component_type": {
            "type": "string",
            "enum": [
              "plugin",
              "theme",
              "core",
              "config"
            ]
          },
          "component_name": {
            "type": "string"
          },
          "installed_version": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "high",
              "medium",
              "low"
            ]
          },
          "cve_id": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string"
          },
          "affected_versions": {
            "type": "string"
          },
          "fixed_in": {
            "type": "string",
            "nullable": true
          },
          "recommended_action": {
            "type": "string"
          },
          "reference_url": {
            "type": "string",
            "nullable": true,
            "format": "uri"
          }
        }
      },
      "ScannerResponse": {
        "type": "object",
        "required": [
          "scan_id",
          "site_url",
          "scan_type",
          "started_at",
          "completed_at",
          "duration_ms",
          "score",
          "findings",
          "summary"
        ],
        "properties": {
          "scan_id": {
            "type": "string",
            "format": "uuid"
          },
          "site_url": {
            "type": "string",
            "format": "uri"
          },
          "scan_type": {
            "type": "string",
            "enum": [
              "quick",
              "full",
              "deep"
            ]
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ms": {
            "type": "integer"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VulnerabilityFinding"
            }
          },
          "summary": {
            "type": "object",
            "required": [
              "critical",
              "high",
              "medium",
              "low"
            ],
            "properties": {
              "critical": {
                "type": "integer"
              },
              "high": {
                "type": "integer"
              },
              "medium": {
                "type": "integer"
              },
              "low": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ExploitabilityRiskInput": {
        "type": "object",
        "description": "Declarative metadata only. No target URL/IP, exploit code, payload, shellcode, scan result or credential is accepted (denylist scan to depth 4).",
        "required": [
          "assetIdHash"
        ],
        "additionalProperties": true,
        "properties": {
          "assetIdHash": {
            "type": "string"
          },
          "sourceMode": {
            "type": "string"
          }
        }
      },
      "ExploitabilityRiskResult": {
        "type": "object",
        "required": [
          "accepted",
          "assetIdHash",
          "score",
          "band",
          "offensiveOutputGenerated",
          "activeScanPerformed",
          "payloadGenerated"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "assetIdHash": {
            "type": "string"
          },
          "sourceMode": {
            "type": "string"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "type": "string"
          },
          "bandLabel": {
            "type": "string"
          },
          "humanReviewRequired": {
            "type": "boolean"
          },
          "confidence": {
            "type": "number"
          },
          "rationale": {
            "type": "object",
            "properties": {
              "summary": {
                "type": "string"
              },
              "topRiskFactors": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "controlsActive": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "humanReviewReason": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "mitigations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "activeScanPerformed": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "payloadGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "storeMode": {
            "type": "string"
          },
          "adapterLabel": {
            "type": "string"
          }
        }
      },
      "AnalyticsMetricsRequest": {
        "type": "object",
        "description": "Optional section filter. Omitting the body (or sending `{}`) serves the full snapshot; `sections: []` serves only the counters envelope. No field can name another tenant — there is deliberately no key/site/license field.",
        "properties": {
          "sections": {
            "type": "array",
            "maxItems": 16,
            "items": {
              "type": "string",
              "enum": [
                "sites",
                "siteDetails",
                "dailyStats",
                "securityScores",
                "brainSummary"
              ]
            }
          }
        }
      },
      "AnalyticsMetricsResponse": {
        "type": "object",
        "description": "The caller's tenant-scoped snapshot. The counters envelope (siteCount/isEmpty/source) is always present; data sections appear only when requested (or when no filter was given). Section sub-shapes are engine-owned aggregates (counts, scores, buckets) — never raw events with identity.",
        "required": [
          "scope",
          "siteCount",
          "isEmpty",
          "source",
          "crossTenantDataServed",
          "piiStored",
          "rawIpStored",
          "userAgentStored",
          "rawPayloadStored",
          "geolocationStored",
          "offensiveOutputGenerated",
          "attackExecuted",
          "blockId"
        ],
        "additionalProperties": true,
        "properties": {
          "scope": {
            "type": "object",
            "required": [
              "scopedTo",
              "fleetWide",
              "plan"
            ],
            "properties": {
              "scopedTo": {
                "type": "string",
                "enum": [
                  "caller-license"
                ]
              },
              "fleetWide": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "plan": {
                "type": "string"
              }
            }
          },
          "siteCount": {
            "type": "integer"
          },
          "isEmpty": {
            "type": "boolean"
          },
          "sites": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "siteDetails": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "dailyStats": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "securityScores": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "brainSummary": {
            "type": "object",
            "additionalProperties": true
          },
          "source": {
            "type": "string"
          },
          "crossTenantDataServed": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "piiStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawIpStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "userAgentStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawPayloadStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "geolocationStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "attackExecuted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "LlaveKeyEntry": {
        "type": "object",
        "description": "ONE fully-bucketed key/secret inventory entry — enum buckets, booleans and small counts only. There is NO free-text field (`referenceId` is rejected over the wire); the shape cannot represent a credential value.",
        "required": [
          "kind",
          "ageBucket",
          "rotationInterval",
          "scopeBreadth",
          "lastUsedBucket",
          "storageLocation",
          "isExposedInPublic"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Catalogued key-kind bucket."
          },
          "ageBucket": {
            "type": "string",
            "description": "Catalogued age bucket."
          },
          "rotationInterval": {
            "type": "string",
            "description": "Catalogued rotation-policy bucket."
          },
          "scopeBreadth": {
            "type": "string",
            "description": "Catalogued scope-breadth bucket."
          },
          "lastUsedBucket": {
            "type": "string",
            "description": "Catalogued last-use bucket."
          },
          "storageLocation": {
            "type": "string",
            "description": "Catalogued storage-class bucket."
          },
          "isExposedInPublic": {
            "type": "boolean"
          },
          "exposureCorroborationCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Must be 0 when not exposed."
          }
        }
      },
      "LlaveSignalRequest": {
        "type": "object",
        "description": "A bucketed inventory snapshot for ONE site. `licenseIdHash` is overridden server-side from the authenticated key. The six must-be-false privacy flags (credentialValueStored / passwordStored / secretValueStored / piiIncluded / rawIpStored / rawDataStored) are rejected 400 when present and not the literal `false`. Any secret-smelling key name or value shape anywhere in the body is a hard 400 (`CREDENTIAL_MATERIAL_REJECTED`).",
        "required": [
          "siteUuid",
          "keys"
        ],
        "additionalProperties": true,
        "properties": {
          "siteUuid": {
            "type": "string",
            "description": "Opaque per-site identifier (one license may cover many sites)."
          },
          "keys": {
            "type": "array",
            "maxItems": 24,
            "items": {
              "$ref": "#/components/schemas/LlaveKeyEntry"
            }
          }
        }
      },
      "LlaveSignalAck": {
        "type": "object",
        "required": [
          "accepted",
          "fleetRiskScore",
          "band",
          "bandLabel",
          "keyCount",
          "exposedKeyCount",
          "highRiskKeyCount",
          "immediateActionCount",
          "receivedAt",
          "replacedPrevious",
          "persistenceMode",
          "persistedToDatabase",
          "adapterLabel",
          "privacyAttestations"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "fleetRiskScore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "type": "string"
          },
          "bandLabel": {
            "type": "string"
          },
          "keyCount": {
            "type": "integer"
          },
          "exposedKeyCount": {
            "type": "integer"
          },
          "highRiskKeyCount": {
            "type": "integer"
          },
          "immediateActionCount": {
            "type": "integer"
          },
          "topRemediation": {
            "description": "Highest-priority recommend-only remediation (rotate / revoke / scope-down / relocate / set-policy / retire), or null.",
            "nullable": true
          },
          "inventoryDigestInput": {
            "type": "string",
            "description": "Identity-free composite digest input."
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "retentionExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "replacedPrevious": {
            "type": "boolean",
            "description": "true ⇔ this license already had a posture for this siteUuid."
          },
          "persistenceMode": {
            "type": "string"
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "adapterLabel": {
            "type": "string"
          },
          "privacyAttestations": {
            "type": "object",
            "description": "Must-be-false attestations mirroring the migration CHECKs.",
            "required": [
              "credentialValueStored",
              "passwordStored",
              "secretValueStored",
              "piiIncluded",
              "rawIpStored",
              "rawDataStored"
            ],
            "properties": {
              "credentialValueStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "passwordStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "secretValueStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "piiIncluded": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "rawIpStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "rawDataStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              }
            }
          }
        }
      },
      "FenixAssessRequest": {
        "type": "object",
        "description": "ONE anonymized, fully-bucketed restore-candidate signal. Every field is a catalogued enum bucket or a small count — the wire shape cannot represent a file path, file name or backup content, and a pre-engine scan hard-400s any path/content-smelling key name or value shape (`RESTORE_CONTENT_REJECTED`). `licenseIdHash` is overridden server-side from the authenticated key. The five must-be-false privacy flags (backupContentStored / filePathsStored / piiIncluded / rawIpStored / rawDataStored) are rejected 400 when present and not the literal `false`.",
        "required": [
          "siteUuid",
          "candidate"
        ],
        "additionalProperties": true,
        "properties": {
          "siteUuid": {
            "type": "string",
            "maxLength": 128,
            "description": "Opaque per-site identifier (one license may cover many sites)."
          },
          "sourceMode": {
            "type": "string",
            "enum": [
              "FOUNDATION_FIXTURE",
              "LIVE_RESTORE_CANDIDATE_SCAN",
              "MOCK_FALLBACK_NO_LIVE"
            ],
            "description": "How the plugin produced the signal. Defaults to LIVE_RESTORE_CANDIDATE_SCAN."
          },
          "candidate": {
            "type": "object",
            "required": [
              "backupAgeBucket",
              "integrityCheckState",
              "knownInfectedOverlapClass",
              "scanVerdict"
            ],
            "properties": {
              "backupAgeBucket": {
                "type": "string",
                "enum": [
                  "UNDER_24H",
                  "D1_3",
                  "D3_7",
                  "D7_30",
                  "OVER_30D",
                  "UNKNOWN"
                ]
              },
              "integrityCheckState": {
                "type": "string",
                "enum": [
                  "VERIFIED_CHAIN_INTACT",
                  "VERIFIED_PARTIAL",
                  "NOT_RUN",
                  "FAILED",
                  "UNKNOWN"
                ]
              },
              "knownInfectedOverlapClass": {
                "type": "string",
                "enum": [
                  "NO_KNOWN_OVERLAP",
                  "PARTIAL_OVERLAP",
                  "FULL_OVERLAP",
                  "UNKNOWN"
                ]
              },
              "scanVerdict": {
                "type": "object",
                "description": "File-CLASS counts from the customer's own scanner (counts only, never a path/name/byte). At least one scanned class is required.",
                "required": [
                  "cleanFileClassCount",
                  "suspiciousFileClassCount",
                  "infectedFileClassCount"
                ],
                "properties": {
                  "cleanFileClassCount": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100000
                  },
                  "suspiciousFileClassCount": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100000
                  },
                  "infectedFileClassCount": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100000
                  }
                }
              }
            }
          }
        }
      },
      "FenixAssessAck": {
        "type": "object",
        "required": [
          "accepted",
          "restoreSafetyScore",
          "band",
          "recommendedPlanId",
          "plan",
          "receivedAt",
          "replacedPrevious",
          "persistenceMode",
          "persistedToDatabase",
          "adapterLabel",
          "restoreExecuted",
          "privacyAttestations"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "restoreSafetyScore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "uncappedScore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Score before worst-signal caps."
          },
          "band": {
            "type": "string",
            "enum": [
              "DO_NOT_RESTORE",
              "QUARANTINE_FIRST",
              "SELECTIVE_RESTORE",
              "GUARDED_RESTORE",
              "SAFE_TO_RESTORE"
            ]
          },
          "bandLabel": {
            "type": "string"
          },
          "bandHeadline": {
            "type": "string"
          },
          "recommendedPlanId": {
            "type": "string",
            "enum": [
              "REBUILD_FROM_CLEAN_SOURCES",
              "QUARANTINE_THEN_RESTORE",
              "RESTORE_DATA_ONLY",
              "FULL_RESTORE_WITH_VERIFICATION_WATCH",
              "FULL_RESTORE_SAFE"
            ]
          },
          "plan": {
            "type": "array",
            "description": "Ordered RECOMMEND-ONLY restore steps — Drokio never executes any of them.",
            "items": {
              "type": "object"
            }
          },
          "appliedCaps": {
            "type": "array",
            "description": "Worst-signal caps that bounded the score (id + reason).",
            "items": {
              "type": "object"
            }
          },
          "counts": {
            "type": "object",
            "description": "Echo of the validated file-class counts."
          },
          "signalDigestInput": {
            "type": "string",
            "description": "Identity-free composite digest input (buckets + counts)."
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "retentionExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "replacedPrevious": {
            "type": "boolean",
            "description": "true ⇔ this license already had an assessment for this siteUuid."
          },
          "persistenceMode": {
            "type": "string"
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "adapterLabel": {
            "type": "string"
          },
          "restoreExecuted": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Recommend-only attestation: Drokio assessed; it did NOT restore."
          },
          "privacyAttestations": {
            "type": "object",
            "description": "Must-be-false attestations mirroring the migration CHECKs.",
            "required": [
              "backupContentStored",
              "filePathsStored",
              "piiIncluded",
              "rawIpStored",
              "rawDataStored"
            ],
            "properties": {
              "backupContentStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "filePathsStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "piiIncluded": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "rawIpStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "rawDataStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              }
            }
          }
        }
      },
      "AtlasReportRequest": {
        "type": "object",
        "description": "ONE edge-anonymized behavioral report. Hard-forbidden keys (rawPayload, payload, query, url, cookie(s), token, email, geo(location), location, headers, body) are rejected 400; legacy ip/ipAddress/userAgent/ua are silently stripped; the must-be-false flags (piiIncluded, rawIpStored, userAgentStored, rawPayloadStored, geolocationStored) are rejected when present and not the literal `false`.",
        "required": [
          "attackType",
          "behaviorClass",
          "severity",
          "payloadHash",
          "siteIdHash",
          "licenseIdHash"
        ],
        "additionalProperties": true,
        "properties": {
          "attackType": {
            "type": "string",
            "enum": [
              "sqli",
              "honeypot_hit",
              "bruteforce_dist",
              "vuln_scanner",
              "api_abuse",
              "scraping",
              "supply_chain",
              "malware_file",
              "bruteforce",
              "skimmer"
            ]
          },
          "behaviorClass": {
            "type": "string",
            "enum": [
              "automated",
              "manual",
              "targeted",
              "distributed",
              "unknown"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ]
          },
          "payloadHash": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,128}$",
            "description": "Opaque hash of the malicious pattern — never the content."
          },
          "siteIdHash": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,128}$",
            "description": "Opaque hash token of the reporting site — a raw identity (email/IP/hostname) is rejected 400."
          },
          "licenseIdHash": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,128}$",
            "description": "Opaque license hash (sybil-resistance axis)."
          },
          "sourceMode": {
            "type": "string",
            "enum": [
              "FOUNDER_PREVIEW_MOCK_SIGNAL",
              "LIVE_SIGNAL_PER_SITE",
              "MOCK_FALLBACK_NO_LIVE"
            ],
            "description": "Optional; any other value normalizes to LIVE_SIGNAL_PER_SITE."
          }
        }
      },
      "AtlasReportAck": {
        "type": "object",
        "required": [
          "accepted",
          "fingerprintKey",
          "storeSize",
          "persistenceMode",
          "adapterLabel",
          "piiStored",
          "rawIpStored",
          "userAgentStored",
          "rawPayloadStored",
          "geolocationStored",
          "offensiveOutputGenerated",
          "attackExecuted",
          "blockId"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "fingerprintKey": {
            "type": "string",
            "description": "Opaque match token `attackType|payloadHash|behaviorClass` — the ONLY echo; never an identity."
          },
          "storeSize": {
            "type": "integer"
          },
          "persistenceMode": {
            "type": "string"
          },
          "adapterLabel": {
            "type": "string"
          },
          "piiStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawIpStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "userAgentStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawPayloadStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "geolocationStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "attackExecuted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "AtlasStackMatchRequest": {
        "type": "object",
        "description": "Bounded corroboration query. Both arrays are optional; an empty query yields zero matches plus the corroboration summary (never the full feed). Each fingerprint key must decompose into engine-vocabulary parts (`attackType|payloadHash|behaviorClass`).",
        "properties": {
          "fingerprintKeys": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "string",
              "maxLength": 300
            }
          },
          "attackTypes": {
            "type": "array",
            "maxItems": 25,
            "items": {
              "type": "string",
              "enum": [
                "sqli",
                "honeypot_hit",
                "bruteforce_dist",
                "vuln_scanner",
                "api_abuse",
                "scraping",
                "supply_chain",
                "malware_file",
                "bruteforce",
                "skimmer"
              ]
            }
          }
        }
      },
      "AtlasStackMatchResponse": {
        "type": "object",
        "required": [
          "feedMode",
          "epoch",
          "matches",
          "matchedCount",
          "queriedCount",
          "corroboration",
          "degradedToEmpty",
          "blockId"
        ],
        "properties": {
          "feedMode": {
            "type": "string",
            "enum": [
              "WATCH",
              "ENFORCE",
              "DISABLED"
            ]
          },
          "epoch": {
            "type": "string",
            "description": "Per-15-min epoch bucket id."
          },
          "matches": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "fingerprintKey",
                "attackType",
                "severity",
                "distinctSites"
              ],
              "properties": {
                "fingerprintKey": {
                  "type": "string"
                },
                "attackType": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "low",
                    "medium",
                    "high",
                    "critical"
                  ]
                },
                "distinctSites": {
                  "type": "integer"
                }
              }
            }
          },
          "matchedCount": {
            "type": "integer"
          },
          "queriedCount": {
            "type": "integer"
          },
          "corroboration": {
            "type": "object",
            "additionalProperties": true,
            "description": "Identity-free corroboration accumulation summary derived from the served feed."
          },
          "degradedToEmpty": {
            "type": "boolean",
            "description": "true ⇔ the store read failed and an empty feed was served."
          },
          "piiStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawIpStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "userAgentStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "rawPayloadStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "geolocationStored": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "attackExecuted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "BovedaVaultPosture": {
        "type": "object",
        "description": "Sanitized, identity-free vault deterrence posture. Only counts survive — no siteIdHash/licenseIdHash of any tenant (including the caller) is ever served.",
        "required": [
          "product",
          "fleetScore",
          "fleetBand",
          "surfaces",
          "corroboratedPatterns",
          "coverage",
          "persistence",
          "scope",
          "privacy"
        ],
        "properties": {
          "product": {
            "type": "string",
            "enum": [
              "boveda"
            ]
          },
          "fleetScore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "fleetBand": {
            "type": "string"
          },
          "isFounderPreview": {
            "type": "boolean"
          },
          "surfaces": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "surface": {
                  "type": "string"
                },
                "reportingSites": {
                  "type": "integer"
                },
                "tripsAbsorbed": {
                  "type": "integer"
                },
                "topScore": {
                  "type": "integer"
                },
                "band": {
                  "type": "string"
                }
              }
            }
          },
          "corroboratedPatterns": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "fingerprintKey": {
                  "type": "string"
                },
                "surfaces": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "distinctSurfaces": {
                  "type": "integer"
                },
                "distinctSites": {
                  "type": "integer"
                },
                "tripCount": {
                  "type": "integer"
                },
                "eligibleForFleetPreblock": {
                  "type": "boolean"
                }
              }
            }
          },
          "coverage": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "catalogSize": {
                "type": "integer"
              },
              "retentionDays": {
                "type": "integer"
              }
            }
          },
          "persistence": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "mode": {
                "type": "string"
              },
              "adapterLabel": {
                "type": "string"
              },
              "sizeSnapshot": {
                "type": "integer"
              }
            }
          },
          "scope": {
            "type": "object",
            "required": [
              "tenantScoping",
              "identityFree"
            ],
            "properties": {
              "tenantScoping": {
                "type": "string",
                "enum": [
                  "CAPABILITY_NOT_SCOPED"
                ]
              },
              "identityFree": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "reason": {
                "type": "string"
              }
            }
          },
          "privacy": {
            "type": "object",
            "additionalProperties": true,
            "description": "Must-be-false vault privacy invariants."
          }
        }
      },
      "VeloScanRequest": {
        "type": "object",
        "required": [
          "sample"
        ],
        "properties": {
          "sample": {
            "type": "string",
            "minLength": 1,
            "maxLength": 6000,
            "description": "A bounded text sample from YOUR OWN system. Never stored, logged or echoed."
          },
          "source": {
            "type": "string",
            "enum": [
              "log",
              "api_response",
              "error_message",
              "database_export",
              "config",
              "other"
            ],
            "description": "Optional allow-listed source label (defaults to `other`)."
          }
        }
      },
      "VeloScanResponse": {
        "type": "object",
        "required": [
          "scanned",
          "product",
          "source",
          "sampleChars",
          "totalMatches",
          "severity",
          "classes",
          "findings",
          "findingsTruncated",
          "privacy",
          "ledger"
        ],
        "properties": {
          "scanned": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "product": {
            "type": "string",
            "enum": [
              "velo"
            ]
          },
          "source": {
            "type": "string"
          },
          "sampleChars": {
            "type": "integer"
          },
          "totalMatches": {
            "type": "integer"
          },
          "severity": {
            "type": "string",
            "enum": [
              "none",
              "warning",
              "critical"
            ]
          },
          "classes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "piiClass",
                "count",
                "severity",
                "remediation"
              ],
              "properties": {
                "piiClass": {
                  "type": "string",
                  "enum": [
                    "email",
                    "phone",
                    "card",
                    "national_id",
                    "health"
                  ]
                },
                "count": {
                  "type": "integer"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "warning",
                    "critical"
                  ]
                },
                "remediation": {
                  "type": "object",
                  "properties": {
                    "classLabel": {
                      "type": "string"
                    },
                    "recommendation": {
                      "type": "string"
                    },
                    "techniques": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "complianceRefs": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "findings": {
            "type": "array",
            "description": "Coarse positions only — never a matched value.",
            "items": {
              "type": "object",
              "properties": {
                "piiClass": {
                  "type": "string"
                },
                "startOffset": {
                  "type": "integer"
                },
                "length": {
                  "type": "integer"
                }
              }
            }
          },
          "findingsTruncated": {
            "type": "boolean"
          },
          "privacy": {
            "type": "object",
            "required": [
              "sampleStored",
              "piiValueStored",
              "rawTextStored",
              "sampleEchoed"
            ],
            "properties": {
              "sampleStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "piiValueStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "rawTextStored": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "sampleEchoed": {
                "type": "boolean",
                "enum": [
                  false
                ]
              }
            }
          },
          "ledger": {
            "type": "object",
            "description": "Best-effort counts-only ledger posture (the scan never depends on it).",
            "properties": {
              "attempted": {
                "type": "boolean"
              },
              "writeOk": {
                "type": "boolean"
              },
              "persistedToDatabase": {
                "type": "boolean"
              },
              "persistenceMode": {
                "type": "string"
              },
              "adapterLabel": {
                "type": "string"
              }
            }
          }
        }
      },
      "GladiadorCoverageRequest": {
        "type": "object",
        "description": "Anonymized control-coverage record: keys are EXCLUSIVELY frozen Gladiador technique ids; values are coverage flags. Unknown keys are rejected (`GLADIADOR_UNKNOWN_TECHNIQUE_ID`). An empty object is valid.",
        "additionalProperties": {
          "type": "object",
          "required": [
            "controlPresent",
            "controlTested"
          ],
          "properties": {
            "controlPresent": {
              "type": "boolean"
            },
            "controlTested": {
              "type": "boolean"
            },
            "daysSinceLastValidation": {
              "type": "number",
              "minimum": 0
            }
          }
        }
      },
      "GladiadorAssessment": {
        "type": "object",
        "required": [
          "accepted",
          "score",
          "band",
          "components",
          "gaps",
          "techniquesEvaluated",
          "techniquesFullyReady",
          "summary",
          "isFoundation",
          "offensiveOutputGenerated",
          "attackExecuted",
          "payloadGenerated",
          "activeScanPerformed",
          "persistedToDatabase",
          "blockId"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "headline": {
                "type": "string"
              },
              "badgeColorHint": {
                "type": "string"
              }
            }
          },
          "components": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "gaps": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "techniquesEvaluated": {
            "type": "integer"
          },
          "techniquesFullyReady": {
            "type": "integer"
          },
          "summary": {
            "type": "string"
          },
          "isFoundation": {
            "type": "boolean"
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "attackExecuted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "payloadGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "activeScanPerformed": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "persistedToDatabase": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "GuardianSesionSignals": {
        "type": "object",
        "description": "Pre-bucketed, anonymized session signals. Any raw identity/telemetry field at any depth is rejected 400 (`GUARDIAN_SESION_FORBIDDEN_PII_FIELD`); unknown top-level fields are rejected too.",
        "required": [
          "sessionRefHash",
          "geoVelocityBucket",
          "deviceFingerprintChange",
          "concurrentSessionBucket",
          "privilegeEscalationDetected",
          "idleThenBurstDetected",
          "idleGapMinutes",
          "burstRequestRatePerMin",
          "sourceMode"
        ],
        "properties": {
          "sessionRefHash": {
            "type": "string",
            "description": "OPAQUE pre-hashed session reference — never a raw session id."
          },
          "geoVelocityBucket": {
            "type": "string",
            "enum": [
              "NONE",
              "PLAUSIBLE",
              "FAST",
              "IMPROBABLE",
              "IMPOSSIBLE"
            ]
          },
          "deviceFingerprintChange": {
            "type": "string",
            "enum": [
              "NONE",
              "MINOR",
              "MAJOR",
              "HARD_SWAP"
            ]
          },
          "concurrentSessionBucket": {
            "type": "string",
            "enum": [
              "SINGLE",
              "LOW",
              "ELEVATED",
              "HIGH"
            ]
          },
          "privilegeEscalationDetected": {
            "type": "boolean"
          },
          "privilegeEscalationSeverity01": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "idleThenBurstDetected": {
            "type": "boolean"
          },
          "idleGapMinutes": {
            "type": "number",
            "minimum": 0
          },
          "burstRequestRatePerMin": {
            "type": "number",
            "minimum": 0
          },
          "sourceMode": {
            "type": "string",
            "enum": [
              "FOUNDATION_FIXTURE",
              "LIVE_SESSION_SIGNALS",
              "MOCK_FALLBACK_NO_LIVE"
            ]
          }
        }
      },
      "GuardianSesionAssessment": {
        "type": "object",
        "required": [
          "accepted",
          "sessionRefHash",
          "sourceMode",
          "hijackRiskScore",
          "band",
          "components",
          "contributingSignals",
          "recommendedActions",
          "summary",
          "isFoundation",
          "recommendOnly",
          "enforcementExecuted",
          "offensiveOutputGenerated",
          "piiAccepted",
          "persistedToDatabase",
          "blockId"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "sessionRefHash": {
            "type": "string",
            "description": "Echo of the opaque hash the caller supplied — never PII."
          },
          "sourceMode": {
            "type": "string"
          },
          "hijackRiskScore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "recommendedDisposition": {
                "type": "string"
              },
              "analystHeadline": {
                "type": "string"
              }
            }
          },
          "components": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "contributingSignals": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "recommendedActions": {
            "type": "array",
            "description": "RECOMMENDED defensive step-up actions only — never executed by the endpoint.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "disruptive": {
                  "type": "boolean"
                },
                "description": {
                  "type": "string"
                }
              }
            }
          },
          "summary": {
            "type": "string"
          },
          "isFoundation": {
            "type": "boolean"
          },
          "recommendOnly": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "enforcementExecuted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "piiAccepted": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "persistedToDatabase": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "ArgosForensicSignals": {
        "type": "object",
        "description": "Already-computed anonymized detector signals. The shape cannot carry a raw payload, IP, geolocation, secret or PII; unknown fields are dropped.",
        "required": [
          "surface",
          "dwellTime",
          "malwareScore",
          "vaultCanaryTrips",
          "deterrenceSignals",
          "colmenaCorroboration",
          "phaseTechniqueCounts"
        ],
        "properties": {
          "surface": {
            "type": "string",
            "enum": [
              "platform",
              "server",
              "pc",
              "cloud",
              "saas",
              "unknown"
            ]
          },
          "dwellTime": {
            "type": "string",
            "enum": [
              "none",
              "minutes",
              "hours",
              "days",
              "weeks_plus"
            ]
          },
          "malwareScore": {
            "type": "number",
            "minimum": 0
          },
          "vaultCanaryTrips": {
            "type": "number",
            "minimum": 0
          },
          "deterrenceSignals": {
            "type": "object",
            "required": [
              "deterrenceScore",
              "decoyEngagementCount",
              "distinctSourceCount"
            ],
            "properties": {
              "deterrenceScore": {
                "type": "number",
                "minimum": 0
              },
              "decoyEngagementCount": {
                "type": "number",
                "minimum": 0
              },
              "distinctSourceCount": {
                "type": "number",
                "minimum": 0
              }
            }
          },
          "colmenaCorroboration": {
            "type": "object",
            "required": [
              "corroborationScore",
              "distinctSites",
              "distinctLicenses",
              "corroborated"
            ],
            "properties": {
              "corroborationScore": {
                "type": "number",
                "minimum": 0
              },
              "distinctSites": {
                "type": "number",
                "minimum": 0
              },
              "distinctLicenses": {
                "type": "number",
                "minimum": 0
              },
              "corroborated": {
                "type": "boolean"
              }
            }
          },
          "phaseTechniqueCounts": {
            "type": "object",
            "required": [
              "recon",
              "intrusion",
              "persistence",
              "lateral",
              "exfil",
              "cleanup"
            ],
            "properties": {
              "recon": {
                "type": "number",
                "minimum": 0
              },
              "intrusion": {
                "type": "number",
                "minimum": 0
              },
              "persistence": {
                "type": "number",
                "minimum": 0
              },
              "lateral": {
                "type": "number",
                "minimum": 0
              },
              "exfil": {
                "type": "number",
                "minimum": 0
              },
              "cleanup": {
                "type": "number",
                "minimum": 0
              }
            }
          },
          "exfiltrationObserved": {
            "type": "boolean"
          },
          "antiForensicsObserved": {
            "type": "boolean"
          },
          "lateralMovementObserved": {
            "type": "boolean"
          },
          "automationObserved": {
            "type": "boolean"
          }
        }
      },
      "ArgosAttribution": {
        "type": "object",
        "required": [
          "accepted",
          "surface",
          "attributionConfidence",
          "band",
          "timeline",
          "phasesPresentCount",
          "leadingActorCluster",
          "actorClusterHypotheses",
          "contributions",
          "topContributors",
          "anonymizedFingerprint",
          "invariants",
          "namedActorAttributed",
          "offensiveOutputGenerated",
          "persistedToDatabase",
          "outboundNetworkPerformed",
          "isFoundation",
          "blockId"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "surface": {
            "type": "string"
          },
          "attributionConfidence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "recommendedDisposition": {
                "type": "string"
              },
              "analystHeadline": {
                "type": "string"
              }
            }
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "phasesPresentCount": {
            "type": "integer"
          },
          "leadingActorCluster": {
            "description": "BEHAVIORAL cohort — never a named actor / nation / person.",
            "nullable": true
          },
          "actorClusterHypotheses": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "contributions": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "topContributors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "anonymizedFingerprint": {
            "type": "string",
            "description": "Non-reversible fingerprint."
          },
          "invariants": {
            "type": "object",
            "additionalProperties": true
          },
          "namedActorAttributed": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "offensiveOutputGenerated": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "persistedToDatabase": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "outboundNetworkPerformed": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "isFoundation": {
            "type": "boolean"
          },
          "blockId": {
            "type": "string"
          }
        }
      },
      "CertifyIssueRequest": {
        "type": "object",
        "required": [
          "credentialKind"
        ],
        "properties": {
          "credentialKind": {
            "type": "string",
            "enum": [
              "site-security-baseline",
              "server-hardening",
              "checkout-integrity",
              "compliance-readiness",
              "fleet-membership"
            ]
          },
          "subjectLabel": {
            "type": "string",
            "maxLength": 256,
            "description": "Optional opaque tag fanning ONE key out into multiple stable subjects (e.g. a site slug — NOT PII). Hashed server-side; never stored or echoed in the clear."
          },
          "validityDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730,
            "default": 90
          },
          "score": {
            "type": "number",
            "nullable": true,
            "description": "Optional attested posture score."
          }
        }
      },
      "CertifyCredential": {
        "type": "object",
        "description": "The minted, tamper-evident credential (identity-free: subject is a server-derived hash).",
        "properties": {
          "schema_version": {
            "type": "string"
          },
          "credential_id": {
            "type": "string"
          },
          "subject_ref_hash": {
            "type": "string"
          },
          "credential_kind": {
            "type": "string"
          },
          "issued_epoch": {
            "type": "integer"
          },
          "expires_epoch": {
            "type": "integer"
          },
          "score": {
            "type": "number",
            "nullable": true
          },
          "band": {
            "type": "string",
            "nullable": true
          },
          "content_hash": {
            "type": "string"
          },
          "signing_status": {
            "type": "string",
            "description": "`signed` or `unsigned-no-key`."
          },
          "public_key_id": {
            "type": "string",
            "nullable": true
          },
          "signature": {
            "description": "Detached Ed25519 signature envelope (public key included), or null when unsigned.",
            "nullable": true
          },
          "revoked": {
            "type": "boolean"
          }
        }
      },
      "CertifyIssueResponse": {
        "type": "object",
        "required": [
          "issued",
          "credential",
          "verify_url",
          "persistenceMode",
          "persistedToDatabase",
          "adapterLabel"
        ],
        "properties": {
          "issued": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "credential": {
            "$ref": "#/components/schemas/CertifyCredential"
          },
          "verify_url": {
            "type": "string",
            "example": "/api/v1/certify/verify/cred_..."
          },
          "persistenceMode": {
            "type": "string"
          },
          "persistedToDatabase": {
            "type": "boolean"
          },
          "adapterLabel": {
            "type": "string"
          }
        }
      },
      "CertifyVerifyResponse": {
        "type": "object",
        "required": [
          "overallValid",
          "reasons",
          "credential",
          "checks",
          "signature"
        ],
        "properties": {
          "overallValid": {
            "type": "boolean",
            "description": "true ONLY when consistent AND signed AND signature-valid AND neither revoked nor expired."
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INCONSISTENT",
                "UNSIGNED",
                "SIGNATURE_INVALID",
                "REVOKED",
                "EXPIRED"
              ]
            }
          },
          "credential": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CertifyCredential"
              },
              {
                "type": "object",
                "properties": {
                  "expired": {
                    "type": "boolean"
                  }
                }
              }
            ]
          },
          "checks": {
            "type": "object",
            "properties": {
              "consistent": {
                "type": "boolean"
              },
              "consistency_failures": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "signature_valid": {
                "type": "boolean"
              },
              "signature_failures": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "revoked": {
                "type": "boolean"
              },
              "expired": {
                "type": "boolean"
              },
              "now_epoch": {
                "type": "integer"
              }
            }
          },
          "signature": {
            "description": "Full envelope for fully-offline third-party re-verification, or null when unsigned.",
            "nullable": true
          }
        }
      },
      "CertifyPublicError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "example": "credential_not_found"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "CertifyRevokeRequest": {
        "type": "object",
        "required": [
          "credentialId"
        ],
        "properties": {
          "credentialId": {
            "type": "string",
            "maxLength": 128
          },
          "subjectLabel": {
            "type": "string",
            "maxLength": 256,
            "description": "The label the credential was issued under (omit for the no-label subject)."
          }
        }
      },
      "CertifyRevokeResponse": {
        "type": "object",
        "required": [
          "credential_id",
          "revoked",
          "found",
          "persistenceMode"
        ],
        "properties": {
          "credential_id": {
            "type": "string"
          },
          "revoked": {
            "type": "boolean"
          },
          "found": {
            "type": "boolean"
          },
          "persistenceMode": {
            "type": "string"
          }
        }
      },
      "TrustStateResponse": {
        "type": "object",
        "description": "Public trust state for a verified site plus a signed attestation. The exact `badge_label` / score sub-shape is produced by `buildTrustPublicResponse`; the `attestation` block is always present.",
        "additionalProperties": true,
        "properties": {
          "attestation": {
            "type": "object",
            "required": [
              "schema_version",
              "subject_id_hash",
              "score",
              "band",
              "issued_epoch",
              "content_hash",
              "signing_status",
              "signature"
            ],
            "properties": {
              "schema_version": {
                "type": "string"
              },
              "subject_id_hash": {
                "type": "string"
              },
              "score": {
                "type": "integer"
              },
              "band": {
                "type": "string"
              },
              "claims": {
                "type": "object",
                "additionalProperties": true
              },
              "issued_epoch": {
                "type": "integer"
              },
              "content_hash": {
                "type": "string"
              },
              "signing_status": {
                "type": "string",
                "example": "unsigned-no-key"
              },
              "signature": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "TrustEvidenceResponse": {
        "type": "object",
        "required": [
          "site",
          "evidence",
          "retrieved_at",
          "disclaimer"
        ],
        "properties": {
          "site": {
            "type": "object",
            "properties": {
              "slug": {
                "type": "string"
              },
              "domain": {
                "type": "string"
              }
            }
          },
          "evidence": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true
          },
          "retrieved_at": {
            "type": "string",
            "format": "date-time"
          },
          "disclaimer": {
            "type": "string"
          }
        }
      },
      "TrustError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "example": "site_not_found"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}
