openapi: 3.1.0
info:
  title: Bairav Portal API
  version: 1.0.1
  summary: Manage agents, policies, keys, the audit ledger and security data.
  description: |-
    The Portal API is what the Bairav console uses. Everything you can do in the console you can do here, within your role.

    **Authentication.** Sign in with `POST /api/auth/breakglass` to get a 1-hour access token and a 14-day refresh token, then send `Authorization: Bearer <access token>`. Your tenant comes from the token. Never send a tenant ID in a request body.

    **Conventions.** Paths are under `/api/` and are not versioned. Errors are `{"detail": ...}`. Lists return `{"items": [...]}` and page with `limit` and `cursor`. Every response carries `X-Request-ID` (send your own to correlate).

    **What this reference does not yet describe.** Request bodies are fully described. Many **response** bodies are not yet typed in the Bairav source, so those operations show an empty success schema. Use the examples in the guides for the calls you will use first.

    This reference is generated from the Bairav source and published only for the operations listed in the portal allowlist.
  contact:
    name: Bairav developer support
    email: BTG.Support@prokraya.com
  x-source:
    repo: Bairav-MVP2
    commit: 870b92fe954c5ecc55c3ae745e2c6f1f8cf43dd1
    exportedAt: 2026-10-29T17:08:05Z
servers:
  - url: https://{host}
    description: Your Bairav deployment
    variables:
      host:
        default: your-tenant.example.com
        description: The hostname of your Bairav deployment.
tags:
  - name: Administration
    description: Users, tenant settings, sensor enrolment tokens and sensor downloads. Admin role required.
  - name: Agent catalog
    description: Approved agents, access requests and grants.
  - name: Agent ledger
    description: Business-level view of what each agent did.
  - name: Agent observability
    description: Executions, traces, models, latency, tokens and policy decisions per agent.
  - name: Agents
    description: The agent registry and lifecycle actions. Suspend is reversible; block is not.
  - name: Assets and vulnerabilities
    description: Software inventory, SBOM uploads and vulnerability assessment.
  - name: Audit ledger
    description: The hash-chained, append-only record of every governed action. Verify it and export it.
  - name: Dashboard
    description: Fleet posture and devices.
  - name: Data lineage
    description: Which agents touch which data stores, and what that exposes.
  - name: Execution events
    description: Raw execution events, traces and redacted exports.
  - name: Gateway keys and requests
    description: Create and revoke gateway keys, and review governed requests.
  - name: Health
    description: Liveness.
  - name: Incidents
    description: Open, investigate and resolve security incidents.
  - name: Intake queue
    description: Newly discovered agents waiting for an approve or reject decision.
  - name: Policies and approvals
    description: Author, version and publish policies, check what they would match, and decide approvals.
  - name: Policy packs
    description: Ready-made sets of policies you can preview and apply.
  - name: Salesforce Agentforce
    description: Connect a Salesforce org and govern its agents.
  - name: Security events and findings
    description: Events, detections, findings, ingest tokens and the ingest dead-letter queue.
  - name: Security posture
    description: Posture and the remediation queue.
  - name: Sensors
    description: Sensor health, coverage and retention.
  - name: Shadow agents
    description: Discover and triage agents that are running without registration.
  - name: Sign-in and session
    description: Get a session token with a local account, refresh it, and read who you are signed in as. Browser single sign-on is not part of this API.
  - name: Simulation lab
    description: Blast radius, exposure scoring and adversarial testing. These are simulations; no live agent action runs.
  - name: Traffic and cost
    description: Requests, tokens and cost accounting, with CSV export.
  - name: Try it out
    description: Dry-run a request or policy change and see the decision without acting.
