{
  "openapi": "3.1.0",
  "info": {
    "title": "Mantis API",
    "description": "REST API for Mantis deployment automation system.\n\nThe OAuth2 authorization-server surface (`/oauth/token`, `/oauth/revoke`, `/oauth/introspect`, `/oauth/consent`, `/oauth/authorize`, `/oauth/jwks`) and the discovery document at `/.well-known/oauth-authorization-server` are intentionally omitted from this spec because they follow RFC 6749 / RFC 8414. Consumers MUST discover those endpoints via `/.well-known/oauth-authorization-server` rather than the OpenAPI document.",
    "contact": {
      "name": "Mantis",
      "url": "https://github.com/MantisPlatform/mantis"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost:3000",
      "description": "Development server"
    },
    {
      "url": "https://api.mantis.example.com",
      "description": "Production server"
    }
  ],
  "paths": {
    "/api/v1/actions": {
      "get": {
        "tags": [
          "actions"
        ],
        "summary": "List all actions (paginated)",
        "description": "Returns a paginated list of all actions.",
        "operationId": "list_actions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of actions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_ActionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "actions"
        ],
        "summary": "Create a new action",
        "description": "Creates a new action with an initial version.",
        "operationId": "create_action",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateActionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Action created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Action with this slug already exists in scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/actions/{id}": {
      "get": {
        "tags": [
          "actions"
        ],
        "summary": "Get action by ID",
        "description": "Returns detailed information about a specific action including all versions.",
        "operationId": "get_action",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Action details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "actions"
        ],
        "summary": "Update action",
        "description": "Updates action metadata (currently only name).",
        "operationId": "update_action",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateActionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Action updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "actions"
        ],
        "summary": "Delete action",
        "description": "Deletes an action and all its versions.",
        "operationId": "delete_action",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Action deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/actions/{id}/versions": {
      "get": {
        "tags": [
          "actions"
        ],
        "summary": "List all versions for an action",
        "description": "Returns all versions of a specific action.",
        "operationId": "list_action_versions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of action versions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ActionVersionResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "actions"
        ],
        "summary": "Create a new version for an action",
        "description": "Adds a new version to an existing action.",
        "operationId": "create_action_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateActionVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Version created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action not found"
          },
          "409": {
            "description": "Version already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/actions/{id}/versions/{version}": {
      "get": {
        "tags": [
          "actions"
        ],
        "summary": "Get specific version of an action",
        "description": "Returns details about a specific version of an action.",
        "operationId": "get_action_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (semantic version)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Action version details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionVersionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "actions"
        ],
        "summary": "Update a specific version of an action",
        "description": "Updates version metadata. Cannot change version number to one that already exists.",
        "operationId": "update_action_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (semantic version)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateActionVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Version updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action or version not found"
          },
          "409": {
            "description": "New version number already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "actions"
        ],
        "summary": "Delete a specific version of an action",
        "description": "Deletes a version from an action. Cannot delete the last remaining version.",
        "operationId": "delete_action_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Action ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (semantic version)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Version deleted"
          },
          "400": {
            "description": "Cannot delete last version"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Action or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/requests": {
      "get": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "List analysis requests with filtering and pagination",
        "operationId": "list_analysis_requests",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status (pending, processing, completed, failed)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Narrow results to a single tenant (admin-only; ignored for tenant-scoped callers)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results to return (default: 50)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Offset for pagination (default: 0)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of analysis requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRequestsListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/requests/{id}/retry": {
      "post": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Retry a failed or exhausted analysis request",
        "description": "Allows admins to retry:\n- Failed requests (status = \"failed\")\n- Pending requests that have exhausted their retries (retry_count >= max_retries)",
        "operationId": "retry_analysis_request",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Analysis request ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Retry scheduled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisRetryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request cannot be retried"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Request not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/settings": {
      "get": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Get current analysis settings (effective = defaults merged with overrides)",
        "operationId": "get_analysis_settings",
        "responses": {
          "200": {
            "description": "Current settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisSettingsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Update analysis settings (stores overrides only)",
        "operationId": "update_analysis_settings",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAnalysisSettingsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisSettingsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid settings"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/settings/defaults": {
      "get": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Get default analysis settings values (from code)",
        "operationId": "get_defaults",
        "responses": {
          "200": {
            "description": "Default settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisDefaultsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/settings/restore": {
      "post": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Restore analysis settings to defaults (clears all overrides)",
        "operationId": "restore_analysis_settings",
        "responses": {
          "200": {
            "description": "Restored settings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisSettingsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/status": {
      "get": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Get AI Analysis status",
        "operationId": "get_analysis_status",
        "responses": {
          "200": {
            "description": "Analysis status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/analysis/test": {
      "post": {
        "tags": [
          "admin-analysis"
        ],
        "summary": "Test analysis with sample log input",
        "operationId": "test_analysis",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestAnalysisRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Analysis result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestAnalysisResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "503": {
            "description": "Analysis service unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/encryption/stats": {
      "get": {
        "tags": [
          "admin-encryption"
        ],
        "summary": "Get encryption statistics for all tables.",
        "operationId": "encryption_stats",
        "responses": {
          "200": {
            "description": "Encryption statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EncryptionStatsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/encryption/verify": {
      "post": {
        "tags": [
          "admin-encryption"
        ],
        "summary": "Verify that an encryption key can decrypt all encrypted records.",
        "description": "This endpoint is rate-limited to 1 attempt per hour to prevent key brute-forcing.",
        "operationId": "verify_encryption",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEncryptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Verification result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyEncryptionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid key format"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers": {
      "get": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "List all identity providers",
        "operationId": "list_identity_providers",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of identity providers",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_IdentityProviderListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Create a new identity provider",
        "operationId": "create_identity_provider",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIdentityProviderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Identity provider created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityProviderDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "409": {
            "description": "Identity provider already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers/discover": {
      "post": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Discover OIDC endpoints from a discovery URL",
        "operationId": "discover_endpoints",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DiscoverEndpointsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Discovery result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverEndpointsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers/{id}": {
      "get": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Get identity provider by ID",
        "operationId": "get_identity_provider",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Identity provider details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityProviderDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Update an identity provider",
        "operationId": "update_identity_provider",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIdentityProviderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Identity provider updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityProviderDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Delete an identity provider",
        "operationId": "delete_identity_provider",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Identity provider deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          },
          "409": {
            "description": "Cannot delete provider with linked users"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers/{id}/role-mappings": {
      "get": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "List role mappings for an identity provider",
        "operationId": "list_role_mappings",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role mappings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RoleMappingResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Create a role mapping for an identity provider",
        "operationId": "create_role_mapping",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRoleMappingRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Role mapping created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleMappingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers/{id}/role-mappings/{mapping_id}": {
      "put": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Update a role mapping",
        "operationId": "update_role_mapping",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mapping_id",
            "in": "path",
            "description": "Role mapping ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRoleMappingRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Role mapping updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleMappingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Mapping not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Delete a role mapping",
        "operationId": "delete_role_mapping",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mapping_id",
            "in": "path",
            "description": "Role mapping ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Role mapping deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Mapping not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/identity-providers/{id}/test": {
      "post": {
        "tags": [
          "admin-identity-providers"
        ],
        "summary": "Test connection to an identity provider",
        "operationId": "test_connection",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Identity provider ID (SqId or numeric)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestConnectionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Connection test result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestConnectionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Identity provider not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/oauth-clients": {
      "get": {
        "tags": [
          "admin"
        ],
        "operationId": "list_clients",
        "responses": {
          "200": {
            "description": "List of OAuth2 clients",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OAuth2ClientResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin"
        ],
        "operationId": "create_client",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOAuth2ClientRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "OAuth2 client created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuth2ClientCreatedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/oauth-clients/{id}": {
      "get": {
        "tags": [
          "admin"
        ],
        "operationId": "get_client",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "OAuth2 client ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OAuth2 client details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuth2ClientResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Client not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "admin"
        ],
        "summary": "Soft delete: deactivate the client. Existing tokens remain valid until they\nexpire or are revoked; new authorize/token exchanges are rejected by the\n`is_active` check in `/oauth/token`.",
        "operationId": "deactivate_client",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "OAuth2 client ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "OAuth2 client deactivated"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Client not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "patch": {
        "tags": [
          "admin"
        ],
        "operationId": "update_client",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "OAuth2 client ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOAuth2ClientRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OAuth2 client updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuth2ClientResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Client not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/oauth-clients/{id}/rotate-secret": {
      "post": {
        "tags": [
          "admin"
        ],
        "operationId": "rotate_oauth_client_secret",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "OAuth2 client ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuth2SecretRotatedResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Client not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/permissions": {
      "get": {
        "tags": [
          "admin-permissions"
        ],
        "summary": "List all permissions grouped by resource",
        "description": "Returns all 57 system permissions grouped by their resource type.\nPermissions are read-only and cannot be created, modified, or deleted.",
        "operationId": "list_permissions",
        "responses": {
          "200": {
            "description": "List of permissions grouped by resource",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PermissionGroupResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/roles": {
      "get": {
        "tags": [
          "admin-roles"
        ],
        "summary": "List all roles",
        "operationId": "list_roles",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of roles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_RoleListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Create a new role",
        "operationId": "create_role",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRoleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Role created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "409": {
            "description": "Role already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/roles/{id}": {
      "get": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Get role by ID",
        "operationId": "get_role",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Update a role",
        "operationId": "update_role",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRoleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Role updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized / Cannot modify system role"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Delete a role",
        "operationId": "delete_role",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Role deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized / Cannot delete system role"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/roles/{id}/permissions": {
      "get": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Get role permissions",
        "operationId": "get_role_permissions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role permissions grouped by resource",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PermissionGroupResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Assign permissions to role",
        "operationId": "assign_permissions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignPermissionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Permissions assigned"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized / Cannot modify system role"
          },
          "404": {
            "description": "Role or permission not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/roles/{id}/permissions/remove": {
      "post": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Remove permissions from role",
        "operationId": "remove_permissions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemovePermissionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Permissions removed"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized / Cannot modify system role"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/roles/{id}/users": {
      "get": {
        "tags": [
          "admin-roles"
        ],
        "summary": "Get users with this role",
        "operationId": "get_role_users",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Role ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Users with this role",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RoleUserResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/users": {
      "get": {
        "tags": [
          "admin-users"
        ],
        "summary": "List all users (paginated)",
        "operationId": "list_users",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive substring match over username and email",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Exact-match account status (active, inactive, locked, pending)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Admin-only: narrow results to a single tenant (plus global users)",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of users",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_AdminUserListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid status filter"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-users"
        ],
        "summary": "Create a new user",
        "operationId": "create_user",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "User created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "409": {
            "description": "User already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/users/{id}": {
      "get": {
        "tags": [
          "admin-users"
        ],
        "summary": "Get user by ID",
        "operationId": "get_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "admin-users"
        ],
        "summary": "Update a user",
        "operationId": "update_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "User updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "admin-users"
        ],
        "summary": "Delete a user",
        "operationId": "delete_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "User deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/users/{id}/password": {
      "post": {
        "tags": [
          "admin-users"
        ],
        "summary": "Reset user password (admin only)",
        "operationId": "reset_password",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Password reset"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/users/{id}/roles": {
      "get": {
        "tags": [
          "admin-users"
        ],
        "summary": "Get user roles",
        "operationId": "get_user_roles",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User roles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RoleResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "admin-users"
        ],
        "summary": "Assign roles to user",
        "operationId": "assign_roles",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignRolesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Roles assigned"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User or role not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/admin/users/{id}/roles/remove": {
      "post": {
        "tags": [
          "admin-users"
        ],
        "summary": "Remove roles from user",
        "operationId": "remove_roles",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoveRolesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Roles removed"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "User not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/disable": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Disable WireGuard for an agent: release its overlay IP and clear its overlay identity.",
        "description": "The teardown counterpart of [`enable_wireguard`]. Releases the allocated overlay IP back\nto the tenant pool and clears the agent's WireGuard columns (public key, overlay IP, and\nany in-flight key-rotation state) so it falls back to the direct mTLS path. Idempotent:\ndisabling an agent that has no overlay is a no-op success.",
        "operationId": "disable_wireguard",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "WireGuard disabled (overlay IP released, identity cleared)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing wireguard:manage permission"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/enable": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Enable WireGuard for an agent: register its public key and allocate an overlay IP.",
        "description": "Called by an agent (or admin on its behalf) to join the overlay. Idempotent: an\nagent that already holds an overlay IP keeps it (its public key is refreshed).",
        "operationId": "enable_wireguard",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnableWireGuardRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "WireGuard enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnableWireGuardResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: malformed key, agent not approved, or not tenant-scoped"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing wireguard:manage permission"
          },
          "404": {
            "description": "Agent not found"
          },
          "409": {
            "description": "Overlay address pool exhausted or quota exceeded"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/endpoint": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Update agent's WireGuard endpoint after STUN discovery.",
        "description": "Called by Tarsus after discovering its public endpoint via STUN.",
        "operationId": "update_agent_endpoint",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEndpointRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Endpoint updated"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/key-rotation": {
      "get": {
        "tags": [
          "wireguard"
        ],
        "summary": "Get the current key rotation status for an agent.",
        "operationId": "get_key_rotation_status",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Key rotation status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyRotationStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Start a WireGuard key rotation.",
        "description": "Called by Tarsus when it has generated a new keypair and wants to register\nthe new public key. During the overlap window (30 seconds by default),\nboth old and new keys will be accepted.",
        "operationId": "start_key_rotation",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartKeyRotationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Key rotation started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartKeyRotationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or rotation already in progress"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/key-rotation/confirm": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Confirm a WireGuard key rotation was successful.",
        "description": "Called by Tarsus after the new key has been verified working.\nThis promotes the pending key to active and clears the rotation state.",
        "operationId": "confirm_key_rotation",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmKeyRotationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Key rotation confirmed"
          },
          "400": {
            "description": "No rotation in progress or rotation ID mismatch"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/key-rotation/rollback": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Rollback a WireGuard key rotation.",
        "description": "Called by Tarsus if the new key fails to establish a connection.\nThis removes the pending key and keeps the current active key.",
        "operationId": "rollback_key_rotation",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollbackKeyRotationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Key rotation rolled back"
          },
          "400": {
            "description": "No rotation in progress or rotation ID mismatch"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/peers": {
      "get": {
        "tags": [
          "wireguard"
        ],
        "summary": "Get peer endpoints for WireGuard connection attempts.",
        "description": "Returns Thorax endpoints and relay information for establishing tunnels.",
        "operationId": "get_peer_endpoints",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Peer endpoints",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeerEndpointsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/status": {
      "get": {
        "tags": [
          "wireguard"
        ],
        "summary": "Get WireGuard status for an agent.",
        "operationId": "get_agent_status",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "WireGuard status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WireGuardStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/agents/{agent_id}/wireguard/turn-credentials": {
      "post": {
        "tags": [
          "wireguard"
        ],
        "summary": "Request short-term TURN credentials.",
        "description": "Returns time-limited TURN credentials compatible with coturn REST API.",
        "operationId": "request_turn_credentials",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "description": "Agent ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TurnCredentialsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "TURN credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TurnCredentialsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Agent not found"
          },
          "503": {
            "description": "TURN not configured"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/2fa/backup-codes/regenerate": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Regenerate backup codes.",
        "description": "Generates new backup codes and invalidates all existing ones.",
        "operationId": "regenerate_backup_codes",
        "responses": {
          "200": {
            "description": "New backup codes generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwoFactorBackupCodesResponse"
                }
              }
            }
          },
          "400": {
            "description": "2FA not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/2fa/disable": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Disable 2FA for the authenticated user.",
        "description": "Requires both the current password and a valid TOTP code.",
        "operationId": "disable_2fa",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwoFactorDisableRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "2FA disabled"
          },
          "400": {
            "description": "Invalid password or code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/2fa/setup": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Initialize 2FA setup for the authenticated user.",
        "description": "Generates a TOTP secret, encrypts it, and returns a QR code for setup.\nThe user must verify the setup with `POST /auth/2fa/verify-setup` to complete.",
        "operationId": "setup_2fa",
        "responses": {
          "200": {
            "description": "2FA setup initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwoFactorSetupResponse"
                }
              }
            }
          },
          "400": {
            "description": "2FA already enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/2fa/status": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Get 2FA status for the authenticated user.",
        "operationId": "get_2fa_status",
        "responses": {
          "200": {
            "description": "2FA status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwoFactorStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/2fa/verify": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Verify 2FA code during login.",
        "description": "Called after password authentication when 2FA is enabled.\nAccepts either a TOTP code or a backup code.",
        "operationId": "verify_2fa",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwoFactorVerifyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired pending token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/2fa/verify-setup": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Verify 2FA setup and enable two-factor authentication.",
        "description": "Validates the TOTP code from the authenticator app, enables 2FA,\nand returns backup codes (shown only once).",
        "operationId": "verify_setup",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TwoFactorVerifySetupRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "2FA enabled with backup codes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwoFactorVerifySetupResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid code or no pending setup",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/api-keys": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "List all API keys for the current user.",
        "description": "GET /auth/api-keys",
        "operationId": "list_api_keys",
        "responses": {
          "200": {
            "description": "List of API keys",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Create a new API key.",
        "description": "POST /auth/api-keys\n\nThe full API key is only returned once in the response.\nStore it securely as it cannot be retrieved again.",
        "operationId": "create_api_key",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "API key created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "409": {
            "description": "Key with this name already exists"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/api-keys/{id}": {
      "delete": {
        "tags": [
          "Authentication"
        ],
        "summary": "Revoke an API key.",
        "description": "DELETE /auth/api-keys/:id",
        "operationId": "revoke_api_key",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "API key ID to revoke",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API key revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid key ID"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Not authorized to revoke this key"
          },
          "404": {
            "description": "API key not found"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "User login endpoint",
        "description": "Authenticates a user with email and password, returns JWT tokens.\nIf two-factor authentication is enabled for the user, returns a pending\ntoken that must be used with the /auth/2fa/verify endpoint.",
        "operationId": "login",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Two-factor authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TwoFactorRequiredResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Logout endpoint",
        "description": "Revokes all tokens for the authenticated user.",
        "operationId": "logout",
        "responses": {
          "200": {
            "description": "Successfully logged out",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoutResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Get current user information",
        "description": "Returns information about the currently authenticated user.",
        "operationId": "me",
        "responses": {
          "200": {
            "description": "User information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/oidc/callback": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Handle OIDC callback from IdP",
        "description": "Validates the callback, exchanges the code for tokens, validates the ID token,\nand creates/updates the user.",
        "operationId": "handle_callback",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "description": "Authorization code",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "State parameter",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "description": "Error code",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error_description",
            "in": "query",
            "description": "Error description",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/oidc/providers": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "List enabled identity providers for SSO login",
        "description": "Returns a list of enabled identity providers that can be used for SSO.\nUsed to render SSO buttons on the login page.",
        "operationId": "list_enabled_providers",
        "responses": {
          "200": {
            "description": "List of enabled providers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EnabledProviderResponse"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/oidc/{provider_id}/login": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Initiate OIDC login flow",
        "description": "Creates OIDC auth state and returns the authorization URL to redirect the user to.",
        "operationId": "initiate_login",
        "parameters": [
          {
            "name": "provider_id",
            "in": "path",
            "description": "Identity provider ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OidcLoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Authorization URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OidcLoginResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Provider not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/password": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Change password for authenticated user",
        "description": "Allows a user to change their own password.",
        "operationId": "change_password",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Password changed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid current password",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/profile": {
      "put": {
        "tags": [
          "auth"
        ],
        "summary": "Update profile for authenticated user",
        "description": "Allows a user to update their own profile information (display name).",
        "operationId": "update_profile",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProfileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Profile updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/refresh": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Refresh access token",
        "description": "Exchanges a valid refresh token for a new access token.\nThe refresh token is read from the HTTP-only cookie.",
        "operationId": "refresh",
        "responses": {
          "200": {
            "description": "Token refreshed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired refresh token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/session": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Read-only session validation",
        "description": "Validates the HTTP-only refresh-token cookie and returns the current user's\nidentity, roles, and permissions. **Does not rotate the refresh token** —\nthis endpoint is intended for SvelteKit SSR `+layout.server.ts` guards that\nneed to answer \"is this session valid and who is it?\" on every navigation\nwithout mutating the browser-held cookie.\n\n`/auth/refresh` rotates the refresh token (revokes the old, issues a new),\nwhich causes a cascade failure when called from SSR: the SSR fetch receives\nthe new cookie but cannot forward it to the browser, so the next SSR call\nsends a now-revoked token and gets 401. This endpoint avoids that problem\nby being read-only.",
        "operationId": "session",
        "responses": {
          "200": {
            "description": "Session valid; returns current user info",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired refresh token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Account disabled or suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/sessions": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "List all active sessions for the authenticated user.",
        "operationId": "list_sessions",
        "responses": {
          "200": {
            "description": "List of active sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "auth"
        ],
        "summary": "Revoke all sessions except the current one.",
        "operationId": "revoke_all_sessions",
        "responses": {
          "200": {
            "description": "Sessions revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionRevokeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/sessions/{id}": {
      "delete": {
        "tags": [
          "auth"
        ],
        "summary": "Revoke a specific session by ID.",
        "operationId": "revoke_session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Session ID to revoke",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Session revoked"
          },
          "400": {
            "description": "Cannot revoke current session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/sse-token": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Create SSE token for secure EventSource connections",
        "description": "Exchanges a valid JWT for a session-level SSE token. The token is short-lived,\nbut the session can be refreshed with the accompanying refresh token.",
        "operationId": "create_sse_token",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SSETokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "SSE token created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SSETokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/auth/sse-token/refresh": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Refresh an existing SSE session token using the refresh token",
        "operationId": "refresh_sse_token",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SSETokenRefreshRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "SSE token refreshed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SSETokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/cache/clear": {
      "post": {
        "tags": [
          "cache"
        ],
        "summary": "Clear all cache entries",
        "description": "Clears all entries from the file cache. Requires cache:manage permission.",
        "operationId": "clear_cache",
        "responses": {
          "200": {
            "description": "Cache cleared",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheClearResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "503": {
            "description": "Cache not available"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/cache/disable": {
      "post": {
        "tags": [
          "cache"
        ],
        "summary": "Disable file caching",
        "description": "Disables the file cache at runtime. Requires cache:manage permission.\nWhen disabled, all storage fetches will go directly to S3/Git.",
        "operationId": "disable_cache",
        "responses": {
          "200": {
            "description": "Cache disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheToggleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "503": {
            "description": "Cache not available"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/cache/enable": {
      "post": {
        "tags": [
          "cache"
        ],
        "summary": "Enable file caching",
        "description": "Enables the file cache at runtime. Requires cache:manage permission.",
        "operationId": "enable_cache",
        "responses": {
          "200": {
            "description": "Cache enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheToggleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "503": {
            "description": "Cache not available"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/cache/stats": {
      "get": {
        "tags": [
          "cache"
        ],
        "summary": "Get cache statistics",
        "description": "Returns current cache statistics including hit rate, entry count, and enabled status.",
        "operationId": "get_cache_stats",
        "responses": {
          "200": {
            "description": "Cache statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheStatsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "503": {
            "description": "Cache not available"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/cache/storage/{id}": {
      "delete": {
        "tags": [
          "cache"
        ],
        "summary": "Clear cache entries for a specific storage",
        "description": "Clears all cache entries associated with a specific S3 or Git storage.\nRequires cache:manage permission.",
        "operationId": "clear_storage_cache",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Storage cache cleared",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheClearResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid storage ID"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "503": {
            "description": "Cache not available"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/certificates/clients/{id}": {
      "get": {
        "tags": [
          "certificates"
        ],
        "summary": "Get client certificate details",
        "description": "Returns detailed information about a specific client's certificate\nincluding validity period and expiration status.",
        "operationId": "get_client_certificate",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Client certificate information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientCertificateInfo"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/certificates/expiring": {
      "get": {
        "tags": [
          "certificates"
        ],
        "summary": "List certificates expiring within threshold",
        "description": "Returns a list of client certificates that will expire within the specified\nnumber of days. Useful for proactive certificate management.",
        "operationId": "list_expiring_certificates",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "description": "Days until expiration threshold (default: 30)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Narrow results to a single tenant (admin-only; ignored for tenant-scoped callers)",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of expiring certificates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpiringCertificatesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/certificates/server": {
      "get": {
        "tags": [
          "certificates"
        ],
        "summary": "Get server certificate information",
        "description": "Returns details about the certificate that terminates Mandible's own TLS,\nread from the configured certificate file (identity cert path, falling back\nto the HTTPS TLS cert). When TLS is terminated by an upstream reverse proxy,\nMandible has no certificate of its own and reports `configured: false`.",
        "operationId": "get_server_certificate",
        "responses": {
          "200": {
            "description": "Server certificate information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerCertificateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/export": {
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Export deployment configuration to version-controlled Nickel/JSON documents.",
        "description": "Composition RBAC: an entity type is included only if the caller holds its\n`<resource>:read` permission. Tenant-scoped. Secrets are never emitted.",
        "operationId": "export_config",
        "responses": {
          "200": {
            "description": "Multi-file config export",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigExportResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "No read access to any exportable resource"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/import": {
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Import deployment configuration from Nickel/JSON documents.",
        "description": "Composition RBAC (no aggregate `config:write`): each entity type present requires its\n`<type>:create` + `<type>:update`. Tenant-confined. Atomic. `dry_run` previews.",
        "operationId": "import_config",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Import result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing create/update permission for an imported type"
          },
          "422": {
            "description": "Validation or conflict failure"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories": {
      "get": {
        "tags": [
          "config"
        ],
        "operationId": "list_repositories",
        "responses": {
          "200": {
            "description": "Repositories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RepositoryResponse"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "config"
        ],
        "operationId": "create_repository",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRepositoryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Repository created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RepositoryResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing config:manage"
          },
          "409": {
            "description": "Repository slug already exists in this tenant"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}": {
      "get": {
        "tags": [
          "config"
        ],
        "operationId": "get_repository",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Repository",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RepositoryResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "config"
        ],
        "operationId": "update_repository",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRepositoryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RepositoryResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "config"
        ],
        "operationId": "delete_repository",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Authoritative repo still owns managed entities"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}/authoritative": {
      "put": {
        "tags": [
          "config"
        ],
        "summary": "Flip a repository to/from Git-authoritative (GitOps reconcile) mode. **Admin-gated**\n(`config:set_authoritative`). Enabling first returns a dry-run divergence preview; the caller\nmust re-submit with `acknowledge_divergence = true` to apply (the first reconcile overwrites\nthe DB projection from Git). Disabling clears provenance so entities become editable again.",
        "operationId": "set_authoritative",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetAuthoritativeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Flip applied or preview returned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetAuthoritativeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failure, or a known git-sync error (bad host/URL, authentication failure, missing branch/ref)"
          },
          "403": {
            "description": "Missing config:set_authoritative"
          },
          "404": {
            "description": "Not found"
          },
          "408": {
            "description": "Git sync operation timed out"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}/conflicts": {
      "get": {
        "tags": [
          "config"
        ],
        "operationId": "list_conflicts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending conflicts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConflictResponse"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}/preview": {
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Branch-scoped read-only preview of the config documents at a Git ref (Phase C). Returns the\nraw `.ncl` documents (secrets are already `<ENCRYPTED>` placeholders in Git) for\ninspection/diff — never writes the DB. Tenant-scoped + eval-capped via the sync engine.",
        "operationId": "preview_repository",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ref",
            "in": "query",
            "description": "Git ref reachable from the configured branch (only that branch is fetched); default: configured branch; an unreachable ref errors",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Config documents at the ref",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "A known git-sync error (bad host/URL, authentication failure, unreachable ref)"
          },
          "404": {
            "description": "Not found"
          },
          "408": {
            "description": "Git sync operation timed out"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}/sync": {
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Trigger a sync of a config repository (pull/push/bidirectional per its configured\ndirection). 3-way conflict detection runs for bidirectional repos; under the `fail`\nstrategy any conflict aborts the run (status `conflict`).",
        "operationId": "sync_repository",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncRepositoryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Sync result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncRepositoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failure, or a known git-sync error (bad host/URL, authentication failure, missing branch/ref)"
          },
          "403": {
            "description": "Missing config:manage"
          },
          "404": {
            "description": "Not found"
          },
          "408": {
            "description": "Git sync operation timed out"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/repositories/{id}/webhook": {
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Trigger a reconcile from a Git-provider webhook. **Not JWT-authenticated** — authenticated by\nthe per-repo HMAC signature over the raw request body (`X-Hub-Signature-256: sha256=<hex>`,\nGitHub/Gitea compatible; `X-Gitea-Signature: <hex>` also accepted). A missing/invalid\nsignature, or a repo with no configured secret, returns `401` without distinguishing the two.\nA burst of webhooks within the debounce window returns `202 { status: \"debounced\" }`.",
        "operationId": "webhook_reconcile",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Raw Git-provider webhook payload (HMAC-signed)",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Reconcile triggered or debounced",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookReconcileResponse"
                }
              }
            }
          },
          "400": {
            "description": "A known git-sync error (bad host/URL, authentication failure, missing branch/ref)"
          },
          "401": {
            "description": "Missing/invalid signature or no webhook secret configured"
          },
          "404": {
            "description": "Repository not found"
          },
          "408": {
            "description": "Git sync operation timed out"
          }
        }
      }
    },
    "/api/v1/config/repositories/{id}/webhook-secret": {
      "put": {
        "tags": [
          "config"
        ],
        "summary": "Configure (or rotate/clear) the per-repository inbound-webhook HMAC secret. **`config:manage`**,\ntenant-confined. The secret is encrypted at rest under a repo-bound AAD and never echoed —\nthe response only reflects `has_webhook_secret`.",
        "operationId": "set_webhook_secret",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Repository id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetWebhookSecretRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Secret set/rotated/cleared",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RepositoryResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing config:manage"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/config/validate": {
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Validate (dry-run) an import without persisting. Same RBAC as import.",
        "operationId": "validate_config",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Validation result (no writes)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing create/update permission for an imported type"
          },
          "422": {
            "description": "Validation failure"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployment-freezes": {
      "get": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "List all deployment freezes (paginated)",
        "operationId": "list_freezes",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-based)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "is_enabled",
            "in": "query",
            "description": "Filter by enabled status",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of deployment freezes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreezeListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "Create a new deployment freeze",
        "operationId": "create_freeze",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFreezeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Freeze created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreezeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "409": {
            "description": "A freeze with this slug already exists in this scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployment-freezes/active": {
      "get": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "List active deployment freezes",
        "operationId": "list_active_freezes",
        "responses": {
          "200": {
            "description": "List of active freezes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FreezeResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployment-freezes/check": {
      "get": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "Check if deployment would be frozen",
        "operationId": "check_freeze",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Environment ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Freeze check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreezeCheckResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployment-freezes/{id}": {
      "get": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "Get deployment freeze by ID",
        "operationId": "get_freeze",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Freeze ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Freeze details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreezeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Freeze not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "Update deployment freeze",
        "operationId": "update_freeze",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Freeze ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFreezeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Freeze updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreezeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Freeze not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "deployment-freezes"
        ],
        "summary": "Delete deployment freeze",
        "operationId": "delete_freeze",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Freeze ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Freeze deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Freeze not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "List all deployments (paginated)",
        "description": "Returns a paginated list of deployments, filtered server-side so that\n`status`, `search` and `period` select across the entire result set rather\nthan within the page that was already loaded. The response carries\n`status_counts`, the per-bucket totals for the same filters minus `status`\nitself, so the filter chips can show real totals.",
        "operationId": "list_deployments",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Admin-only: narrow to one tenant. Ignored for tenant-scoped callers.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive solution/sequence/action-name + status filter",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Status bucket: all (no restriction), running (pending/queued/running/rolling_back), failed, succeeded (success), other (cancelled/rolled_back)",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DeploymentsBucketFilter"
            }
          },
          {
            "name": "period",
            "in": "query",
            "description": "Time window over created_at: day, week, month, quarter, year, relative, or custom. Absent means no time bound.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "description": "Rolling window length in days; only with period=relative",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "RFC 3339 lower bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "description": "RFC 3339 upper bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of deployments with faceted status counts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Contradictory or malformed time window"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "deployments"
        ],
        "summary": "Create a new deployment",
        "description": "Creates and starts a new deployment of a solution to targets.\nUses gRPC to communicate with the orchestration service.\n\nIf no eligible Thorax instance is available for the tenant, the deployment\nrequest is queued and will be dispatched automatically when an instance\nbecomes available. In this case, the response will have `pending: true`.",
        "operationId": "create_deployment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeploymentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Deployment created and started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDeploymentResponse"
                }
              }
            }
          },
          "202": {
            "description": "Deployment queued (awaiting Thorax instance)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDeploymentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution or targets not found"
          },
          "503": {
            "description": "Orchestration service unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/pending": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "List pending dispatch requests",
        "description": "Returns deployment requests that are waiting for an eligible Thorax instance.",
        "operationId": "list_pending_dispatch_requests",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status (pending, processing, dispatched, cancelled, failed)",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of pending dispatch requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PendingDispatchRequestResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/pending/{id}": {
      "delete": {
        "tags": [
          "deployments"
        ],
        "summary": "Cancel a pending dispatch request",
        "description": "Removes a deployment request from the pending queue. Only requests with\nstatus 'pending' or 'processing' can be cancelled.",
        "operationId": "cancel_pending_dispatch_request",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Pending request ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Request cancelled successfully"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Pending request not found"
          },
          "409": {
            "description": "Request cannot be cancelled (already dispatched or failed)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/preview": {
      "post": {
        "tags": [
          "deployments"
        ],
        "summary": "Preview deployment plan",
        "description": "Shows what execution plan would be created without actually creating the deployment.\nUseful for validating deployment configuration and understanding the execution plan\nbefore committing to it.",
        "operationId": "preview_deployment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeploymentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Deployment preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentPreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution, sequence, action or targets not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "Get deployment status",
        "description": "Returns detailed information about a specific deployment.",
        "operationId": "get_deployment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Deployment ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deployment details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Deployment not found"
          },
          "503": {
            "description": "Orchestration service unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}/analysis": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "Get command results with AI analysis for a deployment",
        "description": "Returns all command results for this deployment with their AI-generated\nanalysis (if available). Only failed commands have analysis.",
        "operationId": "get_deployment_analysis",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Deployment UUID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Command results with analysis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CommandResultWithAnalysis"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Deployment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}/cancel": {
      "post": {
        "tags": [
          "deployments"
        ],
        "summary": "Cancel a deployment",
        "description": "Cancels a running deployment.",
        "operationId": "cancel_deployment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Deployment ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/CancelDeploymentRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deployment cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Deployment cannot be cancelled"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Deployment not found"
          },
          "503": {
            "description": "Orchestration service unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}/logs": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "Get deployment logs (SSE stream)",
        "description": "Streams deployment logs in real-time using Server-Sent Events.\nFor completed deployments, returns a status message since real-time\nlogs are only available for active deployments.",
        "operationId": "get_deployment_logs",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Deployment ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Log stream (text/event-stream)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Deployment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}/logs/history": {
      "get": {
        "tags": [
          "deployments"
        ],
        "summary": "Get deployment log history",
        "description": "Returns historical logs for a deployment from the database.\nUse this to retrieve logs after page refresh or for completed deployments.",
        "operationId": "get_deployment_logs_history",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Deployment ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of logs to skip (default: 0)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum logs to return (default: 100, max: 1000)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historical logs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HistoricalDeploymentLogEntry"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Deployment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/deployments/{id}/redeploy": {
      "post": {
        "tags": [
          "deployments"
        ],
        "operationId": "redeploy_deployment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Source deployment ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/RedeployRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "New deployment created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeploymentDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Source deployment not found"
          },
          "503": {
            "description": "Orchestration service unavailable"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environment-states/at-time": {
      "get": {
        "tags": [
          "environment-states"
        ],
        "summary": "Get environment state at time",
        "description": "Returns the state that was active at a specific point in time.",
        "operationId": "get_state_at_time",
        "parameters": [
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timestamp",
            "in": "query",
            "description": "Point in time (ISO 8601)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "State at time",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentStateAtTimeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environment-states/current": {
      "get": {
        "tags": [
          "environment-states"
        ],
        "summary": "Get current environment state",
        "description": "Returns the current deployed state for a solution in an environment.",
        "operationId": "get_current_state",
        "parameters": [
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID (SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Environment state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentStateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "No state found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environment-states/history": {
      "get": {
        "tags": [
          "environment-states"
        ],
        "summary": "Get environment state history",
        "description": "Returns the history of state changes for a solution in an environment.",
        "operationId": "get_history",
        "parameters": [
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "State history",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedEnvironmentStateHistory"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environment-states/orphaned": {
      "get": {
        "tags": [
          "environment-states"
        ],
        "summary": "List surviving state-history rows whose config definition has been deleted\n(orphaned). Reads the denormalized identity columns rather than joining the\n(now-absent) definitions. Tenant-scoped: a tenant caller sees only its own\norphans; `tenant_id IS NULL` is never used as a tenant filter.",
        "operationId": "list_orphaned_history",
        "responses": {
          "200": {
            "description": "Orphaned state-history rows",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrphanedStateHistoryResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environments": {
      "get": {
        "tags": [
          "environments"
        ],
        "summary": "List all environments (paginated, ordered by sort_order)",
        "description": "Returns a paginated list of environments ordered by sort_order (ascending),\nwith an optional case-insensitive `search` filter over the environment name.",
        "operationId": "list_environments",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive name filter",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of environments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_EnvironmentResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "environments"
        ],
        "summary": "Create a new environment",
        "description": "Creates a new environment with the specified name, description, and sort order.",
        "operationId": "create_environment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEnvironmentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Environment created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Environment with this name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environments/{environment_id}/targets": {
      "get": {
        "tags": [
          "environments"
        ],
        "summary": "List targets for an environment",
        "description": "Returns all targets associated with an environment, ordered by priority.",
        "operationId": "list_environment_targets",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID (SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of environment targets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EnvironmentTargetResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          },
          "404": {
            "description": "Environment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "environments"
        ],
        "summary": "Add a target to an environment",
        "description": "Creates an association between an environment and a target.\nRequires admin role.",
        "operationId": "add_environment_target",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddEnvironmentTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Target added to environment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentTargetResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or duplicate"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Environment or target not found"
          },
          "409": {
            "description": "Association already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environments/{environment_id}/targets/count": {
      "get": {
        "tags": [
          "environments"
        ],
        "summary": "Count targets for an environment",
        "description": "Returns the count of targets associated with an environment.\nUseful for promotion/rollback preview to show target count.",
        "operationId": "count_environment_targets",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Target count",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetCountResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Permission denied"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environments/{environment_id}/targets/{target_id}": {
      "delete": {
        "tags": [
          "environments"
        ],
        "summary": "Remove a target from an environment",
        "description": "Deletes the association between an environment and a target.\nRequires admin role.",
        "operationId": "remove_environment_target",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "target_id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Target removed from environment"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Association not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/environments/{id}": {
      "get": {
        "tags": [
          "environments"
        ],
        "summary": "Get environment by ID",
        "description": "Returns details for a specific environment.",
        "operationId": "get_environment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Environment details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Environment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "environments"
        ],
        "summary": "Update environment",
        "description": "Updates an existing environment's details.",
        "operationId": "update_environment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEnvironmentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Environment updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Environment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "environments"
        ],
        "summary": "Delete environment",
        "description": "Deletes an environment. This will also cascade delete any tenant-solution-environment\nrelationships and tenant variables scoped to this environment.",
        "operationId": "delete_environment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Environment deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Environment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/health": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Full health check including database connectivity",
        "operationId": "health_check",
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service is unhealthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health/grpc": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "gRPC service health check",
        "description": "Stays a public endpoint (never 401): a missing OR invalid/expired token is\ntreated as anonymous. The overall `status` (healthy/degraded/unhealthy) is\ndisclosed to everyone so unauthenticated monitors and load balancers can\nobserve an orchestration outage. Authenticated callers additionally get the\nbreaker internals (precise `circuit_state` + failure/success counts);\nanonymous callers have those fields withheld (empty state, zeroed counts) as\nthey are operational reconnaissance. The response schema is kept stable so\nauthenticated consumers (Lens) are unaffected.",
        "operationId": "grpc_health",
        "responses": {
          "200": {
            "description": "gRPC health status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrpcHealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health/live": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Kubernetes liveness probe",
        "description": "Returns 200 if the service is running (not deadlocked).\nThis doesn't check external dependencies.",
        "operationId": "liveness",
        "responses": {
          "200": {
            "description": "Service is alive"
          }
        }
      }
    },
    "/api/v1/health/ready": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Kubernetes readiness probe",
        "description": "Returns 200 if the service can accept traffic. Gates on database\nconnectivity only.\n\nRedis is deliberately NOT gated here, but the dependency is real and broad:\nAPI-key REST is Redis-independent, yet JWT-authenticated REST fail-closes on\nthe Redis JWT-revocation check and SSE needs Redis outright, so a Redis\noutage genuinely degrades the primary REST surface (this is tracked\nseparately as an availability risk). Readiness still does not gate on Redis\nbecause it is a single shared instance: an outage hits every pod identically,\nso marking them all NotReady yields no healthy pod to route to — it converts\ndegradation into a hard total outage. And because this endpoint is\nunauthenticated and rate-limit-exempt, a per-request Redis round-trip would\nitself let probe floods exhaust the shared pool that the fail-closed\nrevocation depends on. Redis health is surfaced via metrics, not this gate.",
        "operationId": "readiness",
        "responses": {
          "200": {
            "description": "Service is ready"
          },
          "503": {
            "description": "Service is not ready"
          }
        }
      }
    },
    "/api/v1/notifications/channels": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List all notification channels (paginated).",
        "operationId": "list_channels",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of notification channels",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Create a new notification channel.",
        "operationId": "create_channel",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChannelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Channel created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "409": {
            "description": "Channel with this slug already exists in this scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/channels/{id}": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "Get a notification channel by ID.",
        "operationId": "get_channel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Channel ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channel details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "notifications"
        ],
        "summary": "Update a notification channel.",
        "operationId": "update_channel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Channel ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChannelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Channel updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "notifications"
        ],
        "summary": "Delete a notification channel.",
        "operationId": "delete_channel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Channel ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Channel deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/channels/{id}/rotate-secret": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Rotate a webhook secret.",
        "description": "Generates a new secret while keeping the old one valid for a grace period.",
        "operationId": "rotate_channel_secret",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Channel ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                }
              }
            }
          },
          "400": {
            "description": "Channel does not support secret rotation"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/channels/{id}/test": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Test a notification channel.",
        "description": "Sends a test notification to verify the channel is configured correctly.",
        "operationId": "test_channel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Channel ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Test result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestChannelResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/deliveries": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List notification deliveries with optional filtering.",
        "description": "Returns a paginated list of notification deliveries. Supports filtering\nby event, channel, subscription, status, and date range.",
        "operationId": "list_deliveries",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "event_id",
            "in": "query",
            "description": "Filter by event ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channel_id",
            "in": "query",
            "description": "Filter by channel ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subscription_id",
            "in": "query",
            "description": "Filter by subscription ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from_date",
            "in": "query",
            "description": "Filter deliveries from this date",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "description": "Filter deliveries to this date",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of notification deliveries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/deliveries/{id}": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "Get a specific notification delivery by ID.",
        "description": "Returns the full details of a single notification delivery including\nits current status, attempt count, and any error information.",
        "operationId": "get_delivery",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Delivery ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Delivery not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/deliveries/{id}/retry": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Retry a failed or dead-lettered notification delivery.",
        "description": "Resets the delivery status to pending and clears retry-related fields\nso the delivery worker will pick it up for immediate retry. Only deliveries\nwith status 'failed' or 'dead_letter' can be retried.",
        "operationId": "retry_delivery",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Delivery ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery queued for retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetryDeliveryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Delivery cannot be retried (invalid status)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Delivery not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/events": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List notification events with optional filtering.",
        "description": "Returns a paginated list of notification events that have been recorded\nin the system. Supports filtering by event type, group, severity, and\nvarious scope filters (tenant, environment, solution).",
        "operationId": "list_events",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "event_type",
            "in": "query",
            "description": "Filter by event type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "event_group",
            "in": "query",
            "description": "Filter by event group",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "severity",
            "in": "query",
            "description": "Filter by severity",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Filter by environment ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "solution_id",
            "in": "query",
            "description": "Filter by solution ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "from_date",
            "in": "query",
            "description": "Filter events from this date",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "description": "Filter events to this date",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of notification events",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/events/{id}": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "Get a specific notification event by ID.",
        "description": "Returns the full details of a single notification event.",
        "operationId": "get_event",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Event ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Event not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/my/subscriptions": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List current user's subscriptions.",
        "operationId": "list_my_subscriptions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of user's subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_SubscriptionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/subscriptions": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List all subscriptions (admin) or filtered by user.",
        "operationId": "list_subscriptions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "enabled",
            "in": "query",
            "description": "Filter by enabled status",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "channel_id",
            "in": "query",
            "description": "Filter by channel ID",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "description": "Filter by user ID (admin only)",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Search by name",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_SubscriptionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Create a new notification subscription.",
        "operationId": "create_subscription",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Subscription created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Channel not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/subscriptions/{id}": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "Get a subscription by ID.",
        "operationId": "get_subscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Subscription ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Subscription not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "notifications"
        ],
        "summary": "Update a subscription.",
        "operationId": "update_subscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Subscription ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSubscriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Subscription updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Subscription not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "notifications"
        ],
        "summary": "Delete a subscription.",
        "operationId": "delete_subscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Subscription ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Subscription deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Subscription not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/subscriptions/{id}/filters": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Add a filter to a subscription.",
        "operationId": "add_filter",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Subscription ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddFilterRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Filter added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilterResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Subscription not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/notifications/subscriptions/{id}/filters/{filter_id}": {
      "delete": {
        "tags": [
          "notifications"
        ],
        "summary": "Remove a filter from a subscription.",
        "operationId": "remove_filter",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Subscription ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "filter_id",
            "in": "path",
            "description": "Filter ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Filter removed"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Subscription or filter not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/patterns": {
      "get": {
        "tags": [
          "patterns"
        ],
        "summary": "`GET /api/v1/patterns` — list/filter/sort clusters (paginated).",
        "operationId": "list_patterns",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed).",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100).",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          },
          {
            "name": "window_days",
            "in": "query",
            "description": "Trailing window in days; filters on `last_seen_at`. Defaults to the\nconfigured detection window when omitted.",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by lifecycle status (`active`, `muted`, `resolved`). Omitted =\nactive + resolved (muted hidden by default).",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "solution_id",
            "in": "query",
            "description": "Filter to patterns that have occurred in this solution.",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "format": "uuid"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Filter to patterns that have occurred in this environment.",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "format": "uuid"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive substring match over title and sample error.",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Admin-only: narrow to one tenant. Ignored for tenant-scoped callers (pinned to their own).",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated patterns",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_PatternResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing patterns:read"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/patterns/recompute": {
      "post": {
        "tags": [
          "patterns"
        ],
        "summary": "`POST /api/v1/patterns/recompute` — trigger an on-demand batch (tenant-scoped).",
        "operationId": "recompute",
        "responses": {
          "202": {
            "description": "Recompute accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecomputeAccepted"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing patterns:manage"
          },
          "429": {
            "description": "Recompute queue full; retry later"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/patterns/stats": {
      "get": {
        "tags": [
          "patterns"
        ],
        "summary": "`GET /api/v1/patterns/stats` — dashboard aggregates.",
        "operationId": "get_stats",
        "parameters": [
          {
            "name": "window_days",
            "in": "query",
            "description": "Trailing window in days for the aggregates. Defaults to the configured\ndetection window when omitted.",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dashboard stats",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PatternStats"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing patterns:read"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/patterns/{id}": {
      "get": {
        "tags": [
          "patterns"
        ],
        "summary": "`GET /api/v1/patterns/{id}` — composite detail (pattern + paginated occurrences).",
        "operationId": "get_pattern",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Pattern id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Occurrence page number (1-indexed).",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Occurrences per page (max 100).",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pattern detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PatternDetail"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing patterns:read"
          },
          "404": {
            "description": "Pattern not found / out of tenant scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "patch": {
        "tags": [
          "patterns"
        ],
        "summary": "`PATCH /api/v1/patterns/{id}` — set lifecycle status (mute/resolve/reactivate).",
        "operationId": "update_pattern",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Pattern id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePatternRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated pattern",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PatternResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid status"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing patterns:manage"
          },
          "404": {
            "description": "Pattern not found / out of tenant scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions": {
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Create a promotion",
        "description": "Creates a new promotion, either immediately or as a pending approval request.",
        "operationId": "create_promotion",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePromotionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Promotion created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromotionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or promotion not allowed"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Source state not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/lifecycles": {
      "get": {
        "tags": [
          "promotions"
        ],
        "summary": "List promotion lifecycles",
        "operationId": "list_lifecycles",
        "responses": {
          "200": {
            "description": "List of lifecycles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LifecycleResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Create a promotion lifecycle",
        "operationId": "create_lifecycle",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLifecycleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Lifecycle created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LifecycleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/lifecycles/{id}/rules": {
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Add a rule to a lifecycle",
        "operationId": "add_lifecycle_rule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Lifecycle ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddLifecycleRuleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Rule created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LifecycleRuleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Lifecycle not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/pending": {
      "get": {
        "tags": [
          "promotions"
        ],
        "summary": "List pending promotion requests",
        "operationId": "list_pending_promotions",
        "parameters": [
          {
            "name": "solution_id",
            "in": "query",
            "description": "Filter by solution",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending promotions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PromotionRequestDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/preview": {
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Preview a promotion",
        "description": "Validates whether a promotion is allowed and returns any blocking reasons.",
        "operationId": "preview_promotion",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PromotionPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Promotion preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromotionPreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Source state not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/{id}": {
      "get": {
        "tags": [
          "promotions"
        ],
        "summary": "Get a promotion request by ID",
        "operationId": "get_promotion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Promotion request ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Promotion request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromotionRequestDto"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Request not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/{id}/approve": {
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Approve a pending promotion",
        "operationId": "approve_promotion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Promotion request ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApprovePromotionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Promotion approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromotionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Request not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/promotions/{id}/reject": {
      "post": {
        "tags": [
          "promotions"
        ],
        "summary": "Reject a pending promotion",
        "operationId": "reject_promotion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Promotion request ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RejectPromotionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Promotion rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromotionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Request not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registration-tokens": {
      "get": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "List all registration tokens (paginated)",
        "description": "Returns a paginated list of all registration tokens.\nCan be filtered by status (active, revoked) and tenant.",
        "operationId": "list_tokens",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status: active, revoked",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of registration tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_RegistrationTokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "Create a new registration token",
        "description": "Creates a new token for automated client registration.\nThe plaintext token is only returned once - store it securely!",
        "operationId": "create_token",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRegistrationTokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Token created - plaintext only shown once!",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationTokenCreatedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registration-tokens/{id}": {
      "get": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "Get registration token details",
        "description": "Returns detailed information about a specific registration token.",
        "operationId": "get_token",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Token ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Token details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationTokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Token not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "Delete a registration token",
        "description": "Permanently deletes a registration token.",
        "operationId": "delete_token",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Token ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Token deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Token not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "patch": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "Update a registration token",
        "description": "Updates token properties (name, max_uses, expires_at, auto_approve).\nCannot update a revoked token.",
        "operationId": "update_token",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Token ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRegistrationTokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Token updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationTokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or token is revoked"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Token not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registration-tokens/{id}/revoke": {
      "post": {
        "tags": [
          "registration-tokens"
        ],
        "summary": "Revoke a registration token",
        "description": "Revokes an active registration token, preventing further use.",
        "operationId": "revoke_token",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Token ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeRegistrationTokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Token revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationTokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Token is already revoked"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Token not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations": {
      "get": {
        "tags": [
          "registrations"
        ],
        "summary": "List all registrations (paginated)",
        "description": "Returns a paginated list of all client registrations.\nCan be filtered by status (pending, approved, revoked).",
        "operationId": "list_registrations",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status: pending, approved, revoked",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "thumbprint_prefix",
            "in": "query",
            "description": "Filter by certificate thumbprint prefix",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of registrations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_RegistrationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations/pre-register": {
      "post": {
        "tags": [
          "registrations"
        ],
        "summary": "Pre-register a client with its certificate thumbprint",
        "description": "This enables the Octopus Deploy-style bootstrap workflow where thumbprints\nare exchanged out-of-band before the first connection. Pre-registered clients\nare immediately approved and can connect as soon as they present a certificate\nmatching the registered thumbprint.",
        "operationId": "pre_register_client",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreRegisterRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Client pre-registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (validation error or duplicate thumbprint)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations/{id}": {
      "get": {
        "tags": [
          "registrations"
        ],
        "summary": "Get registration details",
        "description": "Returns detailed information about a specific registration, including the certificate PEM.",
        "operationId": "get_registration",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Registration details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "registrations"
        ],
        "summary": "Delete a registration",
        "description": "Permanently deletes a registration record.",
        "operationId": "delete_registration",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Registration deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations/{id}/approve": {
      "post": {
        "tags": [
          "registrations"
        ],
        "summary": "Approve a registration",
        "description": "Approves a pending client registration, allowing the client to authenticate.",
        "operationId": "approve_registration",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveRegistrationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Registration approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Registration cannot be approved (not pending)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations/{id}/reject": {
      "post": {
        "tags": [
          "registrations"
        ],
        "summary": "Reject a pending registration",
        "description": "Rejects a pending client registration, preventing it from being approved.\nThis is semantically different from revocation - rejection is for unwanted\nregistration attempts, while revocation is for previously-approved clients.",
        "operationId": "reject_registration",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RejectRegistrationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Registration rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Registration cannot be rejected (not pending)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/registrations/{id}/revoke": {
      "post": {
        "tags": [
          "registrations"
        ],
        "summary": "Revoke a registration",
        "description": "Revokes an approved client registration, preventing the client from authenticating.",
        "operationId": "revoke_registration",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Registration ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeRegistrationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Registration revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Registration cannot be revoked (already revoked)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Registration not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/rollbacks": {
      "post": {
        "tags": [
          "rollbacks"
        ],
        "summary": "Create a rollback deployment",
        "description": "Creates a new deployment that rolls back to a previous state.",
        "operationId": "create_rollback",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRollbackRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Rollback deployment created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollbackResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "No deployment found at target"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/rollbacks/environments/{environment_id}/history": {
      "get": {
        "tags": [
          "rollbacks"
        ],
        "summary": "Get environment state history",
        "description": "Returns the history of state changes for a solution in an environment.",
        "operationId": "get_environment_history",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "State history",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EnvironmentStateHistoryResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/rollbacks/environments/{environment_id}/state": {
      "get": {
        "tags": [
          "rollbacks"
        ],
        "summary": "Get current environment state",
        "description": "Returns the current deployed state for a solution in an environment.",
        "operationId": "get_environment_state",
        "parameters": [
          {
            "name": "environment_id",
            "in": "path",
            "description": "Environment ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "solution_id",
            "in": "query",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "at_time",
            "in": "query",
            "description": "Point in time (ISO 8601)",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Environment state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentStateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "No state found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/rollbacks/preview": {
      "post": {
        "tags": [
          "rollbacks"
        ],
        "summary": "Preview a rollback operation",
        "description": "Returns information about what will be deployed without actually creating a deployment.",
        "operationId": "preview_rollback",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollbackPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Rollback preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollbackPreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "No deployment found at target"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/schedules": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "List all deployment schedules (paginated)",
        "operationId": "list_schedules",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-based)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "is_enabled",
            "in": "query",
            "description": "Filter by enabled status",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of deployment schedules",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Create a new deployment schedule",
        "operationId": "create_schedule",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateScheduleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Schedule created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "409": {
            "description": "Schedule with this slug already exists in scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/schedules/{id}": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "Get deployment schedule by ID",
        "operationId": "get_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schedule details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "schedules"
        ],
        "summary": "Update deployment schedule",
        "operationId": "update_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateScheduleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Schedule updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "schedules"
        ],
        "summary": "Delete deployment schedule",
        "operationId": "delete_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Schedule deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/schedules/{id}/disable": {
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Disable deployment schedule",
        "operationId": "disable_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schedule disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/schedules/{id}/enable": {
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Enable deployment schedule",
        "operationId": "enable_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schedule enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/schedules/{id}/execute-now": {
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Trigger immediate execution of schedule",
        "operationId": "execute_schedule_now",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schedule execution triggered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Schedule not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sequences": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "List all sequences (paginated)",
        "description": "Returns a paginated list of all sequences.",
        "operationId": "list_sequences",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of sequences",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_SequenceResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Create a new sequence",
        "description": "Creates a new sequence with an initial version.",
        "operationId": "create_sequence",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSequenceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Sequence created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Sequence with this slug already exists in scope"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sequences/{id}": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Get sequence by ID",
        "description": "Returns detailed information about a sequence including all versions.",
        "operationId": "get_sequence",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sequence detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Update sequence",
        "description": "Updates sequence metadata (currently only name).",
        "operationId": "update_sequence",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSequenceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Sequence updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "sequences"
        ],
        "summary": "Delete sequence",
        "description": "Deletes a sequence and all its versions.",
        "operationId": "delete_sequence",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Sequence deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sequences/{id}/versions": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "List sequence versions",
        "description": "Returns all versions for a specific sequence.",
        "operationId": "list_sequence_versions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of versions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SequenceVersionResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Create a new sequence version",
        "description": "Adds a new version to an existing sequence.",
        "operationId": "create_sequence_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSequenceVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Version created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence not found"
          },
          "409": {
            "description": "Version already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sequences/{id}/versions/{version}": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Get specific sequence version",
        "description": "Returns a specific version of a sequence by version number.",
        "operationId": "get_sequence_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Version detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceVersionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Update a specific sequence version",
        "description": "Updates version metadata including version number and actions.\nCannot change version number to one that already exists.",
        "operationId": "update_sequence_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSequenceVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Version updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence or version not found"
          },
          "409": {
            "description": "New version number already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "sequences"
        ],
        "summary": "Delete a specific sequence version",
        "description": "Deletes a version from a sequence. Cannot delete the last remaining version.",
        "operationId": "delete_sequence_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Version deleted"
          },
          "400": {
            "description": "Cannot delete last version"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sequences/{id}/versions/{version}/actions": {
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Update sequence version actions",
        "description": "Updates the action order for a specific sequence version.",
        "operationId": "update_sequence_version_actions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Sequence ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSequenceVersionActionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Actions updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Sequence or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/server/info": {
      "get": {
        "tags": [
          "server"
        ],
        "summary": "Get server information for discovery and verification",
        "description": "Returns server identity information including the TLS certificate thumbprint.\nThis endpoint is unauthenticated to allow clients to verify the server\nbefore establishing a connection.\n\nThe thumbprint is pre-computed at startup and cached in AppState to avoid\nblocking file reads on every request.",
        "operationId": "get_server_info",
        "responses": {
          "200": {
            "description": "Server information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerInfoResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/solutions": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "List all solutions (paginated)",
        "description": "Returns a paginated list of all solutions.",
        "operationId": "list_solutions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of solutions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_SolutionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "solutions"
        ],
        "summary": "Create a new solution",
        "description": "Creates a new solution with an initial version.",
        "operationId": "create_solution",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSolutionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Solution created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Solution already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "Get solution by ID",
        "description": "Returns detailed information about a solution including all versions.",
        "operationId": "get_solution",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Solution detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "solutions"
        ],
        "summary": "Update solution",
        "description": "Updates solution metadata (currently only name).",
        "operationId": "update_solution",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSolutionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Solution updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "solutions"
        ],
        "summary": "Delete solution",
        "description": "Deletes a solution and all its versions.",
        "operationId": "delete_solution",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Solution deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}/environment-states": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "Get environment states for a solution",
        "description": "Returns the current deployment state for a solution across all environments.\nUseful for showing a deployment pipeline view.",
        "operationId": "get_solution_environment_states",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Tenant ID for multi-tenant filtering",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Environment states for solution",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SolutionEnvironmentStateResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}/prompted-variables": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "Get prompted variables for a solution",
        "description": "Returns all prompted variables defined for this solution that need values\nat deployment time.",
        "operationId": "get_prompted_variables",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID or SqId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Prompted variables for the solution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptedVariablesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}/versions": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "List solution versions",
        "description": "Returns all versions for a specific solution.",
        "operationId": "list_solution_versions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of versions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SolutionVersionResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "solutions"
        ],
        "summary": "Create a new solution version",
        "description": "Adds a new version to an existing solution.",
        "operationId": "create_solution_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSolutionVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Version created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution not found"
          },
          "409": {
            "description": "Version already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}/versions/{version}": {
      "get": {
        "tags": [
          "solutions"
        ],
        "summary": "Get specific solution version",
        "description": "Returns a specific version of a solution by version number.",
        "operationId": "get_solution_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Version detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVersionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "solutions"
        ],
        "summary": "Update a specific solution version",
        "description": "Updates version metadata including version number and sequences.",
        "operationId": "update_solution_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSolutionVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Version updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution or version not found"
          },
          "409": {
            "description": "New version number already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "solutions"
        ],
        "summary": "Delete a specific solution version",
        "description": "Deletes a version from a solution. Cannot delete the last remaining version.",
        "operationId": "delete_solution_version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Version deleted"
          },
          "400": {
            "description": "Cannot delete last version"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{id}/versions/{version}/sequences": {
      "put": {
        "tags": [
          "solutions"
        ],
        "summary": "Update solution version sequences",
        "description": "Updates the sequence order for a specific solution version.",
        "operationId": "update_solution_version_sequences",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "description": "Version number (e.g., 1.0.0)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSolutionVersionSequencesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Sequences updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVersionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Solution or version not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{solution_id}/variable-sets": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "List variable sets linked to a solution",
        "description": "Returns all variable sets linked to a specific solution.",
        "operationId": "list_solution_variable_sets",
        "parameters": [
          {
            "name": "solution_id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of linked variable sets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SolutionVariableSetLinkResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Solution not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Link a variable set to a solution",
        "description": "Creates a link between a solution and a variable set.\nTenant users can link global sets (read access) or their own tenant's sets.",
        "operationId": "link_variable_set",
        "parameters": [
          {
            "name": "solution_id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkVariableSetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Variable set linked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVariableSetLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Solution or variable set not found"
          },
          "409": {
            "description": "Variable set already linked to solution"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/solutions/{solution_id}/variable-sets/{link_id}": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Get a specific variable set link for a solution",
        "operationId": "get_solution_variable_set_link",
        "parameters": [
          {
            "name": "solution_id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "link_id",
            "in": "path",
            "description": "Link ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Variable set link details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolutionVariableSetLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Link not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Unlink a variable set from a solution",
        "description": "Removes the link between a solution and a variable set.",
        "operationId": "unlink_variable_set",
        "parameters": [
          {
            "name": "solution_id",
            "in": "path",
            "description": "Solution ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "link_id",
            "in": "path",
            "description": "Link ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Variable set unlinked"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Link not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/sse/{resource_type}": {
      "get": {
        "tags": [
          "sse"
        ],
        "summary": "Stream entity events for a resource type (list view).",
        "description": "This endpoint streams all create/update/delete events for a resource type,\nfiltered by the user's tenant. Use this on list pages to receive real-time\nupdates when entities change.\n\n# Security\n\n- Requires valid SSE token\n- Events are filtered by tenant ID\n- Admin resources require admin role",
        "operationId": "stream_resource_events",
        "parameters": [
          {
            "name": "resource_type",
            "in": "path",
            "description": "Resource type to subscribe to",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sse_token",
            "in": "query",
            "description": "SSE authentication token",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "Optional filter by state",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SSE event stream"
          },
          "401": {
            "description": "Invalid or expired SSE token"
          },
          "403": {
            "description": "Not authorized for this resource type"
          },
          "404": {
            "description": "Unknown resource type"
          }
        }
      }
    },
    "/api/v1/sse/{resource_type}/{id}": {
      "get": {
        "tags": [
          "sse"
        ],
        "summary": "Stream entity events for a specific entity (detail view).",
        "description": "This endpoint streams events only for a specific entity ID.\nUse this on detail pages to receive real-time updates for the viewed entity.\n\n# Security\n\n- Requires valid SSE token scoped to the specific resource\n- Events are filtered by resource ID",
        "operationId": "stream_resource_detail_events",
        "parameters": [
          {
            "name": "resource_type",
            "in": "path",
            "description": "Resource type",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "description": "Resource ID to subscribe to",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sse_token",
            "in": "query",
            "description": "SSE authentication token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SSE event stream"
          },
          "401": {
            "description": "Invalid or expired SSE token"
          },
          "403": {
            "description": "Not authorized for this resource"
          },
          "404": {
            "description": "Unknown resource type"
          }
        }
      }
    },
    "/api/v1/statistics/global": {
      "get": {
        "tags": [
          "statistics"
        ],
        "summary": "Get global statistics (admin only)",
        "description": "Returns aggregate deployment statistics and resource counts across all tenants.",
        "operationId": "get_global_statistics",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "description": "Window discriminant: day, week, month, quarter, year, relative, or custom. Defaults to week.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "description": "Rolling window length in days; only with period=relative",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "RFC 3339 lower bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "description": "RFC 3339 upper bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Global statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GlobalStatisticsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Contradictory or malformed time window"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Admin role required"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/git": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "List all Git storage backends (paginated)",
        "operationId": "list_git_storage",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of Git storage backends",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_GitStorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "storage"
        ],
        "summary": "Create a new Git storage backend",
        "operationId": "create_git_storage",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGitStorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Git storage created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitStorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/git/auth": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "List all Git auth configurations (paginated)",
        "operationId": "list_git_auth",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of Git auth configurations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_GitAuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "storage"
        ],
        "summary": "Create a new Git auth configuration",
        "operationId": "create_git_auth",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGitAuthRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Git auth created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitAuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/git/auth/{id}": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "Get Git auth details",
        "operationId": "get_git_auth",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Auth ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Git auth details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitAuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Auth not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "storage"
        ],
        "summary": "Update Git auth",
        "operationId": "update_git_auth",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Auth ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateGitAuthRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Git auth updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitAuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Auth not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "storage"
        ],
        "summary": "Delete Git auth",
        "operationId": "delete_git_auth",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Auth ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Git auth deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Auth not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/git/{id}": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "Get Git storage details",
        "operationId": "get_git_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Git storage details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitStorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "storage"
        ],
        "summary": "Update Git storage",
        "operationId": "update_git_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateGitStorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Git storage updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitStorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "storage"
        ],
        "summary": "Delete Git storage",
        "operationId": "delete_git_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Git storage deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/local": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "List all local storage backends (paginated)",
        "operationId": "list_local_storage",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of local storage backends",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_LocalStorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "storage"
        ],
        "summary": "Create a new local storage backend",
        "operationId": "create_local_storage",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocalStorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Local storage created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocalStorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/local/{id}": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "Get local storage details",
        "operationId": "get_local_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Local storage details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocalStorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "storage"
        ],
        "summary": "Update local storage",
        "operationId": "update_local_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocalStorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Local storage updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocalStorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "storage"
        ],
        "summary": "Delete local storage",
        "operationId": "delete_local_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Local storage deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/s3": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "List all S3 storage backends (paginated)",
        "operationId": "list_s3_storage",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of S3 storage backends",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_S3StorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "storage"
        ],
        "summary": "Create a new S3 storage backend",
        "operationId": "create_s3_storage",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateS3StorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "S3 storage created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/S3StorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/s3/{id}": {
      "get": {
        "tags": [
          "storage"
        ],
        "summary": "Get S3 storage details",
        "operationId": "get_s3_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "S3 storage details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/S3StorageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "storage"
        ],
        "summary": "Update S3 storage",
        "operationId": "update_s3_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateS3StorageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "S3 storage updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/S3StorageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "storage"
        ],
        "summary": "Delete S3 storage",
        "operationId": "delete_s3_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "S3 storage deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/storage/s3/{id}/test": {
      "post": {
        "tags": [
          "storage"
        ],
        "summary": "Test S3 storage connectivity",
        "operationId": "test_s3_storage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Connection test result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/S3ConnectionTestResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Storage not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tags": {
      "get": {
        "tags": [
          "tags"
        ],
        "summary": "List tags (paginated). A tenant sees its adopted tags; an admin sees the whole vocabulary.",
        "operationId": "list_tags",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive key/value filter",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of tags",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_TagResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Create (adopt) a tag. Find-or-create the global `(key, value)` entry, then adopt it for\nthe caller's tenant (idempotent). An admin with no tenant adds a vocabulary entry only.",
        "operationId": "create_tag",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Tag created/adopted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tags/{id}": {
      "get": {
        "tags": [
          "tags"
        ],
        "summary": "Get a tag. A tenant must have adopted it (else 404); an admin may read any.",
        "operationId": "get_tag",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tag ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tag details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tag not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "tags"
        ],
        "summary": "Update a tag (admin-only — the entry is shared across every tenant).",
        "operationId": "update_tag",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tag ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTagRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Tag updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not an administrator"
          },
          "404": {
            "description": "Tag not found"
          },
          "409": {
            "description": "Tag with this key/value already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "tags"
        ],
        "summary": "Destroy a tag's vocabulary entry (admin-only; CASCADE removes all adoptions + uses). A\ntenant must instead `POST /tags/{id}/detach`.",
        "operationId": "delete_tag",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tag ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Tag deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Tenants must detach, not delete"
          },
          "404": {
            "description": "Tag not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tags/{id}/detach": {
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Detach (un-adopt) a tag from the caller's tenant: drop the `tenant_tags` adoption only.\n`targets_tags` is left untouched — it is a global `(target_id, tag_id)` relation and a\ntarget may be shared across tenants, so a tenant removes a tag from its own targets via\n`DELETE /targets/{id}/tags` instead. The shared vocabulary entry survives for other\ntenants. A global admin has no adoption to drop (use DELETE to destroy the entry).",
        "operationId": "detach_tag",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tag ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Tag detached from the tenant"
          },
          "400": {
            "description": "Detach is a tenant operation (a global admin destroys with DELETE)"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tag not adopted by this tenant"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/targets": {
      "get": {
        "tags": [
          "targets"
        ],
        "summary": "List all targets (paginated)",
        "description": "Returns a paginated list of all targets, including their associated tags.",
        "operationId": "list_targets",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of targets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_TargetResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "targets"
        ],
        "summary": "Create a new target",
        "description": "Creates a new target with the specified configuration.",
        "operationId": "create_target",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Target created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Target with this name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/targets/{id}": {
      "get": {
        "tags": [
          "targets"
        ],
        "summary": "Get target details",
        "description": "Returns detailed information about a specific target, including its tags.",
        "operationId": "get_target",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Target details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "targets"
        ],
        "summary": "Update target",
        "description": "Updates target properties.",
        "operationId": "update_target",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Target updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "targets"
        ],
        "summary": "Delete target",
        "description": "Deletes a target and its tag associations.",
        "operationId": "delete_target",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Target deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/targets/{id}/certificates": {
      "get": {
        "tags": [
          "targets"
        ],
        "summary": "Get target certificates",
        "description": "Returns all certificates linked to a target.\nThese certificates enable automatic client-to-target linking during registration.",
        "operationId": "get_target_certificates",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Target certificates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TargetCertificateResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "targets"
        ],
        "summary": "Link certificates to target",
        "description": "Associates one or more certificates with a target.\nWhen a client registers with a certificate that matches one of these,\nthe client session will be automatically linked to this target.",
        "operationId": "link_certificates",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkCertificatesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Certificates linked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TargetCertificateResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target or certificate not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "targets"
        ],
        "summary": "Unlink certificates from target",
        "description": "Removes certificate associations from a target.\nClients with these certificates will no longer auto-link to this target.",
        "operationId": "unlink_certificates",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnlinkCertificatesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Certificates unlinked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TargetCertificateResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/targets/{id}/tags": {
      "get": {
        "tags": [
          "targets"
        ],
        "summary": "Get target tags",
        "description": "Returns all tags associated with a target.",
        "operationId": "get_target_tags",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Target tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "targets"
        ],
        "summary": "Attach tags to target",
        "description": "Associates one or more tags with a target.",
        "operationId": "attach_tags",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachTagsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Tags attached",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target or tag not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "targets"
        ],
        "summary": "Detach tags from target",
        "description": "Removes tag associations from a target.",
        "operationId": "detach_tags",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Target ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DetachTagsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Tags detached",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Target or tag not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "List all tenants (paginated)",
        "description": "Returns a paginated list of all tenants.",
        "operationId": "list_tenants",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive name/description/contact-email filter",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of tenants",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_TenantResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "tenants"
        ],
        "summary": "Create a new tenant",
        "description": "Creates a new tenant with the specified details.",
        "operationId": "create_tenant",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTenantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Tenant created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "409": {
            "description": "Tenant with this name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant by ID",
        "description": "Returns details for a specific tenant including its tags.",
        "operationId": "get_tenant",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "tenants"
        ],
        "summary": "Update tenant",
        "description": "Updates an existing tenant's details.",
        "operationId": "update_tenant",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTenantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Tenant updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "tenants"
        ],
        "summary": "Delete tenant",
        "description": "Deletes a tenant. This will cascade delete all tenant relationships\n(solutions, environments, tags, targets, variables, deployment history).",
        "operationId": "delete_tenant",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Tenant deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/deployments": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant deployments",
        "description": "Returns all deployments for this tenant, paginated and ordered by created_at desc.",
        "operationId": "get_tenant_deployments",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant deployments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_DeploymentResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/environments": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant environments",
        "description": "Returns all environments this tenant has access to.",
        "operationId": "get_tenant_environments",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant environments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/solutions": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant solutions",
        "description": "Returns all solutions enabled for this tenant across all environments.",
        "operationId": "get_tenant_solutions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant solutions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TenantSolutionEnvironmentResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "tenants"
        ],
        "summary": "Attach solution to tenant",
        "description": "Attach a solution to this tenant for a specific environment.",
        "operationId": "attach_solution",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachSolutionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Solution attached"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant, solution, or environment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/solutions/{solution_id}/environments/{env_id}": {
      "delete": {
        "tags": [
          "tenants"
        ],
        "summary": "Detach solution from tenant",
        "description": "Detach a solution from this tenant for a specific environment.",
        "operationId": "detach_solution",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "solution_id",
            "in": "path",
            "description": "Solution ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "env_id",
            "in": "path",
            "description": "Environment ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Solution detached"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/statistics": {
      "get": {
        "tags": [
          "statistics"
        ],
        "summary": "Get tenant statistics",
        "description": "Returns deployment statistics and resource counts for a specific tenant.",
        "operationId": "get_tenant_statistics",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "period",
            "in": "query",
            "description": "Window discriminant: day, week, month, quarter, year, relative, or custom. Defaults to week.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "description": "Rolling window length in days; only with period=relative",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "RFC 3339 lower bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "description": "RFC 3339 upper bound; only with period=custom",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantStatisticsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Contradictory or malformed time window"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized for this tenant"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/tags": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant tags",
        "description": "Returns all tags attached to this tenant.",
        "operationId": "get_tenant_tags",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/targets": {
      "get": {
        "tags": [
          "tenants"
        ],
        "summary": "Get tenant targets",
        "description": "Returns all targets assigned to this tenant, optionally filtered by environment.",
        "operationId": "get_tenant_targets",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Filter by environment ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant targets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "tenants"
        ],
        "summary": "Attach target to tenant",
        "description": "Assign a target to this tenant for a specific environment (or all environments if None).",
        "operationId": "attach_target",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Target attached"
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant or target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{id}/targets/{tid}": {
      "delete": {
        "tags": [
          "tenants"
        ],
        "summary": "Detach target from tenant",
        "description": "Remove a target from this tenant for a specific environment (or all environments if None).",
        "operationId": "detach_target",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tenant ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tid",
            "in": "path",
            "description": "Target ID (numeric or SqId)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Environment ID to detach from (optional, if not provided detaches from all environments)",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Target detached"
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant or target not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/tenants/{tenant_id}/wireguard/summary": {
      "get": {
        "tags": [
          "wireguard"
        ],
        "summary": "Get WireGuard summary for a tenant.",
        "operationId": "get_summary",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "description": "Tenant ID",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "WireGuard summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WireGuardSummaryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "404": {
            "description": "Tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/thorax-instances": {
      "get": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "List all thorax instances (paginated)",
        "description": "Returns a paginated list of thorax instances with optional filters.",
        "operationId": "list_instances",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Filter by tenant ID",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_deregistered",
            "in": "query",
            "description": "Include deregistered instances",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of thorax instances",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_ThoraxInstanceResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/thorax-instances/{id}": {
      "get": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Get thorax instance details",
        "description": "Returns detailed information about a specific thorax instance.",
        "operationId": "get_instance",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Instance details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThoraxInstanceDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Deregister thorax instance",
        "description": "Soft-deletes an instance by marking it as deregistered.",
        "operationId": "deregister_instance",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeregisterThoraxInstanceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Instance deregistered"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "patch": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Update thorax instance",
        "description": "Updates instance properties like global availability or metadata.",
        "operationId": "update_instance",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateThoraxInstanceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Instance updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThoraxInstanceDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/thorax-instances/{id}/config": {
      "patch": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Update a Thorax instance's per-instance runtime configuration overrides.",
        "description": "Sets/clears the heartbeat-cadence and session-timeout overrides that Mandible\npushes to the instance via the heartbeat `config_update` (applied live by the\ninstance). Each field is tri-state: omit to leave unchanged, send `null` to\nclear (revert to default), or send a positive integer to set.",
        "operationId": "update_instance_config",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateThoraxInstanceConfigRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Config updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThoraxInstanceDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/thorax-instances/{id}/tenants": {
      "get": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Get assigned tenants",
        "description": "Returns all tenants assigned to a thorax instance.",
        "operationId": "get_assigned_tenants",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assigned tenants",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssignedTenantResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Assign tenants to instance",
        "description": "Assigns one or more tenants to a thorax instance.",
        "operationId": "assign_tenants",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignTenantsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Tenants assigned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssignedTenantResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance or tenant not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/thorax-instances/{id}/tenants/{tenant_id}": {
      "delete": {
        "tags": [
          "thorax-instances"
        ],
        "summary": "Remove tenant assignment",
        "description": "Removes a tenant assignment from a thorax instance.",
        "operationId": "remove_tenant_assignment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Instance ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tenant_id",
            "in": "path",
            "description": "Tenant ID (UUID)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Tenant assignment removed"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Not authorized"
          },
          "404": {
            "description": "Instance or assignment not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/users/me/preferences": {
      "get": {
        "tags": [
          "user-preferences"
        ],
        "summary": "Get the authenticated user's UI preferences",
        "description": "Returns effective preferences: stored overrides merged over the system\ndefaults. A user who has never saved a preference gets the full default set.",
        "operationId": "get_my_preferences",
        "responses": {
          "200": {
            "description": "Effective preferences for the current user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPreferencesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "user-preferences"
        ],
        "summary": "Update the authenticated user's UI preferences",
        "description": "Partial update: omitted fields keep their current value, and a field sent as\n`null` clears the override so the system default applies again. Returns the\nfull effective preference set after the update.",
        "operationId": "update_my_preferences",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserPreferencesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated effective preferences",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPreferencesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Unknown field, invalid preference value, or an absolute time range (session-only)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/variable-sets": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "List all variable sets (paginated)",
        "description": "Returns a paginated list of variable sets.\n- Admin users see all variable sets.\n- Tenant users see global sets (tenant_id = NULL) plus their own tenant's sets.",
        "operationId": "list_variable_sets",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive name filter",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of variable sets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_VariableSetSummary"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Create a new variable set",
        "description": "Creates a new variable set.\n- Admin users can create global sets (omit tenant_id) or tenant-scoped sets (specify tenant_id).\n- Tenant users can only create sets for their own tenant (tenant_id must be omitted or match).",
        "operationId": "create_variable_set",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVariableSetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Variable set created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableSetResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "409": {
            "description": "Set with this name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/variable-sets/{id}": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Get variable set details",
        "description": "Returns detailed information about a specific variable set.\nAccess depends on user type and set ownership (see verify_variable_set_access).",
        "operationId": "get_variable_set",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Variable set details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableSetResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Update variable set",
        "description": "Updates variable set name and/or description.\nTenant users cannot modify global variable sets.",
        "operationId": "update_variable_set",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateVariableSetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Variable set updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableSetResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions or cannot modify global set"
          },
          "404": {
            "description": "Variable set not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Delete variable set",
        "description": "Deletes a variable set and all its variables.\nTenant users cannot delete global variable sets.",
        "operationId": "delete_variable_set",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Variable set deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions or cannot delete global set"
          },
          "404": {
            "description": "Variable set not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/variable-sets/{id}/variables": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "List variables in a variable set",
        "description": "Returns a paginated list of scoped variables within a specific variable set.",
        "operationId": "list_variable_set_variables",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page (max 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "environment_id",
            "in": "query",
            "description": "Filter by environment scope",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of variables",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paginated_VariableSummary"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Create a variable in a variable set",
        "description": "Creates a new scoped variable within the specified variable set.",
        "operationId": "create_variable_set_variable",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVariableRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Variable created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set not found"
          },
          "409": {
            "description": "Variable name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/variable-sets/{id}/variables/{var_id}": {
      "get": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Get a specific variable from a variable set",
        "description": "Returns detailed information about a specific scoped variable.",
        "operationId": "get_variable_set_variable",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "var_id",
            "in": "path",
            "description": "Variable ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Variable details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set or variable not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Update a variable in a variable set",
        "description": "Updates an existing scoped variable within the specified variable set.",
        "operationId": "update_variable_set_variable",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "var_id",
            "in": "path",
            "description": "Variable ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateVariableRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Variable updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VariableResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set or variable not found"
          },
          "409": {
            "description": "Variable name already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "variable-sets"
        ],
        "summary": "Delete a variable from a variable set",
        "description": "Removes a scoped variable from the specified variable set.",
        "operationId": "delete_variable_set_variable",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Variable set ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "var_id",
            "in": "path",
            "description": "Variable ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Variable deleted"
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Variable set or variable not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/api/v1/wireguard/summary": {
      "get": {
        "tags": [
          "wireguard"
        ],
        "summary": "Global WireGuard summary across all agents visible to the caller.",
        "description": "A global admin (no tenant_id) sees every WireGuard-enabled agent; a\ntenant-scoped caller is filtered to its own tenant. This backs the Lens\nnetwork page's tenant-less summary call (lens/src/lib/api/wireguard.ts).",
        "operationId": "get_global_summary",
        "responses": {
          "200": {
            "description": "WireGuard summary across visible agents",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WireGuardSummaryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Missing wireguard:read permission"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/audit/integrity/{tenant_id}": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Verify audit chain integrity for a tenant",
        "operationId": "verify_tenant_integrity",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "description": "Tenant ID to verify",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Integrity check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrityCheckResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/audit/logs": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "List audit log entries with filtering and pagination",
        "operationId": "list_audit_logs",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Narrow results to a single tenant (admin-only; ignored for tenant-scoped callers)",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Filter by event category",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "severity",
            "in": "query",
            "description": "Filter by severity level",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "actor_type",
            "in": "query",
            "description": "Filter by actor type",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "actor_id",
            "in": "query",
            "description": "Filter by actor ID",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "resource_type",
            "in": "query",
            "description": "Filter by resource type",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "resource_id",
            "in": "query",
            "description": "Filter by resource ID",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "outcome",
            "in": "query",
            "description": "Filter by outcome",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Filter events after this timestamp",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Filter events before this timestamp",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 50,
              "maximum": 100,
              "minimum": 1
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Optional case-insensitive search filter. Matched against entity-specific\ncolumns by each list handler; absent or blank means no filter.",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "tenant_id",
            "in": "query",
            "description": "Admin-only: narrow a tenant-aware list to one tenant (\"see as tenant X\").\nHonored only when the caller is a global-admin (see `effective_tenant_scope`);\nignored by tenant-scoped users and by non-tenant list handlers.",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of audit log entries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/audit/logs/event/{event_id}": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Get a single audit log entry by event UUID",
        "operationId": "get_audit_log_by_event",
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "description": "Event UUID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit log entry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid UUID"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Entry not found"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/audit/logs/{id}": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Get a single audit log entry by ID",
        "operationId": "get_audit_log",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Audit log entry ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit log entry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Entry not found"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    },
    "/audit/stats": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Get audit log statistics",
        "operationId": "get_audit_stats",
        "responses": {
          "200": {
            "description": "Audit statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditStatsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "500": {
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AccessibilityPreferences": {
        "type": "object",
        "description": "Accessibility preferences.\n\nStored in a JSONB column rather than 19 columns because it is a partial\nobject: every field is independently optional and absent means \"the client\nkeeps its own default\". The *shape* is still typed here, so an unknown key or\na wrong-typed value is rejected at the API boundary instead of being written\nthrough as opaque JSON.\n\nField names are camelCase on the wire to match the shape Lens already reads.",
        "properties": {
          "customTextSpacing": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "dyslexicFont": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "focusMode": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "highContrast": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "keyboardShortcutsEnabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "letterSpacing": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          },
          "lineHeight": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          },
          "preferredVoice": {
            "type": [
              "string",
              "null"
            ]
          },
          "readingRuler": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "readingRulerHeight": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "reducedMotion": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "speechAutoHighlight": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "speechChunkPause": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "speechPitch": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          },
          "speechPreferNaturalVoices": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "speechRate": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          },
          "speechReadingMode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SpeechReadingMode"
              }
            ]
          },
          "toastDuration": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "wordSpacing": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "ActionDetailResponse": {
        "type": "object",
        "description": "Action detail response (includes all versions)",
        "required": [
          "id",
          "name",
          "versions",
          "slug",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Action ID"
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Action name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionVersionResponse"
            },
            "description": "All versions"
          }
        }
      },
      "ActionEntryRequest": {
        "type": "object",
        "description": "Action entry in a sequence",
        "required": [
          "order",
          "id",
          "name",
          "version_requirement"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Action ID"
          },
          "name": {
            "type": "string",
            "description": "Action name (for display/validation)"
          },
          "order": {
            "type": "integer",
            "format": "int32",
            "description": "Order index (0-based)",
            "minimum": 0
          },
          "version_requirement": {
            "type": "string",
            "description": "Version requirement (e.g., \"^1.0.0\", \">=2.0.0\")"
          }
        }
      },
      "ActionEntryResponse": {
        "type": "object",
        "description": "Action entry response",
        "required": [
          "order",
          "id",
          "name",
          "version_requirement"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Action ID"
          },
          "name": {
            "type": "string",
            "description": "Action name"
          },
          "order": {
            "type": "integer",
            "format": "int32",
            "description": "Order index",
            "minimum": 0
          },
          "version_requirement": {
            "type": "string",
            "description": "Version requirement"
          }
        }
      },
      "ActionResponse": {
        "type": "object",
        "description": "Action response DTO",
        "required": [
          "id",
          "name",
          "version_count",
          "slug",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Action ID"
          },
          "latest_version": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ActionVersionResponse",
                "description": "Latest version (if any)"
              }
            ]
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Action name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version_count": {
            "type": "integer",
            "description": "Number of versions",
            "minimum": 0
          }
        }
      },
      "ActionVersionResponse": {
        "type": "object",
        "description": "Action version response DTO",
        "required": [
          "id",
          "version",
          "payload_type",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "executor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional executor"
          },
          "id": {
            "type": "string",
            "description": "Version ID"
          },
          "payload_description": {
            "description": "Payload description (JSON representation)"
          },
          "payload_type": {
            "type": "string",
            "description": "Payload type"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version": {
            "type": "string",
            "description": "Version number (semantic version)"
          }
        }
      },
      "ActiveFreezeSummary": {
        "type": "object",
        "description": "Active freeze summary (for deployment blocked response)",
        "required": [
          "id",
          "name",
          "ends_at"
        ],
        "properties": {
          "ends_at": {
            "type": "string",
            "description": "When the freeze ends (UTC)"
          },
          "id": {
            "type": "string",
            "description": "Freeze ID"
          },
          "name": {
            "type": "string",
            "description": "Freeze name"
          }
        }
      },
      "ActivityEntry": {
        "type": "object",
        "description": "Activity entry for the activity timeline",
        "required": [
          "timestamp",
          "event_type",
          "description",
          "resource_type",
          "resource_id"
        ],
        "properties": {
          "description": {
            "type": "string",
            "description": "Human-readable description"
          },
          "event_type": {
            "type": "string",
            "description": "Type of event (e.g., \"deployment_created\", \"target_registered\")"
          },
          "resource_id": {
            "type": "string",
            "description": "ID of the resource"
          },
          "resource_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional resource name for display"
          },
          "resource_type": {
            "type": "string",
            "description": "Type of resource involved"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the activity"
          },
          "user": {
            "type": [
              "string",
              "null"
            ],
            "description": "User who performed the action (if applicable)"
          }
        }
      },
      "AddEnvironmentTargetRequest": {
        "type": "object",
        "description": "Request to add a target to an environment",
        "required": [
          "target_id"
        ],
        "properties": {
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority for deployment ordering (higher = first)"
          },
          "target_id": {
            "type": "string",
            "description": "Target ID"
          }
        }
      },
      "AddFilterRequest": {
        "type": "object",
        "description": "Request to add a filter to an existing subscription.",
        "required": [
          "filter_type",
          "filter_values"
        ],
        "properties": {
          "filter_type": {
            "type": "string",
            "description": "Type of filter (event_type, event_group, severity, environment, solution, tenant)",
            "example": "event_type"
          },
          "filter_values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values to filter on"
          }
        }
      },
      "AddLifecycleRuleRequest": {
        "type": "object",
        "description": "Request to add a lifecycle rule",
        "required": [
          "source_environment_id",
          "target_environment_id"
        ],
        "properties": {
          "allow_skip": {
            "type": "boolean",
            "description": "Whether skipping is allowed"
          },
          "approval_role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role ID required for approval"
          },
          "minimum_soak_time_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Minimum soak time in minutes"
          },
          "requires_approval": {
            "type": "boolean",
            "description": "Whether approval is required"
          },
          "requires_successful_deployment": {
            "type": "boolean",
            "description": "Whether successful deployment is required"
          },
          "source_environment_id": {
            "type": "string",
            "description": "Source environment ID"
          },
          "target_environment_id": {
            "type": "string",
            "description": "Target environment ID"
          }
        }
      },
      "AdminUserDetailResponse": {
        "type": "object",
        "description": "Detailed user response for admin view",
        "required": [
          "id",
          "email",
          "username",
          "status",
          "email_verified",
          "roles",
          "permissions",
          "external_identities",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Account created timestamp"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "email_verified": {
            "type": "boolean",
            "description": "Whether email is verified"
          },
          "external_identities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExternalIdentityResponse"
            },
            "description": "External identity providers linked"
          },
          "id": {
            "type": "string",
            "description": "User ID"
          },
          "last_login_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last login timestamp"
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Effective permissions (through roles)"
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoleResponse"
            },
            "description": "Assigned roles"
          },
          "status": {
            "type": "string",
            "description": "Account status"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID if associated"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name if associated"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last updated timestamp"
          },
          "username": {
            "type": "string",
            "description": "Username"
          }
        }
      },
      "AdminUserListResponse": {
        "type": "object",
        "description": "User list response for admin view",
        "required": [
          "id",
          "email",
          "username",
          "status",
          "email_verified",
          "role_count",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Account created timestamp"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "email_verified": {
            "type": "boolean",
            "description": "Whether email is verified"
          },
          "id": {
            "type": "string",
            "description": "User ID"
          },
          "last_login_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last login timestamp"
          },
          "role_count": {
            "type": "integer",
            "description": "Number of roles assigned",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "description": "Account status (Active, Inactive, Locked, Pending)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID if associated"
          },
          "username": {
            "type": "string",
            "description": "Username"
          }
        }
      },
      "AnalysisConfigResponse": {
        "type": "object",
        "description": "AI Analysis configuration (subset exposed to frontend)",
        "required": [
          "provider_type",
          "api_url",
          "model",
          "timeout_secs",
          "batch_size"
        ],
        "properties": {
          "api_url": {
            "type": "string",
            "description": "API URL for the LLM provider"
          },
          "batch_size": {
            "type": "integer",
            "format": "int64",
            "description": "Batch size for processing"
          },
          "model": {
            "type": "string",
            "description": "Model being used for analysis"
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (ollama or openai)"
          },
          "timeout_secs": {
            "type": "integer",
            "format": "int64",
            "description": "Request timeout in seconds",
            "minimum": 0
          }
        }
      },
      "AnalysisDefaultsResponse": {
        "type": "object",
        "description": "Default settings values (from code, not database).",
        "required": [
          "enabled",
          "provider_type",
          "api_url",
          "model",
          "timeout_secs",
          "check_interval_secs",
          "batch_size",
          "max_input_length",
          "max_retries",
          "temperature",
          "top_p",
          "pattern_detection_enabled",
          "pattern_window_days",
          "pattern_batch_interval_secs",
          "pattern_retention_days",
          "pattern_llm_labeling_enabled",
          "pattern_alert_enabled",
          "pattern_alert_min_deployments",
          "pattern_alert_min_occurrences",
          "pattern_alert_min_targets",
          "pattern_alert_window_days",
          "pattern_label_max_samples",
          "pattern_label_max_input_chars",
          "pattern_relabel_factor",
          "pattern_max_batch_size"
        ],
        "properties": {
          "api_url": {
            "type": "string"
          },
          "batch_size": {
            "type": "integer",
            "format": "int32"
          },
          "check_interval_secs": {
            "type": "integer",
            "format": "int32"
          },
          "enabled": {
            "type": "boolean"
          },
          "max_input_length": {
            "type": "integer",
            "format": "int32"
          },
          "max_retries": {
            "type": "integer",
            "format": "int32"
          },
          "max_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "model": {
            "type": "string"
          },
          "pattern_alert_enabled": {
            "type": "boolean"
          },
          "pattern_alert_min_deployments": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_alert_min_occurrences": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_alert_min_targets": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_alert_window_days": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_batch_interval_secs": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_detection_enabled": {
            "type": "boolean"
          },
          "pattern_label_max_input_chars": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_label_max_samples": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_llm_labeling_enabled": {
            "type": "boolean"
          },
          "pattern_max_batch_size": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_relabel_factor": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_retention_days": {
            "type": "integer",
            "format": "int32"
          },
          "pattern_window_days": {
            "type": "integer",
            "format": "int32"
          },
          "provider_type": {
            "type": "string"
          },
          "temperature": {
            "type": "number",
            "format": "float"
          },
          "timeout_secs": {
            "type": "integer",
            "format": "int32"
          },
          "top_p": {
            "type": "number",
            "format": "float"
          }
        }
      },
      "AnalysisQueueStats": {
        "type": "object",
        "description": "Queue statistics for pending analysis requests",
        "required": [
          "pending",
          "completed_24h",
          "failed_24h"
        ],
        "properties": {
          "completed_24h": {
            "type": "integer",
            "format": "int64",
            "description": "Number of completed in last 24 hours"
          },
          "failed_24h": {
            "type": "integer",
            "format": "int64",
            "description": "Number of failed in last 24 hours"
          },
          "pending": {
            "type": "integer",
            "format": "int64",
            "description": "Number of pending requests"
          }
        }
      },
      "AnalysisRequestResponse": {
        "type": "object",
        "description": "An analysis request in the queue.",
        "required": [
          "id",
          "command_result_id",
          "deployment_id",
          "status",
          "created_at",
          "retry_count",
          "max_retries"
        ],
        "properties": {
          "command_result_id": {
            "type": "string",
            "format": "uuid",
            "description": "Associated command result ID"
          },
          "created_at": {
            "type": "string",
            "description": "When the request was created"
          },
          "deployment_id": {
            "type": "string",
            "format": "uuid",
            "description": "Associated deployment ID"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if failed"
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Exit code from the command"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier"
          },
          "max_retries": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum retry attempts allowed"
          },
          "processed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the request was processed (if completed/failed)"
          },
          "retry_count": {
            "type": "integer",
            "format": "int32",
            "description": "Number of retry attempts made"
          },
          "status": {
            "type": "string",
            "description": "Current status (pending, processing, completed, failed)"
          },
          "stderr_preview": {
            "type": [
              "string",
              "null"
            ],
            "description": "Truncated stderr for context (first 500 chars)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Tenant ID if applicable"
          }
        }
      },
      "AnalysisRequestsListResponse": {
        "type": "object",
        "description": "Paginated list of analysis requests.",
        "required": [
          "requests",
          "total",
          "offset",
          "limit"
        ],
        "properties": {
          "limit": {
            "type": "integer",
            "format": "int64",
            "description": "Current limit"
          },
          "offset": {
            "type": "integer",
            "format": "int64",
            "description": "Current offset"
          },
          "requests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnalysisRequestResponse"
            },
            "description": "The analysis requests"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count matching the filter"
          }
        }
      },
      "AnalysisResult": {
        "type": "object",
        "description": "AI log analysis result",
        "required": [
          "confidence",
          "summary",
          "likely_cause",
          "remediation",
          "analyzed_at"
        ],
        "properties": {
          "analyzed_at": {
            "type": "string",
            "description": "When the analysis was performed"
          },
          "confidence": {
            "type": "number",
            "format": "float",
            "description": "Model confidence score (0.0 to 1.0)"
          },
          "likely_cause": {
            "type": "string",
            "description": "The most probable root cause of this failure"
          },
          "model_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version used for analysis"
          },
          "remediation": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Actionable remediation steps (1-5 steps)"
          },
          "summary": {
            "type": "string",
            "description": "One-sentence summary of what failed and why"
          }
        }
      },
      "AnalysisRetryResponse": {
        "type": "object",
        "description": "Response after retrying an analysis request.",
        "required": [
          "success",
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Message describing the result"
          },
          "request": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AnalysisRequestResponse",
                "description": "The updated request"
              }
            ]
          },
          "success": {
            "type": "boolean",
            "description": "Whether the retry was scheduled successfully"
          }
        }
      },
      "AnalysisSettingsResponse": {
        "type": "object",
        "description": "Response containing effective analysis settings (defaults merged with overrides).",
        "required": [
          "enabled",
          "provider_type",
          "api_url",
          "model",
          "timeout_secs",
          "check_interval_secs",
          "batch_size",
          "max_input_length",
          "max_retries",
          "temperature",
          "top_p",
          "has_api_key",
          "updated_at",
          "overrides",
          "pattern_detection_enabled",
          "pattern_window_days",
          "pattern_batch_interval_secs",
          "pattern_retention_days",
          "pattern_llm_labeling_enabled",
          "pattern_alert_enabled",
          "pattern_alert_min_deployments",
          "pattern_alert_min_occurrences",
          "pattern_alert_min_targets",
          "pattern_alert_window_days",
          "pattern_label_max_samples",
          "pattern_label_max_input_chars",
          "pattern_relabel_factor",
          "pattern_max_batch_size"
        ],
        "properties": {
          "api_url": {
            "type": "string",
            "description": "API URL for the LLM provider"
          },
          "batch_size": {
            "type": "integer",
            "format": "int32",
            "description": "Number of requests per batch"
          },
          "check_interval_secs": {
            "type": "integer",
            "format": "int32",
            "description": "Interval between processing batches"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether AI analysis is enabled"
          },
          "has_api_key": {
            "type": "boolean",
            "description": "Whether an API key is configured"
          },
          "max_input_length": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum input length for analysis"
          },
          "max_retries": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum retry attempts"
          },
          "max_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum number of tokens to generate; null = uncapped"
          },
          "model": {
            "type": "string",
            "description": "Model name"
          },
          "overrides": {
            "$ref": "#/components/schemas/SettingsOverrideFlags",
            "description": "Which fields are user overrides (true) vs defaults (false)"
          },
          "pattern_alert_enabled": {
            "type": "boolean",
            "description": "Whether emerging-pattern alerts fire."
          },
          "pattern_alert_min_deployments": {
            "type": "integer",
            "format": "int32",
            "description": "Min distinct deployments before a pattern can alert."
          },
          "pattern_alert_min_occurrences": {
            "type": "integer",
            "format": "int32",
            "description": "Min total occurrences before a pattern can alert."
          },
          "pattern_alert_min_targets": {
            "type": "integer",
            "format": "int32",
            "description": "Min distinct targets before a pattern can alert."
          },
          "pattern_alert_window_days": {
            "type": "integer",
            "format": "int32",
            "description": "Recurrence window (days) the alert thresholds are evaluated over."
          },
          "pattern_batch_interval_secs": {
            "type": "integer",
            "format": "int32",
            "description": "Seconds between background batch passes."
          },
          "pattern_detection_enabled": {
            "type": "boolean",
            "description": "Master toggle for failure-pattern detection."
          },
          "pattern_label_max_input_chars": {
            "type": "integer",
            "format": "int32",
            "description": "Max characters of LLM-label input (context + samples)."
          },
          "pattern_label_max_samples": {
            "type": "integer",
            "format": "int32",
            "description": "Max error samples sent to the LLM per cluster label."
          },
          "pattern_llm_labeling_enabled": {
            "type": "boolean",
            "description": "Whether to LLM-label clusters (requires AI analysis configured)."
          },
          "pattern_max_batch_size": {
            "type": "integer",
            "format": "int32",
            "description": "Max failures clustered per batch pass."
          },
          "pattern_relabel_factor": {
            "type": "integer",
            "format": "int32",
            "description": "Growth factor (×) before a labeled pattern is relabeled."
          },
          "pattern_retention_days": {
            "type": "integer",
            "format": "int32",
            "description": "Days a resolved/untouched pattern and its occurrences are retained."
          },
          "pattern_window_days": {
            "type": "integer",
            "format": "int32",
            "description": "Trailing window (days) of failures considered for clustering."
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (ollama or openai)"
          },
          "temperature": {
            "type": "number",
            "format": "float",
            "description": "Temperature for LLM generation (0.0-1.0)"
          },
          "timeout_secs": {
            "type": "integer",
            "format": "int32",
            "description": "Request timeout in seconds"
          },
          "tls_ca_cert_path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional path to custom TLS CA certificate"
          },
          "top_p": {
            "type": "number",
            "format": "float",
            "description": "Top-p (nucleus) sampling threshold (0.0-1.0)"
          },
          "updated_at": {
            "type": "string",
            "description": "When settings were last updated"
          }
        }
      },
      "AnalysisStatusResponse": {
        "type": "object",
        "description": "Overall AI Analysis status response",
        "required": [
          "enabled",
          "provider_connected",
          "model_loaded",
          "config",
          "queue"
        ],
        "properties": {
          "config": {
            "$ref": "#/components/schemas/AnalysisConfigResponse",
            "description": "Configuration settings"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether AI analysis is enabled in config"
          },
          "model_loaded": {
            "type": "boolean",
            "description": "Whether the configured model is loaded/ready"
          },
          "provider_connected": {
            "type": "boolean",
            "description": "Whether the LLM provider is reachable"
          },
          "queue": {
            "$ref": "#/components/schemas/AnalysisQueueStats",
            "description": "Queue statistics"
          }
        }
      },
      "ApiKeyListResponse": {
        "type": "object",
        "description": "Response for listing API keys",
        "required": [
          "api_keys"
        ],
        "properties": {
          "api_keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKeyResponse"
            },
            "description": "List of API keys (without secrets)"
          }
        }
      },
      "ApiKeyResponse": {
        "type": "object",
        "description": "Response for a single API key (without the secret)",
        "required": [
          "id",
          "name",
          "key_prefix",
          "scopes",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "When the key was created"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the key expires (null = never)"
          },
          "id": {
            "type": "string",
            "description": "Unique key identifier"
          },
          "key_prefix": {
            "type": "string",
            "description": "Key prefix for display (e.g., \"mnt_7K4vBz9m...\")"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last time the key was used"
          },
          "last_used_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "IP address of last use"
          },
          "name": {
            "type": "string",
            "description": "User-friendly name"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Scopes assigned to this key"
          }
        }
      },
      "ApprovePromotionRequest": {
        "type": "object",
        "description": "Request to approve a promotion",
        "properties": {
          "comment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional approval comment"
          },
          "failure_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FailureStrategyParam",
                "description": "Failure strategy: \"stop_on_first_failure\", \"continue_on_failure\", \"ignore_failures\"\nDefaults to StopOnFirst"
              }
            ]
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum retries per command\nDefaults to 3"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Command priority (higher = more urgent)\nDefaults to 0"
          },
          "rollback_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RollbackStrategyParam",
                "description": "Rollback strategy for the promotion deployment\nDefaults to None"
              }
            ]
          },
          "target_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetExecutionModeDto",
                "description": "Execution mode: \"sequential\", \"parallel\", or {\"rolling\": {\"batch_size\": N}}\nDefaults to Parallel for promotions"
              }
            ]
          },
          "timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Timeout for each command in seconds\nDefaults to 300 (5 minutes)"
          }
        }
      },
      "ApproveRegistrationRequest": {
        "type": "object",
        "description": "Request to approve a registration",
        "properties": {
          "notes": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional notes about the approval"
          }
        }
      },
      "AssignPermissionsRequest": {
        "type": "object",
        "description": "Assign permissions to role request",
        "required": [
          "permission_ids"
        ],
        "properties": {
          "permission_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Permission IDs to assign"
          }
        },
        "additionalProperties": false
      },
      "AssignRolesRequest": {
        "type": "object",
        "description": "Assign roles to user request",
        "required": [
          "role_ids"
        ],
        "properties": {
          "role_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Role IDs to assign"
          }
        },
        "additionalProperties": false
      },
      "AssignTenantsRequest": {
        "type": "object",
        "description": "Assign tenants to thorax instance request",
        "required": [
          "tenant_ids"
        ],
        "properties": {
          "tenant_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of tenant IDs to assign"
          }
        }
      },
      "AssignedTenantResponse": {
        "type": "object",
        "description": "Assigned tenant response DTO",
        "required": [
          "tenant_id",
          "tenant_name",
          "assigned_at"
        ],
        "properties": {
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the tenant was assigned"
          },
          "assigned_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who assigned the tenant (user ID)"
          },
          "tenant_id": {
            "type": "string",
            "description": "Tenant ID"
          },
          "tenant_name": {
            "type": "string",
            "description": "Tenant name"
          }
        }
      },
      "AttachSolutionRequest": {
        "type": "object",
        "description": "Attach solution to tenant request",
        "required": [
          "solution_id",
          "environment_id"
        ],
        "properties": {
          "environment_id": {
            "type": "string",
            "description": "Environment ID"
          },
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          }
        }
      },
      "AttachTagsRequest": {
        "type": "object",
        "description": "Attach tags request",
        "required": [
          "tag_ids"
        ],
        "properties": {
          "tag_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of tag IDs to attach"
          }
        }
      },
      "AttachTargetRequest": {
        "type": "object",
        "description": "Attach target to tenant request",
        "required": [
          "target_id"
        ],
        "properties": {
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (optional - if None, target is for all environments)"
          },
          "target_id": {
            "type": "string",
            "description": "Target ID"
          }
        }
      },
      "AuditLogListResponse": {
        "type": "object",
        "description": "Response for audit log listing",
        "required": [
          "logs",
          "total",
          "page",
          "per_page"
        ],
        "properties": {
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuditLogResponse"
            }
          },
          "page": {
            "type": "integer",
            "format": "int64"
          },
          "per_page": {
            "type": "integer",
            "format": "int64"
          },
          "total": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "AuditLogResponse": {
        "type": "object",
        "description": "Response for a single audit log entry",
        "required": [
          "id",
          "event_id",
          "event_type",
          "event_category",
          "severity",
          "actor_type",
          "action",
          "outcome",
          "occurred_at",
          "entry_hash"
        ],
        "properties": {
          "action": {
            "type": "string"
          },
          "actor_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "actor_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "actor_type": {
            "type": "string"
          },
          "entry_hash": {
            "type": "string"
          },
          "event_category": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time"
          },
          "outcome": {
            "type": "string"
          },
          "outcome_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "severity": {
            "type": "string"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "AuditStatsResponse": {
        "type": "object",
        "description": "Response for audit statistics",
        "required": [
          "total_entries",
          "entries_by_category",
          "entries_by_severity",
          "entries_by_outcome"
        ],
        "properties": {
          "entries_by_category": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CategoryCount"
            }
          },
          "entries_by_outcome": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OutcomeCount"
            }
          },
          "entries_by_severity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SeverityCount"
            }
          },
          "total_entries": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "CacheClearResponse": {
        "type": "object",
        "description": "Response for cache clear operations.",
        "required": [
          "cleared",
          "message"
        ],
        "properties": {
          "cleared": {
            "type": "boolean",
            "description": "Whether the clear operation was successful"
          },
          "entries_cleared": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Number of entries cleared (if available)",
            "minimum": 0
          },
          "message": {
            "type": "string",
            "description": "Descriptive message about the operation"
          }
        }
      },
      "CacheStatsResponse": {
        "type": "object",
        "description": "Cache statistics response.",
        "required": [
          "enabled",
          "hits",
          "misses",
          "hit_rate",
          "entry_count",
          "max_entries"
        ],
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether caching is currently enabled"
          },
          "entry_count": {
            "type": "integer",
            "format": "int64",
            "description": "Current number of entries (approximate)",
            "minimum": 0
          },
          "hit_rate": {
            "type": "number",
            "format": "double",
            "description": "Cache hit rate (0.0 - 1.0)"
          },
          "hits": {
            "type": "integer",
            "format": "int64",
            "description": "Total cache hits",
            "minimum": 0
          },
          "max_entries": {
            "type": "integer",
            "format": "int64",
            "description": "Maximum configured entries",
            "minimum": 0
          },
          "misses": {
            "type": "integer",
            "format": "int64",
            "description": "Total cache misses",
            "minimum": 0
          }
        }
      },
      "CacheToggleResponse": {
        "type": "object",
        "description": "Response for cache enable/disable operations.",
        "required": [
          "enabled",
          "message"
        ],
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "New enabled state"
          },
          "message": {
            "type": "string",
            "description": "Descriptive message"
          }
        }
      },
      "CancelDeploymentRequest": {
        "type": "object",
        "description": "Cancel deployment request",
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional reason for cancellation"
          }
        },
        "additionalProperties": false
      },
      "CategoryCount": {
        "type": "object",
        "required": [
          "category",
          "count"
        ],
        "properties": {
          "category": {
            "type": "string"
          },
          "count": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "CertificateSeverity": {
        "type": "string",
        "description": "Certificate expiry severity level",
        "enum": [
          "ok",
          "warning",
          "critical",
          "expired"
        ]
      },
      "ChangePasswordRequest": {
        "type": "object",
        "description": "Change password request",
        "required": [
          "current_password",
          "new_password"
        ],
        "properties": {
          "current_password": {
            "type": "string",
            "description": "Current password"
          },
          "new_password": {
            "type": "string",
            "description": "New password - must meet complexity requirements (CWE-521)\nMinimum 12 characters with uppercase, lowercase, digit, and special character"
          }
        },
        "additionalProperties": false
      },
      "ChannelListResponse": {
        "type": "object",
        "description": "Response for listing notification channels.",
        "required": [
          "channels",
          "total"
        ],
        "properties": {
          "channels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChannelResponse"
            },
            "description": "List of channels"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count of channels"
          }
        }
      },
      "ChannelResponse": {
        "type": "object",
        "description": "Response representing a notification channel.\n\nNote: Sensitive fields (passwords, secrets, tokens) are never returned.",
        "required": [
          "id",
          "name",
          "slug",
          "channel_type",
          "enabled",
          "circuit_state",
          "consecutive_failures",
          "smtp_password_configured",
          "webhook_secret_configured",
          "slack_bot_token_configured",
          "created_at"
        ],
        "properties": {
          "channel_type": {
            "type": "string",
            "description": "Type of notification channel (email, webhook, slack, teams, discord)",
            "example": "webhook"
          },
          "circuit_state": {
            "type": "string",
            "description": "Circuit breaker state (closed, open, half_open)",
            "example": "closed"
          },
          "consecutive_failures": {
            "type": "integer",
            "format": "int32",
            "description": "Number of consecutive delivery failures"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_by_user_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "discord_webhook_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the channel is enabled"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique channel identifier"
          },
          "name": {
            "type": "string",
            "description": "Channel name"
          },
          "slack_bot_token_configured": {
            "type": "boolean",
            "description": "Whether Slack bot token is configured"
          },
          "slack_channel": {
            "type": [
              "string",
              "null"
            ]
          },
          "slack_webhook_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "slug": {
            "type": "string",
            "description": "Stable, per-scope-unique slug (config-as-code reference key)"
          },
          "smtp_from_address": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_from_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_host": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_password_configured": {
            "type": "boolean",
            "description": "Whether SMTP password is configured (not the actual password)"
          },
          "smtp_port": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "smtp_use_tls": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "smtp_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "teams_workflow_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant ID (null = global/shared channel)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "webhook_headers": {},
          "webhook_secret_configured": {
            "type": "boolean",
            "description": "Whether webhook secret is configured"
          },
          "webhook_secret_rotated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the webhook secret was last rotated"
          },
          "webhook_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ClientCertificateInfo": {
        "type": "object",
        "description": "Client certificate information",
        "required": [
          "registration_id",
          "client_name",
          "thumbprint",
          "subject",
          "issuer",
          "valid_from",
          "valid_until",
          "days_remaining",
          "status",
          "is_valid",
          "expiry_severity"
        ],
        "properties": {
          "client_name": {
            "type": "string",
            "description": "Client name"
          },
          "days_remaining": {
            "type": "integer",
            "format": "int64",
            "description": "Days until expiration"
          },
          "expiry_severity": {
            "$ref": "#/components/schemas/CertificateSeverity",
            "description": "Severity level for expiration"
          },
          "is_valid": {
            "type": "boolean",
            "description": "Whether the certificate is currently valid"
          },
          "issuer": {
            "type": "string",
            "description": "Certificate issuer"
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last time the client was seen (ISO 8601 format)"
          },
          "registration_id": {
            "type": "string",
            "description": "Registration ID (UUID)"
          },
          "status": {
            "type": "string",
            "description": "Registration status"
          },
          "subject": {
            "type": "string",
            "description": "Certificate subject (CN)"
          },
          "thumbprint": {
            "type": "string",
            "description": "Certificate thumbprint (SHA-256)"
          },
          "valid_from": {
            "type": "string",
            "description": "When the certificate becomes valid (ISO 8601 format)"
          },
          "valid_until": {
            "type": "string",
            "description": "When the certificate expires (ISO 8601 format)"
          }
        }
      },
      "CommandResultWithAnalysis": {
        "type": "object",
        "description": "Command result with AI analysis",
        "required": [
          "id",
          "target_id",
          "status",
          "started_at",
          "completed_at",
          "duration_ms"
        ],
        "properties": {
          "action_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action name"
          },
          "analysis": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AnalysisResult",
                "description": "AI-generated analysis result"
              }
            ]
          },
          "completed_at": {
            "type": "string",
            "description": "Command completion time"
          },
          "duration_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Duration in milliseconds"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message"
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Exit code"
          },
          "id": {
            "type": "string",
            "description": "Command result ID"
          },
          "started_at": {
            "type": "string",
            "description": "Command start time"
          },
          "status": {
            "type": "string",
            "description": "Result status (completed, failed, timeout, cancelled)"
          },
          "stderr_tail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Truncated stderr output (last 2000 chars)"
          },
          "stdout_tail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Truncated stdout output (last 2000 chars)"
          },
          "target_id": {
            "type": "string",
            "description": "Target ID the command ran on"
          },
          "target_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target name"
          }
        }
      },
      "ConfigExportResponse": {
        "type": "object",
        "description": "Multi-file config export response. `files` is a deterministic (sorted) map of\nrepo-relative path → document content, mirroring the on-disk layout.",
        "required": [
          "schema_version",
          "files",
          "summary",
          "read_only",
          "tenant_has_authoritative_repo"
        ],
        "properties": {
          "files": {
            "type": "object",
            "description": "Repo-relative path → document content (native Nickel).",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "read_only": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReadOnlyDoc"
            },
            "description": "Documents that are read-only for this caller (Git-managed, or no write permission).\nAlways a subset of `files` keys. The editor locks these and excludes them from import."
          },
          "schema_version": {
            "type": "string",
            "description": "On-disk schema/format version."
          },
          "summary": {
            "$ref": "#/components/schemas/ExportSummary",
            "description": "Per-entity-type counts of what was exported."
          },
          "tenant_has_authoritative_repo": {
            "type": "boolean",
            "description": "True when a Git-authoritative repository governs the caller's scope. The editor uses\nthis for a coarse warning that variables/variable-sets (which carry no provenance\ncolumn, so cannot be locked per-row) may be overwritten on the next sync."
          }
        }
      },
      "ConfirmKeyRotationRequest": {
        "type": "object",
        "description": "Request to confirm a key rotation was successful.\n\nCalled by the agent after the new key has been verified working.\nThis promotes the pending key to active and clears the rotation state.",
        "required": [
          "rotation_id"
        ],
        "properties": {
          "rotation_id": {
            "type": "string",
            "format": "uuid",
            "description": "The rotation ID from the start rotation response."
          }
        }
      },
      "ConflictResponse": {
        "type": "object",
        "description": "A pending 3-way sync conflict for display. The `local`/`remote`/`base` document bodies are\nsecret-free (export redacts; Git only ever held redacted content), so they are safe to\nsurface to the operator for resolution.",
        "required": [
          "id",
          "entity_type"
        ],
        "properties": {
          "base": {
            "type": [
              "string",
              "null"
            ],
            "description": "The common ancestor (last synced) rendering."
          },
          "entity_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "entity_type": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "local": {
            "type": [
              "string",
              "null"
            ],
            "description": "The Mantis (DB) rendering of the entity."
          },
          "remote": {
            "type": [
              "string",
              "null"
            ],
            "description": "The Git rendering of the entity."
          }
        }
      },
      "ConflictStrategyDto": {
        "type": "string",
        "description": "How to handle a document entity that already exists in the target scope.",
        "enum": [
          "fail",
          "skip",
          "upsert"
        ]
      },
      "ConnectionModeDistribution": {
        "type": "object",
        "description": "Distribution of connection modes across agents.",
        "required": [
          "direct_udp",
          "turn_relay",
          "websocket_relay"
        ],
        "properties": {
          "direct_udp": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "turn_relay": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "websocket_relay": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          }
        }
      },
      "CreateActionRequest": {
        "type": "object",
        "description": "Create action request",
        "required": [
          "name",
          "version",
          "payload_type"
        ],
        "properties": {
          "arguments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command arguments"
          },
          "bin": {
            "type": [
              "string",
              "null"
            ],
            "description": "Binary/executable path (required if payload_type is \"command\")"
          },
          "environment_variables": {
            "type": "object",
            "description": "Environment variables",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "executor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional executor (sh, bash, pwsh, zsh, etc.)"
          },
          "file_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Script file name (required if payload_type is \"script\")"
          },
          "name": {
            "type": "string",
            "description": "Action name"
          },
          "payload_type": {
            "type": "string",
            "description": "Payload type (command, script, restart)"
          },
          "relative_path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional relative path within storage"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from `name` when omitted."
          },
          "storage_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Storage ID (required if payload_type is \"script\")"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional tenant owner (admin only); omitted/null = global. Tenant-scoped\ncallers are always forced to their own tenant by `resolve_tenant_id_for_write`."
          },
          "version": {
            "type": "string",
            "description": "Initial version (semantic version)"
          },
          "working_directory": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional working directory"
          }
        }
      },
      "CreateActionVersionRequest": {
        "type": "object",
        "description": "Create action version request",
        "required": [
          "version",
          "payload_type"
        ],
        "properties": {
          "arguments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command arguments"
          },
          "bin": {
            "type": [
              "string",
              "null"
            ],
            "description": "Binary/executable path (required if payload_type is \"command\")"
          },
          "environment_variables": {
            "type": "object",
            "description": "Environment variables",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "executor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional executor (sh, bash, pwsh, zsh, etc.)"
          },
          "file_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Script file name (required if payload_type is \"script\")"
          },
          "payload_type": {
            "type": "string",
            "description": "Payload type (command, script, restart)"
          },
          "relative_path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional relative path within storage"
          },
          "storage_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Storage ID (required if payload_type is \"script\")"
          },
          "version": {
            "type": "string",
            "description": "Version (semantic version)"
          },
          "working_directory": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional working directory"
          }
        }
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "description": "Request to create a new API key",
        "required": [
          "name"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "expires_in_days": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Optional expiration in days (default: no expiration)"
          },
          "name": {
            "type": "string",
            "description": "User-friendly name for the key"
          },
          "scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Optional scopes (empty = full access)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant. A tenant-scoped caller is pinned to its own tenant; only a global admin\nmay set this (omit for a global key). Determines the key's tenant authorization scope."
          }
        }
      },
      "CreateApiKeyResponse": {
        "type": "object",
        "description": "Response for API key creation (includes the full key once)",
        "required": [
          "api_key",
          "full_key",
          "warning"
        ],
        "properties": {
          "api_key": {
            "$ref": "#/components/schemas/ApiKeyResponse",
            "description": "The API key metadata"
          },
          "full_key": {
            "type": "string",
            "description": "The full API key (only shown once!)"
          },
          "warning": {
            "type": "string",
            "description": "Warning message about storing the key"
          }
        }
      },
      "CreateChannelRequest": {
        "type": "object",
        "description": "Request to create a new notification channel.",
        "required": [
          "name",
          "channel_type"
        ],
        "properties": {
          "channel_type": {
            "type": "string",
            "description": "Type of notification channel (email, webhook, slack, teams, discord)",
            "example": "webhook"
          },
          "discord_webhook_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Discord webhook URL"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the channel is enabled (defaults to true)"
          },
          "name": {
            "type": "string",
            "description": "Channel name (must be unique)"
          },
          "slack_bot_token": {
            "type": [
              "string",
              "null"
            ],
            "description": "Slack bot token for advanced integrations (will be encrypted)"
          },
          "slack_channel": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target Slack channel (optional, uses webhook default if not set)"
          },
          "slack_webhook_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Slack incoming webhook URL"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional stable slug (config-as-code reference key). Derived from `name`\nwhen omitted; must be unique within the channel's scope (tenant or global)."
          },
          "smtp_from_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email sender address"
          },
          "smtp_from_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email sender display name"
          },
          "smtp_host": {
            "type": [
              "string",
              "null"
            ],
            "description": "SMTP server hostname"
          },
          "smtp_password": {
            "type": [
              "string",
              "null"
            ],
            "description": "SMTP authentication password (will be encrypted)"
          },
          "smtp_port": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "SMTP server port"
          },
          "smtp_use_tls": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether to use TLS for SMTP connection"
          },
          "smtp_username": {
            "type": [
              "string",
              "null"
            ],
            "description": "SMTP authentication username"
          },
          "teams_workflow_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Microsoft Teams Power Automate workflow URL"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional owning tenant ID. Admin-only; tenant-scoped callers are forced to\ntheir own tenant regardless of this value. Omit / null for a global channel."
          },
          "webhook_headers": {
            "description": "Custom HTTP headers to include in webhook requests"
          },
          "webhook_secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "Webhook signing secret (will be encrypted, auto-generated if not provided)"
          },
          "webhook_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Webhook destination URL (must be HTTPS, validated for SSRF)"
          }
        }
      },
      "CreateDeploymentRequest": {
        "type": "object",
        "description": "Create deployment request",
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID or SqId to deploy directly (mutually exclusive with solution_id and sequence_id)"
          },
          "bypass_cache": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Bypass file cache and fetch fresh content from S3/Git storage.\nWhen true, skips cache lookup and doesn't store fetched content in cache."
          },
          "deployment_timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Overall deployment timeout in seconds (optional, 0 = no timeout)\nThis is the maximum time the entire deployment can run before being cancelled."
          },
          "dry_run": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Dry-run mode: validate deployment configuration without executing.\nWhen true, performs all validation checks but does not create the deployment.\nReturns validation errors and warnings."
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID or SqId for tenant deployments"
          },
          "failure_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FailureStrategyParam",
                "description": "Failure strategy: \"stop_on_first_failure\", \"continue_on_failure\", \"ignore_failures\""
              }
            ]
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum retries per command"
          },
          "on_failure_action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: action ID or SqId to run when this deployment fails.\nMutually exclusive with on_failure_sequence_id and on_failure_solution_id."
          },
          "on_failure_sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: sequence ID or SqId to run when this deployment fails.\nMutually exclusive with on_failure_action_id and on_failure_solution_id."
          },
          "on_failure_solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: solution ID or SqId to run when this deployment fails.\nMutually exclusive with on_failure_action_id and on_failure_sequence_id."
          },
          "override_freeze": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Override active deployment freeze (requires admin role)"
          },
          "override_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for overriding freeze (required if override_freeze is true)"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Command priority (higher = more urgent)"
          },
          "prompted_values": {
            "type": [
              "object",
              "null"
            ],
            "description": "Values for prompted variables (variable_id or name -> value).\nRequired if the solution has prompted variables marked as required.",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "rollback_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RollbackStrategyParam",
                "description": "Rollback strategy: \"none\", \"failed_target_only\", \"all_executed\""
              }
            ]
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID or SqId to deploy directly (mutually exclusive with solution_id and action_id)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID or SqId to deploy (mutually exclusive with sequence_id and action_id)"
          },
          "target_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Specific target IDs or SqIds"
          },
          "target_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetExecutionModeDto",
                "description": "Execution mode: \"sequential\", \"parallel\", or {\"rolling\": {\"batch_size\": N}}"
              }
            ]
          },
          "target_tags": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/TagFilter"
            },
            "description": "Tag-based target selection (key-value pairs)"
          },
          "target_tags_match_all": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "If true, target must match ALL target_tags; if false, ANY tag"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID or SqId for tenant-aware deployments"
          },
          "tenant_tags": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/TagFilter"
            },
            "description": "Tenant tags for bulk tenant deployment"
          },
          "tenant_tags_match_all": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "If true, tenant must match ALL tenant_tags; if false, ANY tag"
          },
          "timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Timeout for each command in seconds"
          },
          "variables": {
            "type": [
              "object",
              "null"
            ],
            "description": "Deployment variables (key -> value)",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "version_requirement": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version requirement (e.g., \"^1.0.0\", \">=2.0.0\")\nIf not specified, uses latest version. Applies to the selected source."
          }
        },
        "additionalProperties": false
      },
      "CreateDeploymentResponse": {
        "type": "object",
        "description": "Response from creating a deployment\n\nA deployment can either be dispatched immediately (if a Thorax instance is available)\nor queued for later processing (if no eligible instance is available).",
        "required": [
          "pending",
          "message"
        ],
        "properties": {
          "deployment": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DeploymentDetailResponse",
                "description": "Full deployment details (present if dispatched immediately)"
              }
            ]
          },
          "deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Deployment ID (present if dispatched immediately)"
          },
          "dry_run_result": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DryRunResponse",
                "description": "Dry-run result (present if dry_run=true in request)"
              }
            ]
          },
          "message": {
            "type": "string",
            "description": "Human-readable status message"
          },
          "pending": {
            "type": "boolean",
            "description": "Whether the deployment is pending instance availability"
          },
          "pending_request_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pending request ID (present if awaiting Thorax instance)"
          }
        }
      },
      "CreateEnvironmentRequest": {
        "type": "object",
        "description": "Create environment request",
        "required": [
          "name"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment description"
          },
          "name": {
            "type": "string",
            "description": "Environment name (e.g., \"Development\", \"Production\")"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from `name` when omitted."
          },
          "sort_order": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Sort order for environment progression (lower = earlier)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional tenant owner (admin only); omitted/null = global. Tenant-scoped\ncallers are always forced to their own tenant by `resolve_tenant_id_for_write`."
          }
        }
      },
      "CreateFreezeRequest": {
        "type": "object",
        "description": "Create deployment freeze request",
        "required": [
          "name",
          "start_time",
          "end_time"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Freeze description"
          },
          "end_time": {
            "type": "string",
            "description": "End time (UTC, ISO 8601 format)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (NULL = applies to all environments)"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the freeze is enabled"
          },
          "name": {
            "type": "string",
            "description": "Freeze name"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date (UTC, ISO 8601 format)"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type: \"daily\", \"weekly\", \"monthly\", \"yearly\" (NULL = one-time)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from `name` when omitted."
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (NULL = applies to all solutions)"
          },
          "start_time": {
            "type": "string",
            "description": "Start time (UTC, ISO 8601 format)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (NULL = applies to all tenants)"
          }
        }
      },
      "CreateGitAuthRequest": {
        "type": "object",
        "description": "Create Git auth request",
        "required": [
          "name",
          "auth_type"
        ],
        "properties": {
          "auth_type": {
            "$ref": "#/components/schemas/GitAuthTypeDto",
            "description": "Auth type (ssh_key, https_basic, https_token)"
          },
          "name": {
            "type": "string",
            "description": "Auth name"
          },
          "password": {
            "type": [
              "string",
              "null"
            ],
            "description": "Password or token (for https auth)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "ssh_passphrase": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH passphrase (for encrypted keys)"
          },
          "ssh_private_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH private key (for ssh auth)"
          },
          "ssh_public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH public key (for ssh auth)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (required for admin users, ignored for tenant-scoped users)"
          },
          "username": {
            "type": [
              "string",
              "null"
            ],
            "description": "Username (for https auth)"
          }
        },
        "additionalProperties": false
      },
      "CreateGitStorageRequest": {
        "type": "object",
        "description": "Create Git storage request",
        "required": [
          "name",
          "path",
          "url",
          "reference"
        ],
        "properties": {
          "auth_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional Git auth ID"
          },
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path": {
            "type": "string",
            "description": "Local path for Git clone"
          },
          "reference": {
            "type": "string",
            "description": "Git reference (branch, tag, or commit)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (required for admin users, ignored for tenant-scoped users)"
          },
          "url": {
            "type": "string",
            "description": "Git repository URL"
          }
        },
        "additionalProperties": false
      },
      "CreateIdentityProviderRequest": {
        "type": "object",
        "description": "Create identity provider request",
        "required": [
          "name",
          "provider_type",
          "issuer_url",
          "client_id",
          "client_secret"
        ],
        "properties": {
          "auto_create_users": {
            "type": "boolean",
            "description": "Whether to auto-create users on first SSO login"
          },
          "client_id": {
            "type": "string",
            "description": "Client ID from the identity provider"
          },
          "client_secret": {
            "type": "string",
            "description": "Client secret from the identity provider"
          },
          "default_role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default role ID for auto-created users"
          },
          "discovery_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Custom discovery URL (optional, derived from issuer_url if not set)"
          },
          "issuer_url": {
            "type": "string",
            "description": "Issuer URL"
          },
          "name": {
            "type": "string",
            "description": "Provider name (unique)"
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (oidc, okta)"
          },
          "scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Scopes to request (defaults to [\"openid\", \"profile\", \"email\"])"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant. A tenant-scoped caller is pinned to its own tenant; only a global admin\nmay set this (omit for a global/platform-wide IdP)."
          }
        },
        "additionalProperties": false
      },
      "CreateLifecycleRequest": {
        "type": "object",
        "description": "Request to create a lifecycle",
        "required": [
          "name"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description"
          },
          "is_default": {
            "type": "boolean",
            "description": "Whether this is the default lifecycle"
          },
          "name": {
            "type": "string",
            "description": "Lifecycle name"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID to scope to (optional)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID to scope to (optional)"
          }
        }
      },
      "CreateLocalStorageRequest": {
        "type": "object",
        "description": "Create local storage request",
        "required": [
          "name",
          "path"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path": {
            "type": "string",
            "description": "File system path"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (required for admin users, ignored for tenant-scoped users)"
          }
        },
        "additionalProperties": false
      },
      "CreateOAuth2ClientRequest": {
        "type": "object",
        "required": [
          "client_name",
          "client_type",
          "redirect_uris",
          "allowed_scopes",
          "default_scopes",
          "grant_types"
        ],
        "properties": {
          "allowed_scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "client_name": {
            "type": "string"
          },
          "client_type": {
            "type": "string"
          },
          "default_scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "grant_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "is_first_party": {
            "type": "boolean"
          },
          "redirect_uris": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant this client is scoped to. `null` means system-wide.\nSystem-wide requires `is_first_party=true` (enforced by DB CHECK)."
          }
        }
      },
      "CreatePromotionRequest": {
        "type": "object",
        "description": "Request to create a promotion",
        "required": [
          "solution_id",
          "source_environment_id",
          "target_environment_id"
        ],
        "properties": {
          "failure_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FailureStrategyParam",
                "description": "Failure strategy: \"stop_on_first_failure\", \"continue_on_failure\", \"ignore_failures\"\nDefaults to StopOnFirst"
              }
            ]
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum retries per command\nDefaults to 3"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Command priority (higher = more urgent)\nDefaults to 0"
          },
          "rollback_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RollbackStrategyParam",
                "description": "Rollback strategy for the promotion deployment\nDefaults to None"
              }
            ]
          },
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          },
          "source_environment_id": {
            "type": "string",
            "description": "Source environment ID"
          },
          "target_environment_id": {
            "type": "string",
            "description": "Target environment ID"
          },
          "target_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetExecutionModeDto",
                "description": "Execution mode: \"sequential\", \"parallel\", or {\"rolling\": {\"batch_size\": N}}\nDefaults to Parallel for promotions"
              }
            ]
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (optional)"
          },
          "timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Timeout for each command in seconds\nDefaults to 300 (5 minutes)"
          }
        }
      },
      "CreateRegistrationTokenRequest": {
        "type": "object",
        "description": "Request to create a new registration token",
        "required": [
          "name"
        ],
        "properties": {
          "auto_approve": {
            "type": "boolean",
            "description": "Whether clients registered with this token are auto-approved (default: true)"
          },
          "default_environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default environment for registered clients"
          },
          "default_roles": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Default roles for registered clients"
          },
          "expected_common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Expected common name for certificate signing requests using this token.\nWhen set, the client must request a CN matching this value (case-insensitive)."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the token expires (ISO 8601 format, null = never)"
          },
          "max_uses": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum uses allowed (null = unlimited)"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name for the token"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID this token belongs to"
          }
        }
      },
      "CreateRepositoryRequest": {
        "type": "object",
        "description": "Create-repository request.",
        "required": [
          "name",
          "git_url"
        ],
        "properties": {
          "auto_sync": {
            "type": "boolean"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_auth_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional `storages_git_auth` credential id (must belong to the same tenant)."
          },
          "git_branch": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug (derived from `name` when omitted)."
          },
          "sync_direction": {
            "type": [
              "string",
              "null"
            ],
            "description": "`pull` | `push` | `bidirectional` (default `bidirectional`)."
          },
          "sync_interval_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (admin only; tenant-scoped callers are forced to their own tenant)."
          }
        }
      },
      "CreateRoleMappingRequest": {
        "type": "object",
        "description": "Create role mapping request",
        "required": [
          "external_group",
          "role_id"
        ],
        "properties": {
          "external_group": {
            "type": "string",
            "description": "External IdP group/claim value to match"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority (higher = processed first, default 0)"
          },
          "role_id": {
            "type": "string",
            "description": "Role ID to assign when matched"
          }
        },
        "additionalProperties": false
      },
      "CreateRoleRequest": {
        "type": "object",
        "description": "Create role request",
        "required": [
          "name"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role description"
          },
          "name": {
            "type": "string",
            "description": "Role name (unique)"
          },
          "permission_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Permission IDs to assign"
          }
        },
        "additionalProperties": false
      },
      "CreateRollbackRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RollbackTargetDto",
            "description": "Rollback target"
          },
          {
            "type": "object",
            "required": [
              "solution_id",
              "environment_id"
            ],
            "properties": {
              "environment_id": {
                "type": "string",
                "description": "Environment ID"
              },
              "failure_strategy": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/FailureStrategyParam",
                    "description": "Failure strategy: \"stop_on_first_failure\", \"continue_on_failure\", \"ignore_failures\"\nDefaults to StopOnFirst"
                  }
                ]
              },
              "max_retries": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int32",
                "description": "Maximum retries per command\nDefaults to 3"
              },
              "priority": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int32",
                "description": "Command priority (higher = more urgent)\nDefaults to 0"
              },
              "rollback_strategy": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/RollbackStrategyParam",
                    "description": "Rollback strategy for the rollback deployment itself\nDefaults to None"
                  }
                ]
              },
              "solution_id": {
                "type": "string",
                "description": "Solution ID"
              },
              "target_mode": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/TargetExecutionModeDto",
                    "description": "Execution mode: \"sequential\", \"parallel\", or {\"rolling\": {\"batch_size\": N}}\nDefaults to Parallel for rollbacks"
                  }
                ]
              },
              "tenant_id": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Tenant ID (optional)"
              },
              "timeout_seconds": {
                "type": [
                  "integer",
                  "null"
                ],
                "format": "int32",
                "description": "Timeout for each command in seconds\nDefaults to 300 (5 minutes)"
              },
              "use_historical_variables": {
                "type": "boolean",
                "description": "Whether to use historical variables"
              }
            }
          }
        ],
        "description": "Request to create a rollback deployment"
      },
      "CreateS3StorageRequest": {
        "type": "object",
        "description": "Create S3 storage request",
        "required": [
          "name",
          "bucket",
          "region"
        ],
        "properties": {
          "access_key_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "AWS Access Key ID (required for auth_type = static)"
          },
          "auth_type": {
            "$ref": "#/components/schemas/S3AuthTypeDto",
            "description": "Authentication type: \"static\" (default) or \"iam_role\""
          },
          "bucket": {
            "type": "string",
            "description": "S3 bucket name"
          },
          "endpoint_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional endpoint URL for S3-compatible services (MinIO, etc.)"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "External ID for cross-account AssumeRole (optional)"
          },
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path_prefix": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional path prefix within the bucket"
          },
          "region": {
            "type": "string",
            "description": "AWS region (e.g., \"us-east-1\")"
          },
          "role_arn": {
            "type": [
              "string",
              "null"
            ],
            "description": "IAM Role ARN (required for auth_type = iam_role)"
          },
          "secret_access_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "AWS Secret Access Key (required for auth_type = static)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (required for admin users, ignored for tenant-scoped users)"
          }
        },
        "additionalProperties": false
      },
      "CreateScheduleRequest": {
        "type": "object",
        "description": "Create deployment schedule request",
        "required": [
          "name",
          "scheduled_time"
        ],
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID to deploy directly (mutually exclusive with solution_id and sequence_id)"
          },
          "deployment_config": {
            "$ref": "#/components/schemas/ScheduledDeploymentConfigDto",
            "description": "Deployment configuration (targets, variables, strategies)"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Schedule description"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID for the deployment"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the schedule is enabled"
          },
          "name": {
            "type": "string",
            "description": "Schedule name"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date (UTC, ISO 8601 format)"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type: \"daily\", \"weekly\", \"monthly\", \"yearly\" (NULL = one-time)"
          },
          "scheduled_time": {
            "type": "string",
            "description": "Scheduled time (UTC, ISO 8601 format)"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID to deploy directly (mutually exclusive with solution_id and action_id)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from name when omitted."
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID to deploy (mutually exclusive with sequence_id and action_id)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (NULL = applies to all tenants)"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone name (e.g., \"America/New_York\", \"Europe/London\").\nDefaults to \"UTC\" if not provided."
          },
          "version_requirement": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version requirement (e.g., \"^1.0.0\", \">=2.0.0\")"
          }
        }
      },
      "CreateSequenceRequest": {
        "type": "object",
        "description": "Create sequence request",
        "required": [
          "name",
          "version"
        ],
        "properties": {
          "actions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ActionEntryRequest"
            },
            "description": "Optional ordered actions (JSON array of action entries)\nEach entry should have: order (number), id (string), name (string), version_requirement (string)"
          },
          "name": {
            "type": "string",
            "description": "Sequence name"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from `name` when omitted."
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional tenant owner (admin only); omitted/null = global. Tenant-scoped\ncallers are always forced to their own tenant by `resolve_tenant_id_for_write`."
          },
          "version": {
            "type": "string",
            "description": "Initial version (semantic version)"
          }
        }
      },
      "CreateSequenceVersionRequest": {
        "type": "object",
        "description": "Create sequence version request",
        "required": [
          "version"
        ],
        "properties": {
          "actions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ActionEntryRequest"
            },
            "description": "Optional ordered actions"
          },
          "version": {
            "type": "string",
            "description": "Version (semantic version)"
          }
        }
      },
      "CreateSolutionRequest": {
        "type": "object",
        "description": "Create solution request",
        "required": [
          "name",
          "version"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Solution name"
          },
          "sequences": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/SequenceEntryRequest"
            },
            "description": "Optional ordered sequences (JSON array of sequence entries)\nEach entry should have: order (number), id (string), name (string), version_requirement (string)"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explicit slug; derived from `name` when omitted."
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional tenant owner (admin only); omitted/null = global. Tenant-scoped\ncallers are always forced to their own tenant by `resolve_tenant_id_for_write`."
          },
          "version": {
            "type": "string",
            "description": "Initial version (semantic version)"
          }
        }
      },
      "CreateSolutionVersionRequest": {
        "type": "object",
        "description": "Create solution version request",
        "required": [
          "version"
        ],
        "properties": {
          "sequences": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/SequenceEntryRequest"
            },
            "description": "Optional ordered sequences"
          },
          "version": {
            "type": "string",
            "description": "Version (semantic version)"
          }
        }
      },
      "CreateSubscriptionRequest": {
        "type": "object",
        "description": "Request to create a new notification subscription.",
        "required": [
          "name",
          "channel_id"
        ],
        "properties": {
          "channel_id": {
            "type": "string",
            "format": "uuid",
            "description": "The notification channel to use"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "email_digest_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Enable email digest mode"
          },
          "email_digest_frequency": {
            "type": [
              "string",
              "null"
            ],
            "description": "Digest frequency (hourly, daily, weekly)",
            "example": "daily"
          },
          "email_recipient_override": {
            "type": [
              "string",
              "null"
            ],
            "description": "Override email recipient (for email channels)"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the subscription is enabled (defaults to true)"
          },
          "filters": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/FilterRequest"
            },
            "description": "Optional filters to apply at creation time"
          },
          "name": {
            "type": "string",
            "description": "Subscription name"
          }
        }
      },
      "CreateTagRequest": {
        "type": "object",
        "description": "Create tag request",
        "required": [
          "key",
          "value"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Tag key"
          },
          "value": {
            "type": "string",
            "description": "Tag value"
          }
        }
      },
      "CreateTargetRequest": {
        "type": "object",
        "description": "Create target request",
        "required": [
          "name",
          "mode",
          "hostname"
        ],
        "properties": {
          "hostname": {
            "type": "string",
            "description": "Hostname or IP address"
          },
          "mode": {
            "type": "string",
            "description": "Target mode (Listen or Poll)"
          },
          "name": {
            "type": "string",
            "description": "Target name"
          },
          "port": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Port number",
            "minimum": 0
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant to adopt the new target into (via the tenants_targets junction). A\ntenant-scoped caller is pinned to its own tenant; only a global admin may set this. Omit\nfor an unadopted/global target."
          }
        }
      },
      "CreateTenantRequest": {
        "type": "object",
        "description": "Create tenant request",
        "required": [
          "name"
        ],
        "properties": {
          "contact_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Contact email"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant description"
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logo URL"
          },
          "name": {
            "type": "string",
            "description": "Tenant name (unique)"
          }
        }
      },
      "CreateUserRequest": {
        "type": "object",
        "description": "Create user request (admin only)",
        "required": [
          "email",
          "username",
          "password"
        ],
        "properties": {
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional display name"
          },
          "email": {
            "type": "string",
            "description": "User email address"
          },
          "password": {
            "type": "string",
            "description": "Password - must meet complexity requirements"
          },
          "role_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Role IDs to assign"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID to associate with"
          },
          "username": {
            "type": "string",
            "description": "Username (unique)"
          }
        },
        "additionalProperties": false
      },
      "CreateVariableRequest": {
        "type": "object",
        "description": "Create scoped variable request",
        "required": [
          "name"
        ],
        "properties": {
          "certificate_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reference IDs for typed variables"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "is_prompted": {
            "type": "boolean",
            "description": "Prompted variable settings"
          },
          "name": {
            "type": "string",
            "description": "Variable name"
          },
          "prompt_control_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Control type: \"text\", \"multiline\", \"checkbox\", \"select\", \"sensitive\""
          },
          "prompt_description": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_required": {
            "type": "boolean"
          },
          "prompt_select_options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Value",
                "description": "Select options as JSON array: [{\"value\": \"a\", \"label\": \"A\"}, ...]"
              }
            ]
          },
          "scope_environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment scope (optional)"
          },
          "value": {
            "type": [
              "string",
              "null"
            ],
            "description": "Plain text value (for non-sensitive variables)"
          },
          "variable_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Variable type: \"string\", \"sensitive\", \"certificate\", \"worker_pool\""
          },
          "worker_pool_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CreateVariableSetRequest": {
        "type": "object",
        "description": "Create variable set request",
        "required": [
          "name"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "name": {
            "type": "string",
            "description": "Set name (must be unique within scope - global or per-tenant)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional tenant ID. Admin can specify for tenant-scoped sets, or omit for global.\nTenant users must omit or match their own tenant."
          }
        }
      },
      "DailyDeploymentCount": {
        "type": "object",
        "description": "Daily deployment count for trend charts",
        "required": [
          "date",
          "count",
          "succeeded",
          "failed"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Total deployments on this day"
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The date"
          },
          "failed": {
            "type": "integer",
            "format": "int64",
            "description": "Failed deployments"
          },
          "succeeded": {
            "type": "integer",
            "format": "int64",
            "description": "Successful deployments"
          }
        }
      },
      "DashboardView": {
        "type": "string",
        "description": "Dashboard sub-view (tri-view: triage / metrics / charts).",
        "enum": [
          "triage",
          "metrics",
          "charts"
        ]
      },
      "DeliveryListResponse": {
        "type": "object",
        "description": "Response for listing notification deliveries.",
        "required": [
          "deliveries",
          "total"
        ],
        "properties": {
          "deliveries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliveryResponse"
            },
            "description": "List of deliveries"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count of deliveries matching the query"
          }
        }
      },
      "DeliveryResponse": {
        "type": "object",
        "description": "Response representing a notification delivery.",
        "required": [
          "id",
          "delivery_id",
          "event_id",
          "subscription_id",
          "channel_id",
          "channel_name",
          "status",
          "destination",
          "attempts",
          "max_attempts",
          "created_at"
        ],
        "properties": {
          "attempts": {
            "type": "integer",
            "format": "int32",
            "description": "Number of delivery attempts made"
          },
          "channel_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the channel used for delivery"
          },
          "channel_name": {
            "type": "string",
            "description": "Name of the channel used for delivery"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the delivery record was created"
          },
          "dead_letter_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for dead lettering"
          },
          "dead_lettered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the delivery was moved to dead letter"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the delivery was successfully completed"
          },
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "Per-row delivery identifier (also used as the Standard Webhooks\n`webhook-id` header value when this row is dispatched to a webhook\nchannel)."
          },
          "destination": {
            "type": "string",
            "description": "Delivery destination (email, URL, etc.)"
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the event that triggered this delivery"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique delivery identifier"
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last error message if delivery failed"
          },
          "max_attempts": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of delivery attempts"
          },
          "next_retry_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the next retry will be attempted"
          },
          "queued_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the delivery was queued"
          },
          "response_latency_ms": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Response latency in milliseconds"
          },
          "response_status_code": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "HTTP response status code (for webhook deliveries)"
          },
          "status": {
            "type": "string",
            "description": "Current delivery status",
            "example": "pending"
          },
          "subscription_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the subscription this delivery is for"
          }
        }
      },
      "DeploymentConfigDto": {
        "type": "object",
        "description": "Deployment configuration DTO",
        "required": [
          "target_mode",
          "failure_strategy",
          "rollback_strategy",
          "priority",
          "timeout_seconds",
          "max_retries",
          "target_ids",
          "target_tags",
          "variables"
        ],
        "properties": {
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID"
          },
          "failure_strategy": {
            "$ref": "#/components/schemas/FailureStrategyParam",
            "description": "Failure strategy"
          },
          "max_retries": {
            "type": "integer",
            "format": "int32",
            "description": "Max retries"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority"
          },
          "rollback_strategy": {
            "$ref": "#/components/schemas/RollbackStrategyParam",
            "description": "Rollback strategy"
          },
          "target_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Target IDs"
          },
          "target_mode": {
            "type": "string",
            "description": "Target execution mode"
          },
          "target_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagFilter"
            },
            "description": "Target tags"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID"
          },
          "timeout_seconds": {
            "type": "integer",
            "format": "int32",
            "description": "Timeout in seconds"
          },
          "variables": {
            "type": "object",
            "description": "Variables",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "DeploymentDetailResponse": {
        "type": "object",
        "description": "Deployment detail response (detailed view with execution plan)",
        "required": [
          "id",
          "source_type",
          "state",
          "progress",
          "total_steps",
          "completed_steps",
          "failed_steps",
          "config",
          "created_at",
          "analysis_enabled"
        ],
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID (if source is action)"
          },
          "action_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action name (if source is action)"
          },
          "action_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action version (if source is action)"
          },
          "analysis_enabled": {
            "type": "boolean",
            "description": "Whether AI analysis is enabled for this deployment system"
          },
          "analysis_status": {
            "type": [
              "string",
              "null"
            ],
            "description": "AI analysis status (pending, processing, complete, failed, or null if no analysis needed)"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Completed timestamp"
          },
          "completed_steps": {
            "type": "integer",
            "description": "Completed steps",
            "minimum": 0
          },
          "config": {
            "$ref": "#/components/schemas/DeploymentConfigDto",
            "description": "Deployment configuration"
          },
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Duration in milliseconds (if completed)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (if tenant deployment)"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name (if tenant deployment)"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message (if failed)"
          },
          "failed_steps": {
            "type": "integer",
            "description": "Failed steps",
            "minimum": 0
          },
          "id": {
            "type": "string",
            "description": "Deployment UUID"
          },
          "plan": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ExecutionPlanDto",
                "description": "Execution plan"
              }
            ]
          },
          "progress": {
            "type": "number",
            "format": "double",
            "description": "Progress percentage (0.0 to 1.0)"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID (if source is sequence)"
          },
          "sequence_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence name (if source is sequence)"
          },
          "sequence_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence version (if source is sequence)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (if source is solution)"
          },
          "solution_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution name (if source is solution)"
          },
          "solution_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version (if source is solution)"
          },
          "source_deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this is a rollback/redeploy, references the source deployment"
          },
          "source_type": {
            "$ref": "#/components/schemas/DeploymentSourceTypeDto",
            "description": "Deployment source type"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Started timestamp"
          },
          "state": {
            "type": "string",
            "description": "Deployment state"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (if tenant deployment)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name (if tenant deployment)"
          },
          "total_steps": {
            "type": "integer",
            "description": "Total steps",
            "minimum": 0
          },
          "triggered_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "User who triggered the deployment"
          },
          "triggered_failure_handler_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this deployment triggered a failure handler, references it"
          },
          "triggered_rollback_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this deployment triggered an automatic rollback, references it"
          }
        }
      },
      "DeploymentInspectorTab": {
        "type": "string",
        "description": "Active tab in the deployment inspector panel.",
        "enum": [
          "output",
          "steps",
          "targets",
          "variables",
          "history"
        ]
      },
      "DeploymentListResponse": {
        "type": "object",
        "description": "Paginated deployments plus the faceted status counts.\n\nShaped as `Paginated<DeploymentResponse>` (same `data` + `meta`) with\n`status_counts` as a sibling field, rather than adding a facet slot to the\nshared [`crate::extractors::Paginated`] envelope that every other list\nendpoint would then carry.",
        "required": [
          "data",
          "meta",
          "status_counts"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeploymentResponse"
            },
            "description": "The deployments on this page."
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata."
          },
          "status_counts": {
            "$ref": "#/components/schemas/DeploymentStatusCounts",
            "description": "Totals per status bucket across all pages, ignoring the status filter."
          }
        }
      },
      "DeploymentPreviewResponse": {
        "type": "object",
        "description": "Deployment preview response - shows execution plan without creating deployment",
        "required": [
          "plan",
          "warnings",
          "target_summary",
          "variables",
          "source_type",
          "source_name"
        ],
        "properties": {
          "plan": {
            "$ref": "#/components/schemas/ExecutionPlanDto",
            "description": "The execution plan that would be created"
          },
          "source_name": {
            "type": "string",
            "description": "Source name"
          },
          "source_type": {
            "type": "string",
            "description": "Source type (solution, sequence, action)"
          },
          "source_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Source version"
          },
          "target_summary": {
            "$ref": "#/components/schemas/TargetSummary",
            "description": "Summary of target status"
          },
          "variables": {
            "type": "object",
            "description": "Resolved variables that will be used",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Warnings about potential issues (e.g., offline targets)"
          }
        }
      },
      "DeploymentResponse": {
        "type": "object",
        "description": "Deployment response DTO (list view)",
        "required": [
          "id",
          "source_type",
          "state",
          "progress",
          "total_steps",
          "completed_steps",
          "failed_steps",
          "created_at"
        ],
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID (if source is action)"
          },
          "action_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action name (if source is action)"
          },
          "action_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action version (if source is action)"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Completed timestamp"
          },
          "completed_steps": {
            "type": "integer",
            "description": "Completed steps",
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Duration in milliseconds (if completed)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (if tenant deployment)"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name (if tenant deployment)"
          },
          "failed_steps": {
            "type": "integer",
            "description": "Failed steps",
            "minimum": 0
          },
          "id": {
            "type": "string",
            "description": "Deployment UUID"
          },
          "progress": {
            "type": "number",
            "format": "double",
            "description": "Progress percentage (0.0 to 1.0)"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID (if source is sequence)"
          },
          "sequence_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence name (if source is sequence)"
          },
          "sequence_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence version (if source is sequence)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (if source is solution)"
          },
          "solution_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution name (if source is solution)"
          },
          "solution_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version (if source is solution)"
          },
          "source_deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this is a rollback/redeploy, references the source deployment"
          },
          "source_type": {
            "$ref": "#/components/schemas/DeploymentSourceTypeDto",
            "description": "Deployment source type"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Started timestamp"
          },
          "state": {
            "type": "string",
            "description": "Deployment state"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (if tenant deployment)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name (if tenant deployment)"
          },
          "total_steps": {
            "type": "integer",
            "description": "Total steps",
            "minimum": 0
          },
          "triggered_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "User who triggered the deployment"
          },
          "triggered_failure_handler_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this deployment triggered a failure handler, references it"
          },
          "triggered_rollback_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "If this deployment triggered an automatic rollback, references it"
          }
        }
      },
      "DeploymentSourceTypeDto": {
        "type": "string",
        "description": "Deployment source type for API responses",
        "enum": [
          "solution",
          "sequence",
          "action"
        ]
      },
      "DeploymentStateBreakdown": {
        "type": "object",
        "description": "Breakdown of deployments by state",
        "required": [
          "pending",
          "running",
          "succeeded",
          "failed",
          "cancelled"
        ],
        "properties": {
          "cancelled": {
            "type": "integer",
            "format": "int64",
            "description": "Cancelled deployments"
          },
          "failed": {
            "type": "integer",
            "format": "int64",
            "description": "Failed deployments"
          },
          "pending": {
            "type": "integer",
            "format": "int64",
            "description": "Deployments waiting to start"
          },
          "rolled_back": {
            "type": "integer",
            "format": "int64",
            "description": "Deployments that have been rolled back"
          },
          "rolling_back": {
            "type": "integer",
            "format": "int64",
            "description": "Deployments currently rolling back"
          },
          "running": {
            "type": "integer",
            "format": "int64",
            "description": "Currently running deployments"
          },
          "succeeded": {
            "type": "integer",
            "format": "int64",
            "description": "Successfully completed deployments"
          }
        }
      },
      "DeploymentStatistics": {
        "type": "object",
        "description": "Deployment statistics with trends",
        "required": [
          "total",
          "by_state",
          "success_rate",
          "deployment_trend"
        ],
        "properties": {
          "avg_duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Average deployment duration in milliseconds"
          },
          "by_state": {
            "$ref": "#/components/schemas/DeploymentStateBreakdown",
            "description": "Breakdown by deployment state"
          },
          "deployment_trend": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DailyDeploymentCount"
            },
            "description": "Daily deployment counts for trend chart"
          },
          "success_rate": {
            "type": "number",
            "format": "double",
            "description": "Success rate as a percentage (0.0 to 100.0)"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of deployments in the period"
          }
        }
      },
      "DeploymentStatusCounts": {
        "type": "object",
        "description": "Deployment counts per status bucket, for the list filter chips.\n\nThese respect every active filter EXCEPT the status filter itself, so the\nchips keep showing the size of the set each one would select. Counting with\nthe status filter applied would render the selected chip's own total and\nzero for all the others.",
        "required": [
          "all",
          "running",
          "failed",
          "succeeded",
          "other"
        ],
        "properties": {
          "all": {
            "type": "integer",
            "format": "int64",
            "description": "Total matching the non-status filters — the \"All\" chip."
          },
          "failed": {
            "type": "integer",
            "format": "int64"
          },
          "other": {
            "type": "integer",
            "format": "int64"
          },
          "running": {
            "type": "integer",
            "format": "int64"
          },
          "succeeded": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "DeploymentsBucketFilter": {
        "type": "string",
        "description": "Deployment list status bucket filter.",
        "enum": [
          "all",
          "running",
          "failed",
          "succeeded",
          "other"
        ]
      },
      "DeploymentsDefaultView": {
        "type": "string",
        "description": "Which rendering the deployments page opens on.\n\nSeparate from [`ListViewMode`]: that is the table/cards pair shared by every\nentity list, and `Inspector` has no meaning on those pages.",
        "enum": [
          "inspector",
          "table",
          "cards"
        ]
      },
      "DeregisterThoraxInstanceRequest": {
        "type": "object",
        "description": "Deregister thorax instance request",
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional reason for deregistration"
          }
        }
      },
      "DetachTagsRequest": {
        "type": "object",
        "description": "Detach tags request",
        "required": [
          "tag_ids"
        ],
        "properties": {
          "tag_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of tag IDs to detach"
          }
        }
      },
      "DiscoverEndpointsRequest": {
        "type": "object",
        "description": "OIDC discovery request",
        "required": [
          "discovery_url"
        ],
        "properties": {
          "discovery_url": {
            "type": "string",
            "description": "Discovery URL (or issuer URL to derive from)"
          }
        },
        "additionalProperties": false
      },
      "DiscoverEndpointsResponse": {
        "type": "object",
        "description": "OIDC discovery response",
        "required": [
          "success"
        ],
        "properties": {
          "endpoints": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/IdentityProviderEndpoints",
                "description": "Discovered endpoints"
              }
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if discovery failed"
          },
          "success": {
            "type": "boolean",
            "description": "Whether discovery was successful"
          }
        }
      },
      "DryRunResponse": {
        "type": "object",
        "description": "Dry-run result - validates deployment configuration without executing",
        "required": [
          "valid",
          "errors",
          "warnings"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Validation errors"
          },
          "plan": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ExecutionPlanDto",
                "description": "The execution plan (if valid)"
              }
            ]
          },
          "target_summary": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetSummary",
                "description": "Summary of target status"
              }
            ]
          },
          "valid": {
            "type": "boolean",
            "description": "Whether the configuration is valid"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Warnings about potential issues"
          }
        }
      },
      "EnableWireGuardRequest": {
        "type": "object",
        "description": "Request to enable WireGuard for an agent: register its public key and receive\nan allocated overlay IP.",
        "required": [
          "public_key"
        ],
        "properties": {
          "public_key": {
            "type": "string",
            "description": "The agent's WireGuard public key (base64)."
          },
          "signing_public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "The agent's Ed25519 signing public key (base64), used for relay\nchallenge-response auth. Optional."
          }
        }
      },
      "EnableWireGuardResponse": {
        "type": "object",
        "description": "Result of enabling WireGuard for an agent.",
        "required": [
          "overlay_ip"
        ],
        "properties": {
          "overlay_ip": {
            "type": "string",
            "description": "The overlay IP allocated to the agent, in CIDR notation (e.g. \"10.99.0.5/32\")."
          }
        }
      },
      "EnabledProviderResponse": {
        "type": "object",
        "description": "Enabled provider info for login page",
        "required": [
          "id",
          "name",
          "provider_type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Provider ID"
          },
          "name": {
            "type": "string",
            "description": "Display name"
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (always \"oidc\")"
          }
        }
      },
      "EncryptionStatsResponse": {
        "type": "object",
        "description": "Response for encryption statistics endpoint.",
        "required": [
          "tables",
          "total_records",
          "encrypted_records",
          "overall_percentage"
        ],
        "properties": {
          "encrypted_records": {
            "type": "integer",
            "format": "int64",
            "description": "Total encrypted records across all tables"
          },
          "overall_percentage": {
            "type": "number",
            "format": "double",
            "description": "Overall encryption percentage"
          },
          "tables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TableEncryptionStats"
            },
            "description": "Statistics per table"
          },
          "total_records": {
            "type": "integer",
            "format": "int64",
            "description": "Total records across all tables"
          }
        }
      },
      "EnvironmentResponse": {
        "type": "object",
        "description": "Environment response DTO",
        "required": [
          "id",
          "name",
          "sort_order",
          "slug",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment description"
          },
          "id": {
            "type": "string",
            "description": "Environment ID"
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Environment name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "sort_order": {
            "type": "integer",
            "format": "int32",
            "description": "Sort order (for progression)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "EnvironmentStateAtTimeResponse": {
        "type": "object",
        "description": "Response for state at time",
        "required": [
          "timestamp_queried"
        ],
        "properties": {
          "state": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/EnvironmentStateHistoryResponse"
              }
            ]
          },
          "timestamp_queried": {
            "type": "string"
          }
        }
      },
      "EnvironmentStateHistoryResponse": {
        "type": "object",
        "description": "Environment state history response",
        "required": [
          "id",
          "deployment_id",
          "state_type",
          "valid_from"
        ],
        "properties": {
          "deployment_id": {
            "type": "string",
            "description": "Deployment ID"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (null if the environment definition has since been deleted)"
          },
          "id": {
            "type": "string",
            "description": "History entry ID"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (null if the solution definition has since been deleted)"
          },
          "solution_version_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version ID"
          },
          "state_type": {
            "type": "string",
            "description": "State type (deployed, rolled_back, promoted)"
          },
          "valid_from": {
            "type": "string",
            "description": "When this state became valid"
          },
          "valid_until": {
            "type": [
              "string",
              "null"
            ],
            "description": "When this state was superseded (null if current)"
          }
        }
      },
      "EnvironmentStateResponse": {
        "type": "object",
        "description": "Environment state response",
        "required": [
          "id",
          "deployment_id",
          "deployed_at"
        ],
        "properties": {
          "deployed_at": {
            "type": "string",
            "description": "When this state was deployed"
          },
          "deployed_by_user_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "User who deployed"
          },
          "deployment_id": {
            "type": "string",
            "description": "Deployment ID that created this state"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (null if the environment definition has since been deleted)"
          },
          "id": {
            "type": "string",
            "description": "State ID"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (null if the solution definition has since been deleted)"
          },
          "solution_version_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version ID"
          }
        }
      },
      "EnvironmentTargetResponse": {
        "type": "object",
        "description": "Environment-Target association response",
        "required": [
          "id",
          "environment_id",
          "target_id",
          "priority",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "When created"
          },
          "environment_id": {
            "type": "string",
            "description": "Environment ID"
          },
          "id": {
            "type": "string",
            "description": "Association ID"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority"
          },
          "target_id": {
            "type": "string",
            "description": "Target ID"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (if multi-tenant)"
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "description": "Error body details",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Error code (e.g., \"NOT_FOUND\", \"VALIDATION_ERROR\")"
          },
          "details": {
            "description": "Optional additional details"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Error response body",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorBody"
          }
        }
      },
      "EventListResponse": {
        "type": "object",
        "description": "Response for listing notification events.",
        "required": [
          "events",
          "total"
        ],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventResponse"
            },
            "description": "List of events"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count of events matching the query"
          }
        }
      },
      "EventResponse": {
        "type": "object",
        "description": "Response representing a notification event.",
        "required": [
          "id",
          "event_type",
          "event_group",
          "severity",
          "source_type",
          "title",
          "context",
          "occurred_at",
          "created_at"
        ],
        "properties": {
          "context": {
            "description": "Additional context data"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the event was recorded"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Environment ID if scoped to an environment"
          },
          "event_group": {
            "type": "string",
            "description": "Event group (e.g., deployment, target, certificate)",
            "example": "deployment"
          },
          "event_type": {
            "type": "string",
            "description": "Type of event (e.g., deployment_started, target_offline)",
            "example": "deployment_started"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique event identifier"
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional detailed message"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the event occurred"
          },
          "severity": {
            "type": "string",
            "description": "Event severity (info, warning, error, critical)",
            "example": "info"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Solution ID if scoped to a solution"
          },
          "source_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "ID of the source entity"
          },
          "source_type": {
            "type": "string",
            "description": "Type of source that generated the event",
            "example": "deployment"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Tenant ID if scoped to a tenant"
          },
          "title": {
            "type": "string",
            "description": "Event title"
          },
          "triggered_by_user_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "User ID that triggered the event (if applicable)"
          }
        }
      },
      "ExecutionPlanDto": {
        "type": "object",
        "description": "Execution plan DTO",
        "required": [
          "target_count",
          "steps",
          "resolved_variables",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name"
          },
          "resolved_variables": {
            "type": "object",
            "description": "Resolved tenant variables",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExecutionStepDto"
            },
            "description": "Execution steps"
          },
          "target_count": {
            "type": "integer",
            "description": "Total number of targets",
            "minimum": 0
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name"
          }
        }
      },
      "ExecutionStepDto": {
        "type": "object",
        "description": "Execution step DTO",
        "required": [
          "id",
          "target_id",
          "target_name",
          "sequence_id",
          "sequence_name",
          "sequence_order",
          "action_id",
          "action_name",
          "action_order",
          "state",
          "retry_count"
        ],
        "properties": {
          "action_id": {
            "type": "string",
            "description": "Action ID"
          },
          "action_name": {
            "type": "string",
            "description": "Action name"
          },
          "action_order": {
            "type": "integer",
            "format": "int32",
            "description": "Action order",
            "minimum": 0
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Completed timestamp"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Duration in milliseconds"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message"
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Exit code"
          },
          "id": {
            "type": "string",
            "description": "Step UUID"
          },
          "retry_count": {
            "type": "integer",
            "format": "int32",
            "description": "Retry count"
          },
          "sequence_id": {
            "type": "string",
            "description": "Sequence ID"
          },
          "sequence_name": {
            "type": "string",
            "description": "Sequence name"
          },
          "sequence_order": {
            "type": "integer",
            "format": "int32",
            "description": "Sequence order",
            "minimum": 0
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Started timestamp"
          },
          "state": {
            "type": "string",
            "description": "Step state"
          },
          "target_id": {
            "type": "string",
            "description": "Target ID"
          },
          "target_name": {
            "type": "string",
            "description": "Target name"
          }
        }
      },
      "ExpiringCertificateResponse": {
        "type": "object",
        "description": "Response for an expiring certificate",
        "required": [
          "registration_id",
          "client_name",
          "thumbprint",
          "status",
          "expires_at",
          "days_remaining",
          "severity"
        ],
        "properties": {
          "client_name": {
            "type": "string",
            "description": "Client name"
          },
          "days_remaining": {
            "type": "integer",
            "format": "int64",
            "description": "Days until expiration (negative if already expired)"
          },
          "expires_at": {
            "type": "string",
            "description": "When the certificate expires (ISO 8601 format)"
          },
          "registration_id": {
            "type": "string",
            "description": "Registration ID (UUID)"
          },
          "severity": {
            "$ref": "#/components/schemas/CertificateSeverity",
            "description": "Severity level"
          },
          "status": {
            "type": "string",
            "description": "Registration status (pending, approved, revoked)"
          },
          "thumbprint": {
            "type": "string",
            "description": "Certificate thumbprint (SHA-256)"
          }
        }
      },
      "ExpiringCertificatesResponse": {
        "type": "object",
        "description": "Response containing list of expiring certificates",
        "required": [
          "certificates",
          "total",
          "warning_count",
          "critical_count",
          "expired_count"
        ],
        "properties": {
          "certificates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExpiringCertificateResponse"
            },
            "description": "List of expiring certificates"
          },
          "critical_count": {
            "type": "integer",
            "description": "Count of certificates in critical state (< 7 days)",
            "minimum": 0
          },
          "expired_count": {
            "type": "integer",
            "description": "Count of already expired certificates",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "description": "Total count of expiring certificates",
            "minimum": 0
          },
          "warning_count": {
            "type": "integer",
            "description": "Count of certificates in warning state (7-30 days)",
            "minimum": 0
          }
        }
      },
      "ExportSummary": {
        "type": "object",
        "description": "Counts of exported entities by type (only types the caller could read appear > 0).",
        "required": [
          "environments",
          "tags",
          "variables",
          "actions",
          "sequences",
          "solutions",
          "freezes",
          "variable_sets",
          "schedules",
          "promotion_lifecycles",
          "notification_channels"
        ],
        "properties": {
          "actions": {
            "type": "integer",
            "minimum": 0
          },
          "environments": {
            "type": "integer",
            "minimum": 0
          },
          "freezes": {
            "type": "integer",
            "minimum": 0
          },
          "notification_channels": {
            "type": "integer",
            "minimum": 0
          },
          "promotion_lifecycles": {
            "type": "integer",
            "minimum": 0
          },
          "schedules": {
            "type": "integer",
            "minimum": 0
          },
          "sequences": {
            "type": "integer",
            "minimum": 0
          },
          "solutions": {
            "type": "integer",
            "minimum": 0
          },
          "tags": {
            "type": "integer",
            "minimum": 0
          },
          "variable_sets": {
            "type": "integer",
            "minimum": 0
          },
          "variables": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "ExternalIdentityResponse": {
        "type": "object",
        "description": "External identity link response",
        "required": [
          "provider_id",
          "provider_name"
        ],
        "properties": {
          "external_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "External email from provider"
          },
          "external_username": {
            "type": [
              "string",
              "null"
            ],
            "description": "External username from provider"
          },
          "last_login_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last login via this provider"
          },
          "provider_id": {
            "type": "string",
            "description": "Identity Provider ID"
          },
          "provider_name": {
            "type": "string",
            "description": "Provider name"
          }
        }
      },
      "FailureStrategyParam": {
        "type": "string",
        "description": "Failure strategy for deployments.",
        "enum": [
          "stop_on_first_failure",
          "continue_on_failure",
          "ignore_failures"
        ]
      },
      "FilterInput": {
        "type": "object",
        "description": "One filter in a subscription's filter set, as sent in the body of a\nsubscription create/update. Mirrors [`AddFilterRequest`] but is a plain\nelement type (no standalone endpoint semantics).",
        "required": [
          "filter_type",
          "filter_values"
        ],
        "properties": {
          "filter_type": {
            "type": "string",
            "description": "Type of filter (event_type, event_group, severity, environment, solution, tenant)",
            "example": "event_type"
          },
          "filter_values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values to filter on"
          }
        }
      },
      "FilterRequest": {
        "type": "object",
        "description": "Request to add a filter during subscription creation.",
        "required": [
          "filter_type",
          "filter_values"
        ],
        "properties": {
          "filter_type": {
            "type": "string",
            "description": "Type of filter (event_type, event_group, severity, environment, solution, tenant)",
            "example": "event_type"
          },
          "filter_values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values to filter on (at least one required)"
          }
        }
      },
      "FilterResponse": {
        "type": "object",
        "description": "Filter response.",
        "required": [
          "id",
          "filter_type",
          "filter_values"
        ],
        "properties": {
          "filter_type": {
            "type": "string",
            "description": "Type of filter (event_type, event_group, severity, environment, solution, tenant)",
            "example": "event_type"
          },
          "filter_values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values to filter on"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Filter ID"
          }
        }
      },
      "FreezeCheckResponse": {
        "type": "object",
        "description": "Freeze check response",
        "required": [
          "is_frozen",
          "active_freezes",
          "can_override"
        ],
        "properties": {
          "active_freezes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActiveFreezeSummary"
            },
            "description": "Active freezes blocking the deployment"
          },
          "can_override": {
            "type": "boolean",
            "description": "Whether user can override (requires admin role)"
          },
          "is_frozen": {
            "type": "boolean",
            "description": "Whether deployment is blocked by a freeze"
          }
        }
      },
      "FreezeListResponse": {
        "type": "object",
        "description": "Paginated freeze list response",
        "required": [
          "items",
          "total",
          "page",
          "per_page"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FreezeResponse"
            },
            "description": "List of freezes"
          },
          "page": {
            "type": "integer",
            "format": "int64",
            "description": "Current page"
          },
          "per_page": {
            "type": "integer",
            "format": "int64",
            "description": "Items per page"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count"
          }
        }
      },
      "FreezeResponse": {
        "type": "object",
        "description": "Deployment freeze response DTO",
        "required": [
          "id",
          "name",
          "slug",
          "start_time",
          "end_time",
          "is_enabled",
          "is_active",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "created_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Created by user ID"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Freeze description"
          },
          "end_time": {
            "type": "string",
            "description": "End time (UTC)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID (if scoped to environment)"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name (if scoped to environment)"
          },
          "id": {
            "type": "string",
            "description": "Freeze ID"
          },
          "is_active": {
            "type": "boolean",
            "description": "Whether the freeze is currently active"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the freeze is enabled"
          },
          "name": {
            "type": "string",
            "description": "Freeze name"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (if scoped to solution)"
          },
          "solution_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution name (if scoped to solution)"
          },
          "start_time": {
            "type": "string",
            "description": "Start time (UTC)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (if scoped to tenant)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name (if scoped to tenant)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "GitAuthResponse": {
        "type": "object",
        "description": "Git auth response (sensitive fields redacted)",
        "required": [
          "id",
          "name",
          "slug",
          "auth_type",
          "has_ssh_private_key",
          "has_ssh_public_key",
          "has_ssh_passphrase",
          "has_username",
          "has_password",
          "created_at"
        ],
        "properties": {
          "auth_type": {
            "$ref": "#/components/schemas/GitAuthTypeDto",
            "description": "Auth type (ssh_key, https_basic, https_token)"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "has_password": {
            "type": "boolean",
            "description": "Whether password is set"
          },
          "has_ssh_passphrase": {
            "type": "boolean",
            "description": "Whether SSH passphrase is set"
          },
          "has_ssh_private_key": {
            "type": "boolean",
            "description": "Whether SSH private key is set"
          },
          "has_ssh_public_key": {
            "type": "boolean",
            "description": "Whether SSH public key is set"
          },
          "has_username": {
            "type": "boolean",
            "description": "Whether username is set"
          },
          "id": {
            "type": "string",
            "description": "Auth ID"
          },
          "name": {
            "type": "string",
            "description": "Auth name"
          },
          "slug": {
            "type": "string",
            "description": "Per-tenant-unique identity slug"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "GitAuthTypeDto": {
        "type": "string",
        "description": "Git authentication type for API requests/responses",
        "enum": [
          "ssh_key",
          "https_basic",
          "https_token"
        ]
      },
      "GitStorageResponse": {
        "type": "object",
        "description": "Git storage response",
        "required": [
          "id",
          "name",
          "slug",
          "path",
          "url",
          "reference",
          "created_at"
        ],
        "properties": {
          "auth_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional Git auth ID"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Storage ID"
          },
          "last_fetched": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last fetch timestamp"
          },
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path": {
            "type": "string",
            "description": "Local path for Git clone"
          },
          "reference": {
            "type": "string",
            "description": "Git reference (branch, tag, or commit)"
          },
          "slug": {
            "type": "string",
            "description": "Per-tenant-unique identity slug"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant ID"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "url": {
            "type": "string",
            "description": "Git repository URL"
          }
        }
      },
      "GlobalStatisticsResponse": {
        "type": "object",
        "description": "Global statistics response (admin only)",
        "required": [
          "deployment_stats",
          "tenant_count",
          "top_tenants",
          "resource_counts",
          "recent_activity"
        ],
        "properties": {
          "deployment_stats": {
            "$ref": "#/components/schemas/DeploymentStatistics",
            "description": "Deployment statistics across all tenants"
          },
          "recent_activity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActivityEntry"
            },
            "description": "Recent global activity (admin-visible events)"
          },
          "resource_counts": {
            "$ref": "#/components/schemas/ResourceCounts",
            "description": "Global resource counts"
          },
          "tenant_count": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of tenants"
          },
          "top_tenants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TopTenantEntry"
            },
            "description": "Top tenants by deployment activity"
          }
        }
      },
      "GrpcHealthResponse": {
        "type": "object",
        "description": "Response for gRPC service health check.",
        "required": [
          "orchestration"
        ],
        "properties": {
          "orchestration": {
            "$ref": "#/components/schemas/GrpcServiceHealth",
            "description": "Health status of the orchestration gRPC service (Thorax)"
          }
        }
      },
      "GrpcServiceHealth": {
        "type": "object",
        "description": "Health status of a single gRPC service.",
        "required": [
          "status",
          "circuit_state",
          "failure_count",
          "success_count"
        ],
        "properties": {
          "circuit_state": {
            "type": "string",
            "description": "Circuit breaker state. Authenticated callers: \"closed\", \"half_open\", or\n\"open\". Empty (\"\") for anonymous callers."
          },
          "failure_count": {
            "type": "integer",
            "format": "int32",
            "description": "Number of consecutive failures (0 for anonymous callers).",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "description": "Overall health status: \"healthy\", \"degraded\", or \"unhealthy\". Disclosed\nto every caller (monitors/load balancers must detect an outage without\ncredentials); only the breaker internals below are gated."
          },
          "success_count": {
            "type": "integer",
            "format": "int32",
            "description": "Number of consecutive successes during recovery (0 for anonymous callers).",
            "minimum": 0
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "description": "Health check response\n\nReturns minimal status information only. Version, component, and build\ndetails are intentionally omitted to avoid leaking deployment information\nto unauthenticated callers.",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "Service status: \"ok\" or \"unavailable\""
          }
        }
      },
      "HistoricalDeploymentLogEntry": {
        "type": "object",
        "description": "Historical deployment log entry DTO (includes stdout/stderr)",
        "required": [
          "id",
          "timestamp",
          "level",
          "event_type",
          "message"
        ],
        "properties": {
          "analysis": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AnalysisResult",
                "description": "AI analysis result (summary, cause, remediation) for failed commands"
              }
            ]
          },
          "event_type": {
            "type": "string",
            "description": "Event type (log, step_update, state_change, progress)"
          },
          "id": {
            "type": "string",
            "description": "Log ID"
          },
          "level": {
            "type": "string",
            "description": "Log level (info, warn, error, debug)"
          },
          "message": {
            "type": "string",
            "description": "Log message"
          },
          "metadata": {
            "description": "Additional structured metadata"
          },
          "stderr": {
            "type": [
              "string",
              "null"
            ],
            "description": "Command stderr output"
          },
          "stdout": {
            "type": [
              "string",
              "null"
            ],
            "description": "Command stdout output"
          },
          "step_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Step ID (if associated with a step)"
          },
          "target_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target ID (if associated with a target)"
          },
          "target_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target name (if associated with a target)"
          },
          "timestamp": {
            "type": "string",
            "description": "Timestamp"
          }
        }
      },
      "IdentityProviderDetailResponse": {
        "type": "object",
        "description": "Detailed identity provider response",
        "required": [
          "id",
          "name",
          "provider_type",
          "issuer_url",
          "client_id",
          "endpoints",
          "scopes",
          "is_enabled",
          "auto_create_users",
          "user_count",
          "created_at"
        ],
        "properties": {
          "auto_create_users": {
            "type": "boolean",
            "description": "Whether to auto-create users on first login"
          },
          "client_id": {
            "type": "string",
            "description": "Client ID"
          },
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "default_role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default role ID for auto-created users"
          },
          "default_role_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default role name for auto-created users"
          },
          "discovery_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "OIDC discovery URL"
          },
          "endpoints": {
            "$ref": "#/components/schemas/IdentityProviderEndpoints",
            "description": "Discovered/configured endpoints"
          },
          "id": {
            "type": "string",
            "description": "Provider ID"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the provider is enabled"
          },
          "issuer_url": {
            "type": "string",
            "description": "Issuer URL"
          },
          "name": {
            "type": "string",
            "description": "Provider name"
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (oidc, okta)"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Configured scopes"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated timestamp"
          },
          "user_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of users linked to this provider"
          }
        }
      },
      "IdentityProviderEndpoints": {
        "type": "object",
        "description": "Identity provider endpoints",
        "properties": {
          "authorization_endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "Authorization endpoint"
          },
          "jwks_uri": {
            "type": [
              "string",
              "null"
            ],
            "description": "JWKS URI"
          },
          "token_endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "Token endpoint"
          },
          "userinfo_endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "Userinfo endpoint"
          }
        }
      },
      "IdentityProviderListResponse": {
        "type": "object",
        "description": "Identity provider list response",
        "required": [
          "id",
          "name",
          "provider_type",
          "issuer_url",
          "is_enabled",
          "user_count",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "id": {
            "type": "string",
            "description": "Provider ID"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the provider is enabled"
          },
          "issuer_url": {
            "type": "string",
            "description": "Issuer URL"
          },
          "name": {
            "type": "string",
            "description": "Provider name"
          },
          "provider_type": {
            "type": "string",
            "description": "Provider type (oidc, okta)"
          },
          "user_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of users linked to this provider"
          }
        }
      },
      "ImportRequest": {
        "type": "object",
        "description": "Import request: the same multi-file shape the export endpoint returns.",
        "required": [
          "files"
        ],
        "properties": {
          "conflict_strategy": {
            "$ref": "#/components/schemas/ConflictStrategyDto",
            "description": "How to handle entities that already exist in scope."
          },
          "dry_run": {
            "type": "boolean",
            "description": "Validate + count only; persist nothing."
          },
          "files": {
            "type": "object",
            "description": "Repo-relative path → document content (Nickel/JSON), as produced by export.",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "ImportResponse": {
        "type": "object",
        "description": "Import result: per-run tallies + the files whose type isn't yet importable.",
        "required": [
          "dry_run",
          "created",
          "updated",
          "skipped",
          "unsupported",
          "ignored_immutable"
        ],
        "properties": {
          "created": {
            "type": "integer",
            "minimum": 0
          },
          "dry_run": {
            "type": "boolean"
          },
          "ignored_immutable": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`<kind>/<slug>@<version>` for already-published versions edited in place — IGNORED because\nversions are immutable (bump the version to apply). Surfaced so the change isn't silently lost."
          },
          "skipped": {
            "type": "integer",
            "minimum": 0
          },
          "unsupported": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Files whose path prefix is not a supported entity type (left untouched)."
          },
          "updated": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "IntegrityCheckResponse": {
        "type": "object",
        "description": "Response for chain integrity verification",
        "required": [
          "is_valid",
          "entries_checked",
          "checked_at"
        ],
        "properties": {
          "broken_at_sequence": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "entries_checked": {
            "type": "integer",
            "format": "int64"
          },
          "is_valid": {
            "type": "boolean"
          }
        }
      },
      "JwtClaims": {
        "type": "object",
        "description": "JWT claims structure",
        "required": [
          "sub",
          "email",
          "username",
          "roles",
          "iss",
          "aud",
          "exp",
          "iat",
          "nbf",
          "jti"
        ],
        "properties": {
          "api_key_scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "API key scopes (only set for API key auth, `None` for JWT-based auth).\nEach scope is `resource:action` (e.g., `\"deployments:create\"`).\nThe wildcard `\"*\"` grants unrestricted access."
          },
          "aud": {
            "type": "string",
            "description": "Token audience"
          },
          "email": {
            "type": "string",
            "description": "User email"
          },
          "exp": {
            "type": "integer",
            "format": "int64",
            "description": "Expiration time (Unix timestamp)"
          },
          "iat": {
            "type": "integer",
            "format": "int64",
            "description": "Issued at (Unix timestamp)"
          },
          "iss": {
            "type": "string",
            "description": "Token issuer"
          },
          "jti": {
            "type": "string",
            "description": "JWT ID (unique identifier)"
          },
          "nbf": {
            "type": "integer",
            "format": "int64",
            "description": "Not before (Unix timestamp)"
          },
          "pending_2fa": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether this is a pending 2FA token (short-lived, cannot access resources)"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "User roles"
          },
          "session_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Session ID for session tracking"
          },
          "sub": {
            "type": "string",
            "description": "Subject (user ID as string for JWT compatibility)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Tenant ID (optional, for multi-tenant context)"
          },
          "username": {
            "type": "string",
            "description": "Username"
          }
        }
      },
      "KeyRotationStatusResponse": {
        "type": "object",
        "description": "Current key rotation status for an agent.",
        "required": [
          "rotation_in_progress"
        ],
        "properties": {
          "current_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current active public key (base64-encoded)."
          },
          "overlap_expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the overlap window expires (if rotation in progress)."
          },
          "pending_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pending public key during rotation (base64-encoded)."
          },
          "rotation_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Rotation ID if rotation is in progress."
          },
          "rotation_in_progress": {
            "type": "boolean",
            "description": "Whether a key rotation is currently in progress."
          }
        }
      },
      "LifecycleResponse": {
        "type": "object",
        "description": "Lifecycle response",
        "required": [
          "id",
          "name",
          "slug",
          "is_default",
          "rules"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description"
          },
          "id": {
            "type": "string",
            "description": "Lifecycle ID"
          },
          "is_default": {
            "type": "boolean",
            "description": "Whether this is default"
          },
          "name": {
            "type": "string",
            "description": "Name"
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LifecycleRuleResponse"
            },
            "description": "Rules in this lifecycle"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)."
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID"
          }
        }
      },
      "LifecycleRuleResponse": {
        "type": "object",
        "description": "Lifecycle rule response",
        "required": [
          "id",
          "source_environment_id",
          "target_environment_id",
          "requires_successful_deployment",
          "requires_approval",
          "allow_skip"
        ],
        "properties": {
          "allow_skip": {
            "type": "boolean",
            "description": "Whether skipping is allowed"
          },
          "id": {
            "type": "string",
            "description": "Rule ID"
          },
          "minimum_soak_time_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Minimum soak time in minutes"
          },
          "requires_approval": {
            "type": "boolean",
            "description": "Whether approval is required"
          },
          "requires_successful_deployment": {
            "type": "boolean",
            "description": "Whether successful deployment is required"
          },
          "source_environment_id": {
            "type": "string",
            "description": "Source environment ID"
          },
          "target_environment_id": {
            "type": "string",
            "description": "Target environment ID"
          }
        }
      },
      "LinkCertificatesRequest": {
        "type": "object",
        "description": "Link certificates to target request",
        "required": [
          "certificate_ids"
        ],
        "properties": {
          "certificate_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of certificate IDs to link"
          }
        }
      },
      "LinkVariableSetRequest": {
        "type": "object",
        "description": "Link variable set to solution request",
        "required": [
          "variable_set_id"
        ],
        "properties": {
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Priority for variable resolution (higher = more specific)"
          },
          "variable_set_id": {
            "type": "string",
            "description": "Variable set ID to link"
          }
        }
      },
      "ListPageSize": {
        "type": "integer",
        "format": "int32",
        "description": "List page size; one of 10, 20, 50, 100.",
        "enum": [
          10,
          20,
          50,
          100
        ]
      },
      "ListViewMode": {
        "type": "string",
        "description": "Renders an entity list as a table or as cards.",
        "enum": [
          "table",
          "cards"
        ]
      },
      "LocalStorageResponse": {
        "type": "object",
        "description": "Local storage response",
        "required": [
          "id",
          "name",
          "slug",
          "path",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Storage ID"
          },
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path": {
            "type": "string",
            "description": "File system path"
          },
          "slug": {
            "type": "string",
            "description": "Per-tenant-unique identity slug"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant ID"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "LoginRequest": {
        "type": "object",
        "description": "Login request with email and password",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "description": "User email address"
          },
          "password": {
            "type": "string",
            "description": "User password"
          }
        },
        "additionalProperties": false
      },
      "LogoutResponse": {
        "type": "object",
        "description": "Logout response",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Success message"
          }
        }
      },
      "MostAffected": {
        "type": "object",
        "description": "A solution ranked by how many recurring failures it experienced.",
        "required": [
          "occurrence_count",
          "pattern_count"
        ],
        "properties": {
          "occurrence_count": {
            "type": "integer",
            "format": "int64"
          },
          "pattern_count": {
            "type": "integer",
            "format": "int64"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "NatType": {
        "type": "string",
        "description": "NAT type classification for connection strategy selection.",
        "enum": [
          "open_internet",
          "full_cone",
          "restricted_cone",
          "port_restricted_cone",
          "symmetric",
          "unknown"
        ]
      },
      "NatTypeDistribution": {
        "type": "object",
        "description": "Distribution of NAT types across agents.",
        "required": [
          "open_internet",
          "full_cone",
          "restricted_cone",
          "port_restricted_cone",
          "symmetric",
          "unknown"
        ],
        "properties": {
          "full_cone": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "open_internet": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "port_restricted_cone": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "restricted_cone": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "symmetric": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "unknown": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          }
        }
      },
      "OAuth2ClientCreatedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/OAuth2ClientResponse"
          },
          {
            "type": "object",
            "required": [
              "client_secret"
            ],
            "properties": {
              "client_secret": {
                "type": "string",
                "description": "Plaintext client secret. Shown only once at creation time."
              }
            }
          }
        ]
      },
      "OAuth2ClientResponse": {
        "type": "object",
        "required": [
          "id",
          "client_id",
          "client_name",
          "client_type",
          "redirect_uris",
          "allowed_scopes",
          "default_scopes",
          "grant_types",
          "is_active",
          "is_first_party",
          "created_at"
        ],
        "properties": {
          "allowed_scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "client_id": {
            "type": "string"
          },
          "client_name": {
            "type": "string"
          },
          "client_type": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "default_scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "grant_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "id": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_first_party": {
            "type": "boolean"
          },
          "redirect_uris": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "OAuth2SecretRotatedResponse": {
        "type": "object",
        "required": [
          "client_id",
          "client_secret"
        ],
        "properties": {
          "client_id": {
            "type": "string"
          },
          "client_secret": {
            "type": "string"
          }
        }
      },
      "OccurrenceResponse": {
        "type": "object",
        "description": "A single failure attributed to a pattern.",
        "required": [
          "id",
          "pattern_id",
          "command_result_id",
          "target_id",
          "occurred_at"
        ],
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "command_result_id": {
            "type": "string",
            "format": "uuid"
          },
          "deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time"
          },
          "pattern_id": {
            "type": "string",
            "format": "uuid"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "target_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "OidcLoginRequest": {
        "type": "object",
        "description": "Request to initiate OIDC login",
        "properties": {
          "redirect_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional redirect URL after successful login"
          }
        }
      },
      "OidcLoginResponse": {
        "type": "object",
        "description": "Response with OIDC authorization URL",
        "required": [
          "authorization_url",
          "state"
        ],
        "properties": {
          "authorization_url": {
            "type": "string",
            "description": "Full authorization URL to redirect the user to"
          },
          "state": {
            "type": "string",
            "description": "State parameter (for debugging, not needed client-side)"
          }
        }
      },
      "OrphanedStateHistoryResponse": {
        "type": "object",
        "description": "A surviving state-history row whose config definition has since been deleted.\nThe solution/environment FK is NULL, but the denormalized name/slug captured at\nwrite time is retained so the historical record stays human-readable.",
        "required": [
          "id",
          "deployment_id",
          "state_type",
          "valid_from"
        ],
        "properties": {
          "action_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized action name (if an action was deployed)"
          },
          "deployment_id": {
            "type": "string",
            "description": "Deployment that produced this state"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment FK (null once the environment definition was deleted)"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized environment name captured at write time"
          },
          "environment_slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized environment slug captured at write time"
          },
          "id": {
            "type": "string",
            "description": "History entry ID"
          },
          "sequence_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized sequence name (if a sequence was deployed)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution FK (null once the solution definition was deleted)"
          },
          "solution_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized solution name captured at write time (survives the delete)"
          },
          "solution_slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Denormalized solution slug captured at write time"
          },
          "state_type": {
            "type": "string",
            "description": "State type (deployed / rolled_back / promoted)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID"
          },
          "valid_from": {
            "type": "string",
            "description": "When this state became valid"
          },
          "valid_until": {
            "type": [
              "string",
              "null"
            ],
            "description": "When this state was superseded"
          }
        }
      },
      "OutcomeCount": {
        "type": "object",
        "required": [
          "outcome",
          "count"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64"
          },
          "outcome": {
            "type": "string"
          }
        }
      },
      "PaginatedEnvironmentStateHistory": {
        "type": "object",
        "description": "Paginated environment state history response",
        "required": [
          "items",
          "total",
          "page",
          "limit"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnvironmentStateHistoryResponse"
            }
          },
          "limit": {
            "type": "integer",
            "format": "int64"
          },
          "page": {
            "type": "integer",
            "format": "int64"
          },
          "total": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "Paginated_ActionResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Action response DTO",
              "required": [
                "id",
                "name",
                "version_count",
                "slug",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Action ID"
                },
                "latest_version": {
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "$ref": "#/components/schemas/ActionVersionResponse",
                      "description": "Latest version (if any)"
                    }
                  ]
                },
                "managed_by_repo_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
                },
                "name": {
                  "type": "string",
                  "description": "Action name"
                },
                "slug": {
                  "type": "string",
                  "description": "Stable slug (config-as-code reference key)"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant owner (null = global/shared)"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                },
                "version_count": {
                  "type": "integer",
                  "description": "Number of versions",
                  "minimum": 0
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_AdminUserListResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "User list response for admin view",
              "required": [
                "id",
                "email",
                "username",
                "status",
                "email_verified",
                "role_count",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Account created timestamp"
                },
                "display_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Display name"
                },
                "email": {
                  "type": "string",
                  "description": "Email address"
                },
                "email_verified": {
                  "type": "boolean",
                  "description": "Whether email is verified"
                },
                "id": {
                  "type": "string",
                  "description": "User ID"
                },
                "last_login_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last login timestamp"
                },
                "role_count": {
                  "type": "integer",
                  "description": "Number of roles assigned",
                  "minimum": 0
                },
                "status": {
                  "type": "string",
                  "description": "Account status (Active, Inactive, Locked, Pending)"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant ID if associated"
                },
                "username": {
                  "type": "string",
                  "description": "Username"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_DeploymentResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Deployment response DTO (list view)",
              "required": [
                "id",
                "source_type",
                "state",
                "progress",
                "total_steps",
                "completed_steps",
                "failed_steps",
                "created_at"
              ],
              "properties": {
                "action_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Action ID (if source is action)"
                },
                "action_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Action name (if source is action)"
                },
                "action_version": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Action version (if source is action)"
                },
                "completed_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Completed timestamp"
                },
                "completed_steps": {
                  "type": "integer",
                  "description": "Completed steps",
                  "minimum": 0
                },
                "created_at": {
                  "type": "string",
                  "description": "Created timestamp"
                },
                "duration_ms": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "format": "int64",
                  "description": "Duration in milliseconds (if completed)"
                },
                "environment_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Environment ID (if tenant deployment)"
                },
                "environment_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Environment name (if tenant deployment)"
                },
                "failed_steps": {
                  "type": "integer",
                  "description": "Failed steps",
                  "minimum": 0
                },
                "id": {
                  "type": "string",
                  "description": "Deployment UUID"
                },
                "progress": {
                  "type": "number",
                  "format": "double",
                  "description": "Progress percentage (0.0 to 1.0)"
                },
                "sequence_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Sequence ID (if source is sequence)"
                },
                "sequence_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Sequence name (if source is sequence)"
                },
                "sequence_version": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Sequence version (if source is sequence)"
                },
                "solution_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Solution ID (if source is solution)"
                },
                "solution_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Solution name (if source is solution)"
                },
                "solution_version": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Solution version (if source is solution)"
                },
                "source_deployment_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "If this is a rollback/redeploy, references the source deployment"
                },
                "source_type": {
                  "$ref": "#/components/schemas/DeploymentSourceTypeDto",
                  "description": "Deployment source type"
                },
                "started_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Started timestamp"
                },
                "state": {
                  "type": "string",
                  "description": "Deployment state"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant ID (if tenant deployment)"
                },
                "tenant_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant name (if tenant deployment)"
                },
                "total_steps": {
                  "type": "integer",
                  "description": "Total steps",
                  "minimum": 0
                },
                "triggered_by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "User who triggered the deployment"
                },
                "triggered_failure_handler_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "If this deployment triggered a failure handler, references it"
                },
                "triggered_rollback_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "If this deployment triggered an automatic rollback, references it"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_EnvironmentResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Environment response DTO",
              "required": [
                "id",
                "name",
                "sort_order",
                "slug",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Environment description"
                },
                "id": {
                  "type": "string",
                  "description": "Environment ID"
                },
                "managed_by_repo_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
                },
                "name": {
                  "type": "string",
                  "description": "Environment name"
                },
                "slug": {
                  "type": "string",
                  "description": "Stable slug (config-as-code reference key)"
                },
                "sort_order": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Sort order (for progression)"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant owner (null = global/shared)"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_GitAuthResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Git auth response (sensitive fields redacted)",
              "required": [
                "id",
                "name",
                "slug",
                "auth_type",
                "has_ssh_private_key",
                "has_ssh_public_key",
                "has_ssh_passphrase",
                "has_username",
                "has_password",
                "created_at"
              ],
              "properties": {
                "auth_type": {
                  "$ref": "#/components/schemas/GitAuthTypeDto",
                  "description": "Auth type (ssh_key, https_basic, https_token)"
                },
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "has_password": {
                  "type": "boolean",
                  "description": "Whether password is set"
                },
                "has_ssh_passphrase": {
                  "type": "boolean",
                  "description": "Whether SSH passphrase is set"
                },
                "has_ssh_private_key": {
                  "type": "boolean",
                  "description": "Whether SSH private key is set"
                },
                "has_ssh_public_key": {
                  "type": "boolean",
                  "description": "Whether SSH public key is set"
                },
                "has_username": {
                  "type": "boolean",
                  "description": "Whether username is set"
                },
                "id": {
                  "type": "string",
                  "description": "Auth ID"
                },
                "name": {
                  "type": "string",
                  "description": "Auth name"
                },
                "slug": {
                  "type": "string",
                  "description": "Per-tenant-unique identity slug"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_GitStorageResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Git storage response",
              "required": [
                "id",
                "name",
                "slug",
                "path",
                "url",
                "reference",
                "created_at"
              ],
              "properties": {
                "auth_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Optional Git auth ID"
                },
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Storage ID"
                },
                "last_fetched": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last fetch timestamp"
                },
                "name": {
                  "type": "string",
                  "description": "Storage name"
                },
                "path": {
                  "type": "string",
                  "description": "Local path for Git clone"
                },
                "reference": {
                  "type": "string",
                  "description": "Git reference (branch, tag, or commit)"
                },
                "slug": {
                  "type": "string",
                  "description": "Per-tenant-unique identity slug"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning tenant ID"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                },
                "url": {
                  "type": "string",
                  "description": "Git repository URL"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_IdentityProviderListResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Identity provider list response",
              "required": [
                "id",
                "name",
                "provider_type",
                "issuer_url",
                "is_enabled",
                "user_count",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Created timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Provider ID"
                },
                "is_enabled": {
                  "type": "boolean",
                  "description": "Whether the provider is enabled"
                },
                "issuer_url": {
                  "type": "string",
                  "description": "Issuer URL"
                },
                "name": {
                  "type": "string",
                  "description": "Provider name"
                },
                "provider_type": {
                  "type": "string",
                  "description": "Provider type (oidc, okta)"
                },
                "user_count": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Number of users linked to this provider"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_LocalStorageResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Local storage response",
              "required": [
                "id",
                "name",
                "slug",
                "path",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Storage ID"
                },
                "name": {
                  "type": "string",
                  "description": "Storage name"
                },
                "path": {
                  "type": "string",
                  "description": "File system path"
                },
                "slug": {
                  "type": "string",
                  "description": "Per-tenant-unique identity slug"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning tenant ID"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_OccurrenceResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "A single failure attributed to a pattern.",
              "required": [
                "id",
                "pattern_id",
                "command_result_id",
                "target_id",
                "occurred_at"
              ],
              "properties": {
                "action_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "command_result_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "deployment_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "environment_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "pattern_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "solution_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "target_id": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_PatternResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "A failure-pattern cluster as returned by the API.",
              "required": [
                "id",
                "fingerprint",
                "signature_template",
                "sample_error",
                "exit_code_class",
                "occurrence_count",
                "target_count",
                "deployment_count",
                "status",
                "first_seen_at",
                "last_seen_at",
                "currently_alerting",
                "created_at",
                "updated_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "currently_alerting": {
                  "type": "boolean"
                },
                "deployment_count": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Distinct deployments in this cluster — the cross-deployment recurrence signal."
                },
                "exit_code_class": {
                  "type": "string"
                },
                "fingerprint": {
                  "type": "string"
                },
                "first_seen_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "last_alerted_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "last_seen_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "llm_cause": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "llm_labeled_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "llm_model_version": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "llm_remediation": {
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "$ref": "#/components/schemas/Value"
                    }
                  ]
                },
                "occurrence_count": {
                  "type": "integer",
                  "format": "int64"
                },
                "regressed_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "sample_error": {
                  "type": "string"
                },
                "signature_template": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "target_count": {
                  "type": "integer",
                  "format": "int32"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid",
                  "description": "Owning tenant; `null` = global/system scope (global-admin-only)."
                },
                "title": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "LLM-assigned title, if labeled."
                },
                "updated_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_RegistrationResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Response for a client registration",
              "required": [
                "id",
                "client_name",
                "thumbprint",
                "status",
                "created_at"
              ],
              "properties": {
                "approved_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the registration was approved"
                },
                "approved_by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Who approved the registration"
                },
                "client_name": {
                  "type": "string",
                  "description": "Client name"
                },
                "created_at": {
                  "type": "string",
                  "description": "When the registration was created"
                },
                "hostname": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Client hostname"
                },
                "id": {
                  "type": "string",
                  "description": "Unique identifier (UUID)"
                },
                "ip_address": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Client IP address"
                },
                "last_seen_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last time the client was seen"
                },
                "machine_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Client machine ID"
                },
                "revocation_reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Reason for revocation"
                },
                "revoked_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the registration was revoked"
                },
                "revoked_by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Who revoked the registration"
                },
                "status": {
                  "type": "string",
                  "description": "Registration status: pending, approved, or revoked"
                },
                "thumbprint": {
                  "type": "string",
                  "description": "Certificate thumbprint (SHA256 hash)"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_RegistrationTokenResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Response for a registration token (without the plaintext token)",
              "required": [
                "id",
                "name",
                "use_count",
                "auto_approve",
                "status",
                "created_at",
                "created_by",
                "can_be_used"
              ],
              "properties": {
                "auto_approve": {
                  "type": "boolean",
                  "description": "Whether clients registered with this token are auto-approved"
                },
                "can_be_used": {
                  "type": "boolean",
                  "description": "Whether the token can currently be used"
                },
                "created_at": {
                  "type": "string",
                  "description": "When the token was created"
                },
                "created_by": {
                  "type": "string",
                  "description": "Who created the token"
                },
                "default_environment": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Default environment for registered clients"
                },
                "default_roles": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "string"
                  },
                  "description": "Default roles for registered clients"
                },
                "expected_common_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Expected common name for certificate signing (if set, CN must match)"
                },
                "expires_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the token expires (null = never)"
                },
                "id": {
                  "type": "string",
                  "description": "Unique identifier (UUID)"
                },
                "max_uses": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "format": "int32",
                  "description": "Maximum uses allowed (null = unlimited)"
                },
                "name": {
                  "type": "string",
                  "description": "Human-readable name for the token"
                },
                "revocation_reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Reason for revocation"
                },
                "revoked_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the token was revoked"
                },
                "revoked_by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Who revoked the token"
                },
                "status": {
                  "type": "string",
                  "description": "Token status: active or revoked"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant ID this token belongs to"
                },
                "use_count": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Current number of uses"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_RoleListResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Role list response",
              "required": [
                "id",
                "name",
                "is_system",
                "user_count",
                "permission_count",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Created timestamp"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Role description"
                },
                "id": {
                  "type": "string",
                  "description": "Role ID"
                },
                "is_system": {
                  "type": "boolean",
                  "description": "Whether this is a system role (cannot be deleted)"
                },
                "name": {
                  "type": "string",
                  "description": "Role name"
                },
                "permission_count": {
                  "type": "integer",
                  "description": "Number of permissions assigned",
                  "minimum": 0
                },
                "user_count": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Number of users with this role"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_S3StorageResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "S3 storage response (sensitive fields redacted)",
              "required": [
                "id",
                "name",
                "slug",
                "bucket",
                "region",
                "auth_type",
                "has_access_key",
                "has_role_arn",
                "created_at"
              ],
              "properties": {
                "auth_type": {
                  "$ref": "#/components/schemas/S3AuthTypeDto",
                  "description": "Authentication type"
                },
                "bucket": {
                  "type": "string",
                  "description": "S3 bucket name"
                },
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "endpoint_url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Endpoint URL (for S3-compatible services)"
                },
                "has_access_key": {
                  "type": "boolean",
                  "description": "Whether access key is set (redacted for security)"
                },
                "has_role_arn": {
                  "type": "boolean",
                  "description": "Whether IAM role is configured"
                },
                "id": {
                  "type": "string",
                  "description": "Storage ID"
                },
                "name": {
                  "type": "string",
                  "description": "Storage name"
                },
                "path_prefix": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Path prefix within the bucket"
                },
                "region": {
                  "type": "string",
                  "description": "AWS region"
                },
                "slug": {
                  "type": "string",
                  "description": "Per-tenant-unique identity slug"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning tenant ID"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_SequenceResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Sequence response DTO",
              "required": [
                "id",
                "name",
                "version_count",
                "slug",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Sequence ID"
                },
                "latest_version": {
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "$ref": "#/components/schemas/SequenceVersionResponse",
                      "description": "Latest version (if any)"
                    }
                  ]
                },
                "managed_by_repo_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
                },
                "name": {
                  "type": "string",
                  "description": "Sequence name"
                },
                "slug": {
                  "type": "string",
                  "description": "Stable slug (config-as-code reference key)"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant owner (null = global/shared)"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                },
                "version_count": {
                  "type": "integer",
                  "description": "Number of versions",
                  "minimum": 0
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_SolutionResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Solution response DTO",
              "required": [
                "id",
                "name",
                "slug",
                "version_count",
                "created_at"
              ],
              "properties": {
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "id": {
                  "type": "string",
                  "description": "Solution ID"
                },
                "latest_version": {
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "$ref": "#/components/schemas/SolutionVersionResponse",
                      "description": "Latest version (if any)"
                    }
                  ]
                },
                "managed_by_repo_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
                },
                "name": {
                  "type": "string",
                  "description": "Solution name"
                },
                "slug": {
                  "type": "string",
                  "description": "Stable slug (config-as-code reference key)"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant owner (null = global/shared)"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                },
                "version_count": {
                  "type": "integer",
                  "description": "Number of versions",
                  "minimum": 0
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_SubscriptionResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Subscription response with associated channel and filter info.",
              "required": [
                "id",
                "name",
                "user_id",
                "channel_id",
                "channel_name",
                "email_digest_enabled",
                "enabled",
                "filters",
                "created_at"
              ],
              "properties": {
                "channel_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Associated channel ID"
                },
                "channel_name": {
                  "type": "string",
                  "description": "Associated channel name"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the subscription was created"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Optional description"
                },
                "email_digest_enabled": {
                  "type": "boolean",
                  "description": "Whether email digest is enabled"
                },
                "email_digest_frequency": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Digest frequency (if enabled) - hourly, daily, weekly",
                  "example": "daily"
                },
                "email_recipient_override": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Email recipient override (if set)"
                },
                "enabled": {
                  "type": "boolean",
                  "description": "Whether the subscription is enabled"
                },
                "filters": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FilterResponse"
                  },
                  "description": "Filters applied to this subscription"
                },
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Subscription ID"
                },
                "name": {
                  "type": "string",
                  "description": "Subscription name"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "When the subscription was last updated"
                },
                "user_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "User who owns this subscription"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_TagResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Tag response DTO",
              "required": [
                "id",
                "key",
                "value"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Tag ID"
                },
                "key": {
                  "type": "string",
                  "description": "Tag key"
                },
                "tenants": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TenantRef"
                  },
                  "description": "Tenants that have adopted this tag (populated on list endpoints only)"
                },
                "value": {
                  "type": "string",
                  "description": "Tag value"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_TargetResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Target response DTO",
              "required": [
                "id",
                "name",
                "mode",
                "hostname",
                "port",
                "tags",
                "created_at"
              ],
              "properties": {
                "assigned_thorax_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When Thorax was assigned"
                },
                "assigned_thorax_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Assigned Thorax instance ID (for topology visualization)"
                },
                "certificate_serial": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Certificate serial for auto-registered targets (links client cert to target)"
                },
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "hostname": {
                  "type": "string",
                  "description": "Hostname or IP address"
                },
                "id": {
                  "type": "string",
                  "description": "Target ID"
                },
                "last_seen_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last seen timestamp"
                },
                "mode": {
                  "type": "string",
                  "description": "Target mode (Listen or Poll)"
                },
                "name": {
                  "type": "string",
                  "description": "Target name"
                },
                "port": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Port number",
                  "minimum": 0
                },
                "status": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Target status (online, stale, offline)"
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagResponse"
                  },
                  "description": "Associated tags (for filtering/preview in deployment forms)"
                },
                "tenants": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TenantRef"
                  },
                  "description": "Tenants that own this target (populated on list endpoints only)"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_TenantResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Tenant response DTO",
              "required": [
                "id",
                "name",
                "created_at"
              ],
              "properties": {
                "contact_email": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Contact email"
                },
                "created_at": {
                  "type": "string",
                  "description": "Creation timestamp"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant description"
                },
                "id": {
                  "type": "string",
                  "description": "Tenant ID"
                },
                "logo_url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Logo URL"
                },
                "name": {
                  "type": "string",
                  "description": "Tenant name"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Last update timestamp"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_ThoraxInstanceResponse": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Thorax instance list response DTO",
              "required": [
                "id",
                "instance_name",
                "hostname",
                "grpc_address",
                "version",
                "status",
                "is_global",
                "tenant_count",
                "registered_at",
                "last_heartbeat_at",
                "active_sessions",
                "active_commands"
              ],
              "properties": {
                "active_commands": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Number of active commands"
                },
                "active_sessions": {
                  "type": "integer",
                  "format": "int32",
                  "description": "Number of active sessions"
                },
                "deregistered_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "When deregistered (if applicable)"
                },
                "grpc_address": {
                  "type": "string",
                  "description": "gRPC address (host:port)"
                },
                "hostname": {
                  "type": "string",
                  "description": "Hostname where instance is running"
                },
                "id": {
                  "type": "string",
                  "description": "Instance ID (UUID)"
                },
                "instance_name": {
                  "type": "string",
                  "description": "Instance name (unique identifier)"
                },
                "is_global": {
                  "type": "boolean",
                  "description": "Whether instance is globally available"
                },
                "last_heartbeat_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Last heartbeat timestamp"
                },
                "registered_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the instance registered"
                },
                "status": {
                  "type": "string",
                  "description": "Current status"
                },
                "tenant_count": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Number of assigned tenants (when not global)"
                },
                "version": {
                  "type": "string",
                  "description": "Thorax version"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_VariableSetSummary": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Variable set summary (for list responses)",
              "required": [
                "id",
                "name",
                "variable_count"
              ],
              "properties": {
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Optional description"
                },
                "id": {
                  "type": "string",
                  "description": "Set ID"
                },
                "name": {
                  "type": "string",
                  "description": "Set name"
                },
                "tenant_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant ID (None for global variable sets)"
                },
                "tenant_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tenant name for display (None for global variable sets)"
                },
                "variable_count": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Number of variables in this set"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "Paginated_VariableSummary": {
        "type": "object",
        "description": "Paginated response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Summary for list responses",
              "required": [
                "id",
                "name",
                "variable_type",
                "is_encrypted",
                "is_prompted"
              ],
              "properties": {
                "description": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "id": {
                  "type": "string"
                },
                "is_encrypted": {
                  "type": "boolean"
                },
                "is_prompted": {
                  "type": "boolean"
                },
                "name": {
                  "type": "string"
                },
                "scope_environment_id": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "variable_type": {
                  "type": "string"
                }
              }
            },
            "description": "The data items"
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta",
            "description": "Pagination metadata"
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "description": "Pagination metadata for responses",
        "required": [
          "total",
          "page",
          "limit",
          "total_pages",
          "has_next",
          "has_prev"
        ],
        "properties": {
          "has_next": {
            "type": "boolean",
            "description": "Whether there are more pages"
          },
          "has_prev": {
            "type": "boolean",
            "description": "Whether there are previous pages"
          },
          "limit": {
            "type": "integer",
            "format": "int64",
            "description": "Items per page"
          },
          "page": {
            "type": "integer",
            "format": "int64",
            "description": "Current page number"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of items"
          },
          "total_pages": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of pages"
          }
        }
      },
      "PatternDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PatternResponse"
          },
          {
            "type": "object",
            "required": [
              "occurrences"
            ],
            "properties": {
              "occurrences": {
                "$ref": "#/components/schemas/Paginated_OccurrenceResponse"
              }
            }
          }
        ],
        "description": "Composite detail view: the pattern plus a paginated page of its occurrences.\n\n`pattern` is flattened into the top-level object (the proven utoipa named\nsub-struct + flatten pattern), and `occurrences` nests the canonical\n[`Paginated`] envelope rather than a bespoke flat shape."
      },
      "PatternResponse": {
        "type": "object",
        "description": "A failure-pattern cluster as returned by the API.",
        "required": [
          "id",
          "fingerprint",
          "signature_template",
          "sample_error",
          "exit_code_class",
          "occurrence_count",
          "target_count",
          "deployment_count",
          "status",
          "first_seen_at",
          "last_seen_at",
          "currently_alerting",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "currently_alerting": {
            "type": "boolean"
          },
          "deployment_count": {
            "type": "integer",
            "format": "int32",
            "description": "Distinct deployments in this cluster — the cross-deployment recurrence signal."
          },
          "exit_code_class": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "first_seen_at": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "last_alerted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time"
          },
          "llm_cause": {
            "type": [
              "string",
              "null"
            ]
          },
          "llm_labeled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "llm_model_version": {
            "type": [
              "string",
              "null"
            ]
          },
          "llm_remediation": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Value"
              }
            ]
          },
          "occurrence_count": {
            "type": "integer",
            "format": "int64"
          },
          "regressed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sample_error": {
            "type": "string"
          },
          "signature_template": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "target_count": {
            "type": "integer",
            "format": "int32"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Owning tenant; `null` = global/system scope (global-admin-only)."
          },
          "title": {
            "type": [
              "string",
              "null"
            ],
            "description": "LLM-assigned title, if labeled."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PatternStats": {
        "type": "object",
        "description": "Dashboard aggregates for a tenant scope over a trailing window (design spec §9).",
        "required": [
          "active_patterns",
          "total_recurring_failures",
          "affected_targets",
          "alerts_fired",
          "trend",
          "top_patterns",
          "most_affected"
        ],
        "properties": {
          "active_patterns": {
            "type": "integer",
            "format": "int64",
            "description": "Distinct active patterns last seen within the window."
          },
          "affected_targets": {
            "type": "integer",
            "format": "int64",
            "description": "Distinct targets that experienced a recurring failure within the window."
          },
          "alerts_fired": {
            "type": "integer",
            "format": "int64",
            "description": "Patterns currently in the alerting state."
          },
          "most_affected": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MostAffected"
            },
            "description": "Solutions most affected by recurring failures within the window."
          },
          "top_patterns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TopPattern"
            },
            "description": "Top patterns ranked by cross-deployment recurrence then recency (§5.4)."
          },
          "total_recurring_failures": {
            "type": "integer",
            "format": "int64",
            "description": "Total occurrences (failed command results) attributed within the window."
          },
          "trend": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TrendBucket"
            },
            "description": "Per-day occurrence counts across the window (ascending by day)."
          }
        }
      },
      "PeerEndpointsResponse": {
        "type": "object",
        "description": "Request to get peer endpoints for connection attempts.",
        "required": [
          "udp_endpoints",
          "turn_servers",
          "relay_url"
        ],
        "properties": {
          "peers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WireGuardPeerInfo"
            },
            "description": "The overlay peers this agent may tunnel to: WG-enabled agents in the same\ntenant (plus global/controller agents), excluding the requester itself."
          },
          "relay_url": {
            "type": "string",
            "description": "WebSocket relay URL (always works)."
          },
          "turn_credentials": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TurnCredentialsResponse",
                "description": "Short-term TURN credentials (if TURN servers provided)."
              }
            ]
          },
          "turn_servers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TurnServerInfo"
            },
            "description": "TURN servers for relay allocation (symmetric NAT)."
          },
          "udp_endpoints": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Direct UDP endpoints to try for hole-punching."
          }
        }
      },
      "PendingDispatchRequestResponse": {
        "type": "object",
        "description": "Pending dispatch request response DTO",
        "required": [
          "id",
          "queued_at",
          "retry_count",
          "status",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Deployment ID (if dispatched)"
          },
          "dispatched_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When dispatched"
          },
          "dispatched_to_instance_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Thorax instance ID (if dispatched)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID if specified"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name if available"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if failed"
          },
          "id": {
            "type": "string",
            "description": "Unique identifier for the pending request"
          },
          "last_retry_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last retry attempt time"
          },
          "queued_at": {
            "type": "string",
            "description": "When the request was queued"
          },
          "retry_count": {
            "type": "integer",
            "format": "int32",
            "description": "Number of retry attempts"
          },
          "status": {
            "type": "string",
            "description": "Current status (pending, processing, dispatched, cancelled, failed)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID if this is a tenant-scoped deployment"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name if available"
          },
          "triggered_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who triggered this deployment request"
          }
        }
      },
      "PermissionGroupResponse": {
        "type": "object",
        "description": "Permission group (grouped by resource)",
        "required": [
          "resource",
          "permissions"
        ],
        "properties": {
          "permissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PermissionResponse"
            },
            "description": "Permissions for this resource"
          },
          "resource": {
            "type": "string",
            "description": "Resource name (e.g., \"users\", \"roles\", \"deployments\")"
          }
        }
      },
      "PermissionResponse": {
        "type": "object",
        "description": "Permission response",
        "required": [
          "id",
          "name",
          "resource",
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "description": "Action on the resource"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Permission description"
          },
          "id": {
            "type": "string",
            "description": "Permission ID"
          },
          "name": {
            "type": "string",
            "description": "Permission name (e.g., \"users:create\")"
          },
          "resource": {
            "type": "string",
            "description": "Resource this permission applies to"
          }
        }
      },
      "PreRegisterRequest": {
        "type": "object",
        "description": "Request to pre-register a client with its certificate thumbprint\n\nThis enables the Octopus Deploy-style bootstrap workflow where thumbprints\nare exchanged out-of-band before the first connection.",
        "required": [
          "client_name",
          "thumbprint"
        ],
        "properties": {
          "client_name": {
            "type": "string",
            "description": "Client name (used for display and identification)"
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional environment label (e.g. \"production\", \"staging\") used to seed\nthe registration metadata."
          },
          "hostname": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional hostname (for documentation purposes)"
          },
          "thumbprint": {
            "type": "string",
            "description": "Certificate thumbprint (SHA-256 hash, 64 hex characters)"
          }
        }
      },
      "PreviewResponse": {
        "type": "object",
        "description": "Branch-scoped preview response: the config documents (path → raw Nickel) at the ref.",
        "required": [
          "git_ref",
          "documents"
        ],
        "properties": {
          "documents": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "git_ref": {
            "type": "string"
          }
        }
      },
      "PromotionPreviewRequest": {
        "type": "object",
        "description": "Request to preview a promotion",
        "required": [
          "solution_id",
          "source_environment_id",
          "target_environment_id"
        ],
        "properties": {
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          },
          "source_environment_id": {
            "type": "string",
            "description": "Source environment ID"
          },
          "target_environment_id": {
            "type": "string",
            "description": "Target environment ID"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (optional)"
          }
        }
      },
      "PromotionPreviewResponse": {
        "type": "object",
        "description": "Response for promotion preview",
        "required": [
          "source_state",
          "validation"
        ],
        "properties": {
          "source_state": {
            "$ref": "#/components/schemas/SourceStateDto",
            "description": "Current state of the source environment"
          },
          "validation": {
            "$ref": "#/components/schemas/PromotionValidationDto",
            "description": "Validation results"
          }
        }
      },
      "PromotionRequestDto": {
        "type": "object",
        "description": "Promotion request summary",
        "required": [
          "id",
          "status",
          "requested_by_user_id",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "When requested"
          },
          "id": {
            "type": "string",
            "description": "Request ID"
          },
          "requested_by_user_id": {
            "type": "string",
            "description": "User who requested"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (null if the solution definition has since been deleted)"
          },
          "status": {
            "type": "string",
            "description": "Status"
          },
          "target_environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target environment ID (null if the environment definition has since been deleted)"
          }
        }
      },
      "PromotionResponse": {
        "type": "object",
        "description": "Response for promotion creation",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Deployment ID if promotion was executed immediately"
          },
          "id": {
            "type": "string",
            "description": "Promotion request ID (if pending approval) or deployment ID"
          },
          "status": {
            "type": "string",
            "description": "Status (pending_approval, queued, etc.)"
          }
        }
      },
      "PromotionValidationDto": {
        "type": "object",
        "description": "Promotion validation result",
        "required": [
          "allowed",
          "requires_approval",
          "blocking_reasons",
          "warnings"
        ],
        "properties": {
          "allowed": {
            "type": "boolean",
            "description": "Whether promotion is allowed"
          },
          "approval_role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role ID required for approval"
          },
          "blocking_reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Reasons blocking the promotion"
          },
          "requires_approval": {
            "type": "boolean",
            "description": "Whether approval is required"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Non-blocking warnings"
          }
        }
      },
      "PromptedVariableDto": {
        "type": "object",
        "description": "Prompted variable definition for deployment-time input",
        "required": [
          "id",
          "name",
          "control_type",
          "required",
          "is_sensitive"
        ],
        "properties": {
          "control_type": {
            "type": "string",
            "description": "Control type (text, multiline, checkbox, select, sensitive)"
          },
          "default_value": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default value (if any, not shown for sensitive variables)"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description/help text for the prompt"
          },
          "id": {
            "type": "string",
            "description": "Variable ID"
          },
          "is_sensitive": {
            "type": "boolean",
            "description": "Whether this is a sensitive variable (for UI masking)"
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "User-facing label for the prompt"
          },
          "name": {
            "type": "string",
            "description": "Variable name"
          },
          "required": {
            "type": "boolean",
            "description": "Whether a value is required"
          },
          "select_options": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Options for select control type"
          }
        }
      },
      "PromptedVariablesResponse": {
        "type": "object",
        "description": "Response for listing prompted variables for a solution",
        "required": [
          "solution_id",
          "variables",
          "required_count"
        ],
        "properties": {
          "required_count": {
            "type": "integer",
            "description": "Count of required variables",
            "minimum": 0
          },
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          },
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptedVariableDto"
            },
            "description": "Prompted variables defined for this solution"
          }
        }
      },
      "ReadOnlyDoc": {
        "type": "object",
        "description": "An exported document the editor must present as read-only (and exclude from import).",
        "required": [
          "path",
          "reason"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "The exact `files` key this applies to."
          },
          "reason": {
            "$ref": "#/components/schemas/ReadOnlyReason"
          },
          "repo_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name of the owning repository (only for `managed`; `None` if out of the caller's scope)."
          }
        }
      },
      "ReadOnlyReason": {
        "type": "string",
        "description": "Why an exported document is read-only in the editor.",
        "enum": [
          "managed",
          "no_write_permission"
        ]
      },
      "RecomputeAccepted": {
        "type": "object",
        "description": "202 response for an accepted recompute request.",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "Always `\"accepted\"`; the batch runs asynchronously on the service."
          }
        }
      },
      "RecurrenceConfigDto": {
        "type": "object",
        "description": "Recurrence configuration DTO",
        "properties": {
          "days_of_month": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            },
            "description": "For monthly: days of month (1-31)"
          },
          "days_of_week": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            },
            "description": "For weekly: days of week (0 = Sunday, 6 = Saturday)"
          },
          "months": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            },
            "description": "For yearly: months (1-12)"
          }
        }
      },
      "RedeployRequest": {
        "type": "object",
        "description": "Redeploy request - creates a new deployment based on an existing one",
        "properties": {
          "bypass_cache": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Bypass file cache and fetch fresh content from S3/Git storage"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Override environment ID or SqId"
          },
          "failure_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FailureStrategyParam",
                "description": "Override failure strategy: \"StopOnFirst\", \"Continue\", \"Ignore\""
              }
            ]
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Override maximum retries per command"
          },
          "on_failure_action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Override failure handler: action ID or SqId to run when this deployment fails."
          },
          "on_failure_sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Override failure handler: sequence ID or SqId to run when this deployment fails."
          },
          "on_failure_solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Override failure handler: solution ID or SqId to run when this deployment fails."
          },
          "override_freeze": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Override active deployment freeze (requires admin role)"
          },
          "override_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for overriding freeze (required if override_freeze is true)"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Override priority (-100 to 100)"
          },
          "prompted_values": {
            "type": [
              "object",
              "null"
            ],
            "description": "Override prompted variable values (variable_id or name -> value)",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "rollback_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RollbackStrategyParam",
                "description": "Override rollback strategy: \"None\", \"FailedTargetOnly\", \"AllExecuted\""
              }
            ]
          },
          "target_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Override target IDs or SqIds"
          },
          "target_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetExecutionModeDto",
                "description": "Override target execution mode: \"Parallel\", \"Sequential\", or {\"Rolling\": {\"batch_size\": N}}"
              }
            ]
          },
          "target_tags": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/TagFilter"
            },
            "description": "Override target tags"
          },
          "timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Override timeout for each command in seconds"
          },
          "variables": {
            "type": [
              "object",
              "null"
            ],
            "description": "Override variables (merged with original deployment variables)",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "RegistrationDetailResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RegistrationResponse",
            "description": "All fields of [`RegistrationResponse`] are inlined into this response."
          },
          {
            "type": "object",
            "required": [
              "certificate_pem"
            ],
            "properties": {
              "certificate_pem": {
                "type": "string",
                "description": "The full certificate in PEM format."
              }
            }
          }
        ],
        "description": "Detailed response including the certificate PEM.\n\nComposed via `#[serde(flatten)]` of [`RegistrationResponse`]; the wire format\nis identical to [`RegistrationResponse`] plus a `certificate_pem` field."
      },
      "RegistrationResponse": {
        "type": "object",
        "description": "Response for a client registration",
        "required": [
          "id",
          "client_name",
          "thumbprint",
          "status",
          "created_at"
        ],
        "properties": {
          "approved_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the registration was approved"
          },
          "approved_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who approved the registration"
          },
          "client_name": {
            "type": "string",
            "description": "Client name"
          },
          "created_at": {
            "type": "string",
            "description": "When the registration was created"
          },
          "hostname": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client hostname"
          },
          "id": {
            "type": "string",
            "description": "Unique identifier (UUID)"
          },
          "ip_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client IP address"
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last time the client was seen"
          },
          "machine_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client machine ID"
          },
          "revocation_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for revocation"
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the registration was revoked"
          },
          "revoked_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who revoked the registration"
          },
          "status": {
            "type": "string",
            "description": "Registration status: pending, approved, or revoked"
          },
          "thumbprint": {
            "type": "string",
            "description": "Certificate thumbprint (SHA256 hash)"
          }
        }
      },
      "RegistrationTokenCreatedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RegistrationTokenResponse",
            "description": "The registration token details"
          },
          {
            "type": "object",
            "required": [
              "plaintext_token"
            ],
            "properties": {
              "plaintext_token": {
                "type": "string",
                "description": "The plaintext token value - ONLY SHOWN ONCE!\nStore this securely, it cannot be retrieved again."
              }
            }
          }
        ],
        "description": "Response when creating a token (includes the plaintext token - only shown once!)"
      },
      "RegistrationTokenResponse": {
        "type": "object",
        "description": "Response for a registration token (without the plaintext token)",
        "required": [
          "id",
          "name",
          "use_count",
          "auto_approve",
          "status",
          "created_at",
          "created_by",
          "can_be_used"
        ],
        "properties": {
          "auto_approve": {
            "type": "boolean",
            "description": "Whether clients registered with this token are auto-approved"
          },
          "can_be_used": {
            "type": "boolean",
            "description": "Whether the token can currently be used"
          },
          "created_at": {
            "type": "string",
            "description": "When the token was created"
          },
          "created_by": {
            "type": "string",
            "description": "Who created the token"
          },
          "default_environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default environment for registered clients"
          },
          "default_roles": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Default roles for registered clients"
          },
          "expected_common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Expected common name for certificate signing (if set, CN must match)"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the token expires (null = never)"
          },
          "id": {
            "type": "string",
            "description": "Unique identifier (UUID)"
          },
          "max_uses": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum uses allowed (null = unlimited)"
          },
          "name": {
            "type": "string",
            "description": "Human-readable name for the token"
          },
          "revocation_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for revocation"
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the token was revoked"
          },
          "revoked_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who revoked the token"
          },
          "status": {
            "type": "string",
            "description": "Token status: active or revoked"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID this token belongs to"
          },
          "use_count": {
            "type": "integer",
            "format": "int32",
            "description": "Current number of uses"
          }
        }
      },
      "RejectPromotionRequest": {
        "type": "object",
        "description": "Request to reject a promotion",
        "required": [
          "reason"
        ],
        "properties": {
          "reason": {
            "type": "string",
            "description": "Reason for rejection"
          }
        }
      },
      "RejectRegistrationRequest": {
        "type": "object",
        "description": "Request to reject a pending registration",
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for rejection (optional but recommended)"
          }
        }
      },
      "RemovePermissionsRequest": {
        "type": "object",
        "description": "Remove permissions from role request",
        "required": [
          "permission_ids"
        ],
        "properties": {
          "permission_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Permission IDs to remove"
          }
        },
        "additionalProperties": false
      },
      "RemoveRolesRequest": {
        "type": "object",
        "description": "Remove roles from user request",
        "required": [
          "role_ids"
        ],
        "properties": {
          "role_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Role IDs to remove"
          }
        },
        "additionalProperties": false
      },
      "RepositoryResponse": {
        "type": "object",
        "description": "Repository response.",
        "required": [
          "id",
          "name",
          "slug",
          "git_url",
          "git_branch",
          "sync_direction",
          "auto_sync",
          "git_authoritative",
          "has_webhook_secret",
          "degraded",
          "created_at"
        ],
        "properties": {
          "auto_sync": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "degraded": {
            "type": "boolean",
            "description": "Phase C staleness SLO: true when this is an authoritative auto-sync repo whose DB\nprojection has aged past `sync_interval_minutes × 3` without a successful sync (or has\nnever synced) — surfaced so operators notice a stalled reconcile."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_auth_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_authoritative": {
            "type": "boolean",
            "description": "Phase C: when true, Git is the source of truth — managed entities are read-only outside\nthe repository and the reconciler pulls Git→DB with Git winning."
          },
          "git_branch": {
            "type": "string"
          },
          "git_url": {
            "type": "string"
          },
          "has_webhook_secret": {
            "type": "boolean",
            "description": "Phase C: whether an inbound-webhook HMAC secret is configured (the secret itself is never\nreturned). When true, `POST .../webhook` can trigger a reconcile."
          },
          "id": {
            "type": "string"
          },
          "last_sync_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_sync_commit": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_sync_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "sync_direction": {
            "type": "string"
          },
          "sync_interval_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant id, or `null` for a GLOBAL (admin-owned, shared) repository."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ResetPasswordRequest": {
        "type": "object",
        "description": "Reset password request (admin only)",
        "required": [
          "new_password"
        ],
        "properties": {
          "new_password": {
            "type": "string",
            "description": "New password - must meet complexity requirements"
          }
        },
        "additionalProperties": false
      },
      "ResourceCounts": {
        "type": "object",
        "description": "Resource counts for a tenant or global",
        "required": [
          "solutions",
          "targets",
          "environments",
          "variables",
          "tags",
          "sequences",
          "actions"
        ],
        "properties": {
          "actions": {
            "type": "integer",
            "format": "int64",
            "description": "Number of actions"
          },
          "environments": {
            "type": "integer",
            "format": "int64",
            "description": "Number of environments"
          },
          "sequences": {
            "type": "integer",
            "format": "int64",
            "description": "Number of sequences"
          },
          "solutions": {
            "type": "integer",
            "format": "int64",
            "description": "Number of solutions"
          },
          "tags": {
            "type": "integer",
            "format": "int64",
            "description": "Number of tags"
          },
          "targets": {
            "type": "integer",
            "format": "int64",
            "description": "Number of targets"
          },
          "variables": {
            "type": "integer",
            "format": "int64",
            "description": "Number of variables"
          }
        }
      },
      "RetryDeliveryResponse": {
        "type": "object",
        "description": "Response from retrying a delivery.",
        "required": [
          "delivery_id",
          "status",
          "message"
        ],
        "properties": {
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the delivery being retried"
          },
          "message": {
            "type": "string",
            "description": "Message describing the action taken"
          },
          "status": {
            "type": "string",
            "description": "New status after retry",
            "example": "pending"
          }
        }
      },
      "RevokeApiKeyResponse": {
        "type": "object",
        "description": "Response for revoking an API key",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Success message"
          }
        }
      },
      "RevokeRegistrationRequest": {
        "type": "object",
        "description": "Request to revoke a registration",
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for revocation (optional but recommended)"
          }
        }
      },
      "RevokeRegistrationTokenRequest": {
        "type": "object",
        "description": "Request to revoke a registration token",
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for revocation (optional but recommended)"
          }
        }
      },
      "RoleDetailResponse": {
        "type": "object",
        "description": "Detailed role response",
        "required": [
          "id",
          "name",
          "is_system",
          "permission_groups",
          "users",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role description"
          },
          "id": {
            "type": "string",
            "description": "Role ID"
          },
          "is_system": {
            "type": "boolean",
            "description": "Whether this is a system role"
          },
          "name": {
            "type": "string",
            "description": "Role name"
          },
          "permission_groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PermissionGroupResponse"
            },
            "description": "Assigned permissions grouped by resource"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated timestamp"
          },
          "users": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoleUserResponse"
            },
            "description": "Users with this role"
          }
        }
      },
      "RoleListResponse": {
        "type": "object",
        "description": "Role list response",
        "required": [
          "id",
          "name",
          "is_system",
          "user_count",
          "permission_count",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role description"
          },
          "id": {
            "type": "string",
            "description": "Role ID"
          },
          "is_system": {
            "type": "boolean",
            "description": "Whether this is a system role (cannot be deleted)"
          },
          "name": {
            "type": "string",
            "description": "Role name"
          },
          "permission_count": {
            "type": "integer",
            "description": "Number of permissions assigned",
            "minimum": 0
          },
          "user_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of users with this role"
          }
        }
      },
      "RoleMappingResponse": {
        "type": "object",
        "description": "Identity-provider role mapping response (external IdP group -> Mantis role)",
        "required": [
          "id",
          "provider_id",
          "external_group",
          "role_id",
          "role_name",
          "priority",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Created timestamp"
          },
          "external_group": {
            "type": "string",
            "description": "External IdP group/claim value to match"
          },
          "id": {
            "type": "string",
            "description": "Mapping ID"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority (higher = processed first)"
          },
          "provider_id": {
            "type": "string",
            "description": "Owning identity provider ID"
          },
          "role_id": {
            "type": "string",
            "description": "Mantis role assigned when the group matches"
          },
          "role_name": {
            "type": "string",
            "description": "Role name (for display)"
          }
        }
      },
      "RoleResponse": {
        "type": "object",
        "description": "Role response (basic)",
        "required": [
          "id",
          "name",
          "is_system"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role description"
          },
          "id": {
            "type": "string",
            "description": "Role ID"
          },
          "is_system": {
            "type": "boolean",
            "description": "Whether this is a system role"
          },
          "name": {
            "type": "string",
            "description": "Role name"
          }
        }
      },
      "RoleUserResponse": {
        "type": "object",
        "description": "User in role context",
        "required": [
          "id",
          "username",
          "email"
        ],
        "properties": {
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name"
          },
          "email": {
            "type": "string",
            "description": "Email"
          },
          "id": {
            "type": "string",
            "description": "User ID"
          },
          "username": {
            "type": "string",
            "description": "Username"
          }
        }
      },
      "RollbackKeyRotationRequest": {
        "type": "object",
        "description": "Request to rollback a key rotation.\n\nCalled by the agent if the new key fails to establish a connection.\nThis removes the pending key and keeps the current active key.",
        "required": [
          "rotation_id"
        ],
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional reason for the rollback (for audit logging)."
          },
          "rotation_id": {
            "type": "string",
            "format": "uuid",
            "description": "The rotation ID from the start rotation response."
          }
        }
      },
      "RollbackPreviewRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RollbackTargetDto",
            "description": "Rollback target"
          },
          {
            "type": "object",
            "required": [
              "solution_id",
              "environment_id"
            ],
            "properties": {
              "environment_id": {
                "type": "string",
                "description": "Environment ID"
              },
              "solution_id": {
                "type": "string",
                "description": "Solution ID"
              },
              "tenant_id": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Tenant ID (optional)"
              },
              "use_historical_variables": {
                "type": "boolean",
                "description": "Whether to use historical variables"
              }
            }
          }
        ],
        "description": "Request to preview a rollback operation"
      },
      "RollbackPreviewResponse": {
        "type": "object",
        "description": "Response for rollback preview",
        "required": [
          "target_deployment_id",
          "deployed_at",
          "variable_snapshot_available",
          "variable_count",
          "deployment_type"
        ],
        "properties": {
          "deployed_at": {
            "type": "string",
            "description": "When the target was originally deployed"
          },
          "deployment_type": {
            "type": "string",
            "description": "Deployment type (rollback or rollback_point_in_time)"
          },
          "solution_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version being deployed"
          },
          "target_deployment_id": {
            "type": "string",
            "description": "Target deployment ID that will be rolled back to"
          },
          "variable_count": {
            "type": "integer",
            "description": "Number of variables in the snapshot",
            "minimum": 0
          },
          "variable_snapshot_available": {
            "type": "boolean",
            "description": "Whether a variable snapshot is available"
          }
        }
      },
      "RollbackResponse": {
        "type": "object",
        "description": "Response for rollback creation",
        "required": [
          "deployment_id",
          "status",
          "deployment_type",
          "source_deployment_id"
        ],
        "properties": {
          "deployment_id": {
            "type": "string",
            "description": "Created deployment ID"
          },
          "deployment_type": {
            "type": "string",
            "description": "Deployment type"
          },
          "source_deployment_id": {
            "type": "string",
            "description": "Source deployment being rolled back to"
          },
          "status": {
            "type": "string",
            "description": "Deployment status"
          }
        }
      },
      "RollbackStrategyParam": {
        "type": "string",
        "description": "Rollback strategy for deployments.",
        "enum": [
          "none",
          "failed_target_only",
          "all_executed"
        ]
      },
      "RollbackTargetDto": {
        "oneOf": [
          {
            "type": "object",
            "description": "Roll back to a specific point in time",
            "required": [
              "timestamp",
              "type"
            ],
            "properties": {
              "timestamp": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "point_in_time"
                ]
              }
            }
          },
          {
            "type": "object",
            "description": "Roll back to a specific deployment",
            "required": [
              "deployment_id",
              "type"
            ],
            "properties": {
              "deployment_id": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "deployment"
                ]
              }
            }
          },
          {
            "type": "object",
            "description": "Roll back to the previous deployment",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "previous"
                ]
              }
            }
          }
        ],
        "description": "Target for a rollback operation"
      },
      "RotateSecretResponse": {
        "type": "object",
        "description": "Response from rotating a webhook secret.",
        "required": [
          "new_secret",
          "rotated_at",
          "grace_period_hours"
        ],
        "properties": {
          "grace_period_hours": {
            "type": "integer",
            "format": "int32",
            "description": "Grace period during which the old secret is also valid",
            "minimum": 0
          },
          "new_secret": {
            "type": "string",
            "description": "The new webhook secret (only returned once, store securely)"
          },
          "rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the secret was rotated"
          }
        }
      },
      "S3AuthTypeDto": {
        "type": "string",
        "description": "S3 authentication type for API requests/responses",
        "enum": [
          "static",
          "iam_role"
        ]
      },
      "S3ConnectionTestResponse": {
        "type": "object",
        "description": "S3 connection test response",
        "required": [
          "success",
          "latency_ms",
          "bucket_exists",
          "read_access"
        ],
        "properties": {
          "bucket_exists": {
            "type": "boolean",
            "description": "Whether the bucket exists and is accessible"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if the test failed"
          },
          "latency_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Time taken for the test in milliseconds",
            "minimum": 0
          },
          "read_access": {
            "type": "boolean",
            "description": "Whether we have read access to the bucket"
          },
          "success": {
            "type": "boolean",
            "description": "Whether the connection test succeeded"
          }
        }
      },
      "S3StorageResponse": {
        "type": "object",
        "description": "S3 storage response (sensitive fields redacted)",
        "required": [
          "id",
          "name",
          "slug",
          "bucket",
          "region",
          "auth_type",
          "has_access_key",
          "has_role_arn",
          "created_at"
        ],
        "properties": {
          "auth_type": {
            "$ref": "#/components/schemas/S3AuthTypeDto",
            "description": "Authentication type"
          },
          "bucket": {
            "type": "string",
            "description": "S3 bucket name"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "endpoint_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Endpoint URL (for S3-compatible services)"
          },
          "has_access_key": {
            "type": "boolean",
            "description": "Whether access key is set (redacted for security)"
          },
          "has_role_arn": {
            "type": "boolean",
            "description": "Whether IAM role is configured"
          },
          "id": {
            "type": "string",
            "description": "Storage ID"
          },
          "name": {
            "type": "string",
            "description": "Storage name"
          },
          "path_prefix": {
            "type": [
              "string",
              "null"
            ],
            "description": "Path prefix within the bucket"
          },
          "region": {
            "type": "string",
            "description": "AWS region"
          },
          "slug": {
            "type": "string",
            "description": "Per-tenant-unique identity slug"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning tenant ID"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "SSETokenRefreshRequest": {
        "type": "object",
        "description": "Request to refresh an SSE session token.",
        "required": [
          "session_id",
          "refresh_token"
        ],
        "properties": {
          "refresh_token": {
            "type": "string",
            "description": "Refresh token associated with the session"
          },
          "session_id": {
            "type": "string",
            "description": "Session identifier to refresh"
          }
        }
      },
      "SSETokenRequest": {
        "type": "object",
        "description": "Request for creating an SSE token\n\nBody is intentionally empty; authentication is provided via Authorization header."
      },
      "SSETokenResponse": {
        "type": "object",
        "description": "Response containing a session-level SSE token and refresh metadata",
        "required": [
          "sse_token",
          "expires_in",
          "session_id",
          "refresh_token"
        ],
        "properties": {
          "expires_in": {
            "type": "integer",
            "format": "int32",
            "description": "Seconds until the token expires",
            "minimum": 0
          },
          "refresh_token": {
            "type": "string",
            "description": "Refresh token used to renew the session"
          },
          "session_id": {
            "type": "string",
            "description": "Session identifier for future refreshes"
          },
          "sse_token": {
            "type": "string",
            "description": "The SSE token used for EventSource authentication"
          }
        }
      },
      "SavedTimeWindow": {
        "type": "object",
        "description": "Saveable time window. period=day|week|month|quarter|year selects a preset; period=relative with days selects a rolling window. An absolute period=custom range is session-only and is rejected here.",
        "required": [
          "period"
        ],
        "properties": {
          "days": {
            "type": "integer",
            "format": "int64",
            "description": "Rolling window length; only with period=relative."
          },
          "period": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month",
              "quarter",
              "year",
              "relative"
            ]
          },
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "Inclusive lower bound; only with period=custom."
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "description": "Inclusive upper bound; only with period=custom."
          }
        }
      },
      "ScheduleListResponse": {
        "type": "object",
        "description": "Paginated schedule list response",
        "required": [
          "items",
          "total",
          "page",
          "per_page"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduleResponse"
            },
            "description": "List of schedules"
          },
          "page": {
            "type": "integer",
            "format": "int64",
            "description": "Current page"
          },
          "per_page": {
            "type": "integer",
            "format": "int64",
            "description": "Items per page"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count"
          }
        }
      },
      "ScheduleResponse": {
        "type": "object",
        "description": "Deployment schedule response DTO",
        "required": [
          "id",
          "name",
          "slug",
          "source_type",
          "deployment_config",
          "scheduled_time",
          "is_enabled",
          "execution_count",
          "created_at",
          "timezone"
        ],
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID (if source is action)"
          },
          "action_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action name (if source is action)"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "created_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Created by user ID"
          },
          "deployment_config": {
            "$ref": "#/components/schemas/ScheduledDeploymentConfigDto",
            "description": "Deployment configuration"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Schedule description"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID"
          },
          "environment_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name"
          },
          "execution_count": {
            "type": "integer",
            "format": "int32",
            "description": "Number of times the schedule has been executed"
          },
          "id": {
            "type": "string",
            "description": "Schedule ID"
          },
          "is_enabled": {
            "type": "boolean",
            "description": "Whether the schedule is enabled"
          },
          "last_executed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last execution time (UTC)"
          },
          "name": {
            "type": "string",
            "description": "Schedule name"
          },
          "next_execution_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Next scheduled execution time (UTC, computed)"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type"
          },
          "scheduled_time": {
            "type": "string",
            "description": "Scheduled time (UTC)"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID (if source is sequence)"
          },
          "sequence_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence name (if source is sequence)"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (if source is solution)"
          },
          "solution_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution name (if source is solution)"
          },
          "source_type": {
            "type": "string",
            "description": "Source type: \"solution\", \"sequence\", or \"action\""
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (if scoped to tenant)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name (if scoped to tenant)"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone name"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version_requirement": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version requirement"
          }
        }
      },
      "ScheduledDeploymentConfigDto": {
        "type": "object",
        "description": "Deployment configuration for scheduled deployments",
        "properties": {
          "failure_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FailureStrategyParam",
                "description": "Failure strategy: \"stop_on_first_failure\", \"continue_on_failure\", \"ignore_failures\""
              }
            ]
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Max retry attempts"
          },
          "on_failure_action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: action ID to run when deployment fails"
          },
          "on_failure_sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: sequence ID to run when deployment fails"
          },
          "on_failure_solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional failure handler: solution ID to run when deployment fails"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Priority level (-100 to 100)"
          },
          "rollback_strategy": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RollbackStrategyParam",
                "description": "Rollback strategy: \"none\", \"failed_target_only\", \"all_executed\""
              }
            ]
          },
          "target_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Target IDs for the deployment"
          },
          "target_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TargetExecutionModeDto",
                "description": "Target execution mode: \"sequential\", \"parallel\", or {\"rolling\": {\"batch_size\": N}}"
              }
            ]
          },
          "target_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagFilter"
            },
            "description": "Target tags for selection"
          },
          "timeout_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Timeout in seconds"
          },
          "variables": {
            "type": "object",
            "description": "Variables to pass to the deployment",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "SequenceDetailResponse": {
        "type": "object",
        "description": "Sequence detail response (includes all versions)",
        "required": [
          "id",
          "name",
          "versions",
          "slug",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Sequence ID"
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Sequence name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceVersionResponse"
            },
            "description": "All versions"
          }
        }
      },
      "SequenceEntryRequest": {
        "type": "object",
        "description": "Sequence entry in a solution",
        "required": [
          "order",
          "id",
          "name",
          "version_requirement"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Sequence ID"
          },
          "name": {
            "type": "string",
            "description": "Sequence name (for display/validation)"
          },
          "order": {
            "type": "integer",
            "format": "int32",
            "description": "Order index (0-based)",
            "minimum": 0
          },
          "version_requirement": {
            "type": "string",
            "description": "Version requirement (e.g., \"^1.0.0\", \">=2.0.0\")"
          }
        }
      },
      "SequenceEntryResponse": {
        "type": "object",
        "description": "Sequence entry response",
        "required": [
          "order",
          "id",
          "name",
          "version_requirement"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Sequence ID"
          },
          "name": {
            "type": "string",
            "description": "Sequence name"
          },
          "order": {
            "type": "integer",
            "format": "int32",
            "description": "Order index",
            "minimum": 0
          },
          "version_requirement": {
            "type": "string",
            "description": "Version requirement"
          }
        }
      },
      "SequenceResponse": {
        "type": "object",
        "description": "Sequence response DTO",
        "required": [
          "id",
          "name",
          "version_count",
          "slug",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Sequence ID"
          },
          "latest_version": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SequenceVersionResponse",
                "description": "Latest version (if any)"
              }
            ]
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Sequence name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version_count": {
            "type": "integer",
            "description": "Number of versions",
            "minimum": 0
          }
        }
      },
      "SequenceVersionResponse": {
        "type": "object",
        "description": "Sequence version response DTO",
        "required": [
          "id",
          "version",
          "actions",
          "created_at"
        ],
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionEntryResponse"
            },
            "description": "Ordered actions in this sequence version"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Version ID"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version": {
            "type": "string",
            "description": "Version number (semantic version)"
          }
        }
      },
      "ServerCapability": {
        "type": "string",
        "description": "Server capability types",
        "enum": [
          "listen",
          "poll"
        ]
      },
      "ServerCertificateInfo": {
        "type": "object",
        "description": "Server certificate information",
        "required": [
          "thumbprint",
          "subject",
          "issuer",
          "valid_from",
          "valid_until",
          "days_remaining",
          "serial_number",
          "is_valid",
          "expiry_severity"
        ],
        "properties": {
          "days_remaining": {
            "type": "integer",
            "format": "int64",
            "description": "Days until expiration"
          },
          "expiry_severity": {
            "$ref": "#/components/schemas/CertificateSeverity",
            "description": "Severity level for expiration"
          },
          "is_valid": {
            "type": "boolean",
            "description": "Whether the certificate is currently valid"
          },
          "issuer": {
            "type": "string",
            "description": "Certificate issuer"
          },
          "serial_number": {
            "type": "string",
            "description": "Certificate serial number (hex)"
          },
          "subject": {
            "type": "string",
            "description": "Certificate subject (CN)"
          },
          "thumbprint": {
            "type": "string",
            "description": "Certificate thumbprint (SHA-256)"
          },
          "valid_from": {
            "type": "string",
            "description": "When the certificate becomes valid (ISO 8601 format)"
          },
          "valid_until": {
            "type": "string",
            "description": "When the certificate expires (ISO 8601 format)"
          }
        }
      },
      "ServerCertificateResponse": {
        "type": "object",
        "description": "Response for server certificate info endpoint",
        "required": [
          "configured"
        ],
        "properties": {
          "certificate": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ServerCertificateInfo",
                "description": "Server certificate details (None if not configured)"
              }
            ]
          },
          "configured": {
            "type": "boolean",
            "description": "Whether the server certificate is configured"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if certificate couldn't be read"
          }
        }
      },
      "ServerInfoResponse": {
        "type": "object",
        "description": "Server information response for discovery and verification\n\nThis endpoint is unauthenticated to allow clients to discover\nand verify the server before establishing trust.",
        "required": [
          "server_name",
          "server_version",
          "capabilities",
          "registration_enabled"
        ],
        "properties": {
          "capabilities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ServerCapability"
            },
            "description": "Supported communication capabilities"
          },
          "registration_enabled": {
            "type": "boolean",
            "description": "Whether new client registration is enabled"
          },
          "server_name": {
            "type": "string",
            "description": "Human-readable server name"
          },
          "server_thumbprint": {
            "type": [
              "string",
              "null"
            ],
            "description": "SHA256 thumbprint of the server's TLS certificate\n\nClients can use this to verify they're connecting to the expected server.\nFormat: lowercase hex string (64 characters)."
          },
          "server_version": {
            "type": "string",
            "description": "Server version (semver)"
          }
        }
      },
      "SessionListResponse": {
        "type": "object",
        "description": "Response for session list",
        "required": [
          "sessions"
        ],
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionResponse"
            },
            "description": "List of active sessions"
          }
        }
      },
      "SessionResponse": {
        "type": "object",
        "description": "Response for a user session",
        "required": [
          "id",
          "ip_address",
          "last_active_at",
          "created_at",
          "is_current"
        ],
        "properties": {
          "browser": {
            "type": [
              "string",
              "null"
            ],
            "description": "Browser name (e.g., \"Chrome 120\")"
          },
          "created_at": {
            "type": "string",
            "description": "Session created timestamp (ISO 8601)"
          },
          "device_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Friendly device name (e.g., \"Chrome on macOS\")"
          },
          "device_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Device category: desktop, mobile, tablet, unknown"
          },
          "id": {
            "type": "string",
            "description": "Session ID"
          },
          "ip_address": {
            "type": "string",
            "description": "Client IP address"
          },
          "is_current": {
            "type": "boolean",
            "description": "Whether this is the current session"
          },
          "last_active_at": {
            "type": "string",
            "description": "Last activity timestamp (ISO 8601)"
          },
          "os": {
            "type": [
              "string",
              "null"
            ],
            "description": "Operating system (e.g., \"macOS 10.15\")"
          }
        }
      },
      "SessionRevokeResponse": {
        "type": "object",
        "description": "Response for revoking sessions",
        "required": [
          "revoked_count",
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Success message"
          },
          "revoked_count": {
            "type": "integer",
            "description": "Number of sessions revoked",
            "minimum": 0
          }
        }
      },
      "SetAuthoritativeRequest": {
        "type": "object",
        "description": "Request to flip a repository's Git-authoritative mode (Phase C).",
        "required": [
          "enabled"
        ],
        "properties": {
          "acknowledge_divergence": {
            "type": "boolean",
            "description": "Required to actually ENABLE: acknowledges the divergence preview (the first reconcile\noverwrites the DB projection from Git, Git wins). Ignored when disabling. Without it,\nenabling returns a dry-run preview and does not flip."
          },
          "enabled": {
            "type": "boolean",
            "description": "Enable (Git becomes the source of truth) or disable (revert to bidirectional editing)."
          }
        }
      },
      "SetAuthoritativeResponse": {
        "type": "object",
        "description": "Response from the authoritative-flip endpoint.",
        "required": [
          "git_authoritative",
          "status",
          "conflicts",
          "requires_acknowledgement",
          "would_delete"
        ],
        "properties": {
          "conflicts": {
            "type": "integer",
            "description": "Number of conflicts (blocked deletions) the reconcile held back.",
            "minimum": 0
          },
          "git_authoritative": {
            "type": "boolean",
            "description": "The repository's authoritative flag after this call."
          },
          "preview": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SyncPullTally",
                "description": "Reconcile tallies — a dry-run divergence preview when `requires_acknowledgement`, else the\napplied first reconcile."
              }
            ]
          },
          "requires_acknowledgement": {
            "type": "boolean",
            "description": "True when enabling was withheld pending acknowledgement: review `preview`, then re-submit\nwith `acknowledge_divergence = true`."
          },
          "status": {
            "type": "string",
            "description": "Outcome of the reconcile this call ran: `success` | `conflict` | `failed` (`success` for a\ndisable, or for an unacknowledged enable's dry-run preview). An acknowledged enable whose\nfirst reconcile left blocked Git-side deletions reports `conflict` here — the flag IS set,\nbut the divergence is not fully applied."
          },
          "would_delete": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Config documents that the first reconcile would (or did) DELETE from the DB — the\nhighest-risk part of the divergence, surfaced so the operator acknowledges it explicitly."
          }
        }
      },
      "SetWebhookSecretRequest": {
        "type": "object",
        "description": "Set/rotate/clear the inbound-webhook HMAC secret request.",
        "properties": {
          "secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "The shared HMAC secret a Git host will sign payloads with. Rotates an existing secret;\n`null` clears it (disabling the webhook). The value is encrypted at rest and never\nreturned."
          }
        }
      },
      "SettingsOverrideFlags": {
        "type": "object",
        "description": "Flags indicating which settings are user overrides vs defaults.",
        "required": [
          "enabled",
          "provider_type",
          "api_url",
          "model",
          "timeout_secs",
          "check_interval_secs",
          "batch_size",
          "max_input_length",
          "max_retries",
          "temperature",
          "top_p",
          "max_tokens"
        ],
        "properties": {
          "api_url": {
            "type": "boolean"
          },
          "batch_size": {
            "type": "boolean"
          },
          "check_interval_secs": {
            "type": "boolean"
          },
          "enabled": {
            "type": "boolean"
          },
          "max_input_length": {
            "type": "boolean"
          },
          "max_retries": {
            "type": "boolean"
          },
          "max_tokens": {
            "type": "boolean"
          },
          "model": {
            "type": "boolean"
          },
          "provider_type": {
            "type": "boolean"
          },
          "temperature": {
            "type": "boolean"
          },
          "timeout_secs": {
            "type": "boolean"
          },
          "top_p": {
            "type": "boolean"
          }
        }
      },
      "SeverityCount": {
        "type": "object",
        "required": [
          "severity",
          "count"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64"
          },
          "severity": {
            "type": "string"
          }
        }
      },
      "ShortcutAction": {
        "type": "string",
        "description": "A rebindable keyboard action.\n\nLike [`ThemeKey`], the server owns the action vocabulary and Lens keys its\nlabel/default-key/category registry off the generated union.",
        "enum": [
          "go-dashboard",
          "go-deployments",
          "go-targets",
          "go-settings",
          "search",
          "help",
          "toggle-focus-mode",
          "toggle-reading-ruler"
        ]
      },
      "ShortcutOverride": {
        "type": "object",
        "description": "One rebound keyboard shortcut.\n\nOnly the action and its replacement key are stored: the label, category and\ndefault key are presentation belonging to the Lens registry, and storing them\nwould let a stale row override a changed default.",
        "required": [
          "action",
          "customKey"
        ],
        "properties": {
          "action": {
            "$ref": "#/components/schemas/ShortcutAction"
          },
          "customKey": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "SolutionDetailResponse": {
        "type": "object",
        "description": "Solution detail response (includes all versions)",
        "required": [
          "id",
          "name",
          "slug",
          "versions",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Solution ID"
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Solution name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SolutionVersionResponse"
            },
            "description": "All versions"
          }
        }
      },
      "SolutionEnvironmentStateResponse": {
        "type": "object",
        "description": "Environment state for a solution across all environments",
        "required": [
          "environment_id",
          "environment_name",
          "environment_sort_order",
          "target_count",
          "has_targets"
        ],
        "properties": {
          "current_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Currently deployed version (null if not deployed)"
          },
          "deployed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When deployed (null if not deployed)"
          },
          "deployed_by_username": {
            "type": [
              "string",
              "null"
            ],
            "description": "Username of who deployed (null if not deployed)"
          },
          "deployment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Deployment ID (null if not deployed)"
          },
          "environment_id": {
            "type": "string",
            "description": "Environment ID"
          },
          "environment_name": {
            "type": "string",
            "description": "Environment name"
          },
          "environment_sort_order": {
            "type": "integer",
            "format": "int32",
            "description": "Environment sort order (for progression)"
          },
          "has_targets": {
            "type": "boolean",
            "description": "Whether this environment has any targets configured"
          },
          "target_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of targets configured for this environment"
          }
        }
      },
      "SolutionResponse": {
        "type": "object",
        "description": "Solution response DTO",
        "required": [
          "id",
          "name",
          "slug",
          "version_count",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Solution ID"
          },
          "latest_version": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SolutionVersionResponse",
                "description": "Latest version (if any)"
              }
            ]
          },
          "managed_by_repo_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owning config repository (null = not Git-managed). When set, this definition is\nmanaged by a config repository and is read-only via the API/UI — edit it in Git."
          },
          "name": {
            "type": "string",
            "description": "Solution name"
          },
          "slug": {
            "type": "string",
            "description": "Stable slug (config-as-code reference key)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant owner (null = global/shared)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version_count": {
            "type": "integer",
            "description": "Number of versions",
            "minimum": 0
          }
        }
      },
      "SolutionVariableSetLinkResponse": {
        "type": "object",
        "description": "Solution-variable set link response",
        "required": [
          "id",
          "solution_id",
          "variable_set_id",
          "variable_set_name",
          "priority",
          "variable_count"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Link ID"
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority for variable resolution"
          },
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          },
          "variable_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of variables in this set"
          },
          "variable_set_id": {
            "type": "string",
            "description": "Variable set ID"
          },
          "variable_set_name": {
            "type": "string",
            "description": "Variable set name"
          }
        }
      },
      "SolutionVersionResponse": {
        "type": "object",
        "description": "Solution version response DTO",
        "required": [
          "id",
          "version",
          "sequence_count",
          "sequences",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "id": {
            "type": "string",
            "description": "Version ID"
          },
          "sequence_count": {
            "type": "integer",
            "description": "Number of sequences (for list view performance, avoids loading full sequence data)",
            "minimum": 0
          },
          "sequences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceEntryResponse"
            },
            "description": "Ordered sequences in this solution version"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "version": {
            "type": "string",
            "description": "Version number (semantic version)"
          }
        }
      },
      "SourceStateDto": {
        "type": "object",
        "description": "Source environment state summary",
        "required": [
          "deployed_at",
          "deployment_id"
        ],
        "properties": {
          "deployed_at": {
            "type": "string",
            "description": "When it was deployed"
          },
          "deployment_id": {
            "type": "string",
            "description": "Deployment ID"
          },
          "solution_version_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution version ID"
          }
        }
      },
      "SpeechReadingMode": {
        "type": "string",
        "description": "How much of the page text-to-speech reads at a time.",
        "enum": [
          "selection",
          "paragraph",
          "page"
        ]
      },
      "StartKeyRotationRequest": {
        "type": "object",
        "description": "Request to start a WireGuard key rotation.\n\nThe agent generates a new keypair and registers the new public key with the server.\nDuring the overlap window (default 30 seconds), both old and new keys are accepted.",
        "required": [
          "new_public_key"
        ],
        "properties": {
          "new_public_key": {
            "type": "string",
            "description": "The new WireGuard public key (base64-encoded 32 bytes)."
          },
          "rotation_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Optional rotation ID for idempotency (UUIDv8 format).\nIf not provided, the server will generate one."
          }
        }
      },
      "StartKeyRotationResponse": {
        "type": "object",
        "description": "Response after starting a key rotation.",
        "required": [
          "rotation_id",
          "overlap_expires_at",
          "current_key",
          "pending_key"
        ],
        "properties": {
          "current_key": {
            "type": "string",
            "description": "Current active public key (base64-encoded)."
          },
          "overlap_expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the overlap window expires (both keys accepted until this time)."
          },
          "pending_key": {
            "type": "string",
            "description": "Pending public key (base64-encoded)."
          },
          "rotation_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this rotation operation (for audit correlation)."
          }
        }
      },
      "StatisticsPeriod": {
        "type": "string",
        "description": "Time window for dashboard statistics queries.",
        "enum": [
          "day",
          "week",
          "month",
          "quarter",
          "year"
        ]
      },
      "SubscriptionResponse": {
        "type": "object",
        "description": "Subscription response with associated channel and filter info.",
        "required": [
          "id",
          "name",
          "user_id",
          "channel_id",
          "channel_name",
          "email_digest_enabled",
          "enabled",
          "filters",
          "created_at"
        ],
        "properties": {
          "channel_id": {
            "type": "string",
            "format": "uuid",
            "description": "Associated channel ID"
          },
          "channel_name": {
            "type": "string",
            "description": "Associated channel name"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the subscription was created"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "email_digest_enabled": {
            "type": "boolean",
            "description": "Whether email digest is enabled"
          },
          "email_digest_frequency": {
            "type": [
              "string",
              "null"
            ],
            "description": "Digest frequency (if enabled) - hourly, daily, weekly",
            "example": "daily"
          },
          "email_recipient_override": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email recipient override (if set)"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the subscription is enabled"
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterResponse"
            },
            "description": "Filters applied to this subscription"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Subscription ID"
          },
          "name": {
            "type": "string",
            "description": "Subscription name"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the subscription was last updated"
          },
          "user_id": {
            "type": "string",
            "format": "uuid",
            "description": "User who owns this subscription"
          }
        }
      },
      "SyncPullTally": {
        "type": "object",
        "description": "Per-run import tallies (when the sync pulled Git → DB).",
        "required": [
          "created",
          "updated",
          "skipped",
          "unsupported",
          "ignored_immutable"
        ],
        "properties": {
          "created": {
            "type": "integer",
            "minimum": 0
          },
          "ignored_immutable": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`<kind>/<slug>@<version>` for already-published versions edited in place in Git — IGNORED\n(versions are immutable; bump the version to apply). Surfaced so the change isn't silently lost."
          },
          "skipped": {
            "type": "integer",
            "minimum": 0
          },
          "unsupported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "updated": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "SyncRepositoryRequest": {
        "type": "object",
        "description": "Trigger-sync request: override the conflict strategy and/or preview without writing.",
        "properties": {
          "conflict_strategy": {
            "type": [
              "string",
              "null"
            ],
            "description": "`fail` (default) | `skip` (DB wins conflicts) | `upsert` (Git wins conflicts)."
          },
          "dry_run": {
            "type": "boolean",
            "description": "Validate + detect conflicts without writing to the DB, Git, or `sync_conflicts`."
          }
        }
      },
      "SyncRepositoryResponse": {
        "type": "object",
        "description": "Trigger-sync response.",
        "required": [
          "status",
          "direction",
          "dry_run",
          "conflicts"
        ],
        "properties": {
          "conflicts": {
            "type": "integer",
            "description": "Number of 3-way conflicts detected (recorded to `sync_conflicts` unless dry-run).",
            "minimum": 0
          },
          "direction": {
            "type": "string",
            "description": "`pull` | `push` | `bidirectional` (the repository's configured direction)."
          },
          "dry_run": {
            "type": "boolean"
          },
          "head_commit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Repository HEAD after the run."
          },
          "pulled": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SyncPullTally",
                "description": "Import tallies (when the direction pulled)."
              }
            ]
          },
          "pushed_commit": {
            "type": [
              "string",
              "null"
            ],
            "description": "New commit pushed to Git (when the direction pushed and there were changes)."
          },
          "status": {
            "type": "string",
            "description": "`success` | `conflict` | `failed`."
          }
        }
      },
      "TableEncryptionStats": {
        "type": "object",
        "description": "Statistics for a single table's encryption status.",
        "required": [
          "table_id",
          "total",
          "encrypted",
          "unencrypted",
          "percentage"
        ],
        "properties": {
          "encrypted": {
            "type": "integer",
            "format": "int64",
            "description": "Number of encrypted records"
          },
          "percentage": {
            "type": "number",
            "format": "double",
            "description": "Encryption percentage (0.0 - 100.0)"
          },
          "table_id": {
            "type": "string",
            "description": "Table identifier (generic name, not actual table name for security)"
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of records"
          },
          "unencrypted": {
            "type": "integer",
            "format": "int64",
            "description": "Number of unencrypted records"
          }
        }
      },
      "TableVerificationResult": {
        "type": "object",
        "description": "Verification result for a single table.",
        "required": [
          "table_id",
          "verified",
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "integer",
            "format": "int64",
            "description": "Number of records that failed verification"
          },
          "table_id": {
            "type": "string",
            "description": "Table identifier (generic name)"
          },
          "verified": {
            "type": "integer",
            "format": "int64",
            "description": "Number of records successfully verified"
          }
        }
      },
      "TagFilter": {
        "type": "object",
        "description": "Tag filter for selecting targets or tenants",
        "required": [
          "key",
          "value"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Tag key"
          },
          "value": {
            "type": "string",
            "description": "Tag value"
          }
        }
      },
      "TagResponse": {
        "type": "object",
        "description": "Tag response DTO",
        "required": [
          "id",
          "key",
          "value"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Tag ID"
          },
          "key": {
            "type": "string",
            "description": "Tag key"
          },
          "tenants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TenantRef"
            },
            "description": "Tenants that have adopted this tag (populated on list endpoints only)"
          },
          "value": {
            "type": "string",
            "description": "Tag value"
          }
        }
      },
      "TargetCertificateResponse": {
        "type": "object",
        "description": "Certificate response for target associations",
        "required": [
          "id",
          "common_name",
          "serial_number",
          "certificate_type",
          "revoked",
          "valid_from",
          "valid_until",
          "linked_at"
        ],
        "properties": {
          "certificate_type": {
            "type": "string",
            "description": "Certificate type (client, server, ca)"
          },
          "common_name": {
            "type": "string",
            "description": "Common name (CN) from the certificate"
          },
          "id": {
            "type": "string",
            "description": "Certificate ID"
          },
          "linked_at": {
            "type": "string",
            "description": "When the certificate was linked to this target"
          },
          "revoked": {
            "type": "boolean",
            "description": "Whether the certificate is revoked"
          },
          "serial_number": {
            "type": "string",
            "description": "Certificate serial number (for matching during registration)"
          },
          "valid_from": {
            "type": "string",
            "description": "Certificate validity start"
          },
          "valid_until": {
            "type": "string",
            "description": "Certificate validity end"
          }
        }
      },
      "TargetCountResponse": {
        "type": "object",
        "description": "Target count response",
        "required": [
          "environment_id",
          "count"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of targets configured"
          },
          "environment_id": {
            "type": "string",
            "description": "Environment ID"
          }
        }
      },
      "TargetDetailResponse": {
        "type": "object",
        "description": "Target detail response (includes tags)",
        "required": [
          "id",
          "name",
          "mode",
          "hostname",
          "port",
          "tags",
          "created_at"
        ],
        "properties": {
          "assigned_thorax_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When Thorax was assigned"
          },
          "assigned_thorax_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Assigned Thorax instance ID (for topology visualization)"
          },
          "certificate_serial": {
            "type": [
              "string",
              "null"
            ],
            "description": "Certificate serial for auto-registered targets (links client cert to target)"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "hostname": {
            "type": "string",
            "description": "Hostname or IP address"
          },
          "id": {
            "type": "string",
            "description": "Target ID"
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last seen timestamp"
          },
          "mode": {
            "type": "string",
            "description": "Target mode (Listen or Poll)"
          },
          "name": {
            "type": "string",
            "description": "Target name"
          },
          "port": {
            "type": "integer",
            "format": "int32",
            "description": "Port number",
            "minimum": 0
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target status (online, stale, offline)"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagResponse"
            },
            "description": "Associated tags"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "TargetExecutionModeDto": {
        "oneOf": [
          {
            "type": "string",
            "description": "Execute on all targets in parallel",
            "enum": [
              "parallel"
            ]
          },
          {
            "type": "string",
            "description": "Execute on targets sequentially (one at a time)",
            "enum": [
              "sequential"
            ]
          },
          {
            "type": "object",
            "description": "Execute in rolling waves (n targets at a time)",
            "required": [
              "rolling"
            ],
            "properties": {
              "rolling": {
                "type": "object",
                "description": "Execute in rolling waves (n targets at a time)",
                "required": [
                  "batch_size"
                ],
                "properties": {
                  "batch_size": {
                    "type": "integer",
                    "format": "int32",
                    "minimum": 0
                  }
                }
              }
            }
          }
        ],
        "description": "Target execution mode DTO"
      },
      "TargetResponse": {
        "type": "object",
        "description": "Target response DTO",
        "required": [
          "id",
          "name",
          "mode",
          "hostname",
          "port",
          "tags",
          "created_at"
        ],
        "properties": {
          "assigned_thorax_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When Thorax was assigned"
          },
          "assigned_thorax_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Assigned Thorax instance ID (for topology visualization)"
          },
          "certificate_serial": {
            "type": [
              "string",
              "null"
            ],
            "description": "Certificate serial for auto-registered targets (links client cert to target)"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "hostname": {
            "type": "string",
            "description": "Hostname or IP address"
          },
          "id": {
            "type": "string",
            "description": "Target ID"
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last seen timestamp"
          },
          "mode": {
            "type": "string",
            "description": "Target mode (Listen or Poll)"
          },
          "name": {
            "type": "string",
            "description": "Target name"
          },
          "port": {
            "type": "integer",
            "format": "int32",
            "description": "Port number",
            "minimum": 0
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target status (online, stale, offline)"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagResponse"
            },
            "description": "Associated tags (for filtering/preview in deployment forms)"
          },
          "tenants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TenantRef"
            },
            "description": "Tenants that own this target (populated on list endpoints only)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "TargetSummary": {
        "type": "object",
        "description": "Summary of target status for preview",
        "required": [
          "total",
          "online",
          "offline",
          "stale"
        ],
        "properties": {
          "offline": {
            "type": "integer",
            "description": "Number of offline targets",
            "minimum": 0
          },
          "online": {
            "type": "integer",
            "description": "Number of online targets",
            "minimum": 0
          },
          "stale": {
            "type": "integer",
            "description": "Number of stale targets (not checked in recently)",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "description": "Total number of targets",
            "minimum": 0
          }
        }
      },
      "TenantDetailResponse": {
        "type": "object",
        "description": "Detailed tenant response with relationships",
        "required": [
          "id",
          "name",
          "tags",
          "created_at"
        ],
        "properties": {
          "contact_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Contact email"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant description"
          },
          "id": {
            "type": "string",
            "description": "Tenant ID"
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logo URL"
          },
          "name": {
            "type": "string",
            "description": "Tenant name"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagResponse"
            },
            "description": "Tenant tags"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "TenantRef": {
        "type": "object",
        "description": "Minimal owning-tenant descriptor for list rows (All-Tenants Tenant column).",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "TenantResponse": {
        "type": "object",
        "description": "Tenant response DTO",
        "required": [
          "id",
          "name",
          "created_at"
        ],
        "properties": {
          "contact_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Contact email"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant description"
          },
          "id": {
            "type": "string",
            "description": "Tenant ID"
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logo URL"
          },
          "name": {
            "type": "string",
            "description": "Tenant name"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          }
        }
      },
      "TenantSolutionEnvironmentResponse": {
        "type": "object",
        "description": "Tenant-solution-environment relationship response",
        "required": [
          "solution_id",
          "solution_name",
          "environment_id",
          "environment_name",
          "is_active"
        ],
        "properties": {
          "environment_id": {
            "type": "string",
            "description": "Environment ID"
          },
          "environment_name": {
            "type": "string",
            "description": "Environment name"
          },
          "is_active": {
            "type": "boolean",
            "description": "Is the relationship active"
          },
          "solution_id": {
            "type": "string",
            "description": "Solution ID"
          },
          "solution_name": {
            "type": "string",
            "description": "Solution name"
          }
        }
      },
      "TenantStatisticsResponse": {
        "type": "object",
        "description": "Tenant statistics response",
        "required": [
          "tenant_id",
          "tenant_name",
          "deployment_stats",
          "resource_counts",
          "recent_activity"
        ],
        "properties": {
          "deployment_stats": {
            "$ref": "#/components/schemas/DeploymentStatistics",
            "description": "Deployment statistics"
          },
          "recent_activity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActivityEntry"
            },
            "description": "Recent activity entries"
          },
          "resource_counts": {
            "$ref": "#/components/schemas/ResourceCounts",
            "description": "Resource counts"
          },
          "tenant_id": {
            "type": "string",
            "description": "Tenant ID"
          },
          "tenant_name": {
            "type": "string",
            "description": "Tenant name"
          }
        }
      },
      "TestAnalysisRequest": {
        "type": "object",
        "description": "Request to test analysis with sample log input.",
        "required": [
          "log_text"
        ],
        "properties": {
          "log_text": {
            "type": "string",
            "description": "Sample log text to analyze (can include stdout, stderr, error message)"
          }
        }
      },
      "TestAnalysisResponse": {
        "type": "object",
        "description": "Response from test analysis.",
        "required": [
          "success",
          "duration_ms"
        ],
        "properties": {
          "confidence": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "description": "Confidence score (0.0-1.0)"
          },
          "duration_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Time taken in milliseconds",
            "minimum": 0
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if analysis failed"
          },
          "likely_cause": {
            "type": [
              "string",
              "null"
            ],
            "description": "Likely root cause"
          },
          "remediation": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Suggested remediation steps"
          },
          "success": {
            "type": "boolean",
            "description": "Whether the analysis succeeded"
          },
          "summary": {
            "type": [
              "string",
              "null"
            ],
            "description": "Summary of the error"
          }
        }
      },
      "TestChannelResponse": {
        "type": "object",
        "description": "Response from testing a notification channel.",
        "required": [
          "success",
          "latency_ms"
        ],
        "properties": {
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message if the test failed"
          },
          "latency_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Response latency in milliseconds",
            "minimum": 0
          },
          "success": {
            "type": "boolean",
            "description": "Whether the test was successful"
          }
        }
      },
      "TestConnectionDetails": {
        "type": "object",
        "description": "Detailed connection test results",
        "required": [
          "discovery_reachable",
          "authorization_reachable",
          "token_reachable",
          "jwks_reachable",
          "response_time_ms"
        ],
        "properties": {
          "authorization_reachable": {
            "type": "boolean",
            "description": "Whether the authorization endpoint is reachable"
          },
          "discovery_reachable": {
            "type": "boolean",
            "description": "Whether the discovery endpoint is reachable"
          },
          "jwks_reachable": {
            "type": "boolean",
            "description": "Whether the JWKS endpoint is reachable"
          },
          "response_time_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Response time in milliseconds",
            "minimum": 0
          },
          "token_reachable": {
            "type": "boolean",
            "description": "Whether the token endpoint is reachable"
          }
        }
      },
      "TestConnectionRequest": {
        "type": "object",
        "description": "Test connection request",
        "properties": {
          "client_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional: test with specific client credentials"
          },
          "client_secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional: test with specific client secret"
          }
        },
        "additionalProperties": false
      },
      "TestConnectionResponse": {
        "type": "object",
        "description": "Test connection response",
        "required": [
          "success",
          "message"
        ],
        "properties": {
          "details": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TestConnectionDetails",
                "description": "Detailed test results"
              }
            ]
          },
          "message": {
            "type": "string",
            "description": "Test result message"
          },
          "success": {
            "type": "boolean",
            "description": "Whether the connection test was successful"
          }
        }
      },
      "ThemeKey": {
        "type": "string",
        "description": "A colour palette declared in Lens's `app.css` as a `:root[data-theme='…']`\nblock.\n\nThe server owns this vocabulary. It reaches Lens through the\nOpenAPI-generated `ThemeKey` union, and the client registry supplies only\nlabels and grouping keyed by that union — there is no second hand-written\nlist of theme keys anywhere.",
        "enum": [
          "twin",
          "nebula",
          "sequoia",
          "sunset",
          "oceanic",
          "royal",
          "copper",
          "light",
          "slate",
          "ember",
          "aurora",
          "synthwave",
          "terminal",
          "bubblegum",
          "mono",
          "dracula",
          "nord",
          "tokyonight",
          "catppuccin",
          "gruvbox",
          "rosepine",
          "onedark",
          "monokai",
          "solarized",
          "everforest",
          "ayu",
          "kanagawa"
        ]
      },
      "ThoraxInstanceDetailResponse": {
        "type": "object",
        "description": "Thorax instance detail response DTO",
        "required": [
          "id",
          "instance_name",
          "hostname",
          "grpc_address",
          "version",
          "capabilities",
          "status",
          "is_global",
          "registered_at",
          "last_heartbeat_at",
          "active_sessions",
          "active_commands",
          "uptime_secs",
          "assigned_tenants",
          "created_at"
        ],
        "properties": {
          "active_commands": {
            "type": "integer",
            "format": "int32",
            "description": "Number of active commands"
          },
          "active_sessions": {
            "type": "integer",
            "format": "int32",
            "description": "Number of active sessions"
          },
          "assigned_tenants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AssignedTenantResponse"
            },
            "description": "Assigned tenants (when not global)"
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Instance capabilities"
          },
          "cfg_heartbeat_interval_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Per-instance heartbeat-cadence override (seconds); null = no override."
          },
          "cfg_session_timeout_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Per-instance session-timeout override (seconds); null = no override."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Created timestamp"
          },
          "deregistered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When deregistered (if applicable)"
          },
          "deregistered_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reason for deregistration (if applicable)"
          },
          "grpc_address": {
            "type": "string",
            "description": "gRPC address (host:port)"
          },
          "hostname": {
            "type": "string",
            "description": "Hostname where instance is running"
          },
          "id": {
            "type": "string",
            "description": "Instance ID (UUID)"
          },
          "instance_name": {
            "type": "string",
            "description": "Instance name (unique identifier)"
          },
          "is_global": {
            "type": "boolean",
            "description": "Whether instance is globally available"
          },
          "last_heartbeat_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last heartbeat timestamp"
          },
          "metadata": {
            "description": "Optional metadata"
          },
          "registered_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the instance registered"
          },
          "status": {
            "type": "string",
            "description": "Current status"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last updated timestamp"
          },
          "uptime_secs": {
            "type": "integer",
            "format": "int64",
            "description": "Instance uptime in seconds"
          },
          "version": {
            "type": "string",
            "description": "Thorax version"
          }
        }
      },
      "ThoraxInstanceResponse": {
        "type": "object",
        "description": "Thorax instance list response DTO",
        "required": [
          "id",
          "instance_name",
          "hostname",
          "grpc_address",
          "version",
          "status",
          "is_global",
          "tenant_count",
          "registered_at",
          "last_heartbeat_at",
          "active_sessions",
          "active_commands"
        ],
        "properties": {
          "active_commands": {
            "type": "integer",
            "format": "int32",
            "description": "Number of active commands"
          },
          "active_sessions": {
            "type": "integer",
            "format": "int32",
            "description": "Number of active sessions"
          },
          "deregistered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When deregistered (if applicable)"
          },
          "grpc_address": {
            "type": "string",
            "description": "gRPC address (host:port)"
          },
          "hostname": {
            "type": "string",
            "description": "Hostname where instance is running"
          },
          "id": {
            "type": "string",
            "description": "Instance ID (UUID)"
          },
          "instance_name": {
            "type": "string",
            "description": "Instance name (unique identifier)"
          },
          "is_global": {
            "type": "boolean",
            "description": "Whether instance is globally available"
          },
          "last_heartbeat_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last heartbeat timestamp"
          },
          "registered_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the instance registered"
          },
          "status": {
            "type": "string",
            "description": "Current status"
          },
          "tenant_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of assigned tenants (when not global)"
          },
          "version": {
            "type": "string",
            "description": "Thorax version"
          }
        }
      },
      "TimeWindow": {
        "type": "object",
        "description": "Time window. period=day|week|month|quarter|year selects a preset; period=relative with days selects a rolling window; period=custom with since and until (RFC 3339) selects an absolute span.",
        "required": [
          "period"
        ],
        "properties": {
          "days": {
            "type": "integer",
            "format": "int64",
            "description": "Rolling window length; only with period=relative."
          },
          "period": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month",
              "quarter",
              "year",
              "relative",
              "custom"
            ]
          },
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "Inclusive lower bound; only with period=custom."
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "description": "Inclusive upper bound; only with period=custom."
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "description": "Token response containing access and refresh tokens",
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "user"
        ],
        "properties": {
          "access_token": {
            "type": "string",
            "description": "JWT access token"
          },
          "expires_in": {
            "type": "integer",
            "format": "int64",
            "description": "Access token expiration in seconds"
          },
          "refresh_token": {
            "type": [
              "string",
              "null"
            ],
            "description": "Refresh token (optional)"
          },
          "token_type": {
            "type": "string",
            "description": "Token type (always \"Bearer\")"
          },
          "user": {
            "$ref": "#/components/schemas/UserResponse",
            "description": "User information"
          }
        }
      },
      "TopPattern": {
        "type": "object",
        "description": "A ranked pattern in the dashboard \"top recurring\" list.",
        "required": [
          "id",
          "fingerprint",
          "exit_code_class",
          "deployment_count",
          "occurrence_count",
          "target_count",
          "status",
          "last_seen_at"
        ],
        "properties": {
          "deployment_count": {
            "type": "integer",
            "format": "int64"
          },
          "exit_code_class": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time"
          },
          "occurrence_count": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string"
          },
          "target_count": {
            "type": "integer",
            "format": "int64"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "TopTenantEntry": {
        "type": "object",
        "description": "Top tenant entry for global dashboard",
        "required": [
          "tenant_id",
          "tenant_name",
          "deployment_count",
          "success_rate"
        ],
        "properties": {
          "deployment_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of deployments in the period"
          },
          "success_rate": {
            "type": "number",
            "format": "double",
            "description": "Success rate as a percentage"
          },
          "tenant_id": {
            "type": "string",
            "description": "Tenant ID"
          },
          "tenant_name": {
            "type": "string",
            "description": "Tenant name"
          }
        }
      },
      "TrendBucket": {
        "type": "object",
        "description": "One day's occurrence count in the trend series.",
        "required": [
          "day",
          "occurrences"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date"
          },
          "occurrences": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "TurnCredentialsRequest": {
        "type": "object",
        "description": "Request for TURN credentials.",
        "properties": {
          "ttl_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Requested TTL in seconds (max 43200 = 12 hours).",
            "minimum": 0
          }
        }
      },
      "TurnCredentialsResponse": {
        "type": "object",
        "description": "Response with short-term TURN credentials.\n\nCredentials are compatible with coturn's TURN REST API format.",
        "required": [
          "username",
          "password",
          "ttl_seconds",
          "expires_at",
          "servers"
        ],
        "properties": {
          "expires_at": {
            "type": "integer",
            "format": "int64",
            "description": "When credentials expire (Unix timestamp)."
          },
          "password": {
            "type": "string",
            "description": "HMAC-based password."
          },
          "servers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TurnServerInfo"
            },
            "description": "TURN servers these credentials are valid for."
          },
          "ttl_seconds": {
            "type": "integer",
            "format": "int32",
            "description": "Credential lifetime in seconds.",
            "minimum": 0
          },
          "username": {
            "type": "string",
            "description": "Time-based username (format: <expires_at>:<agent_id>)."
          }
        }
      },
      "TurnServerInfo": {
        "type": "object",
        "description": "TURN server information.",
        "required": [
          "address",
          "protocol",
          "name"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "Server address (host:port format)."
          },
          "name": {
            "type": "string",
            "description": "Server identifier for logging."
          },
          "protocol": {
            "type": "string",
            "description": "Transport protocol: \"udp\", \"tcp\", or \"tls\"."
          },
          "realm": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional server realm for authentication."
          }
        }
      },
      "TwoFactorBackupCodesResponse": {
        "type": "object",
        "description": "Response for backup codes regeneration",
        "required": [
          "backup_codes"
        ],
        "properties": {
          "backup_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "New backup codes (shown only once)\nEach code is 8 characters, formatted as XXXX-XXXX"
          }
        }
      },
      "TwoFactorDisableRequest": {
        "type": "object",
        "description": "Request to disable 2FA",
        "required": [
          "password",
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "6-digit TOTP code for verification"
          },
          "password": {
            "type": "string",
            "description": "Current password for verification"
          }
        },
        "additionalProperties": false
      },
      "TwoFactorRequiredResponse": {
        "type": "object",
        "description": "Login response when 2FA is required",
        "required": [
          "requires_2fa",
          "pending_token"
        ],
        "properties": {
          "pending_token": {
            "type": "string",
            "description": "Pending token to use with 2FA verification (5-minute TTL)"
          },
          "requires_2fa": {
            "type": "boolean",
            "description": "Indicates 2FA is required to complete login"
          }
        }
      },
      "TwoFactorSetupResponse": {
        "type": "object",
        "description": "Response for 2FA setup initiation",
        "required": [
          "qr_code_data_url",
          "otpauth_uri",
          "secret"
        ],
        "properties": {
          "otpauth_uri": {
            "type": "string",
            "description": "The otpauth URI for manual entry in authenticator apps"
          },
          "qr_code_data_url": {
            "type": "string",
            "description": "Data URL containing the QR code image (PNG in base64)"
          },
          "secret": {
            "type": "string",
            "description": "The plain BASE32 secret formatted for manual entry (e.g., \"YBB2 QH4P H3GG ...\")"
          }
        }
      },
      "TwoFactorStatusResponse": {
        "type": "object",
        "description": "Response for 2FA status check",
        "required": [
          "enabled",
          "backup_codes_remaining"
        ],
        "properties": {
          "backup_codes_remaining": {
            "type": "integer",
            "format": "int64",
            "description": "Number of remaining unused backup codes"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether 2FA is enabled"
          },
          "enabled_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When 2FA was enabled (if enabled)"
          }
        }
      },
      "TwoFactorVerifyRequest": {
        "type": "object",
        "description": "Request to verify TOTP code during login",
        "required": [
          "code",
          "pending_token"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "6-digit TOTP code or 8-character backup code"
          },
          "pending_token": {
            "type": "string",
            "description": "Pending authentication token from login response"
          }
        },
        "additionalProperties": false
      },
      "TwoFactorVerifySetupRequest": {
        "type": "object",
        "description": "Request to verify TOTP code during 2FA setup",
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "6-digit TOTP code from authenticator app"
          }
        },
        "additionalProperties": false
      },
      "TwoFactorVerifySetupResponse": {
        "type": "object",
        "description": "Response for 2FA setup verification (includes backup codes)",
        "required": [
          "enabled",
          "backup_codes"
        ],
        "properties": {
          "backup_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Backup codes (shown only once during setup)\nEach code is 8 characters, formatted as XXXX-XXXX"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether 2FA is now enabled"
          }
        }
      },
      "UnlinkCertificatesRequest": {
        "type": "object",
        "description": "Unlink certificates from target request",
        "required": [
          "certificate_ids"
        ],
        "properties": {
          "certificate_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of certificate IDs to unlink"
          }
        }
      },
      "UpdateActionRequest": {
        "type": "object",
        "description": "Update action request",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action name"
          }
        }
      },
      "UpdateActionVersionRequest": {
        "type": "object",
        "description": "Update action version request",
        "properties": {
          "executor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional executor (sh, bash, pwsh, zsh, etc.)"
          },
          "payload_description": {
            "description": "Payload description (JSON representation)"
          },
          "payload_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Payload type (Command, Script, Restart)"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version (semantic version)"
          }
        }
      },
      "UpdateAnalysisSettingsRequest": {
        "type": "object",
        "description": "Request to update analysis settings.",
        "properties": {
          "api_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "API key (write-only, encrypted before storage)"
          },
          "api_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "API URL for the LLM provider"
          },
          "batch_size": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Number of requests per batch"
          },
          "check_interval_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Interval between processing batches"
          },
          "clear_api_key": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Set to true to clear the API key"
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether AI analysis is enabled"
          },
          "max_input_length": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum input length for analysis"
          },
          "max_retries": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum retry attempts"
          },
          "max_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum number of tokens to generate"
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model name"
          },
          "pattern_alert_enabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "pattern_alert_min_deployments": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_alert_min_occurrences": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_alert_min_targets": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_alert_window_days": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_batch_interval_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_detection_enabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "pattern_label_max_input_chars": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_label_max_samples": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_llm_labeling_enabled": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "pattern_max_batch_size": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_relabel_factor": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_retention_days": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "pattern_window_days": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "provider_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Provider type (ollama or openai)"
          },
          "temperature": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "description": "Temperature for LLM generation (0.0-1.0)"
          },
          "timeout_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Request timeout in seconds"
          },
          "tls_ca_cert_path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional path to custom TLS CA certificate"
          },
          "top_p": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "description": "Top-p (nucleus) sampling threshold (0.0-1.0)"
          }
        }
      },
      "UpdateChannelRequest": {
        "type": "object",
        "description": "Request to update an existing notification channel.",
        "properties": {
          "discord_webhook_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the channel is enabled"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated channel name"
          },
          "slack_bot_token": {
            "type": [
              "string",
              "null"
            ],
            "description": "New Slack bot token (will be encrypted)"
          },
          "slack_channel": {
            "type": [
              "string",
              "null"
            ]
          },
          "slack_webhook_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_from_address": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_from_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_host": {
            "type": [
              "string",
              "null"
            ]
          },
          "smtp_password": {
            "type": [
              "string",
              "null"
            ],
            "description": "New SMTP password (will be encrypted)"
          },
          "smtp_port": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "smtp_use_tls": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "smtp_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "teams_workflow_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "webhook_headers": {},
          "webhook_secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "New webhook secret (will be encrypted)"
          },
          "webhook_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "UpdateEndpointRequest": {
        "type": "object",
        "description": "Request to update agent's WireGuard endpoint information.",
        "required": [
          "public_endpoint",
          "nat_type"
        ],
        "properties": {
          "nat_type": {
            "$ref": "#/components/schemas/NatType",
            "description": "Detected NAT type."
          },
          "public_endpoint": {
            "type": "string",
            "description": "Public endpoint as discovered by STUN (host:port format)."
          }
        }
      },
      "UpdateEnvironmentRequest": {
        "type": "object",
        "description": "Update environment request",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment description"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment name"
          },
          "sort_order": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Sort order for environment progression"
          }
        }
      },
      "UpdateFreezeRequest": {
        "type": "object",
        "description": "Update deployment freeze request",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Freeze description"
          },
          "end_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "End time (UTC, ISO 8601 format)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID"
          },
          "is_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the freeze is enabled"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Freeze name"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID"
          },
          "start_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Start time (UTC, ISO 8601 format)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID"
          }
        }
      },
      "UpdateGitAuthRequest": {
        "type": "object",
        "description": "Update Git auth request",
        "properties": {
          "auth_type": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/GitAuthTypeDto",
                "description": "Auth type (ssh_key, https_basic, https_token)"
              }
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Auth name"
          },
          "password": {
            "type": [
              "string",
              "null"
            ],
            "description": "Password or token (for https auth)"
          },
          "ssh_passphrase": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH passphrase (for encrypted keys)"
          },
          "ssh_private_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH private key (for ssh auth)"
          },
          "ssh_public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "SSH public key (for ssh auth)"
          },
          "username": {
            "type": [
              "string",
              "null"
            ],
            "description": "Username (for https auth)"
          }
        },
        "additionalProperties": false
      },
      "UpdateGitStorageRequest": {
        "type": "object",
        "description": "Update Git storage request",
        "properties": {
          "auth_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional Git auth ID"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Storage name"
          },
          "path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Local path for Git clone"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "Git reference (branch, tag, or commit)"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Git repository URL"
          }
        },
        "additionalProperties": false
      },
      "UpdateIdentityProviderRequest": {
        "type": "object",
        "description": "Update identity provider request",
        "properties": {
          "auto_create_users": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether to auto-create users"
          },
          "client_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client ID (optional update)"
          },
          "client_secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client secret (optional update - only if rotating)"
          },
          "default_role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default role ID for auto-created users (null to remove)"
          },
          "is_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the provider is enabled"
          },
          "issuer_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Issuer URL (optional update)"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Provider name (optional update)"
          },
          "scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Scopes (optional update)"
          },
          "trust_unverified_email": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "When true, allow linking an OIDC identity to an existing local user by email\nif the ID token's `email_verified` claim is true. Default false fails closed\non cross-IdP email collisions."
          }
        },
        "additionalProperties": false
      },
      "UpdateLocalStorageRequest": {
        "type": "object",
        "description": "Update local storage request",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Storage name"
          },
          "path": {
            "type": [
              "string",
              "null"
            ],
            "description": "File system path"
          }
        },
        "additionalProperties": false
      },
      "UpdateOAuth2ClientRequest": {
        "type": "object",
        "properties": {
          "allowed_scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "client_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "default_scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "grant_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "is_active": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "redirect_uris": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "UpdatePatternRequest": {
        "type": "object",
        "description": "PATCH body to change a pattern's lifecycle status (mute/resolve/reactivate).",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "New status: `active` (reactivate), `muted`, or `resolved`."
          }
        }
      },
      "UpdateProfileRequest": {
        "type": "object",
        "description": "Update user profile request",
        "properties": {
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name (optional, max 100 characters)\nSet to null or empty string to clear the display name"
          }
        },
        "additionalProperties": false
      },
      "UpdateRegistrationTokenRequest": {
        "type": "object",
        "description": "Request to update a registration token",
        "properties": {
          "auto_approve": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether clients registered with this token are auto-approved"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the token expires (ISO 8601 format, null = never)"
          },
          "max_uses": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Maximum uses allowed (null = unlimited)"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable name for the token"
          }
        }
      },
      "UpdateRepositoryRequest": {
        "type": "object",
        "description": "Update-repository request (slug + tenant are immutable; sync state is engine-managed).",
        "properties": {
          "auto_sync": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_auth_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_branch": {
            "type": [
              "string",
              "null"
            ]
          },
          "git_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "sync_direction": {
            "type": [
              "string",
              "null"
            ]
          },
          "sync_interval_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          }
        }
      },
      "UpdateRoleMappingRequest": {
        "type": "object",
        "description": "Update role mapping request (only provided fields change)",
        "properties": {
          "external_group": {
            "type": [
              "string",
              "null"
            ],
            "description": "External IdP group/claim value to match"
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Priority (higher = processed first)"
          },
          "role_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role ID to assign when matched"
          }
        },
        "additionalProperties": false
      },
      "UpdateRoleRequest": {
        "type": "object",
        "description": "Update role request",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role description (optional update)"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role name (optional update)"
          }
        },
        "additionalProperties": false
      },
      "UpdateS3StorageRequest": {
        "type": "object",
        "description": "Update S3 storage request",
        "properties": {
          "access_key_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "AWS Access Key ID"
          },
          "auth_type": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/S3AuthTypeDto",
                "description": "Authentication type: \"static\" or \"iam_role\""
              }
            ]
          },
          "bucket": {
            "type": [
              "string",
              "null"
            ],
            "description": "S3 bucket name"
          },
          "endpoint_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional endpoint URL for S3-compatible services (MinIO, etc.)"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "External ID for cross-account AssumeRole"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Storage name"
          },
          "path_prefix": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional path prefix within the bucket"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "description": "AWS region (e.g., \"us-east-1\")"
          },
          "role_arn": {
            "type": [
              "string",
              "null"
            ],
            "description": "IAM Role ARN"
          },
          "secret_access_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "AWS Secret Access Key"
          }
        },
        "additionalProperties": false
      },
      "UpdateScheduleRequest": {
        "type": "object",
        "description": "Update deployment schedule request",
        "properties": {
          "action_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Action ID (mutually exclusive with solution_id and sequence_id)"
          },
          "deployment_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ScheduledDeploymentConfigDto",
                "description": "Deployment configuration"
              }
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Schedule description (None = no change, Some(None) = clear, Some(Some(v)) = set)"
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment ID"
          },
          "is_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the schedule is enabled"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Schedule name"
          },
          "recurrence_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceConfigDto",
                "description": "Recurrence configuration"
              }
            ]
          },
          "recurrence_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence end date"
          },
          "recurrence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Recurrence type"
          },
          "scheduled_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scheduled time (UTC, ISO 8601 format)"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence ID (mutually exclusive with solution_id and action_id)"
          },
          "solution_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution ID (mutually exclusive with sequence_id and action_id)"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ],
            "description": "IANA timezone name (e.g., \"America/New_York\", \"Europe/London\")"
          },
          "version_requirement": {
            "type": [
              "string",
              "null"
            ],
            "description": "Version requirement"
          }
        }
      },
      "UpdateSequenceRequest": {
        "type": "object",
        "description": "Update sequence request",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sequence name"
          }
        }
      },
      "UpdateSequenceVersionActionsRequest": {
        "type": "object",
        "description": "Update sequence version actions request",
        "required": [
          "actions"
        ],
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionEntryRequest"
            },
            "description": "Ordered actions"
          }
        }
      },
      "UpdateSequenceVersionRequest": {
        "type": "object",
        "description": "Update sequence version request",
        "properties": {
          "actions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ActionEntryRequest"
            },
            "description": "Ordered actions - optional, keeps current if not provided"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "New version number (semantic version) - optional, keeps current if not provided"
          }
        }
      },
      "UpdateSolutionRequest": {
        "type": "object",
        "description": "Update solution request",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Solution name"
          }
        }
      },
      "UpdateSolutionVersionRequest": {
        "type": "object",
        "description": "Update solution version request",
        "properties": {
          "sequences": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/SequenceEntryRequest"
            },
            "description": "Optional ordered sequences (replaces existing if provided)"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "New version number (optional, semantic version)"
          }
        }
      },
      "UpdateSolutionVersionSequencesRequest": {
        "type": "object",
        "description": "Update solution version sequences request",
        "required": [
          "sequences"
        ],
        "properties": {
          "sequences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceEntryRequest"
            },
            "description": "Ordered sequences"
          }
        }
      },
      "UpdateSubscriptionRequest": {
        "type": "object",
        "description": "Request to update a subscription.",
        "properties": {
          "channel_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Updated channel ID"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated description"
          },
          "email_digest_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Updated email digest enabled status"
          },
          "email_digest_frequency": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated digest frequency (hourly, daily, weekly)",
            "example": "daily"
          },
          "email_recipient_override": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated email recipient override"
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Updated enabled status"
          },
          "filters": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/FilterInput"
            },
            "description": "Full replacement set of filters. When present, the subscription's filters\nbecome exactly this set (applied as an atomic delete-then-insert); an\nempty array clears all filters. Omit the field to leave existing filters\nunchanged — single-filter add/remove still go through the dedicated\nfilter endpoints."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Updated name"
          }
        }
      },
      "UpdateTagRequest": {
        "type": "object",
        "description": "Update tag request",
        "properties": {
          "key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tag key"
          },
          "value": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tag value"
          }
        }
      },
      "UpdateTargetRequest": {
        "type": "object",
        "description": "Update target request",
        "properties": {
          "hostname": {
            "type": [
              "string",
              "null"
            ],
            "description": "Hostname or IP address (validated against private/internal addresses)"
          },
          "mode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target mode (Listen or Poll)"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Target name"
          },
          "port": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Port number",
            "minimum": 0
          }
        }
      },
      "UpdateTenantRequest": {
        "type": "object",
        "description": "Update tenant request",
        "properties": {
          "contact_email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Contact email"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant description"
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logo URL"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name"
          }
        }
      },
      "UpdateThoraxInstanceConfigRequest": {
        "type": "object",
        "description": "Update a Thorax instance's per-instance runtime configuration overrides.\n\nEach field is tri-state (see [`double_option`]): omit to leave unchanged,\nsend `null` to clear (revert to the instance default), or send a positive\ninteger to set. Mandible pushes set overrides to the instance via the\nheartbeat `config_update`, which the instance applies live.",
        "properties": {
          "heartbeat_interval_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Heartbeat cadence override (seconds, > 0)."
          },
          "session_timeout_secs": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "description": "Session-timeout override (seconds, > 0)."
          }
        }
      },
      "UpdateThoraxInstanceRequest": {
        "type": "object",
        "description": "Update thorax instance request",
        "properties": {
          "is_global": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Toggle global availability (true = available to all tenants)"
          },
          "metadata": {
            "description": "Optional metadata JSON"
          }
        }
      },
      "UpdateUserPreferencesRequest": {
        "type": "object",
        "description": "Partial preference update. Omit a field to leave it unchanged; send `null` to\nreset it to the system default.",
        "properties": {
          "accessibility_prefs": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AccessibilityPreferences"
              }
            ]
          },
          "dashboard_default_view": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DashboardView"
              }
            ]
          },
          "deployment_inspector_tab": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DeploymentInspectorTab"
              }
            ]
          },
          "deployments_bucket_filter": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DeploymentsBucketFilter"
              }
            ]
          },
          "deployments_default_view": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DeploymentsDefaultView"
              }
            ]
          },
          "list_page_size": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ListPageSize"
              }
            ]
          },
          "list_view_mode": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ListViewMode"
              }
            ]
          },
          "shortcut_overrides": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ShortcutOverride"
            }
          },
          "statistics_window": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TimeWindow",
                "description": "Accepts any [`TimeWindow`], including an absolute range, so that an\nunsaveable range is rejected by name rather than silently dropped."
              }
            ]
          },
          "theme": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ThemeKey"
              }
            ]
          }
        },
        "additionalProperties": false
      },
      "UpdateUserRequest": {
        "type": "object",
        "description": "Update user request (admin only)",
        "properties": {
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name (optional update)"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email address (optional update)"
          },
          "email_verified": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether email is verified"
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Account status (Active, Inactive, Locked, Pending)"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID to associate with (null to remove)"
          },
          "username": {
            "type": [
              "string",
              "null"
            ],
            "description": "Username (optional update)"
          }
        },
        "additionalProperties": false
      },
      "UpdateVariableRequest": {
        "type": "object",
        "description": "Update scoped variable request",
        "properties": {
          "certificate_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_prompted": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_control_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_description": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_required": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "prompt_select_options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Value"
              }
            ]
          },
          "scope_environment_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "value": {
            "type": [
              "string",
              "null"
            ]
          },
          "variable_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "worker_pool_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "UpdateVariableSetRequest": {
        "type": "object",
        "description": "Update variable set request",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Set name (must be unique within tenant)"
          }
        }
      },
      "UserPreferencesResponse": {
        "type": "object",
        "description": "Effective preferences for the authenticated user.",
        "required": [
          "theme",
          "list_view_mode",
          "dashboard_default_view",
          "statistics_window",
          "deployment_inspector_tab",
          "list_page_size",
          "deployments_bucket_filter",
          "deployments_default_view"
        ],
        "properties": {
          "accessibility_prefs": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AccessibilityPreferences",
                "description": "Accessibility preferences. Every field is optional; an absent field means\nthe client keeps its own default. Null when nothing was ever stored."
              }
            ]
          },
          "dashboard_default_view": {
            "$ref": "#/components/schemas/DashboardView",
            "description": "Dashboard sub-view to land on."
          },
          "deployment_inspector_tab": {
            "$ref": "#/components/schemas/DeploymentInspectorTab",
            "description": "Deployment inspector tab to open first."
          },
          "deployments_bucket_filter": {
            "$ref": "#/components/schemas/DeploymentsBucketFilter",
            "description": "Deployment list status bucket filter."
          },
          "deployments_default_view": {
            "$ref": "#/components/schemas/DeploymentsDefaultView",
            "description": "Deployments page rendering to land on."
          },
          "list_page_size": {
            "$ref": "#/components/schemas/ListPageSize",
            "description": "List page size; one of 10, 20, 50, 100."
          },
          "list_view_mode": {
            "$ref": "#/components/schemas/ListViewMode",
            "description": "Entity list rendering mode."
          },
          "shortcut_overrides": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ShortcutOverride"
            },
            "description": "Rebound keyboard shortcuts, or null when unset."
          },
          "statistics_window": {
            "$ref": "#/components/schemas/SavedTimeWindow",
            "description": "Saved time window for dashboard statistics: a preset, or a rolling\nwindow of `days`. Absolute ranges are session-only and never stored."
          },
          "theme": {
            "$ref": "#/components/schemas/ThemeKey",
            "description": "Colour palette to apply to the interface."
          }
        }
      },
      "UserResponse": {
        "type": "object",
        "description": "User response DTO",
        "required": [
          "id",
          "email",
          "username",
          "status",
          "email_verified",
          "roles",
          "permissions",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Account created timestamp"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "email_verified": {
            "type": "boolean",
            "description": "Whether email is verified"
          },
          "id": {
            "type": "string",
            "description": "User ID"
          },
          "last_login_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last login timestamp"
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Aggregated permissions from all assigned roles"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "User roles"
          },
          "status": {
            "type": "string",
            "description": "Account status"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant this user belongs to; null for global/system admins"
          },
          "username": {
            "type": "string",
            "description": "Username"
          }
        }
      },
      "Value": {},
      "VariableResponse": {
        "type": "object",
        "description": "Scoped variable response DTO",
        "required": [
          "id",
          "name",
          "variable_type",
          "is_encrypted",
          "is_prompted",
          "prompt_required",
          "created_at"
        ],
        "properties": {
          "certificate_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "is_encrypted": {
            "type": "boolean"
          },
          "is_prompted": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "prompt_control_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_description": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt_required": {
            "type": "boolean"
          },
          "prompt_select_options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Value"
              }
            ]
          },
          "scope_environment_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "scope_variable_set_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "value": {
            "type": [
              "string",
              "null"
            ],
            "description": "Value (masked if sensitive)"
          },
          "variable_type": {
            "type": "string"
          },
          "worker_pool_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "VariableSetResponse": {
        "type": "object",
        "description": "Variable set response DTO",
        "required": [
          "id",
          "name",
          "variable_count",
          "solution_count",
          "created_at"
        ],
        "properties": {
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "created_by_user_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Created by user ID"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "id": {
            "type": "string",
            "description": "Set ID"
          },
          "name": {
            "type": "string",
            "description": "Set name"
          },
          "solution_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of solutions using this set"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (None for global variable sets)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name for display (None for global variable sets)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last update timestamp"
          },
          "variable_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of variables in this set"
          }
        }
      },
      "VariableSetSummary": {
        "type": "object",
        "description": "Variable set summary (for list responses)",
        "required": [
          "id",
          "name",
          "variable_count"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional description"
          },
          "id": {
            "type": "string",
            "description": "Set ID"
          },
          "name": {
            "type": "string",
            "description": "Set name"
          },
          "tenant_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant ID (None for global variable sets)"
          },
          "tenant_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tenant name for display (None for global variable sets)"
          },
          "variable_count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of variables in this set"
          }
        }
      },
      "VariableSummary": {
        "type": "object",
        "description": "Summary for list responses",
        "required": [
          "id",
          "name",
          "variable_type",
          "is_encrypted",
          "is_prompted"
        ],
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "is_encrypted": {
            "type": "boolean"
          },
          "is_prompted": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "scope_environment_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "variable_type": {
            "type": "string"
          }
        }
      },
      "VerifyEncryptionRequest": {
        "type": "object",
        "description": "Request to verify encryption key.",
        "required": [
          "key"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Base64-encoded encryption key to verify"
          }
        }
      },
      "VerifyEncryptionResponse": {
        "type": "object",
        "description": "Response for encryption verification endpoint.",
        "required": [
          "success",
          "total_verified",
          "total_errors",
          "table_results"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether verification was successful overall"
          },
          "table_results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TableVerificationResult"
            },
            "description": "Results per table"
          },
          "total_errors": {
            "type": "integer",
            "format": "int64",
            "description": "Total errors encountered"
          },
          "total_verified": {
            "type": "integer",
            "format": "int64",
            "description": "Total records verified"
          }
        }
      },
      "WebhookReconcileResponse": {
        "type": "object",
        "description": "Inbound Git-provider webhook reconcile response.",
        "required": [
          "status",
          "conflicts"
        ],
        "properties": {
          "conflicts": {
            "type": "integer",
            "description": "Conflicts the reconcile held back (blocked deletions / 3-way conflicts).",
            "minimum": 0
          },
          "head_commit": {
            "type": [
              "string",
              "null"
            ],
            "description": "HEAD commit the reconcile observed (absent when debounced or on a push-only repo)."
          },
          "status": {
            "type": "string",
            "description": "`reconciled` (a sync ran) | `debounced` (a recent sync already covers HEAD) | `duplicate`\n(this provider delivery id was already accepted — replay / double-delivery, skipped)."
          }
        }
      },
      "WireGuardPeerInfo": {
        "type": "object",
        "description": "A WireGuard overlay peer the requesting agent may tunnel to.",
        "required": [
          "agent_id",
          "public_key",
          "overlay_ip",
          "allowed_ips"
        ],
        "properties": {
          "agent_id": {
            "type": "string",
            "format": "uuid",
            "description": "The peer agent's registration ID."
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Addresses routed to this peer (its overlay /32)."
          },
          "endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "The peer's discovered endpoint (host:port) for direct UDP, if known."
          },
          "overlay_ip": {
            "type": "string",
            "description": "The peer's overlay IP in CIDR notation (e.g. \"10.99.0.5/32\")."
          },
          "public_key": {
            "type": "string",
            "description": "The peer's WireGuard public key (base64)."
          }
        }
      },
      "WireGuardStatusResponse": {
        "type": "object",
        "description": "WireGuard connection status for an agent.",
        "required": [
          "enabled"
        ],
        "properties": {
          "connection_mode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current connection mode: \"direct_udp\", \"turn_relay\", or \"websocket_relay\"."
          },
          "controller_overlay_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "The assigned controller's overlay IP (the address the agent tunnels its Thorax\ngRPC to)."
          },
          "controller_public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "The assigned controller's (Thorax) WireGuard public key, if the agent has an\nactive session pinned to a WireGuard-enabled controller."
          },
          "controller_udp_endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "The assigned controller's advertised WireGuard UDP endpoint."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether WireGuard transport is enabled for this agent."
          },
          "last_handshake": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last successful WireGuard handshake time."
          },
          "nat_type": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/NatType",
                "description": "Detected NAT type."
              }
            ]
          },
          "overlay_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "Agent's overlay IP address (if assigned)."
          },
          "public_endpoint": {
            "type": [
              "string",
              "null"
            ],
            "description": "Agent's public endpoint (if known)."
          }
        }
      },
      "WireGuardSummaryResponse": {
        "type": "object",
        "description": "Summary of WireGuard usage for a tenant.",
        "required": [
          "total_enabled",
          "connected",
          "nat_type_distribution",
          "connection_mode_distribution"
        ],
        "properties": {
          "connected": {
            "type": "integer",
            "format": "int64",
            "description": "Agents currently connected via WireGuard.",
            "minimum": 0
          },
          "connection_mode_distribution": {
            "$ref": "#/components/schemas/ConnectionModeDistribution",
            "description": "Connection mode distribution."
          },
          "nat_type_distribution": {
            "$ref": "#/components/schemas/NatTypeDistribution",
            "description": "NAT type distribution."
          },
          "total_enabled": {
            "type": "integer",
            "format": "int64",
            "description": "Total agents with WireGuard enabled.",
            "minimum": 0
          }
        }
      }
    },
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT access token"
      }
    }
  },
  "tags": [
    {
      "name": "health",
      "description": "Health check endpoints"
    },
    {
      "name": "server",
      "description": "Server information and discovery"
    },
    {
      "name": "auth",
      "description": "Authentication endpoints"
    },
    {
      "name": "actions",
      "description": "Action management"
    },
    {
      "name": "sequences",
      "description": "Sequence management"
    },
    {
      "name": "solutions",
      "description": "Solution management"
    },
    {
      "name": "targets",
      "description": "Target management"
    },
    {
      "name": "tags",
      "description": "Tag management"
    },
    {
      "name": "environments",
      "description": "Environment management"
    },
    {
      "name": "tenants",
      "description": "Tenant management (multi-tenancy)"
    },
    {
      "name": "deployments",
      "description": "Deployment execution"
    },
    {
      "name": "storage",
      "description": "Storage backend management"
    },
    {
      "name": "certificates",
      "description": "Certificate expiration monitoring"
    },
    {
      "name": "registrations",
      "description": "Client registration management"
    },
    {
      "name": "audit",
      "description": "Immutable audit log access"
    },
    {
      "name": "cache",
      "description": "File cache management"
    },
    {
      "name": "schedules",
      "description": "Deployment schedule management"
    },
    {
      "name": "freezes",
      "description": "Deployment freeze periods"
    },
    {
      "name": "rollbacks",
      "description": "Deployment rollback operations"
    },
    {
      "name": "promotions",
      "description": "Solution promotion workflows"
    },
    {
      "name": "statistics",
      "description": "Platform statistics and metrics"
    },
    {
      "name": "admin",
      "description": "Administrative operations"
    },
    {
      "name": "notifications",
      "description": "Notification channels and subscriptions"
    },
    {
      "name": "sse",
      "description": "Server-Sent Events for real-time updates"
    },
    {
      "name": "wireguard",
      "description": "WireGuard transport coordination (NAT traversal, key rotation)"
    },
    {
      "name": "config",
      "description": "Config-as-Code: export/import and Git-backed repositories"
    }
  ]
}