components:
  schemas:
    AckOperatorBody:
      additionalProperties: false
      properties:
        owner:
          description: Operator org (the token's 'owner' claim), when present.
          examples:
            - acme
          type: string
        sub:
          description: Operator subject (the token's 'sub' claim, server-extracted).
          examples:
            - alice
          type: string
      required:
        - sub
      type: object
    AckStateBody:
      additionalProperties: false
      properties:
        alertId:
          description: Opaque client alert identity (kind:subject).
          examples:
            - projected-floor-breach
          type: string
        at:
          description: When the latest event was recorded (RFC 3339).
          format: date-time
          type: string
        note:
          description: Optional operator-authored handoff note.
          examples:
            - called BACEN, awaiting callback
          type: string
        operator:
          $ref: "#/components/schemas/AckOperatorBody"
          description: Server-extracted operator who recorded the latest event.
        state:
          description: "'acknowledged' or 'open' (open = latest event was a reopen)."
          examples:
            - acknowledged
          type: string
      required:
        - alertId
        - state
        - operator
        - at
      type: object
    ApproveShiftHandoffOutputBody:
      additionalProperties: false
      properties:
        approvedAt:
          format: date-time
          type: string
        handoff:
          $ref: "#/components/schemas/ShiftHandoffBody"
        receiptId:
          type: string
      required:
        - receiptId
        - approvedAt
        - handoff
      type: object
    CreateAckBody:
      additionalProperties: false
      properties:
        action:
          description: "'acknowledge' marks the alert handled; 'reopen' flips it back to open."
          enum:
            - acknowledge
            - reopen
          examples:
            - acknowledge
          type: string
        alertId:
          description: Opaque client alert identity (kind:subject).
          examples:
            - projected-floor-breach
          type: string
        note:
          description: Optional operator handoff note (≤500 chars).
          type: string
      required:
        - alertId
        - action
      type: object
    CreateDeleteRequestBody:
      additionalProperties: false
      properties:
        note:
          description: Optional reason (≤500 chars). Operator free-text only.
          type: string
        userId:
          description: The target user to delete.
          examples:
            - "42"
          type: string
      required:
        - userId
      type: object
    CreateShiftHandoffBody:
      additionalProperties: false
      properties:
        evidence:
          description: One or more immutable canonical evidence references.
          items:
            $ref: "#/components/schemas/EvidenceReferenceBody"
          type:
            - array
            - "null"
        note:
          description: Operator-authored context (1..1200 characters).
          type: string
      required:
        - note
        - evidence
      type: object
    DecideOperationApprovalBody:
      additionalProperties: false
      properties:
        decision:
          description: The checker's decision.
          enum:
            - approved
            - rejected
          type: string
        note:
          description: Optional decision reason (≤500 chars).
          type: string
      required:
        - decision
      type: object
    DecisionBody:
      additionalProperties: false
      properties:
        note:
          description: Optional decision reason (≤500 chars).
          type: string
      type: object
    DeleteOperatorBody:
      additionalProperties: false
      properties:
        owner:
          description: Operator org (the token's 'owner' claim), when present.
          examples:
            - acme
          type: string
        sub:
          description: Operator subject (the token's 'sub' claim, server-extracted).
          examples:
            - alice
          type: string
      required:
        - sub
      type: object
    DeleteRequestStateBody:
      additionalProperties: false
      properties:
        at:
          description: When the latest event was recorded (RFC 3339).
          format: date-time
          type: string
        note:
          description: Optional operator-authored reason.
          examples:
            - offboarding after a role change
          type: string
        operator:
          $ref: "#/components/schemas/DeleteOperatorBody"
          description: Server-extracted operator who recorded the latest event (the maker on 'requested'; the checker otherwise).
        state:
          description: "Latest workflow action: 'requested' (pending a checker), 'approved' (deleted), 'rejected', or 'failed' (execution failed, retryable)."
          enum:
            - requested
            - approved
            - rejected
            - failed
          examples:
            - requested
          type: string
        userId:
          description: The target user the workflow is about.
          examples:
            - "42"
          type: string
      required:
        - userId
        - state
        - operator
        - at
      type: object
    Detail:
      additionalProperties: false
      properties:
        code:
          description: "Stable, machine-readable domain error code scoped to the emitting service (format: <SERVICE>-NNNN)."
          type: string
        correlationId:
          description: Request-scoped correlation identifier echoing X-Request-ID.
          examples:
            - req-7a3f9c2e
          type: string
        detail:
          description: A human-readable explanation specific to this occurrence of the problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: "#/components/schemas/ErrorDetail"
          type:
            - array
            - "null"
        instance:
          description: A URI reference that identifies the specific occurrence of the problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: A short, human-readable summary of the problem type. This value should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
        upstream:
          $ref: "#/components/schemas/Upstream"
          description: "RFC 9457 extension member: the error a proxied third-party provider reported. Absent unless the emitting service explicitly surfaced one."
      required:
        - correlationId
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
    EvidenceReferenceBody:
      additionalProperties: false
      properties:
        label:
          description: Stable human label for the canonical evidence path.
          examples:
            - STR operation abc
          type: string
        path:
          description: Canonical Cabine application path.
          examples:
            - /str/operations/abc
          type: string
      required:
        - path
        - label
      type: object
    HandoffDetailOutputBody:
      additionalProperties: false
      properties:
        handoff:
          $ref: "#/components/schemas/ShiftHandoffBody"
        history:
          items:
            $ref: "#/components/schemas/HandoffHistoryEventBody"
          type: array
      required:
        - handoff
        - history
      type: object
    HandoffHistoryEventBody:
      additionalProperties: false
      properties:
        actor:
          $ref: "#/components/schemas/HandoffOperatorBody"
        at:
          format: date-time
          type: string
        eventId:
          type: string
        status:
          enum:
            - draft
            - submitted
            - approved
          type: string
      required:
        - eventId
        - status
        - actor
        - at
      type: object
    HandoffOperatorBody:
      additionalProperties: false
      properties:
        owner:
          description: Operator organization from the bearer token.
          type: string
        sub:
          description: Operator subject from the bearer token.
          type: string
      required:
        - sub
      type: object
    ListAcksResponse:
      additionalProperties: false
      properties:
        acks:
          description: Current ack-state per requested id that has a live event.
          items:
            $ref: "#/components/schemas/AckStateBody"
          type: array
      required:
        - acks
      type: object
    ListDeleteRequestsResponse:
      additionalProperties: false
      properties:
        requests:
          description: Current workflow state per requested user id that has a live event.
          items:
            $ref: "#/components/schemas/DeleteRequestStateBody"
          type: array
      required:
        - requests
      type: object
    ListOperationApprovalsResponse:
      additionalProperties: false
      properties:
        approvals:
          description: Current state of every workflow, latest-first, optionally filtered by status.
          items:
            $ref: "#/components/schemas/OperationApprovalStateBody"
          type: array
      required:
        - approvals
      type: object
    ListShiftHandoffsOutputBody:
      additionalProperties: false
      properties:
        handoffs:
          items:
            $ref: "#/components/schemas/ShiftHandoffBody"
          type: array
      required:
        - handoffs
      type: object
    OperationApprovalDeliveryBody:
      additionalProperties: false
      properties:
        attemptCount:
          description: How many delivery attempts have run so far.
          format: int64
          type: integer
        lastAttemptAt:
          description: When the most recent attempt ran.
          format: date-time
          type: string
        lastStatusCode:
          description: The HTTP status SPI last answered with, when a response was received.
          format: int64
          type: integer
        outcome:
          description: "pending: still retrying. succeeded: the decision landed on the SPI operation. refused: SPI answered 422 and did not apply the decision. exhausted: gave up after the maximum number of delivery attempts without a delivered answer. Read the operation in Lerian SPI before you propose again."
          enum:
            - pending
            - succeeded
            - refused
            - exhausted
          type: string
      required:
        - outcome
        - attemptCount
      type: object
    OperationApprovalStateBody:
      additionalProperties: false
      properties:
        action:
          description: The opaque resolution proposed; the Cabine API never interprets it.
          enum:
            - ATTACH_BACEN_RESOURCE
            - CONFIRM_NOT_APPLIED
          examples:
            - ATTACH_BACEN_RESOURCE
          type: string
        approvalId:
          description: The workflow's own identity — use this in GET and decision paths.
          examples:
            - 9b2f6c1e-4d7a-4e83-a5c0-3f1d8e2b7a46
          type: string
        at:
          description: When the latest event was recorded (RFC 3339).
          format: date-time
          type: string
        bacenResourceId:
          description: Set only when action=ATTACH_BACEN_RESOURCE.
          type: string
        checker:
          $ref: "#/components/schemas/DeleteOperatorBody"
          description: Server-extracted decider identity, once decided.
        decisionDeadline:
          description: Past this instant only 'expired' may follow 'requested'.
          format: date-time
          type: string
        delivery:
          $ref: "#/components/schemas/OperationApprovalDeliveryBody"
          description: The delivery status of the decision sent to Lerian SPI, once at least one attempt has run.
        digest:
          description: Hex SHA-256 the maker echoed (the SPI operation's requestFingerprint).
          type: string
        maker:
          $ref: "#/components/schemas/DeleteOperatorBody"
          description: Server-extracted proposer identity.
        note:
          description: Optional operator-authored reason.
          type: string
        operationId:
          description: The SPI DICT/MED operationId this approval concerns.
          examples:
            - 5c8e1a47-2b9d-4f60-8e3a-d1f47b09c625
          type: string
        state:
          description: Latest workflow lifecycle action.
          enum:
            - requested
            - approved
            - rejected
            - expired
          examples:
            - requested
          type: string
      required:
        - approvalId
        - operationId
        - state
        - action
        - digest
        - maker
        - decisionDeadline
        - at
      type: object
    ProposeOperationApprovalBody:
      additionalProperties: false
      properties:
        action:
          description: The opaque resolution proposed.
          enum:
            - ATTACH_BACEN_RESOURCE
            - CONFIRM_NOT_APPLIED
          type: string
        bacenResourceId:
          description: Required (UUID) when action=ATTACH_BACEN_RESOURCE; must be absent when action=CONFIRM_NOT_APPLIED.
          type: string
        digest:
          description: Hex SHA-256 (64 lowercase hex chars) — the SPI operation's requestFingerprint.
          type: string
        note:
          description: Optional maker-authored reason.
          type: string
        operationId:
          description: The SPI DICT/MED operationId this approval concerns (UUID).
          type: string
      required:
        - operationId
        - action
        - digest
      type: object
    ShiftHandoffBody:
      additionalProperties: false
      properties:
        approvedBy:
          $ref: "#/components/schemas/HandoffOperatorBody"
        createdAt:
          format: date-time
          type: string
        evidence:
          items:
            $ref: "#/components/schemas/EvidenceReferenceBody"
          type: array
        id:
          description: Stable handoff identifier.
          type: string
        note:
          type: string
        owner:
          $ref: "#/components/schemas/HandoffOperatorBody"
        receiptId:
          type: string
        status:
          enum:
            - draft
            - submitted
            - approved
          type: string
        submittedBy:
          $ref: "#/components/schemas/HandoffOperatorBody"
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - status
        - owner
        - note
        - evidence
        - createdAt
        - updatedAt
      type: object
    Upstream:
      additionalProperties: false
      properties:
        code:
          description: The upstream provider's own error code, verbatim.
          examples:
            - E4001
          type: string
        message:
          description: The upstream provider's own error message, verbatim (bounded, never its raw response body).
          examples:
            - account not found at provider
          type: string
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: JWT
      description: JWT bearer token issued by the identity provider.
      scheme: bearer
      type: http
info:
  description: The Cabine API serves Lerian Cabine, the operators' console over Lerian's native rails. Use it to acknowledge alerts, hand off shifts, delete operator users with four-eyes approval, and decide Lerian SPI operations under manual review with four-eyes approval.
  title: Lerian Cabine API
  version: 1.0.0
openapi: 3.1.0
paths:
  /v1/acks:
    get:
      description: Returns the current acknowledgement state (latest non-expired event) for each requested opaque alert-id that has one. Ids without a live event are omitted. Operator attribution (sub/owner) is server-extracted, never client-supplied.
      operationId: listAcks
      parameters:
        - description: Bearer JWT token.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT token.
            type: string
        - description: Comma-separated list of opaque alert-ids to look up.
          explode: false
          in: query
          name: alert_ids
          schema:
            description: Comma-separated list of opaque alert-ids to look up.
            examples:
              - projected-floor-breach
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListAcksResponse"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: List current ack-state for alert-ids
      tags:
        - OperatorState
      x-mint:
        href: /pt/reference/rails/cabine/list-current-ack-state-for-alert-ids
    post:
      description: Appends an acknowledge/reopen event for an opaque alert-id and returns the resulting current state. The operator identity recorded on the event is derived from the bearer token's claims (sub/owner) — a body that carries a sub or operator field is refused with 422. Operator A cannot acknowledge as operator B.
      operationId: createAck
      parameters:
        - description: Bearer JWT token. The operator identity recorded on the event is derived from THIS token, never the body.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT token. The operator identity recorded on the event is derived from THIS token, never the body.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateAckBody"
              description: Acknowledge or reopen an opaque alert-id.
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AckStateBody"
          description: Created
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Acknowledge or reopen an alert-id
      tags:
        - OperatorState
      x-mint:
        href: /pt/reference/rails/cabine/acknowledge-or-reopen-an-alert-id
  /v1/handoffs:
    get:
      operationId: listShiftHandoffs
      parameters:
        - in: header
          name: Authorization
          schema:
            type: string
        - description: Optional current-status filter.
          explode: false
          in: query
          name: status
          schema:
            description: Optional current-status filter.
            enum:
              - draft
              - submitted
              - approved
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListShiftHandoffsOutputBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: List current shift handoffs
      tags:
        - ShiftHandoffs
      x-mint:
        href: /pt/reference/rails/cabine/list-current-shift-handoffs
    post:
      operationId: createShiftHandoffDraft
      parameters:
        - in: header
          name: Authorization
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateShiftHandoffBody"
              description: Create an auditable shift-handoff draft.
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShiftHandoffBody"
          description: Created
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Create a shift-handoff draft
      tags:
        - ShiftHandoffs
      x-mint:
        href: /pt/reference/rails/cabine/create-a-shift-handoff-draft
  /v1/handoffs/{handoffId}:
    get:
      operationId: getShiftHandoff
      parameters:
        - in: header
          name: Authorization
          schema:
            type: string
        - in: path
          name: handoffId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HandoffDetailOutputBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Get a handoff and its immutable audit history
      tags:
        - ShiftHandoffs
      x-mint:
        href: /pt/reference/rails/cabine/get-a-handoff-and-its-immutable-audit-history
  /v1/handoffs/{handoffId}/approve:
    post:
      description: "Requires a normal-user principal: an application token is refused with 403, and any other token type is refused with 401 at the gate. The approver must differ from both draft owner and submitter. The approval event id is the immutable receipt id."
      operationId: approveShiftHandoff
      parameters:
        - in: header
          name: Authorization
          schema:
            type: string
        - in: path
          name: handoffId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApproveShiftHandoffOutputBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Approve a handoff and issue its receipt
      tags:
        - ShiftHandoffs
      x-mint:
        href: /pt/reference/rails/cabine/approve-a-handoff-and-issue-its-receipt
  /v1/handoffs/{handoffId}/submit:
    post:
      operationId: submitShiftHandoff
      parameters:
        - in: header
          name: Authorization
          schema:
            type: string
        - in: path
          name: handoffId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShiftHandoffBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Submit a handoff for review
      tags:
        - ShiftHandoffs
      x-mint:
        href: /pt/reference/rails/cabine/submit-a-handoff-for-review
  /v1/operation-approvals:
    get:
      description: Returns the current state of every workflow, optionally filtered by lifecycle status.
      operationId: listOperationApprovals
      parameters:
        - description: Bearer JWT.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT.
            type: string
        - description: Optional lifecycle filter — e.g. the checker's queue (?status=requested).
          explode: false
          in: query
          name: status
          schema:
            description: Optional lifecycle filter — e.g. the checker's queue (?status=requested).
            enum:
              - requested
              - approved
              - rejected
              - expired
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListOperationApprovalsResponse"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: List operation-approval workflows
      tags:
        - OperationApprovalFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/list-operation-approval-workflows
    post:
      description: Raises a four-eyes proposal for an SPI operationId. The MAKER identity is the bearer token's sub, and the token MUST be a normal-user principal (403 otherwise). A second live proposal for the same operationId is rejected (409).
      operationId: proposeOperationApproval
      parameters:
        - description: "Bearer JWT. Must be a normal-user principal (the MAKER): an application token is refused with 403, and any other token type is refused with 401 at the gate."
          in: header
          name: Authorization
          schema:
            description: "Bearer JWT. Must be a normal-user principal (the MAKER): an application token is refused with 403, and any other token type is refused with 401 at the gate."
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposeOperationApprovalBody"
              description: Propose a four-eyes resolution for an SPI operationId. The Cabine API validates shape only, never regulatory meaning.
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperationApprovalStateBody"
          description: Created
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Propose an operation-approval resolution (maker)
      tags:
        - OperationApprovalFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/propose-an-operation-approval-resolution-maker
  /v1/operation-approvals/{approvalId}:
    get:
      operationId: getOperationApproval
      parameters:
        - description: Bearer JWT.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT.
            type: string
        - in: path
          name: approvalId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperationApprovalStateBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Get one operation-approval workflow
      tags:
        - OperationApprovalFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/get-one-operation-approval-workflow
  /v1/operation-approvals/{approvalId}/decision:
    post:
      description: The CHECKER decides a pending proposal. The checker (token sub) MUST be a normal-user principal (403 otherwise) and MUST differ from the maker (four-eyes, 403 on self-approval). A decision after the deadline is 410; a decision on an already-decided workflow is 409.
      operationId: decideOperationApproval
      parameters:
        - description: "Bearer JWT. Must be a normal-user principal (the CHECKER): an application token is refused with 403, and any other token type is refused with 401 at the gate. Must differ from the maker (four-eyes)."
          in: header
          name: Authorization
          schema:
            description: "Bearer JWT. Must be a normal-user principal (the CHECKER): an application token is refused with 403, and any other token type is refused with 401 at the gate. Must differ from the maker (four-eyes)."
            type: string
        - description: The workflow being decided.
          in: path
          name: approvalId
          required: true
          schema:
            description: The workflow being decided.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DecideOperationApprovalBody"
              description: The checker's decision.
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperationApprovalStateBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Approve or reject an operation-approval workflow (checker)
      tags:
        - OperationApprovalFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/approve-or-reject-an-operation-approval-workflow-checker
  /v1/user-deletes:
    get:
      description: Returns the current state (latest non-expired event) for each requested target user id that has one. Operator attribution is server-extracted, never client-supplied.
      operationId: listUserDeleteRequests
      parameters:
        - description: Bearer JWT token.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT token.
            type: string
        - description: Comma-separated list of target user ids to look up.
          explode: false
          in: query
          name: user_ids
          schema:
            description: Comma-separated list of target user ids to look up.
            examples:
              - 42,7
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListDeleteRequestsResponse"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: List current user-delete workflow state
      tags:
        - UserDeleteFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/list-current-user-delete-workflow-state
    post:
      description: Raises a four-eyes deletion request for a user. The MAKER identity is the bearer token's sub (a sub/operator field in the body is rejected). A second pending request for the same user is rejected (409).
      operationId: createUserDeleteRequest
      parameters:
        - description: Bearer JWT. A normal-user or an application principal may request a deletion; only a normal-user may decide one. The MAKER identity recorded on the request is derived from THIS token, never the body.
          in: header
          name: Authorization
          schema:
            description: Bearer JWT. A normal-user or an application principal may request a deletion; only a normal-user may decide one. The MAKER identity recorded on the request is derived from THIS token, never the body.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateDeleteRequestBody"
              description: Raise a four-eyes deletion request for a user.
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeleteRequestStateBody"
          description: Created
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Request a user deletion (maker)
      tags:
        - UserDeleteFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/request-a-user-deletion-maker
  /v1/user-deletes/{userId}/approve:
    post:
      description: The CHECKER approves a pending request. The checker (token sub) MUST differ from the maker (four-eyes, 403 otherwise). On approval the Cabine API executes the deletion in Access Manager with a service credential, recording 'approved' ONLY on success; an execution failure records 'failed' (retryable) and returns 502.
      operationId: approveUserDeleteRequest
      parameters:
        - description: "Bearer JWT. Must be a normal-user principal: an application token is refused with 403, and any other token type is refused with 401 at the gate. The CHECKER identity is derived from THIS token; it MUST differ from the requester (four-eyes)."
          in: header
          name: Authorization
          schema:
            description: "Bearer JWT. Must be a normal-user principal: an application token is refused with 403, and any other token type is refused with 401 at the gate. The CHECKER identity is derived from THIS token; it MUST differ from the requester (four-eyes)."
            type: string
        - description: The target user whose pending delete request is being decided.
          in: path
          name: userId
          required: true
          schema:
            description: The target user whose pending delete request is being decided.
            examples:
              - "42"
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DecisionBody"
              description: Optional decision note.
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeleteRequestStateBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Approve a user-delete request (checker) and execute the deletion
      tags:
        - UserDeleteFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/approve-a-user-delete-request-checker-and-execute-the-deletion
  /v1/user-deletes/{userId}/reject:
    post:
      description: The CHECKER rejects a pending request (no deletion executed). The checker MUST differ from the maker (four-eyes).
      operationId: rejectUserDeleteRequest
      parameters:
        - description: "Bearer JWT. Must be a normal-user principal: an application token is refused with 403, and any other token type is refused with 401 at the gate. The CHECKER identity is derived from THIS token; it MUST differ from the requester (four-eyes)."
          in: header
          name: Authorization
          schema:
            description: "Bearer JWT. Must be a normal-user principal: an application token is refused with 403, and any other token type is refused with 401 at the gate. The CHECKER identity is derived from THIS token; it MUST differ from the requester (four-eyes)."
            type: string
        - description: The target user whose pending delete request is being decided.
          in: path
          name: userId
          required: true
          schema:
            description: The target user whose pending delete request is being decided.
            examples:
              - "42"
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DecisionBody"
              description: Optional decision note.
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeleteRequestStateBody"
          description: OK
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Detail"
          description: Error
      security:
        - BearerAuth: []
      summary: Reject a user-delete request (checker)
      tags:
        - UserDeleteFourEyes
      x-mint:
        href: /pt/reference/rails/cabine/reject-a-user-delete-request-checker
servers:
  - url: https://api.example.com
    description: Replace the example host with the URL provided during environment onboarding.