paths:
  /api/admin/downloads/sensor:
    post:
      description: "Settings → Sensor deployment: downloadable endpoint-sensor package (F-10.6)."
      operationId: download_sensor_package_api_admin_downloads_sensor_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SensorPackageBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Download sensor package
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/downloads/sensor-msi:
    post:
      description: |-
        Settings → Sensor deployment: MSI counterpart to /downloads/sensor.

        Two distinct downloads, mirroring the ZIP package's own two buttons:
          - token_name omitted -> the plain, generic MSI as-is. SERVERURL/TOKEN
            are supplied by whoever runs it (msiexec ... SERVERURL=... TOKEN=...).
          - token_name set -> a fresh enrollment token for THIS tenant, baked
            into a per-download copy of the MSI as real default property values
            (see _build_preconfigured_msi) — a plain double-click installs and
            enrolls with no prompts and no separate launcher script.
      operationId: download_sensor_msi_api_admin_downloads_sensor_msi_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SensorPackageBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Download sensor msi
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/enrollment-tokens:
    get:
      operationId: list_tokens_api_admin_enrollment_tokens_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List tokens
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      operationId: create_token_api_admin_enrollment_tokens_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TokenBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create a sensor enrolment token
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
      description: Create a `bst_` token a sensor uses in the `X-Sensor-Token` header. The secret is shown once. Admin role required.
  /api/admin/enrollment-tokens/{token_id}:
    delete:
      operationId: revoke_token_api_admin_enrollment_tokens__token_id__delete
      parameters:
        - in: path
          name: token_id
          required: true
          schema:
            title: Token Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Revoke token
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/enrollment-tokens/{token_id}/purge:
    delete:
      description: |-
        Hard-delete an enrollment token row (removes it from the list entirely).
        Unlike revoke (which keeps an audit-visible 'revoked' row), this is a
        permanent deletion — used to tidy up obsolete/revoked tokens.
      operationId: delete_token_api_admin_enrollment_tokens__token_id__purge_delete
      parameters:
        - in: path
          name: token_id
          required: true
          schema:
            title: Token Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete token
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/settings:
    get:
      operationId: get_settings_api_admin_settings_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get settings
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    put:
      operationId: put_settings_api_admin_settings_put
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__admin_org__SettingsBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Put settings
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/users:
    get:
      operationId: list_users_api_admin_users_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List users
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      operationId: create_user_api_admin_users_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create user
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/admin/users/{user_id}:
    patch:
      operationId: update_user_api_admin_users__user_id__patch
      parameters:
        - in: path
          name: user_id
          required: true
          schema:
            title: User Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserPatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Update user
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    delete:
      operationId: delete_user_api_admin_users__user_id__delete
      parameters:
        - in: path
          name: user_id
          required: true
          schema:
            title: User Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete user
      tags:
        - Administration
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents:
    get:
      operationId: list_agents_api_agents_get
      parameters:
        - in: query
          name: lifecycle
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Lifecycle
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List agents
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/rescore:
    post:
      description: |-
        Recompute risk/confidence/priority for EVERY discovered entity, and backfill
        the model for gateway-registered (OpenAI) agents from their recent traffic.

        Gateway agents/LLMs are created outside the sensor telemetry pipeline, so they
        are never scored at discovery the way sensor agents are — this fills that gap.
        The score is computed inline from the pure scoring functions and written with a
        minimal INSERT (inputs_event_ids left to its column default) so it cannot hit
        the empty-array pitfall that silently broke gateway scoring. Each entity runs in
        its own savepoint; per-entity failures are collected and returned with the exact
        error instead of surfacing a blank 500.
      operationId: rescore_api_agents_rescore_post
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Rescore
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}:
    get:
      operationId: agent_detail_api_agents__entity_id__get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent detail
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/block:
    post:
      operationId: block_api_agents__entity_id__block_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReasonBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Block
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/delegations:
    get:
      operationId: get_delegations_api_agents__entity_id__delegations_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get delegations
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    put:
      description: |-
        Replace the DECLARED "hands work to" list. Admin or reviewer. Observed links are never removed by this: dropping a
        declared link that was also observed leaves it observed-only.
      operationId: set_delegations_api_agents__entity_id__delegations_put
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DelegationBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Set delegations
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/delete:
    post:
      operationId: delete_agent_api_agents__entity_id__delete_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReasonBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete agent
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/platform-owner:
    post:
      description: |-
        Assign / replace / remove an agent's PLATFORM owner. Admin or reviewer — the
        same people who assign it at intake. The system owner is never touched. The
        ledger row records the platform owner who held the agent when the change was made
        (ctx.platform_owner) and the full before/after, so history from the previous
        tenure is never rewritten; ctx.system_owner stays the discovered system owner.
      operationId: change_platform_owner_api_agents__entity_id__platform_owner_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlatformOwnerBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Change platform owner
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/policies:
    post:
      description: Manually attach an enabled policy to this agent (F-05.5). Idempotent.
      operationId: attach_policy_api_agents__entity_id__policies_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AttachBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Attach policy
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/policies/{policy_id}:
    delete:
      description: Remove a manual policy attachment (does not affect scope-based matches).
      operationId: detach_policy_api_agents__entity_id__policies__policy_id__delete
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Detach policy
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/prompts:
    get:
      description: |-
        Prompt telemetry (sensor event 'agent.prompts'): severity counts plus the
        most recent prompts sent to this agent, newest first. Works for any
        lifecycle — reviewers use it at intake, auditors after approval.
      operationId: agent_prompts_api_agents__entity_id__prompts_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent prompts
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/reactivate:
    post:
      operationId: reactivate_api_agents__entity_id__reactivate_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Reactivate
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/rereview:
    post:
      operationId: rereview_api_agents__entity_id__rereview_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Rereview
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/agents/{entity_id}/suspend:
    post:
      operationId: suspend_api_agents__entity_id__suspend_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReasonBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Suspend
      tags:
        - Agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/approvals:
    get:
      operationId: list_approvals_api_approvals_get
      parameters:
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Status
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List approvals
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/approvals/{approval_id}/decide:
    post:
      operationId: decide_approval_api_approvals__approval_id__decide_post
      parameters:
        - in: path
          name: approval_id
          required: true
          schema:
            title: Approval Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__governance__DecideBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Decide approval
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/auth/breakglass:
    post:
      operationId: breakglass_api_auth_breakglass_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BreakglassBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenPair"
          description: A token pair.
        "401":
          description: The email or password is wrong, the account is disabled, or the credentials match more than one tenant.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Sign in with a local account
      tags:
        - Sign-in and session
      security: []
      x-response-schema-documented: true
      description: |
        Exchange an email and password for a session. This is the only sign-in that works without a browser, so it is the way a script or service obtains a token for this API. Browser single sign-on (Microsoft Entra ID) is separate.

        The access token lasts **1 hour** and the refresh token **14 days**. Send the access token as `Authorization: Bearer <token>` on every other call.

        If the same email and password match accounts in more than one tenant, the call fails with `401` rather than guessing.

        Treat these credentials as secrets: use a dedicated account with the narrowest role that works.
  /api/auth/me:
    get:
      operationId: me_api_auth_me_get
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Me"
          description: The identity behind the token.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get the signed-in identity
      tags:
        - Sign-in and session
      security:
        - BearerJWT: []
      x-response-schema-documented: true
      description: Returns who the token belongs to, the tenant, the role and the list of permissions the role grants. The server enforces permissions on every call; this list is for building your own UI.
  /api/auth/refresh:
    post:
      operationId: refresh_api_auth_refresh_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RefreshBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenPair"
          description: A new token pair.
        "401":
          description: The refresh token is invalid or expired.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Refresh a session
      tags:
        - Sign-in and session
      security: []
      x-response-schema-documented: true
      description: Swap a refresh token for a new access token and a new refresh token. Use the new refresh token next time.
  /api/bairav-ledger/agents:
    get:
      description: |-
        Every agent the platform knows about — sensor-discovered and gateway-
        registered — with its activity rollup and open-issue counts, for triage.
      operationId: agents_api_bairav_ledger_agents_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agents
      tags:
        - Agent ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/bairav-ledger/agents/{entity_id}/detail:
    get:
      description: |-
        Recent activity, flagged prompts and enforcement decisions for one agent —
        the drill-down a triager opens from the rollup.
      operationId: agent_detail_api_bairav_ledger_agents__entity_id__detail_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent detail
      tags:
        - Agent ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/bairav-ledger/events:
    get:
      operationId: events_api_bairav_ledger_events_get
      parameters:
        - in: query
          name: source
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Source
        - in: query
          name: min_severity
          required: false
          schema:
            default: info
            title: Min Severity
            type: string
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Q
        - in: query
          name: limit
          required: false
          schema:
            default: 200
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Events
      tags:
        - Agent ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/bairav-ledger/overview:
    get:
      operationId: overview_api_bairav_ledger_overview_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Overview
      tags:
        - Agent ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/access-requests:
    get:
      description: |-
        `mine`  — requests I filed.
        `owned` — requests for agents whose linked owner is me (empty if I own none).
        `all`   — admin: everything; reviewer: only agents with no active owner
                  (the governance fallback); anyone else: 403.
        The scope is enforced in SQL here, not trusted from the client.
      operationId: list_access_requests_api_catalog_access_requests_get
      parameters:
        - in: query
          name: scope
          required: false
          schema:
            default: mine
            enum:
              - mine
              - owned
              - all
            title: Scope
            type: string
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Status
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List access requests
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/access-requests/{request_id}/cancel:
    post:
      operationId: cancel_request_api_catalog_access_requests__request_id__cancel_post
      parameters:
        - in: path
          name: request_id
          required: true
          schema:
            title: Request Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Cancel request
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/access-requests/{request_id}/decide:
    post:
      operationId: decide_request_api_catalog_access_requests__request_id__decide_post
      parameters:
        - in: path
          name: request_id
          required: true
          schema:
            title: Request Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__catalog__DecideBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Decide request
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/agents:
    get:
      description: |-
        Approved / active agents only, as a deliberately small DTO — purpose,
        owner, risk and the data the agent touches. Never capabilities, tools,
        credentials or trust internals (those stay on Agent Detail).
      operationId: list_catalog_agents_api_catalog_agents_get
      parameters:
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Q
        - in: query
          name: team
          required: false
          schema:
            default: []
            items:
              type: string
            title: Team
            type: array
        - in: query
          name: data
          required: false
          schema:
            default: []
            items:
              type: string
            title: Data
            type: array
        - in: query
          name: risk
          required: false
          schema:
            default: []
            items:
              type: string
            title: Risk
            type: array
        - in: query
          name: access
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Access
        - in: query
          name: limit
          required: false
          schema:
            default: 200
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List catalog agents
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/agents/{entity_id}/access-requests:
    post:
      operationId: request_access_api_catalog_agents__entity_id__access_requests_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AccessRequestBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Request access
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/agents/{entity_id}/grants:
    get:
      operationId: list_grants_api_catalog_agents__entity_id__grants_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List grants
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/grants/{grant_id}/revoke:
    post:
      operationId: revoke_grant_api_catalog_grants__grant_id__revoke_post
      parameters:
        - in: path
          name: grant_id
          required: true
          schema:
            title: Grant Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RevokeBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Revoke grant
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/catalog/owner-candidates:
    get:
      description: |-
        Enabled users an agent can be assigned to. Admin/reviewer only (they are
        the ones who approve intake / change owners); a deliberately narrower payload
        than the admin-only user list (name + email only: no role, no auth/SSO fields).
      operationId: owner_candidates_api_catalog_owner_candidates_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Owner candidates
      tags:
        - Agent catalog
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/dashboard/posture:
    get:
      operationId: posture_api_dashboard_posture_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Posture
      tags:
        - Dashboard
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/devices:
    get:
      operationId: devices_api_devices_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Devices
      tags:
        - Dashboard
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/enforcement:
    get:
      description: |-
        The enforcement feed, newest first, one page at a time.

        Paging is a keyset cursor on the immutable `ev.id` (`before_id` = the last id of the previous page,
        echoed back as `next_cursor`), so a page never shifts or repeats while new decisions arrive. The
        filters (decision / entity_id / tier / policy name / window) are applied HERE, before the page is cut,
        so `total` is the real number of matching decisions and a filter reaches decisions beyond the first
        page (the feed used to be a fixed newest-300 list that the screen filtered locally).
        `facets` (first page only) lists every agent and policy that has a decision, independent of the
        filters, to fill the filter dropdowns; `stats.breakdown_24h` is the unfiltered 24h decision count.
      operationId: enforcement_feed_api_enforcement_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 200
            title: Limit
            type: integer
        - in: query
          name: before_id
          required: false
          schema:
            anyOf:
              - type: integer
              - type: "null"
            title: Before Id
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Decision
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: tier
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Tier
        - in: query
          name: policy
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Policy
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Enforcement feed
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/gateway/db-metrics:
    get:
      description: |-
        DB observability KPIs: volume, per-table/op, per-agent counts (drives the
        flow's DB animation), hourly series and the slowest queries.
      operationId: db_metrics_api_gateway_db_metrics_get
      parameters:
        - in: query
          name: hours
          required: false
          schema:
            default: 24
            maximum: 720
            title: Hours
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: DB metrics
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/gateway/db-queries:
    get:
      description: Live DB query log (Datadog-style) — the SQL each chat ran, redacted.
      operationId: db_queries_api_gateway_db_queries_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 200
            maximum: 1000
            title: Limit
            type: integer
        - in: query
          name: agent
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent
        - in: query
          name: table
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Table
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: DB queries
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/gateway/keys:
    get:
      operationId: list_keys_api_gateway_keys_get
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
          description: The gateway keys.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List gateway keys
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: true
      description: Lists gateway keys with their prefix, upstream and status. The secret is never returned after creation.
    post:
      operationId: create_key_api_gateway_keys_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/KeyBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GatewayKeyCreated"
          description: The new key. The secret is shown once.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create a gateway key
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: true
      description: |
        Create a key for the Bairav AI Gateway. **Admin role required.**

        The response contains the key in `token` and ready-to-use `openai_base_url`. **This is the only time the secret is shown.** Store it now.

        Keep using your own provider key in the `Authorization` header of your model calls; the gateway forwards it and never stores it. See the [Gateway quickstart](/docs/quickstarts/gateway).
  /api/gateway/keys/{key_id}:
    delete:
      operationId: revoke_key_api_gateway_keys__key_id__delete
      parameters:
        - in: path
          name: key_id
          required: true
          schema:
            title: Key Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  revoked:
                    type: boolean
          description: The key is revoked.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Revoke a gateway key
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: true
      description: Revokes the key so it stops working immediately. The row stays visible, marked revoked, for the audit trail. Admin role required.
  /api/gateway/keys/{key_id}/purge:
    delete:
      description: |-
        Hard-delete a gateway key row (used to tidy up revoked keys). Unlike revoke
        (which keeps an audit-visible 'revoked' row), this removes it permanently.
      operationId: delete_key_api_gateway_keys__key_id__purge_delete
      parameters:
        - in: path
          name: key_id
          required: true
          schema:
            title: Key Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete key
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/gateway/metrics:
    get:
      description: |-
        KPIs for the OpenAI LLM Monitoring dashboard: volumes by decision/stage/
        agent/model, tokens, latency, and an hourly time-series over the window.

        Reads the SAME facts and definitions as /api/traffic (shared/traffic_facts.py): an unknown value is NULL, never 0 - tokens are summed over
        model calls that reported usage only (NULL when none did), latency over measured completed calls only. `allowed` / `blocked` / `gated` /
        `errors` are request OUTCOMES (allowed + blocked + gated + errors = total; an allowed request the upstream answered with HTTP >= 400 is an error).
      operationId: metrics_api_gateway_metrics_get
      parameters:
        - in: query
          name: hours
          required: false
          schema:
            default: 24
            maximum: 720
            title: Hours
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Metrics
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/gateway/requests:
    get:
      operationId: list_requests_api_gateway_requests_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 100
            maximum: 500
            title: Limit
            type: integer
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Decision
        - in: query
          name: agent
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List requests
      tags:
        - Gateway keys and requests
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/health:
    get:
      operationId: health_api_health_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
      summary: Health
      tags:
        - Health
      security: []
      x-response-schema-documented: false
  /api/health/inference:
    get:
      description: |-
        Readiness for the two LLM-backed subsystems (the NL policy compiler and
        Agent-Bairav's Plain-English authoring) — each backend's own `health()` is
        reused unchanged, this endpoint only aggregates. Read-only, no persistence,
        safe to poll. Never touches `decide()` — inference readiness is completely
        independent of deterministic-evaluator health, matching §13's boundary.
      operationId: inference_health_api_health_inference_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Inference health
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/intake:
    get:
      operationId: list_intake_api_intake_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List intake
      tags:
        - Intake queue
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/intake/{entity_id}/approve:
    post:
      operationId: approve_api_intake__entity_id__approve_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ApproveBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Approve
      tags:
        - Intake queue
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/intake/{entity_id}/reject:
    post:
      operationId: reject_api_intake__entity_id__reject_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RejectBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Reject
      tags:
        - Intake queue
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/ledger:
    get:
      operationId: list_ledger_api_ledger_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            title: Limit
            type: integer
        - in: query
          name: before_id
          required: false
          schema:
            anyOf:
              - type: integer
              - type: "null"
            title: Before Id
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Cursor
        - in: query
          name: actor
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Actor
        - in: query
          name: action
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Action
        - in: query
          name: category
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Category
        - in: query
          name: exclude_category
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Exclude Category
        - in: query
          name: subject_table
          required: false
          schema:
            anyOf:
              - maxLength: 80
                type: string
              - type: "null"
            title: Subject Table
        - in: query
          name: subject_id
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Subject Id
        - in: query
          name: owner
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Owner
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: correlation_id
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Correlation Id
        - in: query
          name: result
          required: false
          schema:
            anyOf:
              - maxLength: 20
                type: string
              - type: "null"
            title: Result
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Q
        - in: query
          name: entry_id
          required: false
          schema:
            anyOf:
              - type: integer
              - type: "null"
            title: Entry Id
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List ledger
      tags:
        - Audit ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/ledger/agent-actions:
    get:
      description: |-
        Agent Audit Ledger: one row per GOVERNED AGENT ACTION, not per DB write.

        The append-only chain (list_ledger above) records portal state changes; this is
        the operational view a reviewer actually audits — what each agent tried to do,
        against which system, how policy decided, who approved it and what happened —
        assembled from the real enforcement record:

          gateway_requests   — every LLM action the AI Gateway saw (decision, policy,
                               model, tokens, latency, redacted prompt/response)
          gateway_db_queries — the SQL an agent ran during that work
          approval_requests  — who approved/denied a held action
          audit_ledger       — the hash-chain entry covering the same event

        Nothing is synthesised: a field with no source is returned null so the UI can
        show "—" rather than invent a value.
      operationId: agent_actions_api_ledger_agent_actions_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 500
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent actions
      tags:
        - Audit ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/ledger/export.csv:
    get:
      description: Requires the `export_audit` permission. At most 50,000 rows.
      operationId: export_csv_api_ledger_export_csv_get
      parameters:
        - in: query
          name: actor
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Actor
        - in: query
          name: action
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Action
        - in: query
          name: category
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Category
        - in: query
          name: exclude_category
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Exclude Category
        - in: query
          name: subject_table
          required: false
          schema:
            anyOf:
              - maxLength: 80
                type: string
              - type: "null"
            title: Subject Table
        - in: query
          name: subject_id
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Subject Id
        - in: query
          name: owner
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Owner
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: correlation_id
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Correlation Id
        - in: query
          name: result
          required: false
          schema:
            anyOf:
              - maxLength: 20
                type: string
              - type: "null"
            title: Result
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 120
                type: string
              - type: "null"
            title: Q
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Export the audit ledger as CSV
      tags:
        - Audit ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/ledger/head:
    get:
      description: The current head of the tenant's hash chain. Record it somewhere outside Bairav and pass it later as `expected_head` to `GET /api/ledger/verify`.
      operationId: head_api_ledger_head_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get the ledger head
      tags:
        - Audit ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/ledger/verify:
    get:
      description: |
        Runs the ledger's own verification and reports the first break, if any, with a reason per entry. Pass `expected_head` to check against a head hash you recorded earlier, which also detects truncation. See [Audit ledger](/docs/concepts/audit-ledger).
      operationId: verify_api_ledger_verify_get
      parameters:
        - description: an entry_hash recorded earlier from GET /api/ledger/head
          in: query
          name: expected_head
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            description: an entry_hash recorded earlier from GET /api/ledger/head
            title: Expected Head
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Verify the audit ledger
      tags:
        - Audit ledger
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage:
    get:
      description: |-
        Tenant-wide KPIs by default; `agent_id` narrows every count to just
        that agent's own edges - matching the reference control-plane's own
        behavior exactly (its KPI row is computed from the SAME agent-filtered
        `graph` its Map/Data/Issues tabs use - `DataLineage.jsx:245-270`).

        The four `*_paths`/`ways_data_can_leave`/`issues_found` fields mirror the
        reference's own KPI row wording; `agents`/`data_sources`/`crown_jewels`/
        `edges`/`ungoverned_edges` are this endpoint's original fields, kept for
        backward compatibility.
      operationId: lineage_summary_api_lineage_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage summary
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/agents:
    get:
      description: |-
        Per-agent 'pick an agent' cards (LIN-161): real source/tool/destination
        counts, critical stores, exits, unprotected paths and the top issue.
        Registered before the generic /`{node_kind}`/`{node_id}` route below so
        'agents' is never mistaken for a node_kind path param.
      operationId: lineage_agent_cards_api_lineage_agents_get
      parameters:
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage agent cards
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events:
    get:
      description: |-
        Paginated, filterable raw event feed - same keyset-pagination shape as
        ledger.py::list_ledger (before_id/limit, next_cursor = last id when the
        page is full).
      operationId: list_events_api_lineage_events_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            title: Limit
            type: integer
        - in: query
          name: before_id
          required: false
          schema:
            anyOf:
              - type: integer
              - type: "null"
            title: Before Id
        - in: query
          name: event_kind
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Kind
        - in: query
          name: event_source
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Source
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: ok
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: "null"
            title: Ok
        - in: query
          name: trace_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Trace Id
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Q
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List events
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events/agents/{entity_id}/execution-summary:
    get:
      description: |-
        Counts by event_kind/event_source, plus a daily sparkline - the
        Overview tab's real, non-fabricated activity summary. `days` is capped at
        90 so the sparkline query stays bounded.
      operationId: agent_execution_summary_api_lineage_events_agents__entity_id__execution_summary_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
        - in: query
          name: days
          required: false
          schema:
            default: 14
            title: Days
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent execution summary
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events/export.csv:
    get:
      operationId: export_csv_api_lineage_events_export_csv_get
      parameters:
        - in: query
          name: event_kind
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Kind
        - in: query
          name: event_source
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Source
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: ok
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: "null"
            title: Ok
        - in: query
          name: trace_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Trace Id
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Q
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Export CSV
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events/export.json:
    get:
      description: |-
        Redacted-by-construction export (every `detail` string leaf was already
        masked at ingestion, shared/lineage_events.py::record_execution_event) -
        RBAC-gated the same way audit export is (routers/auth.py's export_audit
        permission, held by admin/auditor).
      operationId: export_json_api_lineage_events_export_json_get
      parameters:
        - in: query
          name: event_kind
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Kind
        - in: query
          name: event_source
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Event Source
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: ok
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: "null"
            title: Ok
        - in: query
          name: trace_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Trace Id
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Q
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Export JSON
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events/risk/{agent_id}:
    get:
      description: |-
        LINEAGE_REARCHITECTURE.md §32 / design-docs/07_LINEAGE_RISK_ENGINE.md -
        a real, documented weighted score over this agent's own lineage_edges/
        lineage_events, not an invented number.
      operationId: agent_lineage_risk_api_lineage_events_risk__agent_id__get
      parameters:
        - in: path
          name: agent_id
          required: true
          schema:
            title: Agent Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent lineage risk
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/events/traces/{trace_id}:
    get:
      description: |-
        Every event sharing one trace_id, chronological - the "what happened
        during this unit of work" grouping (LINEAGE_REARCHITECTURE.md §5): one
        HTTP request/chat call today, honestly not a multi-call conversation
        until a caller adopts the optional run_id header (see
        LINEAGE_INSTRUMENTATION_GAPS.md).
      operationId: get_trace_api_lineage_events_traces__trace_id__get
      parameters:
        - in: path
          name: trace_id
          required: true
          schema:
            title: Trace Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get trace
      tags:
        - Execution events
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/findings:
    get:
      description: |-
        Real governance findings (LIN-160), ordered worst-first, each carrying
        the policy suggestion that would close it. Tenant-wide by default;
        `agent_id` narrows to just that agent's own findings.
      operationId: lineage_findings_api_lineage_findings_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage findings
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/stores:
    get:
      description: Per-store rollup (LIN-163) - the reference's 'Data' tab.
      operationId: lineage_store_rollup_api_lineage_stores_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage store rollup
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}:
    get:
      operationId: lineage_node_api_lineage__node_kind___node_id__get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage node
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}/downstream:
    get:
      operationId: lineage_downstream_api_lineage__node_kind___node_id__downstream_get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
        - in: query
          name: depth
          required: false
          schema:
            maximum: 20
            minimum: 1
            title: Depth
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage downstream
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}/flow:
    get:
      description: |-
        The reference's one-hop Sources/Tools/Destinations flow diagram
        (LIN-162) - agent-only, since a data_source has no 'own' outgoing edges
        in this schema (see lineage_service.py's module docstring).
      operationId: lineage_flow_api_lineage__node_kind___node_id__flow_get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage flow
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}/impact:
    get:
      operationId: lineage_impact_api_lineage__node_kind___node_id__impact_get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage impact
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}/paths:
    get:
      description: |-
        The path inspector (the reference's tracePaths()): every
        source -> agent -> destination path through one node, with the real
        enforcing / monitoring policies standing on it. `node_kind` may also be
        'external' here (an outside destination has no row of its own; its label
        is its id), which is why this route validates its own kinds.
      operationId: lineage_paths_api_lineage__node_kind___node_id__paths_get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
        - in: query
          name: window
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Window
        - in: query
          name: sensitivity
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Sensitivity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage paths
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/lineage/{node_kind}/{node_id}/upstream:
    get:
      operationId: lineage_upstream_api_lineage__node_kind___node_id__upstream_get
      parameters:
        - in: path
          name: node_kind
          required: true
          schema:
            title: Node Kind
            type: string
        - in: path
          name: node_id
          required: true
          schema:
            title: Node Id
            type: string
        - in: query
          name: depth
          required: false
          schema:
            maximum: 20
            minimum: 1
            title: Depth
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Lineage upstream
      tags:
        - Data lineage
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/agents:
    get:
      description: "Agents to pick from (registry agents that are not deleted). `environment` is always null: it is not recorded."
      operationId: list_agents_api_observability_agents_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 200
            maximum: 500
            minimum: 1
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List agents
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/agents/executions:
    get:
      description: |-
        Executions, newest first: gateway requests and/or saved Try It Out dry runs (`source`, default all). Each item has `source` and
        `execution_id` (`g:<id>` / `s:<uuid>`, unique across sources: use it as the key). `trace_id` of a gateway execution is resolved through
        the lineage event the gateway wrote for the request (null when the request has none, e.g. a pre-flight block that never identified an
        agent); a dry run's `trace_id` is its own (it writes no lineage). Gateway-only paging is keyset on id; mixed paging is keyset on
        (started_at, source, key).
      operationId: list_executions_api_observability_agents_executions_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - format: uuid
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: environment
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Environment
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - succeeded
                  - failed
                  - blocked
                  - gated
                type: string
              - type: "null"
            title: Status
        - description: gateway | simulation | all
          in: query
          name: source
          required: false
          schema:
            default: all
            description: gateway | simulation | all
            enum:
              - gateway
              - simulation
              - all
            title: Source
            type: string
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List executions
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/agents/executions/{execution_id}:
    get:
      description: |-
        One execution with its derived steps, the policy decisions recorded for it (policy version resolved from `policy_versions` by
        evaluation time), typed links and related security events / findings. Steps come only from real rows; what cannot be derived is a
        `not_instrumented` step. Never prompts, responses, tool arguments or reasoning.
      operationId: get_execution_api_observability_agents_executions__execution_id__get
      parameters:
        - in: path
          name: execution_id
          required: true
          schema:
            title: Execution Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get execution
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/agents/summary:
    get:
      operationId: agents_summary_api_observability_agents_summary_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - format: uuid
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: environment
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Environment
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - description: gateway | simulation | all
          in: query
          name: source
          required: false
          schema:
            default: all
            description: gateway | simulation | all
            enum:
              - gateway
              - simulation
              - all
            title: Source
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agents summary
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/agents/{entity_id}/security:
    get:
      description: |-
        One agent's security posture: its assets, findings (by severity + the open items), a timeline of finding changes, coverage (what is and is not
        assessed, and why) and the recommended remediation in priority order. Everything is read from rows the platform holds; a missing input is named.
      operationId: agent_security_api_observability_agents__entity_id__security_get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent security
      tags:
        - Security posture
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/models:
    get:
      operationId: list_models_api_observability_models_get
      parameters:
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List models
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/models/{model}:
    get:
      operationId: get_model_api_observability_models__model__get
      parameters:
        - in: path
          name: model
          required: true
          schema:
            title: Model
            type: string
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get model
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/traces:
    get:
      description: Traces whose events fall in the window, newest first. A trace that began before `since` shows only its in-window events.
      operationId: list_traces_api_observability_traces_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - format: uuid
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: environment
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Environment
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - ok
                  - error
                  - blocked
                  - gated
                  - unknown
                type: string
              - type: "null"
            title: Status
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List traces
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/observability/traces/{trace_id}:
    get:
      description: "Ordered spans of one trace. Never reasoning/chain-of-thought, prompts, responses or tool arguments: see the module docstring."
      operationId: get_trace_api_observability_traces__trace_id__get
      parameters:
        - in: path
          name: trace_id
          required: true
          schema:
            title: Trace Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get trace
      tags:
        - Agent observability
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies:
    get:
      operationId: list_policies_api_policies_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List policies
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      operationId: create_policy_api_policies_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/author:
    post:
      description: |-
        Plain-English sentence -> a proposed policy draft (Agent-Bairav, a local
        reasoning-capable LLM). This NEVER saves a policy - the caller reviews the
        draft in the composer and creates it via the normal POST /api/policies,
        exactly like a hand-built rule (the composer never saves straight from
        prose). Requires the same role as creating a policy, since drafting is the
        first step of the same action.
      operationId: author_policy_api_policies_author_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthorBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Author policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/compile:
    post:
      description: |-
        Natural language -> draft structured policy. NEVER persists — the draft is
        returned for the Composer to show the author, who edits/confirms it and then
        calls the pre-existing POST /api/policies to actually save it (§15 step 6).
        Fails closed (§22): an unreachable/misbehaving model returns `ok: false`
        with `errors` set, never a default-active or guessed-at policy.
      operationId: compile_policy_api_policies_compile_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompileBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Compile policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/conflicts:
    post:
      description: |-
        Deterministic-only conflict analysis (§19) — never asks an LLM which policy
        wins. Reuses the exact ACTION_PRECEDENCE `decide()` already applies, so a
        conflict verdict here always matches what enforcement would actually do.
      operationId: check_conflicts_api_policies_conflicts_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConflictCheckBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Check conflicts
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/fields:
    get:
      description: |-
        The condition-field catalog the composer and Try It Out build from —
        attribute fields (WHICH agent), request fields (WHAT is happening), the
        known capability list and the wildcard groups. Served from the engine's own
        constants so the UI never carries a second copy that can drift.
      operationId: policy_fields_api_policies_fields_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Policy fields
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/preview:
    post:
      operationId: preview_api_policies_preview_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PreviewBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Preview
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/replay:
    post:
      description: |-
        Re-check real past gateway decisions against TODAY's published rules. Reads
        `gateway_requests`; builds each request's canonical input; runs the same pipeline
        (deterministic) and compares with what the gateway decided then. Nothing is executed and
        no historical row is touched. Limits, stated rather than hidden: tool-call arguments and
        unmasked values were never stored, the answer of a blocked/held request was the refusal text
        (so it is not replayed), and the situation is reconstructed from the request record.
      operationId: replay_past_actions_api_policies_replay_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__simulation__ReplayBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Replay past actions
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/scenarios:
    get:
      operationId: list_scenarios_api_policies_scenarios_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List scenarios
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      description: Save a test case ("re-runs against every future draft"). Authors only — enforced here.
      operationId: save_scenario_api_policies_scenarios_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SaveBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Save scenario
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/scenarios/run:
    post:
      description: |-
        Run scenarios through the real pipeline and compare the outcome with the expected posture. Read-only. A case a behaviour rule
        decides is run again with the AI judge (bounded: concurrency, a case cap and a time budget); a case the judge could not answer is
        `unable_to_evaluate`, never a pass. With drafts → authors only; the run is then audited once.
      operationId: run_scenarios_api_policies_scenarios_run_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__simulation__RunBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Run scenarios
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/scenarios/{scenario_id}:
    delete:
      operationId: delete_scenario_api_policies_scenarios__scenario_id__delete
      parameters:
        - in: path
          name: scenario_id
          required: true
          schema:
            title: Scenario Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete scenario
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/simulate:
    post:
      description: |-
        Dry run of what Bairav would decide if THIS agent attempted THIS action in THIS
        situation right now. The whole answer comes from `shared.simulation.run_simulation` — the
        gateway's own pipeline, then STOP (see that module for the exact write boundary).
      operationId: simulate_policy_api_policies_simulate_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SimulateBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Simulate policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/simulate/examples:
    get:
      description: |-
        Real material to start a Try It Out scenario from: what THIS agent has actually been
        asked and answered through the gateway (already masked there), the tools it calls, and
        the most recent request each covering rule stopped. Read-only — same data, same tenant
        audience as /gateway/requests; no audit, no side effects. Tool-call ARGUMENTS are not
        recorded by the gateway, so replays carry tool names only.
      operationId: simulate_examples_api_policies_simulate_examples_get
      parameters:
        - in: query
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Simulate examples
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/simulate/inputs:
    get:
      description: |-
        The inputs worth asking for: the situation signals and text surfaces the rules that apply to THIS
        agent doing THIS action actually read (so the form shows "Number of records", not every field the
        engine knows). Read-only — no policy is evaluated against a request, nothing is written. Draft rules
        are authors-only, server-side.
      operationId: simulate_inputs_api_policies_simulate_inputs_get
      parameters:
        - in: query
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
        - in: query
          name: capability
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Capability
        - in: query
          name: policy_set
          required: false
          schema:
            default: published
            enum:
              - published
              - with_drafts
            title: Policy Set
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Simulate inputs
      tags:
        - Try it out
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/{policy_id}:
    patch:
      description: Toggle and/or edit a policy. Only the fields present in the request change.
      operationId: update_policy_api_policies__policy_id__patch
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyPatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Update policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    delete:
      description: |-
        Delete a policy (meeting ask: duplicates could only be disabled, never
        removed). Soft delete — the row is hidden and disabled, its manual
        attachments are dropped, but enforcement history / approvals keep resolving
        the policy name through their FKs.
      operationId: delete_policy_api_policies__policy_id__delete
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/{policy_id}/draft:
    put:
      description: |-
        Store (or replace) the pending draft of a published rule. The published rule keeps enforcing
        untouched: no version bump, no policy_versions row, no re-evaluation.
      operationId: save_policy_draft_api_policies__policy_id__draft_put
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyDraftBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Save policy draft
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    delete:
      description: Drop the pending draft; the published rule is untouched.
      operationId: discard_policy_draft_api_policies__policy_id__draft_delete
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Discard policy draft
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/{policy_id}/publish:
    post:
      description: |-
        Publish in one call, in one transaction.

        * ACTIVE/DISABLED with a pending draft: apply it (content -> version + 1 and a policy_versions row, like PATCH;
          `enabled` -> ACTIVE/DISABLED like the toggle), clear the draft, ledger `policy.published`.
        * DRAFT / VALIDATED / PENDING_APPROVAL: walk the legal chain to ACTIVE (a `policy.transitioned` entry per hop, then
          one `policy.published`); the version stays what it is (a rule saved as a draft is v1).
        * anything else: 409.
      operationId: publish_policy_api_policies__policy_id__publish_post
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Publish policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/{policy_id}/transition:
    post:
      description: |-
        Explicit lifecycle transitions beyond the two the existing PATCH/DELETE
        endpoints already cover (ACTIVE`<->`DISABLED via `enabled`, ->ARCHIVED via
        delete — both left completely unchanged, since worker_app/gateway_app
        filter on `enabled`/`deleted_at` directly and must never need to learn
        about a new lifecycle concept). This endpoint is what actually reaches the
        states those two can't: DRAFT->VALIDATED, VALIDATED->PENDING_APPROVAL,
        PENDING_APPROVAL->ACTIVE.

        Design correction made while implementing this (documented in
        POLICIES_COMPLETION.md rather than silently done): §18 originally proposed
        reusing `approval_requests` for the PENDING_APPROVAL->ACTIVE step. That
        table's `entity_id` column is NOT NULL — it structurally cannot represent
        "approve this policy itself" (there is no agent/entity involved), so this
        transition is a plain `manage_policies`-gated action instead, not a second
        approval-request row. Dual-control (a different reviewer than the author)
        is not enforced — a real gap if that guarantee is later required.
      operationId: transition_policy_api_policies__policy_id__transition_post
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TransitionBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Transition policy
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policies/{policy_id}/versions:
    get:
      operationId: list_policy_versions_api_policies__policy_id__versions_get
      parameters:
        - in: path
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List policy versions
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-evaluations/{evaluation_id}/explain:
    get:
      description: |-
        The explanation is derived from the RECORDED decision, never re-guessed by
        an LLM (§21). When the evaluation predates `context_snapshot` (POL migration
        19), the context is reconstructed from the entity's CURRENT state instead —
        `reconstructed: true` on the response says so explicitly rather than silently
        presenting a best-effort trace as an exact historical one.
      operationId: explain_evaluation_api_policy_evaluations__evaluation_id__explain_get
      parameters:
        - in: path
          name: evaluation_id
          required: true
          schema:
            title: Evaluation Id
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Explain evaluation
      tags:
        - Policies and approvals
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-packs:
    get:
      operationId: list_packs_api_policy_packs_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List packs
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      description: |-
        A custom pack: starts empty, custom (editable), unapplied. Framework/
        category default to the "your own bundle" values — a seeded reference
        pack (GDPR, SOC 2, ...) only ever comes from bootstrap, never this route.
      operationId: create_pack_api_policy_packs_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PackBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create pack
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-packs/{pack_id}:
    delete:
      description: |-
        Delete a CUSTOM pack. The rules, in order of safety:
          * a seeded reference pack is never deletable (403);
          * a pack is refused (409) while any rule it created is still live and enabled: deleting the bundle must never
            silently stop, or hide the origin of, a control that is enforcing right now. Disable or delete those rules first;
          * otherwise the pack and its (non-enforcing) templates are removed. Rules a pack already created are ordinary rules
            and are NOT touched (there is no link from a rule back to its pack), so a disabled rule survives the deletion.
        The deletion is ledgered (`policy_pack.deleted`); the ledger rows about the pack stay.
      operationId: delete_pack_api_policy_packs__pack_id__delete
      parameters:
        - in: path
          name: pack_id
          required: true
          schema:
            title: Pack Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Delete pack
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-packs/{pack_id}/apply:
    post:
      operationId: apply_pack_api_policy_packs__pack_id__apply_post
      parameters:
        - in: path
          name: pack_id
          required: true
          schema:
            title: Pack Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Apply pack
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-packs/{pack_id}/preview:
    post:
      operationId: preview_pack_api_policy_packs__pack_id__preview_post
      parameters:
        - in: path
          name: pack_id
          required: true
          schema:
            title: Pack Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Preview pack
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/policy-packs/{pack_id}/templates:
    post:
      description: |-
        Add one rule template to a pack — copied from an existing policy's
        fields, or freshly authored (frontend supplies the same body either way).
        Only a custom, not-yet-applied pack can be edited; a seeded reference pack
        is apply-only, and an applied pack's templates are already live — adding
        to it here would look like it changed the rules it already created.
      operationId: add_pack_template_api_policy_packs__pack_id__templates_post
      parameters:
        - in: path
          name: pack_id
          required: true
          schema:
            title: Pack Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PackTemplateBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Add pack template
      tags:
        - Policy packs
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/agents:
    get:
      operationId: list_agents_api_salesforce_agents_get
      parameters:
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Q
        - in: query
          name: remote_status
          required: false
          schema:
            anyOf:
              - maxLength: 20
                type: string
              - type: "null"
            title: Remote Status
        - in: query
          name: lifecycle
          required: false
          schema:
            anyOf:
              - maxLength: 20
                type: string
              - type: "null"
            title: Lifecycle
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List agents
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/agents/{entity_id}:
    get:
      operationId: agent_detail_api_salesforce_agents__entity_id__get
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Agent detail
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/agents/{entity_id}/test-conversation:
    post:
      description: |-
        Run a real conversation with a published, active agent through the Agent API. The agent's actions are LIVE (a flow can create or change real
        records), so the caller must acknowledge that. The Salesforce session is always ended.
      operationId: test_conversation_api_salesforce_agents__entity_id__test_conversation_post
      parameters:
        - in: path
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TestConversationIn"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Test conversation
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/connect/start:
    post:
      operationId: connect_start_api_salesforce_connect_start_post
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Connect start
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/connection:
    get:
      operationId: get_connection_api_salesforce_connection_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get connection
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    put:
      operationId: put_connection_api_salesforce_connection_put
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConnectionIn"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Put connection
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    delete:
      operationId: disconnect_api_salesforce_connection_delete
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Disconnect
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/connection/test:
    post:
      operationId: connection_test_api_salesforce_connection_test_post
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Connection test
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/findings:
    get:
      description: "Every governance finding (SF-001 .. SF-006) of every Salesforce agent, worst first: the Governance tab's list without one detail call per agent."
      operationId: list_findings_api_salesforce_findings_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List findings
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/overview:
    get:
      operationId: overview_api_salesforce_overview_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Overview
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/sessions:
    get:
      operationId: list_sessions_api_salesforce_sessions_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: before
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Before
        - in: query
          name: limit
          required: false
          schema:
            default: 25
            maximum: 100
            minimum: 1
            title: Limit
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List sessions
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/sessions/{session_id}:
    get:
      operationId: get_session_api_salesforce_sessions__session_id__get
      parameters:
        - in: path
          name: session_id
          required: true
          schema:
            title: Session Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get session
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/salesforce/sync:
    post:
      operationId: sync_now_api_salesforce_sync_post
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Sync now
      tags:
        - Salesforce Agentforce
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assessment/run:
    post:
      description: |-
        Start the chosen assessments now: one `assessment_runs` row per kind (status running) and one background job each. At most ONE manual run per tenant per 60 s
        (429 with Retry-After). A vulnerability scan with the advisory source disabled finishes as `skipped`: that is a coverage gap, not a clean result.
      operationId: run_assessment_api_security_assessment_run_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__security_assets__RunBody"
              default:
                kinds:
                  - asset_sync
                  - vuln_scan
                  - config_assess
      responses:
        "202":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Run assessment
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assessment/runs:
    get:
      operationId: list_assessment_runs_api_security_assessment_runs_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 20
            maximum: 100
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: kind
          required: false
          schema:
            anyOf:
              - enum:
                  - asset_sync
                  - vuln_scan
                  - config_assess
                  - rescan
                  - self_inventory
                type: string
              - type: "null"
            title: Kind
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List assessment runs
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assessment/settings:
    get:
      operationId: get_assessment_settings_api_security_assessment_settings_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get assessment settings
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    put:
      description: |-
        Only the fields present in the body change (`approved_models: null` clears the list back to "not configured"). The advisory source stays OFF until `osv_enabled`
        is set to true; the base URL must be https on a host the OPERATOR allow-listed.
      operationId: put_assessment_settings_api_security_assessment_settings_put
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__security_assets__SettingsBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Put assessment settings
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assets:
    get:
      description: |-
        Inventoried assets, A-Z by name. `components` is the sum over the asset's CURRENT inventory documents (null = no inventory received). `findings.open` counts
        open / acknowledged / investigating findings only (an accepted risk or a false positive is not open).
      operationId: list_assets_api_security_assets_get
      parameters:
        - in: query
          name: type
          required: false
          schema:
            anyOf:
              - enum:
                  - agent
                  - model
                  - model_deployment
                  - dependency_set
                  - container_image
                  - harness
                  - mcp_server
                  - tool
                  - runtime_environment
                  - external_connection
                  - data_resource
                type: string
              - type: "null"
            title: Type
        - in: query
          name: coverage
          required: false
          schema:
            anyOf:
              - enum:
                  - assessed
                  - stale
                  - not_assessed
                  - no_inventory
                type: string
              - type: "null"
            title: Coverage
        - in: query
          name: reason
          required: false
          schema:
            anyOf:
              - enum:
                  - assessed
                  - sensor_not_installed
                  - no_inventory
                  - no_sbom
                  - scanner_not_configured
                  - unsupported_asset
                  - scan_pending
                  - scan_failed
                  - stale
                type: string
              - type: "null"
            title: Reason
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Q
        - in: query
          name: owner
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Owner
        - in: query
          name: has_findings
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: "null"
            title: Has Findings
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - enum:
                  - low
                  - medium
                  - high
                  - critical
                type: string
              - type: "null"
            title: Severity
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 500
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List assets
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assets/summary:
    get:
      description: '`coverage_pct` = assessed / inventoried x 100 (null with no assets). `assessed` means inventory AND a recent assessment exist: it is not "secure".'
      operationId: assets_summary_api_security_assets_summary_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Assets summary
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/assets/{asset_id}:
    get:
      operationId: asset_detail_api_security_assets__asset_id__get
      parameters:
        - in: path
          name: asset_id
          required: true
          schema:
            title: Asset Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Asset detail
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/detections:
    get:
      operationId: list_detections_api_security_detections_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List detections
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/detections/fixtures:
    get:
      operationId: list_fixtures_api_security_detections_fixtures_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List fixtures
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/detections/{rule_id}:
    get:
      operationId: detection_detail_api_security_detections__rule_id__get
      parameters:
        - in: path
          name: rule_id
          required: true
          schema:
            title: Rule Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Detection detail
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    patch:
      operationId: tune_detection_api_security_detections__rule_id__patch
      parameters:
        - in: path
          name: rule_id
          required: true
          schema:
            title: Rule Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RulePatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Tune detection
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/detections/{rule_id}/test:
    post:
      description: |-
        Evaluate the rule IN MEMORY - over a labelled synthetic fixture, or over this tenant's recent real events. The ONLY thing persisted is
        a security_detection_runs row with mode 'test': no finding, no security_events row, no audit entry, no notification.
      operationId: test_detection_api_security_detections__rule_id__test_post
      parameters:
        - in: path
          name: rule_id
          required: true
          schema:
            title: Rule Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RuleTest"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Test detection
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/events:
    get:
      operationId: list_events_api_security_events_get
      parameters:
        - in: query
          name: search
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Search
        - in: query
          name: event_type
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Event Type
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Severity
        - in: query
          name: source_kind
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Source Kind
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: identity
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Identity
        - in: query
          name: trace_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Trace Id
        - in: query
          name: correlation_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Correlation Id
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Decision
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: is_test
          required: false
          schema:
            default: false
            title: Is Test
            type: boolean
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List events
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/events/export.csv:
    get:
      description: |-
        ≤ 50 000 rows, same filters as the list. Needs `export_evidence` AND tenant policy export.allow_evidence_export. Cells are masked
        (and restricted callers get the reduced view) and neutralised against spreadsheet formula injection. Every export is audited.
      operationId: export_events_api_security_events_export_csv_get
      parameters:
        - in: query
          name: search
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Search
        - in: query
          name: event_type
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Event Type
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Severity
        - in: query
          name: source_kind
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Source Kind
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: identity
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Identity
        - in: query
          name: trace_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Trace Id
        - in: query
          name: correlation_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Correlation Id
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Decision
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: is_test
          required: false
          schema:
            default: false
            title: Is Test
            type: boolean
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Export events
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/events/facets:
    get:
      description: Counts over the last 7 days (real events only), each facet capped at 50 values.
      operationId: event_facets_api_security_events_facets_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Event facets
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/events/{event_id}:
    get:
      operationId: event_detail_api_security_events__event_id__get
      parameters:
        - in: path
          name: event_id
          required: true
          schema:
            maximum: 4611686018427388000
            minimum: 1
            title: Event Id
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Event detail
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings:
    get:
      operationId: list_findings_api_security_findings_get
      parameters:
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Status
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Severity
        - in: query
          name: rule_key
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Rule Key
        - in: query
          name: category
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Category
        - in: query
          name: entity_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Entity Id
        - in: query
          name: assignee
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Assignee
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: kind
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Kind
        - in: query
          name: asset_type
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Asset Type
        - in: query
          name: asset_id
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Asset Id
        - in: query
          name: priority
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Priority
        - in: query
          name: advisory_id
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Advisory Id
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List findings
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}:
    get:
      operationId: finding_detail_api_security_findings__finding_id__get
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Finding detail
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/accept-risk:
    post:
      description: |-
        Accept the risk of a vulnerability / configuration finding for a limited time. Admin only (`accept_risk`). `expires_at` must be in the future and at most
        the tenant's accepted_risk_max_days away. When it passes the finding reopens by itself (ledger `security.finding.risk_expired`).
      operationId: accept_finding_risk_api_security_findings__finding_id__accept_risk_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AcceptRisk"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Accept finding risk
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/assign:
    post:
      description: Assign a finding to a person of THIS workspace whose role can see Security (`view_security`); `null` unassigns. Ledger `security.finding.assigned`.
      operationId: assign_finding_api_security_findings__finding_id__assign_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__security__AssignBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Assign finding
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/feedback:
    post:
      description: Analyst feedback feeds the rule's false_positive_rate. It never changes the finding's status or the rule by itself.
      operationId: finding_feedback_api_security_findings__finding_id__feedback_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FindingFeedback"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Finding feedback
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/incident:
    post:
      description: Create an incident from this finding, or - with `incident_id` - link it to an existing one. Human action only.
      operationId: finding_to_incident_api_security_findings__finding_id__incident_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/FindingIncident"
                - type: "null"
              title: Body
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Finding to incident
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/notes:
    get:
      operationId: list_finding_notes_api_security_findings__finding_id__notes_get
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List finding notes
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      description: |-
        A standalone analyst note on a finding (it changes nothing else). The ledger entry `security.finding.note` records the note id and length, not the text; the
        text lives in security_finding_notes and appears in the finding's `triage_history` as `kind: "note"`.
      operationId: add_finding_note_api_security_findings__finding_id__notes_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__security__NoteBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Add finding note
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/remediation:
    post:
      description: |-
        Record who fixes a finding and by when (owner of the same workspace whose role can see Security, due date not in the past, optional plan text). A person's
        decision only: nothing is changed on the asset. Sending the same values again is a no-op (no ledger entry). Ledger `security.finding.remediation_planned`.
      operationId: plan_finding_remediation_api_security_findings__finding_id__remediation_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RemediationBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Plan finding remediation
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/rescan:
    post:
      description: |-
        Re-read the current inventory and re-run what produced the finding: a vulnerability finding is re-matched against the advisory data, a configuration
        finding re-runs its one check. -> `{result: still_present | verified_fixed | not_evaluable, reason, finding}`. `verified_fixed` resolves the finding with
        the verification recorded; `not_evaluable` never resolves it. Ledger `security.finding.rescanned`.
      operationId: rescan_finding_api_security_findings__finding_id__rescan_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Rescan finding
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/findings/{finding_id}/status:
    post:
      description: |-
        Resolution policy (docs/security/SECURITY_FINDINGS_AND_RISK.md): runtime findings keep the manual lifecycle, but `resolved` and `false_positive`
        need a note of at least 10 characters. Vulnerability / configuration / coverage findings return 409 `verification_required` for `resolved` (only a
        verified rescan resolves them), 409 `accept_risk_required` for `accepted_risk` (own endpoint), and `false_positive` needs the same note.
      operationId: set_finding_status_api_security_findings__finding_id__status_post
      parameters:
        - in: path
          name: finding_id
          required: true
          schema:
            title: Finding Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FindingStatus"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Set finding status
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/incidents:
    get:
      description: |-
        Newest first (created_at DESC, id DESC - stable under later edits, unlike updated_at). `status=open` is every status except
        resolved and closed. `assignee` is a user id or `none` (unassigned). `search` is a case-insensitive literal substring of the title (no wildcard semantics).
      operationId: list_incidents_api_security_incidents_get
      parameters:
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - open
                  - new
                  - investigating
                  - resolved
                  - closed
                  - reopened
                type: string
              - type: "null"
            title: Status
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - enum:
                  - low
                  - medium
                  - high
                  - critical
                type: string
              - type: "null"
            title: Severity
        - in: query
          name: assignee
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Assignee
        - in: query
          name: search
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Search
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List incidents
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      operationId: create_incident_api_security_incidents_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IncidentCreate"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create incident
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/incidents/{incident_id}:
    get:
      operationId: get_incident_api_security_incidents__incident_id__get
      parameters:
        - in: path
          name: incident_id
          required: true
          schema:
            title: Incident Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get incident
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    patch:
      operationId: patch_incident_api_security_incidents__incident_id__patch
      parameters:
        - in: path
          name: incident_id
          required: true
          schema:
            title: Incident Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IncidentPatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Patch incident
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/incidents/{incident_id}/comments:
    post:
      description: Analyst note, stored verbatim as plain text (no markup interpretation, ‹= 4000 chars). The UI must render it escaped.
      operationId: add_comment_api_security_incidents__incident_id__comments_post
      parameters:
        - in: path
          name: incident_id
          required: true
          schema:
            title: Incident Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommentIn"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Add comment
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/incidents/{incident_id}/links:
    post:
      description: |-
        Link evidence (finding / shadow candidate / agent / event / execution / policy decision / simulation run) that exists in THIS tenant,
        with an optional short note. Idempotent: re-linking returns the existing link with `created: false` and writes no second timeline/audit
        entry. The response carries the link row `id`, the target `ref_id`, `title`, `href` (a real UI route or null) and `note`.
      operationId: add_incident_link_api_security_incidents__incident_id__links_post
      parameters:
        - in: path
          name: incident_id
          required: true
          schema:
            title: Incident Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LinkIn"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Add incident link
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/incidents/{incident_id}/transition:
    post:
      description: |-
        new -> investigating|resolved, investigating -> resolved, resolved -> closed|reopened, closed -> reopened,
        reopened -> investigating|resolved. Anything else (including "to the same state") is 409. `resolved` needs a non-blank `resolution`;
        `closed` keeps the recorded resolution and stamps closed_at; reopening clears resolved_at / closed_at / resolution (the timeline keeps them).
      operationId: transition_incident_api_security_incidents__incident_id__transition_post
      parameters:
        - in: path
          name: incident_id
          required: true
          schema:
            title: Incident Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TransitionIn"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Transition incident
      tags:
        - Incidents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/ingest-tokens:
    get:
      operationId: list_tokens_api_security_ingest_tokens_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List tokens
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      description: |
        Create an `obt_` token for the [Ingest API](/docs/api/ingest/bairav-ingest-api). Requires the `manage_observability` permission.

        The secret is returned **once** and stored only as an Argon2id hash. The token is bound to a telemetry source and tenant. At most 50 active tokens per tenant.
      operationId: create_token_api_security_ingest_tokens_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TokenCreate"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create an ingest token
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/ingest-tokens/{token_id}:
    delete:
      operationId: revoke_token_api_security_ingest_tokens__token_id__delete
      parameters:
        - in: path
          name: token_id
          required: true
          schema:
            title: Token Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Revoke token
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/ingest/dead-letters:
    get:
      description: Security-ingest events that validated but could not be stored (a processing failure, not a validation reject).
      operationId: list_dead_letters_api_security_ingest_dead_letters_get
      parameters:
        - in: query
          name: status
          required: false
          schema:
            default: pending
            enum:
              - pending
              - replayed
              - all
            title: Status
            type: string
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List dead letters
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/ingest/dead-letters/replay:
    post:
      operationId: replay_dead_letter_route_api_security_ingest_dead_letters_replay_post
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/portal_api__routers__security__ReplayBody"
                - type: "null"
              title: Body
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Replay dead letter route
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/investigations:
    get:
      description: |-
        What people are working on right now, from three existing tables (nothing is stored for it): findings in status `investigating`; incidents that are open
        (new / investigating / reopened, the one definition of open); shadow candidates that are escalated or assigned and not resolved or suppressed. Newest update
        first, keyset pagination. `status` only accepts `open`.
      operationId: list_investigations_api_security_investigations_get
      parameters:
        - in: query
          name: status
          required: false
          schema:
            const: open
            default: open
            title: Status
            type: string
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List investigations
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/overview:
    get:
      description: |-
        Everything on the Security landing page, from real tables. No number here is hard-coded; a count of zero is a real zero because
        the table was read. Filters (API_CHANGES section 3):
          range      24h | 7d | 30d. Scopes what is a COUNT OVER TIME: events, the trend, recent violations, activity and `findings_new`.
                     Finding / candidate / incident figures are CURRENT STATE ("open now") and are not narrowed by the range, so a tile and the
                     findings list it opens always agree.
          agent_id   narrows events, findings, shadow candidates and the agent ranking to one agent (tenant-wide: observed / registered agents,
                     incidents, source health).
          severity   comma list of finding severities; narrows the finding figures only.
        Definitions:
          observed_agents   discovered_entities of type 'agent' not in lifecycle 'deleted' (every agent any source has seen)
          registered_agents agents-table rows (published to the catalog) whose entity is not deleted
          suspected/confirmed_unmanaged  shadow_agent_candidates by classification, excluding ones suppressed by an exception/false positive
          repeated_policy_violations  open findings of DET-001 / DET-012
          findings_awaiting_triage    open findings with no assignee
          backlog.total               open findings + new shadow candidates + open incidents (open = not resolved and not closed)
      operationId: overview_api_security_overview_get
      parameters:
        - in: query
          name: range
          required: false
          schema:
            default: 24h
            pattern: ^(24h|7d|30d)$
            title: Range
            type: string
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Severity
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Overview
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/posture:
    get:
      operationId: posture_api_security_posture_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Posture
      tags:
        - Security posture
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/remediation-queue:
    get:
      description: |-
        Open vulnerability / configuration / coverage findings in remediation order: priority P1 -> P4 (none last), then technical severity (critical first), then
        age (oldest first). `assignee` = unassigned | me | `<user id>`; `priority` = P1..P4 (repeatable). Keyset pagination.
      operationId: remediation_queue_api_security_remediation_queue_get
      parameters:
        - in: query
          name: assignee
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Assignee
        - in: query
          name: priority
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Priority
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 400
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Remediation queue
      tags:
        - Security posture
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/sbom:
    post:
      description: |-
        Upload an inventory (CycloneDX 1.4-1.6 JSON, SPDX 2.3 JSON, requirements.txt, package-lock.json v2/v3) as the RAW request body (gzip allowed with
        `Content-Encoding: gzip`). 20 MB / 50 000 components. Idempotent on (subject, sha256 of the document).
      operationId: upload_sbom_api_security_sbom_post
      parameters:
        - in: query
          name: subject_type
          required: true
          schema:
            enum:
              - agent
              - container_image
              - dependency_set
              - platform
            title: Subject Type
            type: string
        - in: query
          name: subject_id
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Subject Id
        - in: query
          name: subject_key
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Subject Key
        - in: query
          name: subject_name
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Subject Name
        - in: query
          name: source
          required: false
          schema:
            default: upload
            enum:
              - upload
              - ci
              - self_inventory
            title: Source
            type: string
        - in: query
          name: filename
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Filename
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Upload SBOM
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/sources:
    get:
      operationId: list_sources_api_security_sources_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List sources
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/triage-activity:
    get:
      description: |-
        What PEOPLE did, newest first, merged from finding status changes (audit ledger), finding feedback, incident transitions, incident
        comments and shadow reviews with a human actor. System actions (a scan reopening a candidate, a detection reopening a finding) are not
        triage. Keyset on (at, id); tenant comes from the JWT; restricted callers see neutral subject titles and no free text.
      operationId: triage_activity_api_security_triage_activity_get
      parameters:
        - in: query
          name: kind
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: "null"
            title: Kind
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Triage activity
      tags:
        - Security events and findings
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/security/vulnerabilities:
    get:
      description: |-
        Component-level advisory matches of the CURRENT inventory (a superseded document is history), most severe first. `fixable` = the advisory publishes at least
        one fixed version for the package. `severity_basis = not_published` means the advisory publishes no severity: the shown `medium` is provisional.
      operationId: list_vulnerabilities_api_security_vulnerabilities_get
      parameters:
        - in: query
          name: severity
          required: false
          schema:
            anyOf:
              - enum:
                  - low
                  - medium
                  - high
                  - critical
                type: string
              - type: "null"
            title: Severity
        - in: query
          name: asset_id
          required: false
          schema:
            anyOf:
              - maxLength: 64
                type: string
              - type: "null"
            title: Asset Id
        - in: query
          name: ecosystem
          required: false
          schema:
            anyOf:
              - maxLength: 20
                type: string
              - type: "null"
            title: Ecosystem
        - in: query
          name: fixable
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: "null"
            title: Fixable
        - in: query
          name: state
          required: false
          schema:
            default: affected
            enum:
              - affected
              - fixed
              - withdrawn
              - all
            title: State
            type: string
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Q
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 500
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List vulnerabilities
      tags:
        - Assets and vulnerabilities
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/sensors:
    get:
      operationId: list_sensors_api_sensors_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List sensors
      tags:
        - Sensors
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/sensors/coverage:
    get:
      description: Monitoring coverage for the given agents. A malformed id is a 422; an id that is not this tenant's is absent from `items`.
      operationId: coverage_api_sensors_coverage_get
      parameters:
        - in: query
          name: entity_id
          required: true
          schema:
            items:
              type: string
            title: Entity Id
            type: array
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Coverage
      tags:
        - Sensors
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/sensors/retention:
    get:
      operationId: get_retention_api_sensors_retention_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get retention
      tags:
        - Sensors
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    put:
      operationId: put_retention_api_sensors_retention_put
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RetentionBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Put retention
      tags:
        - Sensors
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents:
    get:
      operationId: list_candidates_api_shadow_agents_get
      parameters:
        - in: query
          name: classification
          required: false
          schema:
            anyOf:
              - enum:
                  - managed
                  - suspected_unmanaged
                  - confirmed_unmanaged
                  - authorized_exception
                  - false_positive
                  - insufficient_evidence
                type: string
              - type: "null"
            title: Classification
        - in: query
          name: band
          required: false
          schema:
            anyOf:
              - enum:
                  - low
                  - medium
                  - high
                type: string
              - type: "null"
            title: Band
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - new
                  - in_review
                  - resolved
                type: string
              - type: "null"
            title: Status
        - in: query
          name: source
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Source
        - in: query
          name: registry_match
          required: false
          schema:
            anyOf:
              - enum:
                  - none
                  - possible
                  - linked
                type: string
              - type: "null"
            title: Registry Match
        - in: query
          name: assignee
          required: false
          schema:
            anyOf:
              - maxLength: 36
                type: string
              - type: "null"
            title: Assignee
        - in: query
          name: search
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Search
        - in: query
          name: include_suppressed
          required: false
          schema:
            default: false
            title: Include Suppressed
            type: boolean
        - in: query
          name: include_low
          required: false
          schema:
            default: false
            title: Include Low
            type: boolean
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 300
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List candidates
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/method:
    get:
      description: "The live scoring method: categories, caps, band thresholds, catalogue version and the plain-language caveats."
      operationId: method_api_shadow_agents_method_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Method
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/scan:
    post:
      description: "Run discovery now for the caller's tenant. Idempotent: a repeat with no new evidence creates and updates nothing."
      operationId: scan_api_shadow_agents_scan_post
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Scan
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/signatures:
    get:
      operationId: signatures_api_shadow_agents_signatures_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Signatures
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/signatures/{key}:
    patch:
      operationId: patch_signature_api_shadow_agents_signatures__key__patch
      parameters:
        - in: path
          name: key
          required: true
          schema:
            title: Key
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SignaturePatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Patch signature
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}:
    get:
      operationId: get_candidate_api_shadow_agents__candidate_id__get
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get candidate
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}/assign:
    post:
      operationId: assign_api_shadow_agents__candidate_id__assign_post
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__shadow_agents__AssignBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Assign
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}/escalate:
    post:
      operationId: escalate_api_shadow_agents__candidate_id__escalate_post
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EscalateBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Escalate
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}/link:
    post:
      operationId: link_api_shadow_agents__candidate_id__link_post
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LinkBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Link
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}/request-registration:
    post:
      description: "Ask for the agent to be registered. A notification and a review record only: nothing is registered or modified."
      operationId: request_registration_api_shadow_agents__candidate_id__request_registration_post
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/portal_api__routers__shadow_agents__NoteBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Request registration
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/shadow-agents/{candidate_id}/review:
    post:
      operationId: review_api_shadow_agents__candidate_id__review_post
      parameters:
        - in: path
          name: candidate_id
          required: true
          schema:
            title: Candidate Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReviewBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Review
      tags:
        - Shadow agents
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations:
    get:
      description: Recorded simulations, newest first — what "Recent simulations" lists.
      operationId: recent_api_simulations_get
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            default: 8
            maximum: 50
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: before_seq
          required: false
          schema:
            anyOf:
              - type: integer
              - type: "null"
            title: Before Seq
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Recent
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/access-change:
    post:
      operationId: access_change_api_simulations_access_change_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AccessChangeBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Access change
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/adversarial:
    post:
      operationId: adversarial_api_simulations_adversarial_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AdversarialBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Adversarial
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/adversarial/fleet:
    post:
      description: Queue a whole-fleet run. Returns at once with a job to poll — never holds the request open.
      operationId: adversarial_fleet_api_simulations_adversarial_fleet_post
      responses:
        "202":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Adversarial fleet
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/adversarial/start:
    post:
      description: |-
        Queue the Standard suite on ONE agent as a live job (kind `adversarial`): poll GET /jobs/`{id}` for `current` / `results[]`. The
        synchronous POST /adversarial still answers in one response; this is the same run, watchable attack by attack.
      operationId: adversarial_start_api_simulations_adversarial_start_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AdversarialBody"
        required: true
      responses:
        "202":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Adversarial start
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/attacks:
    get:
      operationId: list_attacks_api_simulations_attacks_get
      parameters:
        - in: query
          name: include_inactive
          required: false
          schema:
            default: false
            title: Include Inactive
            type: boolean
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List attacks
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      operationId: create_attack_api_simulations_attacks_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AttackBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create attack
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/attacks/{code}:
    patch:
      description: |-
        A built-in attack can only be switched on or off (its wording is versioned in code; copy it to change it).
        A custom attack can be edited.
      operationId: update_attack_api_simulations_attacks__code__patch
      parameters:
        - in: path
          name: code
          required: true
          schema:
            title: Code
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AttackPatch"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Update attack
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/blast-radius:
    get:
      operationId: blast_radius_api_simulations_blast_radius_get
      parameters:
        - in: query
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Blast radius
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/exposure:
    get:
      operationId: exposure_api_simulations_exposure_get
      parameters:
        - in: query
          name: entity_id
          required: true
          schema:
            title: Entity Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Exposure
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/exposure/fleet:
    get:
      operationId: exposure_fleet_api_simulations_exposure_fleet_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Exposure fleet
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/guardrails:
    post:
      operationId: guardrails_api_simulations_guardrails_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GuardrailsBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Guardrails
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/jobs/{run_id}:
    get:
      operationId: get_job_api_simulations_jobs__run_id__get
      parameters:
        - in: path
          name: run_id
          required: true
          schema:
            title: Run Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get job
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/jobs/{run_id}/cancel:
    post:
      operationId: cancel_job_api_simulations_jobs__run_id__cancel_post
      parameters:
        - in: path
          name: run_id
          required: true
          schema:
            title: Run Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Cancel job
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/jobs/{run_id}/record:
    post:
      description: Keep a finished fleet run as evidence (its result is already stored by the server).
      operationId: record_job_api_simulations_jobs__run_id__record_post
      parameters:
        - in: path
          name: run_id
          required: true
          schema:
            title: Run Id
            type: string
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Record job
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/meta:
    get:
      description: "What the screen needs to build its pickers: the permission list, history windows, limits."
      operationId: meta_api_simulations_meta_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Meta
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/publish-check:
    get:
      description: "Before a rule is published: which guardrail tests would stop holding, and which real requests change."
      operationId: publish_check_api_simulations_publish_check_get
      parameters:
        - in: query
          name: policy_id
          required: true
          schema:
            title: Policy Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Publish check
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/record:
    post:
      description: |-
        "Record as evidence". The server re-runs the setup and stores its own result — nothing the client sends is trusted
        as a result. Writes `simulation_runs` and one tamper-evident ledger entry. With an `idempotency_key`, a repeat from the same person
        returns the first record (`200`, `replayed: true`).
      operationId: record_api_simulations_record_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RecordBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Record
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/rule-change:
    post:
      operationId: rule_change_api_simulations_rule_change_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RuleChangeBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Rule change
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/rules:
    get:
      description: |-
        The rules a person can rehearse a change on, each with the changes that make sense for it. Unpublished
        rules are listed for authors only.
      operationId: list_rules_api_simulations_rules_get
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List rules
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/runs:
    get:
      description: Saved test runs, newest first (keyset on created_at, seq). Another tenant's runs and agents are invisible (RLS).
      operationId: list_runs_api_simulations_runs_get
      parameters:
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: limit
          required: false
          schema:
            default: 20
            maximum: 100
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List runs
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
    post:
      description: |-
        Run Simulation: a policy dry run of one agent / one attempted action, ALWAYS saved (see the module docstring). Idempotent per
        (tenant, user, `idempotency_key`): a repeat returns the first run with `200` and `replayed: true`.
      operationId: create_run_api_simulations_runs_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/shared__sim_runs__RunBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Create run
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/runs/{run_id}:
    get:
      operationId: get_run_api_simulations_runs__run_id__get
      parameters:
        - in: path
          name: run_id
          required: true
          schema:
            title: Run Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get run
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/simulations/{run_id}:
    get:
      operationId: get_recorded_api_simulations__run_id__get
      parameters:
        - in: path
          name: run_id
          required: true
          schema:
            title: Run Id
            type: string
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get recorded
      tags:
        - Simulation lab
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/export.csv:
    get:
      description: |-
        Server-side CSV of the same facts as /summary and /requests (same filters). `level=summary`: one row per group (`group_by`, `bucket`, `fill` as in the
        summary) and a final TOTAL row; `level=records`: one row per request, newest first, at most 50 000 (`# truncated: true` when more matched). Cost columns exist
        only for callers with view_cost (otherwise they are ABSENT, not zero). Header lines start with `#`. Text cells are formula-neutralised. Every export is
        written to the ledger as `traffic.exported` (filters, row count, level).
      operationId: export_csv_api_traffic_export_csv_get
      parameters:
        - in: query
          name: level
          required: false
          schema:
            default: summary
            enum:
              - summary
              - records
            title: Level
            type: string
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: group_by
          required: false
          schema:
            anyOf:
              - enum:
                  - time
                  - agent
                  - model
                  - provider
                  - decision
                  - status
                  - severity
                type: string
              - type: "null"
            title: Group By
        - in: query
          name: bucket
          required: false
          schema:
            default: day
            enum:
              - hour
              - day
              - week
              - month
            title: Bucket
            type: string
        - in: query
          name: fill
          required: false
          schema:
            default: true
            title: Fill
            type: boolean
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: model
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Model
        - in: query
          name: provider
          required: false
          schema:
            anyOf:
              - maxLength: 60
                type: string
              - type: "null"
            title: Provider
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - enum:
                  - allowed
                  - gated
                  - blocked
                  - blocked_policy
                  - blocked_output
                  - blocked_preflight
                  - blocked_killswitch
                  - error
                type: string
              - type: "null"
            title: Decision
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - ok
                  - blocked
                  - gated
                  - error
                type: string
              - type: "null"
            title: Status
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Q
        - in: query
          name: cost_state
          required: false
          schema:
            anyOf:
              - items:
                  enum:
                    - priced
                    - provider_reported
                    - unpriced
                    - usage_unknown
                    - self_hosted_unavailable
                    - not_applicable
                    - failed_call
                  type: string
                type: array
              - type: "null"
            title: Cost State
        - in: query
          name: operation
          required: false
          schema:
            anyOf:
              - enum:
                  - chat
                  - embeddings
                  - other
                type: string
              - type: "null"
            title: Operation
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Export CSV
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/requests:
    get:
      operationId: list_requests_api_traffic_requests_get
      parameters:
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: model
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Model
        - in: query
          name: provider
          required: false
          schema:
            anyOf:
              - maxLength: 60
                type: string
              - type: "null"
            title: Provider
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - enum:
                  - allowed
                  - gated
                  - blocked
                  - blocked_policy
                  - blocked_output
                  - blocked_preflight
                  - blocked_killswitch
                  - error
                type: string
              - type: "null"
            title: Decision
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - ok
                  - blocked
                  - gated
                  - error
                type: string
              - type: "null"
            title: Status
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Q
        - in: query
          name: cost_state
          required: false
          schema:
            anyOf:
              - items:
                  enum:
                    - priced
                    - provider_reported
                    - unpriced
                    - usage_unknown
                    - self_hosted_unavailable
                    - not_applicable
                    - failed_call
                  type: string
                type: array
              - type: "null"
            title: Cost State
        - in: query
          name: operation
          required: false
          schema:
            anyOf:
              - enum:
                  - chat
                  - embeddings
                  - other
                type: string
              - type: "null"
            title: Operation
        - in: query
          name: limit
          required: false
          schema:
            default: 50
            maximum: 200
            minimum: 1
            title: Limit
            type: integer
        - in: query
          name: cursor
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Cursor
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: List requests
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/requests/{request_id}:
    get:
      operationId: get_request_api_traffic_requests__request_id__get
      parameters:
        - in: path
          name: request_id
          required: true
          schema:
            title: Request Id
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Get request
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/spikes:
    get:
      description: |-
        Token spikes per agent (any signed-in role, tenant-scoped by RLS): recent window [now - w, now) against the prior window [now - 2w, now - w), over
        requests that were model calls WITH recorded usage only (never NULL as 0). Qualifies when the baseline window has >= `min_baseline` such requests,
        baseline tokens > 0 and recent / baseline >= `factor` (exactly at the factor qualifies). `ratio` / `multiple` (1 decimal) are JSON numbers, tokens integers.
      operationId: spikes_api_traffic_spikes_get
      parameters:
        - in: query
          name: window_hours
          required: false
          schema:
            default: 6
            maximum: 168
            minimum: 1
            title: Window Hours
            type: integer
        - in: query
          name: min_baseline
          required: false
          schema:
            default: 4
            maximum: 1000
            minimum: 1
            title: Min Baseline
            type: integer
        - in: query
          name: factor
          required: false
          schema:
            default: 2
            exclusiveMinimum: 1
            maximum: 100
            title: Factor
            type: number
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - format: uuid
                type: string
              - type: "null"
            title: Agent Id
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Spikes
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/summary:
    get:
      description: |-
        `pricing` (default true; needs view_cost, else null): where the prices behind the estimate come from, see docs/security/API_CHANGES_DEMO.md section 1.
        A caller that does not show it (the chart and the group tables) passes `pricing=false` and skips its one extra statement.
      operationId: summary_api_traffic_summary_get
      parameters:
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: group_by
          required: false
          schema:
            anyOf:
              - enum:
                  - time
                  - agent
                  - model
                  - provider
                  - decision
                  - status
                  - severity
                type: string
              - type: "null"
            title: Group By
        - in: query
          name: bucket
          required: false
          schema:
            default: day
            enum:
              - hour
              - day
              - week
              - month
            title: Bucket
            type: string
        - in: query
          name: fill
          required: false
          schema:
            default: true
            title: Fill
            type: boolean
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Agent Id
        - in: query
          name: model
          required: false
          schema:
            anyOf:
              - maxLength: 200
                type: string
              - type: "null"
            title: Model
        - in: query
          name: provider
          required: false
          schema:
            anyOf:
              - maxLength: 60
                type: string
              - type: "null"
            title: Provider
        - in: query
          name: decision
          required: false
          schema:
            anyOf:
              - enum:
                  - allowed
                  - gated
                  - blocked
                  - blocked_policy
                  - blocked_output
                  - blocked_preflight
                  - blocked_killswitch
                  - error
                type: string
              - type: "null"
            title: Decision
        - in: query
          name: status
          required: false
          schema:
            anyOf:
              - enum:
                  - ok
                  - blocked
                  - gated
                  - error
                type: string
              - type: "null"
            title: Status
        - in: query
          name: q
          required: false
          schema:
            anyOf:
              - maxLength: 100
                type: string
              - type: "null"
            title: Q
        - in: query
          name: cost_state
          required: false
          schema:
            anyOf:
              - items:
                  enum:
                    - priced
                    - provider_reported
                    - unpriced
                    - usage_unknown
                    - self_hosted_unavailable
                    - not_applicable
                    - failed_call
                  type: string
                type: array
              - type: "null"
            title: Cost State
        - in: query
          name: operation
          required: false
          schema:
            anyOf:
              - enum:
                  - chat
                  - embeddings
                  - other
                type: string
              - type: "null"
            title: Operation
        - in: query
          name: pricing
          required: false
          schema:
            default: true
            title: Pricing
            type: boolean
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Summary
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
  /api/traffic/telemetry-usage:
    get:
      description: |-
        Usage that OTLP spans (OpenLIT and other exporters) reported, as a SEPARATE block - never part of the gateway totals, lists or exports: a call seen by both
        the gateway and OpenLIT has two different trace ids and cannot be de-duplicated, so adding the two would double count. Rows are attributed to an agent when the
        span identity names exactly one registered agent (else `unattributed`) and priced with the same calculation and catalogue as gateway rows, at the span's time.
        Needs view_security; amounts need view_cost (else `cost: null`, `restricted: true`).
      operationId: telemetry_usage_api_traffic_telemetry_usage_get
      parameters:
        - in: query
          name: since
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Since
        - in: query
          name: until
          required: false
          schema:
            anyOf:
              - format: date-time
                type: string
              - type: "null"
            title: Until
        - in: query
          name: agent_id
          required: false
          schema:
            anyOf:
              - maxLength: 40
                type: string
              - type: "null"
            title: Agent Id
      responses:
        "200":
          content:
            application/json:
              schema: {}
          description: Successful Response
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPValidationError"
          description: Validation Error
      summary: Telemetry usage
      tags:
        - Traffic and cost
      security:
        - BearerJWT: []
      x-response-schema-documented: false
components:
  securitySchemes:
    BearerJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: The access token from `POST /api/auth/breakglass` or `POST /api/auth/refresh`.
  responses:
    Unauthorized:
      description: The token is missing, invalid or expired. Refresh it, or sign in again.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Forbidden:
      description: Your role does not allow this. The `detail` names the missing permission or role.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
  schemas:
    AcceptRisk:
      additionalProperties: false
      properties:
        expires_at:
          format: date-time
          title: Expires At
          type: string
        reason:
          maxLength: 1000
          minLength: 10
          title: Reason
          type: string
      required:
        - reason
        - expires_at
      title: AcceptRisk
      type: object
    AccessChangeBody:
      properties:
        add_capability:
          anyOf:
            - maxLength: 120
              type: string
            - type: "null"
          title: Add Capability
        autonomous:
          default: false
          title: Autonomous
          type: boolean
        entity_id:
          title: Entity Id
          type: string
        history_days:
          default: 30
          enum:
            - 7
            - 30
            - 90
          title: History Days
          type: integer
        remove_capability:
          anyOf:
            - maxLength: 120
              type: string
            - type: "null"
          title: Remove Capability
      required:
        - entity_id
      title: AccessChangeBody
      type: object
    AccessRequestBody:
      properties:
        reason:
          maxLength: 2000
          minLength: 1
          title: Reason
          type: string
      required:
        - reason
      title: AccessRequestBody
      type: object
    AdversarialBody:
      properties:
        entity_id:
          title: Entity Id
          type: string
      required:
        - entity_id
      title: AdversarialBody
      type: object
    ApproveBody:
      properties:
        capabilities:
          default: []
          items:
            type: string
          title: Capabilities
          type: array
        data_sensitivity:
          enum:
            - public
            - internal
            - confidential
            - pii
          title: Data Sensitivity
          type: string
        display_name:
          anyOf:
            - type: string
            - type: "null"
          title: Display Name
        domain:
          anyOf:
            - type: string
            - type: "null"
          title: Domain
        intended_users:
          anyOf:
            - type: string
            - type: "null"
          title: Intended Users
        oversight_level:
          enum:
            - assistive
            - supervised
            - autonomous
          title: Oversight Level
          type: string
        owner_department:
          minLength: 1
          title: Owner Department
          type: string
        owner_name:
          minLength: 1
          title: Owner Name
          type: string
        owner_user_id:
          anyOf:
            - type: string
            - type: "null"
          title: Owner User Id
        ownership:
          default: unknown
          enum:
            - internal
            - vendor
            - unknown
          title: Ownership
          type: string
        purpose:
          anyOf:
            - type: string
            - type: "null"
          title: Purpose
      required:
        - data_sensitivity
        - oversight_level
        - owner_name
        - owner_department
      title: ApproveBody
      type: object
    AttachBody:
      properties:
        policy_id:
          title: Policy Id
          type: string
      required:
        - policy_id
      title: AttachBody
      type: object
    AttackBody:
      properties:
        active:
          default: true
          title: Active
          type: boolean
        amount:
          anyOf:
            - minimum: 0
              type: number
            - type: "null"
          title: Amount
        attack_type:
          maxLength: 120
          minLength: 1
          title: Attack Type
          type: string
        cant:
          anyOf:
            - maxLength: 200
              type: string
            - type: "null"
          title: Cant
        category:
          enum:
            - prompt_injection
            - tool_misuse
            - unauthorized_access
            - policy_bypass
            - unsafe_delegation
            - sensitive_data_access
            - capability_abuse
          title: Category
          type: string
        goal:
          default: ""
          maxLength: 500
          title: Goal
          type: string
        name:
          maxLength: 200
          minLength: 1
          title: Name
          type: string
        needs:
          items:
            type: string
          maxItems: 12
          minItems: 1
          title: Needs
          type: array
        needs_delegation:
          default: false
          title: Needs Delegation
          type: boolean
        prompt:
          maxLength: 4000
          minLength: 1
          title: Prompt
          type: string
        response:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Response
        tool_input:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Tool Input
      required:
        - name
        - attack_type
        - category
        - needs
        - prompt
      title: AttackBody
      type: object
    AttackPatch:
      properties:
        active:
          anyOf:
            - type: boolean
            - type: "null"
          title: Active
        amount:
          anyOf:
            - minimum: 0
              type: number
            - type: "null"
          title: Amount
        attack_type:
          anyOf:
            - maxLength: 120
              minLength: 1
              type: string
            - type: "null"
          title: Attack Type
        cant:
          anyOf:
            - maxLength: 200
              type: string
            - type: "null"
          title: Cant
        category:
          anyOf:
            - enum:
                - prompt_injection
                - tool_misuse
                - unauthorized_access
                - policy_bypass
                - unsafe_delegation
                - sensitive_data_access
                - capability_abuse
              type: string
            - type: "null"
          title: Category
        goal:
          anyOf:
            - maxLength: 500
              type: string
            - type: "null"
          title: Goal
        name:
          anyOf:
            - maxLength: 200
              minLength: 1
              type: string
            - type: "null"
          title: Name
        needs:
          anyOf:
            - items:
                type: string
              maxItems: 12
              minItems: 1
              type: array
            - type: "null"
          title: Needs
        needs_delegation:
          anyOf:
            - type: boolean
            - type: "null"
          title: Needs Delegation
        prompt:
          anyOf:
            - maxLength: 4000
              minLength: 1
              type: string
            - type: "null"
          title: Prompt
        response:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Response
        tool_input:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Tool Input
      title: AttackPatch
      type: object
    AuthorBody:
      properties:
        text:
          maxLength: 500
          minLength: 1
          title: Text
          type: string
      required:
        - text
      title: AuthorBody
      type: object
    BreakglassBody:
      properties:
        email:
          title: Email
          type: string
        password:
          title: Password
          type: string
      required:
        - email
        - password
      title: BreakglassBody
      type: object
    CommentIn:
      properties:
        body:
          maxLength: 4000
          minLength: 1
          title: Body
          type: string
      required:
        - body
      title: CommentIn
      type: object
    CompileBody:
      properties:
        text:
          maxLength: 500
          minLength: 1
          title: Text
          type: string
      required:
        - text
      title: CompileBody
      type: object
    ConflictCheckBody:
      properties:
        action:
          enum:
            - block
            - require_approval
            - flag
            - notify
          title: Action
          type: string
        definition:
          additionalProperties: true
          title: Definition
          type: object
        exclude_policy_id:
          anyOf:
            - type: string
            - type: "null"
          title: Exclude Policy Id
      required:
        - definition
        - action
      title: ConflictCheckBody
      type: object
    ConnectionIn:
      properties:
        auto_deactivate_on_block:
          anyOf:
            - type: boolean
            - type: "null"
          title: Auto Deactivate On Block
        client_id:
          maxLength: 300
          title: Client Id
          type: string
        my_domain:
          maxLength: 300
          title: My Domain
          type: string
        poll_interval_s:
          anyOf:
            - maximum: 3600
              minimum: 60
              type: integer
            - type: "null"
          title: Poll Interval S
      required:
        - my_domain
        - client_id
      title: ConnectionIn
      type: object
    DelegationBody:
      properties:
        delegates_to:
          items:
            type: string
          maxItems: 50
          title: Delegates To
          type: array
        reason:
          anyOf:
            - maxLength: 1000
              type: string
            - type: "null"
          title: Reason
      title: DelegationBody
      type: object
    EscalateBody:
      properties:
        severity:
          anyOf:
            - enum:
                - low
                - medium
                - high
                - critical
              type: string
            - type: "null"
          title: Severity
        title:
          anyOf:
            - maxLength: 300
              minLength: 1
              type: string
            - type: "null"
          title: Title
      title: EscalateBody
      type: object
    FindingFeedback:
      additionalProperties: false
      properties:
        note:
          anyOf:
            - maxLength: 1000
              type: string
            - type: "null"
          title: Note
        verdict:
          enum:
            - true_positive
            - false_positive
            - needs_tuning
          title: Verdict
          type: string
      required:
        - verdict
      title: FindingFeedback
      type: object
    FindingIncident:
      additionalProperties: false
      properties:
        description:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Description
        incident_id:
          anyOf:
            - format: uuid
              type: string
            - type: "null"
          title: Incident Id
        severity:
          anyOf:
            - enum:
                - low
                - medium
                - high
                - critical
              type: string
            - type: "null"
          title: Severity
        title:
          anyOf:
            - maxLength: 300
              minLength: 1
              type: string
            - type: "null"
          title: Title
      title: FindingIncident
      type: object
    FindingStatus:
      additionalProperties: false
      properties:
        note:
          anyOf:
            - maxLength: 1000
              type: string
            - type: "null"
          title: Note
        status:
          enum:
            - open
            - acknowledged
            - investigating
            - false_positive
            - resolved
            - accepted_risk
          title: Status
          type: string
      required:
        - status
      title: FindingStatus
      type: object
    GuardrailsBody:
      properties:
        entity_id:
          anyOf:
            - type: string
            - type: "null"
          title: Entity Id
        judge:
          default: auto
          enum:
            - auto
            - off
          title: Judge
          type: string
      title: GuardrailsBody
      type: object
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: "#/components/schemas/ValidationError"
          title: Detail
          type: array
      title: HTTPValidationError
      type: object
    IncidentCreate:
      properties:
        assignee_id:
          anyOf:
            - maxLength: 64
              type: string
            - type: "null"
          title: Assignee Id
        description:
          default: ""
          maxLength: 8000
          title: Description
          type: string
        links:
          items:
            $ref: "#/components/schemas/LinkIn"
          maxItems: 50
          title: Links
          type: array
        severity:
          enum:
            - low
            - medium
            - high
            - critical
          title: Severity
          type: string
        title:
          maxLength: 300
          minLength: 1
          title: Title
          type: string
      required:
        - title
        - severity
      title: IncidentCreate
      type: object
    IncidentPatch:
      properties:
        assignee_id:
          anyOf:
            - maxLength: 64
              type: string
            - type: "null"
          title: Assignee Id
        description:
          anyOf:
            - maxLength: 8000
              type: string
            - type: "null"
          title: Description
        severity:
          anyOf:
            - enum:
                - low
                - medium
                - high
                - critical
              type: string
            - type: "null"
          title: Severity
        title:
          anyOf:
            - maxLength: 300
              minLength: 1
              type: string
            - type: "null"
          title: Title
      title: IncidentPatch
      type: object
    KeyBody:
      properties:
        base_url:
          anyOf:
            - maxLength: 300
              type: string
            - type: "null"
          title: Base Url
        name:
          maxLength: 100
          minLength: 1
          title: Name
          type: string
        provider_billing_mode:
          anyOf:
            - enum:
                - commercial
                - self_hosted
                - unknown
              type: string
            - type: "null"
          title: Provider Billing Mode
        upstream_base_url:
          default: https://api.openai.com/v1
          maxLength: 300
          title: Upstream Base Url
          type: string
      required:
        - name
      title: KeyBody
      type: object
    LinkBody:
      properties:
        entity_id:
          format: uuid
          title: Entity Id
          type: string
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Note
      required:
        - entity_id
      title: LinkBody
      type: object
    LinkIn:
      description: "`ref_id` is the contract name; `id` is accepted as an alias (the first release used it, and create-time `links[]` still does)."
      properties:
        id:
          anyOf:
            - maxLength: 80
              minLength: 1
              type: string
            - type: "null"
          title: Id
        kind:
          enum:
            - finding
            - candidate
            - entity
            - event
            - execution
            - policy_decision
            - simulation
          title: Kind
          type: string
        note:
          anyOf:
            - maxLength: 500
              type: string
            - type: "null"
          title: Note
        ref_id:
          anyOf:
            - maxLength: 80
              minLength: 1
              type: string
            - type: "null"
          title: Ref Id
      required:
        - kind
      title: LinkIn
      type: object
    PackBody:
      properties:
        description:
          anyOf:
            - type: string
            - type: "null"
          title: Description
        name:
          minLength: 1
          title: Name
          type: string
      required:
        - name
      title: PackBody
      type: object
    PackTemplateBody:
      properties:
        action:
          default: flag
          enum:
            - block
            - require_approval
            - flag
            - notify
          title: Action
          type: string
        definition:
          additionalProperties: true
          title: Definition
          type: object
        description:
          anyOf:
            - type: string
            - type: "null"
          title: Description
        name:
          minLength: 1
          title: Name
          type: string
      required:
        - name
        - definition
      title: PackTemplateBody
      type: object
    PlatformOwnerBody:
      properties:
        owner_user_id:
          anyOf:
            - type: string
            - type: "null"
          title: Owner User Id
        reason:
          anyOf:
            - maxLength: 1000
              type: string
            - type: "null"
          title: Reason
      title: PlatformOwnerBody
      type: object
    PolicyBody:
      properties:
        action:
          default: block
          enum:
            - block
            - require_approval
            - flag
            - notify
          title: Action
          type: string
        compiler_version:
          anyOf:
            - type: string
            - type: "null"
          title: Compiler Version
        definition:
          additionalProperties: true
          title: Definition
          type: object
        description:
          anyOf:
            - type: string
            - type: "null"
          title: Description
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Metadata
        model_used:
          anyOf:
            - type: string
            - type: "null"
          title: Model Used
        name:
          minLength: 1
          title: Name
          type: string
        natural_language_source:
          anyOf:
            - type: string
            - type: "null"
          title: Natural Language Source
        status:
          anyOf:
            - enum:
                - DRAFT
                - VALIDATED
                - ACTIVE
              type: string
            - type: "null"
          title: Status
      required:
        - name
        - definition
      title: PolicyBody
      type: object
    PolicyDraftBody:
      description: |-
        A saved-but-unpublished change to an ACTIVE/DISABLED rule: only the fields sent are stored.
        `enabled` false/true means "disable"/"enable" once published. None = not sent.
      properties:
        action:
          anyOf:
            - enum:
                - block
                - require_approval
                - flag
                - notify
              type: string
            - type: "null"
          title: Action
        definition:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Definition
        description:
          anyOf:
            - type: string
            - type: "null"
          title: Description
        enabled:
          anyOf:
            - type: boolean
            - type: "null"
          title: Enabled
        name:
          anyOf:
            - minLength: 1
              type: string
            - type: "null"
          title: Name
      title: PolicyDraftBody
      type: object
    PolicyPatch:
      description: |-
        Every field optional: the same endpoint serves the enable/disable toggle and
        a full edit, so a toggle can never accidentally blank out a rule body.
      properties:
        action:
          anyOf:
            - enum:
                - block
                - require_approval
                - flag
                - notify
              type: string
            - type: "null"
          title: Action
        definition:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Definition
        description:
          anyOf:
            - type: string
            - type: "null"
          title: Description
        enabled:
          anyOf:
            - type: boolean
            - type: "null"
          title: Enabled
        name:
          anyOf:
            - minLength: 1
              type: string
            - type: "null"
          title: Name
      title: PolicyPatch
      type: object
    PreviewBody:
      properties:
        definition:
          additionalProperties: true
          title: Definition
          type: object
      required:
        - definition
      title: PreviewBody
      type: object
    ReasonBody:
      properties:
        reason:
          anyOf:
            - type: string
            - type: "null"
          title: Reason
      title: ReasonBody
      type: object
    RecordBody:
      properties:
        idempotency_key:
          anyOf:
            - maxLength: 56
              minLength: 8
              type: string
            - type: "null"
          title: Idempotency Key
        kind:
          enum:
            - rule_change
            - access_change
            - guardrails
            - adversarial
            - blast_radius
            - exposure
          title: Kind
          type: string
        label:
          anyOf:
            - maxLength: 200
              type: string
            - type: "null"
          title: Label
        params:
          additionalProperties: true
          title: Params
          type: object
      required:
        - kind
      title: RecordBody
      type: object
    RefreshBody:
      properties:
        refresh_token:
          title: Refresh Token
          type: string
      required:
        - refresh_token
      title: RefreshBody
      type: object
    RejectBody:
      properties:
        reason:
          anyOf:
            - type: string
            - type: "null"
          title: Reason
      title: RejectBody
      type: object
    RemediationBody:
      additionalProperties: false
      description: "Only the fields that are SENT change (`owner_id: null` clears the owner, an absent `owner_id` leaves it)."
      properties:
        due:
          anyOf:
            - format: date
              type: string
            - type: "null"
          title: Due
        owner_id:
          anyOf:
            - format: uuid
              type: string
            - type: "null"
          title: Owner Id
        plan:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Plan
      title: RemediationBody
      type: object
    RetentionBody:
      additionalProperties: false
      description: "`null` clears (disables) that table's retention; a key left out is unchanged. Whole days, 1-3650."
      properties:
        dead_letter_retention_days:
          anyOf:
            - maximum: 3650
              minimum: 1
              type: integer
            - type: "null"
          title: Dead Letter Retention Days
        telemetry_retention_days:
          anyOf:
            - maximum: 3650
              minimum: 1
              type: integer
            - type: "null"
          title: Telemetry Retention Days
      title: RetentionBody
      type: object
    ReviewBody:
      properties:
        decision:
          enum:
            - assign
            - note
            - approve_known
            - false_positive
            - confirm_unmanaged
            - insufficient_evidence
            - reopen
            - link_registered
            - request_registration
            - escalate
            - exception_granted
          title: Decision
          type: string
        expires_at:
          anyOf:
            - format: date-time
              type: string
            - type: "null"
          title: Expires At
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Note
      required:
        - decision
      title: ReviewBody
      type: object
    RevokeBody:
      properties:
        reason:
          maxLength: 2000
          minLength: 1
          title: Reason
          type: string
      required:
        - reason
      title: RevokeBody
      type: object
    RuleChangeBody:
      properties:
        ai_sample:
          default: 50
          maximum: 100
          minimum: 0
          title: Ai Sample
          type: integer
        change:
          enum:
            - off
            - block
            - require_approval
            - flag
            - notify
            - draft
          title: Change
          type: string
        history_days:
          default: 30
          enum:
            - 7
            - 30
            - 90
          title: History Days
          type: integer
        policy_id:
          title: Policy Id
          type: string
      required:
        - policy_id
        - change
      title: RuleChangeBody
      type: object
    RulePatch:
      additionalProperties: false
      description: "Tuning only. `extra=forbid`: a body that tries to send `logic` is a 422, not silently ignored."
      properties:
        change_note:
          maxLength: 500
          minLength: 1
          title: Change Note
          type: string
        description:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Description
        enabled:
          anyOf:
            - type: boolean
            - type: "null"
          title: Enabled
        pattern:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              maxItems: 6
              type: array
            - type: "null"
          title: Pattern
        severity:
          anyOf:
            - enum:
                - low
                - medium
                - high
                - critical
              type: string
            - type: "null"
          title: Severity
        threshold:
          anyOf:
            - maximum: 100000
              minimum: 1
              type: integer
            - type: "null"
          title: Threshold
        window_seconds:
          anyOf:
            - maximum: 2592000
              minimum: 60
              type: integer
            - type: "null"
          title: Window Seconds
      required:
        - change_note
      title: RulePatch
      type: object
    RuleTest:
      additionalProperties: false
      properties:
        fixture_id:
          anyOf:
            - maxLength: 100
              minLength: 1
              type: string
            - type: "null"
          title: Fixture Id
        window_hours:
          anyOf:
            - maximum: 720
              minimum: 1
              type: integer
            - type: "null"
          title: Window Hours
      title: RuleTest
      type: object
    RunInput:
      additionalProperties: false
      properties:
        answer:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Answer
        capability:
          anyOf:
            - maxLength: 120
              type: string
            - type: "null"
          title: Capability
        prompt:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Prompt
        signals:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Signals
        tool_input:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Tool Input
      title: RunInput
      type: object
    SaveBody:
      properties:
        capability:
          anyOf:
            - maxLength: 200
              type: string
            - type: "null"
          title: Capability
        category:
          anyOf:
            - maxLength: 100
              type: string
            - type: "null"
          title: Category
        entity_id:
          title: Entity Id
          type: string
        expected_decision:
          anyOf:
            - enum:
                - allowed
                - flagged
                - notified
                - gated
                - blocked
              type: string
            - type: "null"
          title: Expected Decision
        name:
          maxLength: 200
          minLength: 1
          title: Name
          type: string
        question:
          anyOf:
            - maxLength: 500
              type: string
            - type: "null"
          title: Question
        request:
          additionalProperties: true
          title: Request
          type: object
        sample_prompt:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Sample Prompt
        sample_response:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Sample Response
        sample_tool_call:
          anyOf:
            - maxLength: 4000
              type: string
            - type: "null"
          title: Sample Tool Call
      required:
        - name
        - entity_id
      title: SaveBody
      type: object
    SensorPackageBody:
      properties:
        token_name:
          anyOf:
            - maxLength: 100
              type: string
            - type: "null"
          title: Token Name
      title: SensorPackageBody
      type: object
    SignaturePatch:
      properties:
        clear_weight_override:
          default: false
          title: Clear Weight Override
          type: boolean
        enabled:
          anyOf:
            - type: boolean
            - type: "null"
          title: Enabled
        note:
          anyOf:
            - maxLength: 500
              type: string
            - type: "null"
          title: Note
        weight_override:
          anyOf:
            - maximum: 40
              minimum: 0
              type: integer
            - type: "null"
          title: Weight Override
      title: SignaturePatch
      type: object
    SimulateBody:
      additionalProperties: false
      properties:
        candidate:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Candidate
        capabilities:
          anyOf:
            - items:
                type: string
              type: array
            - type: "null"
          title: Capabilities
        context:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Context
        data_sensitivity:
          anyOf:
            - type: string
            - type: "null"
          title: Data Sensitivity
        entity_id:
          anyOf:
            - type: string
            - type: "null"
          title: Entity Id
        exercised_only:
          default: false
          title: Exercised Only
          type: boolean
        judge:
          default: off
          enum:
            - auto
            - off
          title: Judge
          type: string
        model:
          anyOf:
            - type: string
            - type: "null"
          title: Model
        note:
          anyOf:
            - type: string
            - type: "null"
          title: Note
        policy_set:
          default: published
          enum:
            - published
            - with_drafts
          title: Policy Set
          type: string
        record:
          default: false
          title: Record
          type: boolean
        request:
          anyOf:
            - additionalProperties: true
              type: object
            - type: "null"
          title: Request
        sample_prompt:
          anyOf:
            - type: string
            - type: "null"
          title: Sample Prompt
        sample_response:
          anyOf:
            - type: string
            - type: "null"
          title: Sample Response
        sample_tool_call:
          anyOf:
            - type: string
            - type: "null"
          title: Sample Tool Call
      title: SimulateBody
      type: object
    TestConversationIn:
      properties:
        acknowledge_live_actions:
          default: false
          title: Acknowledge Live Actions
          type: boolean
        messages:
          items:
            type: string
          maxItems: 5
          minItems: 1
          title: Messages
          type: array
      required:
        - messages
      title: TestConversationIn
      type: object
    TokenBody:
      properties:
        name:
          maxLength: 100
          minLength: 1
          title: Name
          type: string
      required:
        - name
      title: TokenBody
      type: object
    TokenCreate:
      additionalProperties: false
      properties:
        name:
          maxLength: 200
          minLength: 1
          title: Name
          type: string
        source_kind:
          default: imported
          enum:
            - mcp_gateway
            - api_gateway
            - otel
            - imported
            - infrastructure
            - sensor
            - test_fixture
          title: Source Kind
          type: string
        source_name:
          anyOf:
            - maxLength: 200
              minLength: 1
              type: string
            - type: "null"
          title: Source Name
      required:
        - name
      title: TokenCreate
      type: object
    TransitionBody:
      properties:
        to_status:
          enum:
            - DRAFT
            - VALIDATED
            - PENDING_APPROVAL
            - ACTIVE
            - DISABLED
            - ARCHIVED
          title: To Status
          type: string
      required:
        - to_status
      title: TransitionBody
      type: object
    TransitionIn:
      properties:
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Note
        resolution:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Resolution
        to:
          enum:
            - investigating
            - resolved
            - closed
            - reopened
          title: To
          type: string
      required:
        - to
      title: TransitionIn
      type: object
    UserBody:
      properties:
        display_name:
          minLength: 1
          title: Display Name
          type: string
        email:
          minLength: 3
          title: Email
          type: string
        password:
          anyOf:
            - minLength: 8
              type: string
            - type: "null"
          title: Password
        role:
          default: viewer
          enum:
            - admin
            - reviewer
            - auditor
            - viewer
          title: Role
          type: string
        terms_accepted:
          default: false
          title: Terms Accepted
          type: boolean
      required:
        - email
        - display_name
      title: UserBody
      type: object
    UserPatch:
      properties:
        display_name:
          anyOf:
            - minLength: 1
              type: string
            - type: "null"
          title: Display Name
        password:
          anyOf:
            - minLength: 8
              type: string
            - type: "null"
          title: Password
        role:
          anyOf:
            - enum:
                - admin
                - reviewer
                - auditor
                - viewer
              type: string
            - type: "null"
          title: Role
      title: UserPatch
      type: object
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          title: Location
          type: array
        msg:
          title: Message
          type: string
        type:
          title: Error Type
          type: string
      required:
        - loc
        - msg
        - type
      title: ValidationError
      type: object
    portal_api__routers__admin_org__SettingsBody:
      properties:
        approval_sla_hours:
          default: 24
          enum:
            - 4
            - 8
            - 24
            - 48
            - 72
          title: Approval Sla Hours
          type: integer
        offline_after_seconds:
          maximum: 604800
          minimum: 60
          title: Offline After Seconds
          type: integer
        require_reject_reason:
          default: true
          title: Require Reject Reason
          type: boolean
        retention_days:
          maximum: 1825
          minimum: 90
          title: Retention Days
          type: integer
        stale_after_seconds:
          maximum: 86400
          minimum: 60
          title: Stale After Seconds
          type: integer
      required:
        - stale_after_seconds
        - offline_after_seconds
        - retention_days
      title: SettingsBody
      type: object
    portal_api__routers__catalog__DecideBody:
      properties:
        decision:
          enum:
            - approved
            - declined
          title: Decision
          type: string
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Note
      required:
        - decision
      title: DecideBody
      type: object
    portal_api__routers__governance__DecideBody:
      properties:
        decision:
          enum:
            - approved
            - denied
          title: Decision
          type: string
        note:
          anyOf:
            - type: string
            - type: "null"
          title: Note
      required:
        - decision
      title: DecideBody
      type: object
    portal_api__routers__security__AssignBody:
      additionalProperties: false
      properties:
        assignee_id:
          anyOf:
            - format: uuid
              type: string
            - type: "null"
          title: Assignee Id
      title: AssignBody
      type: object
    portal_api__routers__security__NoteBody:
      additionalProperties: false
      properties:
        note:
          maxLength: 2000
          minLength: 1
          title: Note
          type: string
      required:
        - note
      title: NoteBody
      type: object
    portal_api__routers__security__ReplayBody:
      additionalProperties: false
      properties:
        ids:
          anyOf:
            - items:
                format: uuid
                type: string
              maxItems: 200
              type: array
            - type: "null"
          title: Ids
        limit:
          default: 200
          maximum: 200
          minimum: 1
          title: Limit
          type: integer
      title: ReplayBody
      type: object
    portal_api__routers__security_assets__RunBody:
      additionalProperties: false
      properties:
        kinds:
          items:
            enum:
              - asset_sync
              - vuln_scan
              - config_assess
            type: string
          maxItems: 3
          minItems: 1
          title: Kinds
          type: array
      title: RunBody
      type: object
    portal_api__routers__security_assets__SettingsBody:
      additionalProperties: false
      properties:
        accepted_risk_max_days:
          anyOf:
            - type: integer
            - type: "null"
          title: Accepted Risk Max Days
        approved_models:
          anyOf:
            - items:
                type: string
              type: array
            - type: "null"
          title: Approved Models
        approved_providers:
          anyOf:
            - items:
                type: string
              type: array
            - type: "null"
          title: Approved Providers
        osv_base_url:
          anyOf:
            - maxLength: 200
              type: string
            - type: "null"
          title: Osv Base Url
        osv_enabled:
          anyOf:
            - type: boolean
            - type: "null"
          title: Osv Enabled
        scan_interval_hours:
          anyOf:
            - type: integer
            - type: "null"
          title: Scan Interval Hours
      title: SettingsBody
      type: object
    portal_api__routers__shadow_agents__AssignBody:
      properties:
        assignee_id:
          anyOf:
            - format: uuid
              type: string
            - type: "null"
          title: Assignee Id
      title: AssignBody
      type: object
    portal_api__routers__shadow_agents__NoteBody:
      properties:
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: "null"
          title: Note
      title: NoteBody
      type: object
    portal_api__routers__simulation__ReplayBody:
      properties:
        agent_id:
          anyOf:
            - type: string
            - type: "null"
          title: Agent Id
        only_changes:
          default: true
          title: Only Changes
          type: boolean
        window_days:
          default: 7
          enum:
            - 1
            - 7
            - 30
          title: Window Days
          type: integer
      title: ReplayBody
      type: object
    portal_api__routers__simulation__RunBody:
      properties:
        category:
          anyOf:
            - type: string
            - type: "null"
          title: Category
        ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: "null"
          title: Ids
        judge:
          anyOf:
            - enum:
                - auto
                - off
              type: string
            - type: "null"
          title: Judge
        policy_set:
          default: published
          enum:
            - published
            - with_drafts
          title: Policy Set
          type: string
      title: RunBody
      type: object
    shared__sim_runs__RunBody:
      additionalProperties: false
      properties:
        agent_id:
          maxLength: 64
          minLength: 1
          title: Agent Id
          type: string
        idempotency_key:
          anyOf:
            - maxLength: 64
              type: string
            - type: "null"
          title: Idempotency Key
        input:
          $ref: "#/components/schemas/RunInput"
        judge:
          default: auto
          enum:
            - off
            - auto
          title: Judge
          type: string
        policy_set:
          default: published
          enum:
            - published
            - with_drafts
          title: Policy Set
          type: string
      required:
        - agent_id
      title: RunBody
      type: object
    Error:
      type: object
      required:
        - detail
      properties:
        detail:
          description: A message, or a list of validation problems.
          oneOf:
            - type: string
            - type: array
              items:
                type: object
                additionalProperties: true
    TokenPair:
      type: object
      required:
        - access_token
        - refresh_token
        - token_type
      properties:
        access_token:
          type: string
          description: A signed token, valid for 1 hour.
        refresh_token:
          type: string
          description: Valid for 14 days. Use it with `POST /api/auth/refresh`.
        token_type:
          type: string
          const: bearer
    Me:
      type: object
      properties:
        user_id:
          type: string
        email:
          type: string
        role:
          type: string
          enum:
            - admin
            - reviewer
            - auditor
            - viewer
        display_name:
          type:
            - string
            - "null"
        last_login_at:
          type:
            - string
            - "null"
          format: date-time
        tenant_id:
          type: string
        tenant_name:
          type: string
        tenant:
          type: object
          additionalProperties: true
        permissions:
          type: array
          items:
            type: string
      additionalProperties: true
    GatewayKeyCreated:
      type: object
      required:
        - id
        - name
        - token
        - openai_base_url
      properties:
        id:
          type: string
        name:
          type: string
        token:
          type: string
          description: The gateway key, `bst_<8 hex>.<secret>`. Shown once.
        provider_billing_mode:
          type: string
          enum:
            - commercial
            - self_hosted
            - unknown
        openai_base_url:
          type: string
          description: Use this as the `base_url` of your OpenAI-compatible client. It contains the secret.
        note:
          type: string
