# Generated by scripts/openapi/BuildPublicSpec.mjs from openapi/decionis-api.yaml. Do not edit.
openapi: 3.1.0
info:
  title: Decionis Policy Evaluation API
  version: 0.6.0
  description: |
    Decionis evaluates captured execution intent against versioned policies
    before the caller performs the action. SDKs delegate policy judgment to this
    service and locally enforce the signed decision. New SDK API keys can be
    associated with an industry so Decionis provisions a starter encoded policy
    binding server-side; applications do not receive or implement policy logic.

    v0.2 adds: escalation-ready proof-packet export for dossiers and decision
    chains; the ops spend-control gates (spend admission + disbursement authority
    with duplicate-payment detection); native-surface decision federation; and the
    anonymous eBay Marketplace Account Deletion compliance endpoint required for an
    eBay production keyset.

    v0.3 adds the policy-as-code draft endpoints: turn unstructured policy
    sources (PDF, JSON, XML, transaction and audit logs, uploads) and live
    policy-source connectors (Jira, Confluence, Notion, Google Drive, Git
    repositories, SAP) into a reviewable strategy draft or an executable,
    compiler-validated policy pack.

    v0.4 adds the zero-human agent lane: anonymous provisional workspace
    minting with a signed issuer watermark, the public dossier verification
    trio (verify, proof-bundle, reproduce) behind expiring share-link
    capabilities, workspace claiming by email OTP, and org-wide share-link
    revocation.

    v0.5 documents the UCP checkout authority and merchant verification-key
    surfaces, exact UCP release negotiation, and additive Protocol 1.1 effect
    evidence without changing legacy finalization records.

    v0.6 makes the execution grant a REST resource: `/v1/authority/grants`
    issues it, and its `claims`, `receipts` and `reconciliations` claim it,
    finalize it and resolve an INDETERMINATE attempt. `enforce-and-bind`,
    `verify-token`, `claim-token`, `consume-token` and `finalize-token` stay
    as deprecated aliases of the same handlers. It adds managed escalations,
    presence providers and provider keys, held allowances, governed plans,
    policy records and proposals with workspace invariants, edge policy
    bundles, the execution-grant and policy-bundle key sets, outcome
    agreements, statements, charges and disputes, hosted-gateway
    authorizations, keys and TCP resources, and the commerce payment and
    Business Central surfaces.

    This is the public subset of the API. It leaves out the platform operator's
    routes and the service-to-service routes between Decionis components.
servers:
  - url: https://api.decionis.com
security:
  - ApiKeyAuth: []
tags:
  - name: Decisions
    description: Evaluate an action before it runs, read why a decision held, and send the signals it weighs.
  - name: Execution grants
    description: Bind one approved action to a single-use grant, claim it before commit and record what happened.
  - name: Escalations
    description: Follow and cancel the Presence escalations Decionis runs when a person must approve.
  - name: Cases
    description: Read and decide the decisions waiting for a person.
  - name: Allowances
    description: Define held allowances and read what each one still holds.
  - name: Governed plans
    description: Register a multi-step plan and follow each step's status.
  - name: Policies
    description: Create, validate and change policies, their proposals and your workspace invariants.
  - name: Assessments
    description: Submit records and findings for an assessment and read the signed results.
  - name: Dossiers and verification
    description: Fetch, export and verify Decision Dossiers, decision chains and evidence packs.
  - name: Outcomes
    description: Outcome agreements, signed statements, charges, drift reports and disputes.
  - name: Provider keys
    description: Register and revoke the keys that sign effect receipts, attestations, usage reports and signals.
  - name: Presence providers
    description: Choose which presence providers your policies may name.
  - name: Edge
    description: Signed policy bundles, entitlement and usage reports for the edge evaluator.
  - name: Hosted gateway
    description: Set up, sign on to and run hosted gateways and their TCP routes.
  - name: UCP
    description: Authorize UCP checkout completions and manage merchant verification keys.
  - name: Commerce
    description: Commerce Gate readiness, ERP data, history assessments, payment evidence and platform callbacks.
  - name: Business Central connections
    description: Connect, verify, rotate and disconnect Business Central companies.
  - name: Onboarding and auth
    description: Mint a workspace, claim it, inspect the credential you hold or revoke it.
  - name: Analytics
    description: Experiment analytics events and growth reports.
  - name: Health
    description: Check that the API is reachable.
paths:
  /v1/health:
    get:
      operationId: getHealth
      tags:
        - Health
      summary: Validate API connectivity
      security: []
      responses:
        "200":
          description: API is reachable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthResponse"
  /health:
    get:
      operationId: getRootHealth
      tags:
        - Health
      summary: Read the origin liveness probe
      description: Same inert handler as /v1/health; exempt from authentication and request-capacity shedding.
      security: []
      responses:
        "200":
          description: API is reachable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthResponse"
  /ready:
    get:
      operationId: getRootReadiness
      tags:
        - Health
      summary: Read the origin readiness probe
      description: Runs only a SELECT 1 with a 1500 ms timeout; exempt from authentication and request-capacity shedding. Creates no decision or dossier.
      security: []
      responses:
        "200":
          description: The database is reachable
        "503":
          description: The database readiness check failed or timed out
  /v1/ready:
    get:
      operationId: getReadiness
      tags:
        - Health
      summary: Read the API readiness probe
      description: Alias of /ready with the same bounded database check and probe exemptions.
      security: []
      responses:
        "200":
          description: The database is reachable
        "503":
          description: The database readiness check failed or timed out
  /v1/protocol/evaluate-decision:
    post:
      operationId: evaluateDecision
      tags:
        - Decisions
      summary: Evaluate captured execution intent without executing it
      description: Canonical SDK/API route for Decionis execution-gate decisions.
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProtocolEvaluateDecisionRequest"
      responses:
        "200":
          description: Policy decision
          headers:
            x-decionis-warning:
              $ref: "#/components/headers/DecionisWarning"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProtocolEvaluateDecisionResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
        "500":
          $ref: "#/components/responses/Error"
  /v1/authority/enforce-and-bind:
    post:
      operationId: enforceAndBindAgentAction
      tags:
        - Execution grants
      deprecated: true
      summary: Evaluate and bind one exact agent action to a single-use execution grant
      description: |
        Deprecated alias of `POST /v1/authority/grants`: the same handler,
        kept registered so AgentSafe 0.3.8, the Go govern client and installed
        SDKs keep working byte-for-byte. Removal is a later, separate decision.

        Agent-Safe enforcement route. Decionis recomputes the SHA-256
        hash of the canonical execution intent, evaluates policy in ENFORCEMENT
        mode, and issues a short-lived Ed25519 execution grant only for an ALLOW
        evaluated in ENFORCEMENT mode. SHADOW records the same exact intent and
        dossier evidence without issuing an execution grant.
        When Idempotency-Key is supplied, it must exactly match the intent_id
        embedded in the signed intent; intent_id is the grant issuance boundary.
        The intent's own `context.idempotency_key` is hashed into the intent
        and is not this header: any other header value answers 400
        AUTHORITY_IDEMPOTENCY_KEY_MISMATCH, with a `message` saying so.
        ESCALATE, REVIEW_REQUIRED, BLOCK, dependency errors, and binding errors
        never receive a grant. A Presence approval is accepted only after
        Decionis verifies the action-bound request and sealed receipt directly
        with Presence; approval then becomes evidence for a fresh policy
        evaluation, not authority by itself.
        A presence attestation (`evidence.humanApproval.provider`
        `attestation`) is a presence provider's compact JWS, typ
        `decionis-presence-attestation+jwt`, verified against a key the
        organisation registered at `/v1/execution/provider-keys` with purpose
        `presence_attestation` (see PresenceAttestationClaims). On success its
        facts are written to `agent_safe.human_approval` (provider, verified,
        method, approver_role, subject, attestation_id, key_id,
        approved_action_digest, approved_at, expires_at, and token_match /
        network_validated when the provider sent them) for policy rules to
        match, and the resulting ExecutionBinding records the attested
        approval. An ESCALATE becomes an ALLOW only when the organisation's
        policy has a rule matching those facts. A refused attestation is a 409
        with one of the PresenceAttestationRefusal codes, and no evaluation
        runs.
        A signed producer signal (`evidence.signals[].token`) is a producer's
        compact JWS, typ `decionis-signed-signal+jwt`, standing for up to
        thirty days and bound to no intent: a cardholder's delegation to an
        agent, say (see SignedSignalClaims). Each is verified before any
        evaluation against a key the organisation registered at
        `/v1/execution/provider-keys` with purpose `signed_signal`, or
        against the JWKS of an admitted presence provider, and its facts are
        written to `agent_safe.signed_signals.<name>` (verified, producer,
        method, subject, signal_id, key_id, issued_at, expires_at,
        evidence_digest, what it asserted, and `covers` / `covers_intent`:
        what of this intent it covers). A policy names the fact with
        `required_signals` as a dotted path
        (`agent_safe.signed_signals.card_delegation`) and decides with rules;
        the ExecutionBinding records the facts, and the claim rebuilds them
        and re-checks the key and the expiry. Signals may come with or
        without a human approval, in any mode, and beside a managed
        escalation. A refused signal is a 409 with one of the
        SignedSignalRefusal codes; no evaluation runs and no event fires.
        The token itself is never recorded, only its SHA-256 as
        `evidence_digest`.
        A runtime that read the target before asking states what it read in
        `context.agent_safe.precondition` (ExecutionTargetPrecondition:
        `version`, optional `state`, `source`, `read_at`), inside the intent
        hash. Policy reads it as `agent_safe.precondition`, and a bundle's
        `allowed_transitions` read its `state`; the grant binds `version` as
        `binding.expected_state_version`, and the claim's attestation carries
        it to a verifying provider, which refuses the write
        (`TARGET_STATE_CHANGED`) once the target has moved on. A malformed
        precondition is a 400 `INTENT_PRECONDITION_INVALID`, and nothing is
        evaluated.
        An ESCALATE in ENFORCEMENT, direct or managed, is queued to the
        organisation's event subscribers as `authority.escalation_required`,
        carrying the policy's selector and who proves the person (the
        `verification` block: `provider`, `methods`, `level`); and once the
        intent is presented again with human approval evidence, the answer
        is queued as `authority.escalation_resolved` (the fresh decision's
        outcome, or REFUSED with the refusal code), with the proof's facts
        and never the proof. Delivery never affects a decision. The same
        routing rides on an ESCALATE decision as `escalation_requirement`
        for the runtime from agent-safe-pipeline/0.3.7 on, and for no other
        client.
        The action space the deciding policy release was checked against
        rides on the decision as `action_manifest_digest` (the release's
        `actionManifestDigest`, or null when no governed release decided or
        its release attached no ActionManifest) for the runtime from
        agent-safe-pipeline/0.5.1 on, and for no other client. The runtime
        compares it with the action space it loaded and reports a
        difference; it changes nothing about the decision.
        When escalation.mode is MANAGED and policy returns ESCALATE, Decionis
        persists the original exact intent and orchestrates the policy-issued
        Presence ceremony. The response remains non-authorizing and carries a
        managed_escalation status locator; no ExecutionBinding or execution
        token exists until signed Presence evidence is independently verified
        and current policy is evaluated again.
        The decision carries the dossier's `verification` envelope (the same
        share-safe page `evaluate-decision` attaches) for a client that can
        read it: one identifying itself as `agent-safe-pipeline/0.2.0` or
        later, or as `govern/2.0.0` or later (the workflow gate), in its
        User-Agent. Every other client receives the decision exactly as
        before, so a gate that mirrors this schema strictly never meets a
        field it does not know.
        On this operation, a `context.decionis_policy` is treated as on
        evaluate-decision: its `sha256` must be the SHA-256 of its `content`,
        and one that asks for `enforce: true` has its policy file published as
        the workspace's enforced policy only when the key holds
        `policy:write`, `policy:*` or `org:*`; for any other key the decision
        is unaffected, nothing is published, and the response carries
        `x-decionis-warning: POLICY_ENFORCE_SCOPE_MISSING`. No other
        operation whose body or answer carries an execution intent
        (verify-token, consume-token, claim-token, or the execution grant of
        /v1/ucp/checkout/authorize) publishes a policy file or sends that
        header, whatever the key holds.
        A key whose only evaluation scope is `decision:shadow` (an AgentSafe
        hosted gateway's) runs SHADOW and nothing else: any other mode answers
        403 DECISION_SHADOW_MODE_DENIED, a body carrying
        `context.decionis_policy`, `evidence` or `escalation` answers 400
        DECISION_SHADOW_FIELD_DENIED (naming the `field`), and the evaluation
        is recorded and signed without dispatching to the organization's
        integrations.
        A key whose evaluation scope is `decision:enforce` (an enforced
        AgentSafe hosted gateway's) runs SHADOW or ENFORCEMENT, may open a
        managed escalation, and answers 400 DECISION_ENFORCE_FIELD_DENIED for a
        body carrying `context.decionis_policy`: it never publishes policy.
        The scopes each mode needs: SHADOW takes one of `decision:write`,
        `decision:run`, `decision:*`, `org:*`, `decision:shadow` or
        `decision:enforce`; PARALLEL and ENFORCEMENT take one of
        `decision:write`, `decision:*`, `org:*` or `decision:enforce`, so a key
        that runs SHADOW can still answer 403 FORBIDDEN in ENFORCEMENT. The
        workspace counts too: a provisional workspace that no owner has claimed,
        or an AWS service workspace, runs SHADOW only, and any other mode
        answers 403 PROVISIONAL_WORKSPACE_SHADOW_ONLY (or
        SERVICE_WORKSPACE_SHADOW_ONLY) whatever the key holds, with a
        `message`. An owner claims a provisional workspace through
        `POST /v1/orgs/{org_id}/claim/start` and `/claim/verify`; claiming
        does not widen a key's scopes. A SHADOW success therefore says nothing
        about whether ENFORCEMENT will be accepted.
        When a grant is issued under Protocol 1.1 and the intent named no
        `expected_effect_digest`, the decision is unchanged and
        `x-decionis-warning` carries EXPECTED_EFFECT_DIGEST_MISSING: that grant
        accepts no effect evidence at finalization or reconciliation, so its
        effect can never be confirmed.
        A held allowance (`/v1/authority/allowances`) is a named,
        organisation-scoped counter that policy draws on: the rule that
        approved the action names it in `then.allowance`, with the amount
        fixed or read from `action.parameters` by JSON pointer, and the
        ExecutionBinding records the draw as `allowance_draws`. A grant is
        issued only once that amount is reserved against the allowance, tied
        to the grant. When it cannot be, no grant is issued and the decision
        is `BLOCK` (`should_execute` false, `execution_eligible` false,
        `execution_binding_digest` null) with one of these reason codes after
        the evaluation's own:
        `ALLOWANCE_EXHAUSTED` (what remains, the limit less what unclaimed
        grants reserve, what open or unknown claims hold, and what committed
        claims consumed within the window, is less than the amount),
        `ALLOWANCE_UNDEFINED` (the organisation defines no allowance under
        that key) or `ALLOWANCE_AMOUNT_INVALID` (the parameters give no
        positive whole amount). It is a refusal and not an ESCALATE because
        no approval creates capacity: only raising the allowance's own limit
        does (a top-up, which needs `policy:write` or `org:*` and so never an
        agent's key), after which the action may be proposed again. The
        dossier keeps the evaluation as it was decided; the refusal is the
        authority's, at the moment of the grant. The claim converts the
        reservation in the transaction that consumes the grant, and
        finalization settles it: COMMITTED keeps it, FAILED releases it,
        INDETERMINATE holds it until reconciliation, and a grant never claimed
        releases it when it expires. An allowance is a counter and never a
        concurrency scope: grants drawing on one allowance are claimed and
        carried out concurrently while it has room.
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionAuthorityRequest"
      responses:
        "200":
          description: Bound policy decision; only ALLOW carries an execution token. A draw on a held allowance that cannot be reserved answers BLOCK with ALLOWANCE_EXHAUSTED, ALLOWANCE_UNDEFINED or ALLOWANCE_AMOUNT_INVALID.
          headers:
            x-decionis-warning:
              $ref: "#/components/headers/DecionisWarning"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionAuthorityDecision"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Presence evidence, a presence attestation or a signed signal failed verification, MANAGED escalation was combined with human-approval evidence, or the idempotency key is already bound
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/PresenceAttestationRefusal"
                  - $ref: "#/components/schemas/SignedSignalRefusal"
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/ExecutionAuthorityDecision"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Authority or grant store unavailable; no execution is authorized
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/ExecutionAuthorityDecision"
  /v1/authority/grants:
    post:
      operationId: createAuthorityGrant
      tags:
        - Execution grants
      summary: Evaluate one exact agent action and bind it to a single-use execution grant
      description: |
        The grant resource. Decionis recomputes the SHA-256 hash of the
        canonical execution intent, evaluates policy, and issues a
        short-lived Ed25519 execution grant only for an ALLOW evaluated in
        ENFORCEMENT mode. This is the handler of the deprecated alias
        `POST /v1/authority/enforce-and-bind`, registered twice: every rule
        documented there (Idempotency-Key binding, Presence and attestation
        evidence, signed signals, MANAGED escalation, the verification
        envelope by client version, `context.decionis_policy`, the
        `decision:shadow` confinement, the scopes each mode needs and the
        workspace-owner rule, the EXPECTED_EFFECT_DIGEST_MISSING warning, and
        the BLOCK when a held allowance cannot be reserved) applies here
        unchanged.

        The issued grant is addressed afterwards as
        `/v1/authority/grants/{grantId}`, where `grantId` is the grant's
        `jti`: the `execution_token_jti` of this response, the `jti` recorded
        for the grant, and the `jti` claim of the signed execution token.

        `POST /v1/authority/evaluate` and `POST /v1/authority/enforce`, which
        the legacy `@decionis/sdk-node` 0.1.0 calls and this API never served,
        answer 410 `LEGACY_AUTHORITY_ROUTE_RETIRED` naming this route and
        `@decionis/sdk`, which replaces that package.

        `executor` (optional) says who will carry the grant out. It is never
        part of the canonical intent, its hash, or the grant's binding. When
        `executor.style` is `permit` and a grant was issued, the decision also
        carries `permit_id` (the grant's jti), `intent_sha256` (the intent
        hash as bare hex, written as `dossier_sha256` is) and `expires_at`
        (`execution_token_expires_at`). Without `executor`, or with
        `dispatch`, the response is exactly the enforce-and-bind response. A
        MANAGED escalation's locator-only summary carries no grant, so it never
        carries permit fields.
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionAuthorityRequest"
      responses:
        "200":
          description: Bound policy decision; only ALLOW carries an execution token
          headers:
            x-decionis-warning:
              $ref: "#/components/headers/DecionisWarning"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionAuthorityDecision"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Presence evidence, a presence attestation or a signed signal failed verification, MANAGED escalation was combined with human-approval evidence, or the idempotency key is already bound
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/PresenceAttestationRefusal"
                  - $ref: "#/components/schemas/SignedSignalRefusal"
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/ExecutionAuthorityDecision"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Authority or grant store unavailable; no execution is authorized
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/ExecutionAuthorityDecision"
  /v1/authority/grants/{grantId}:
    parameters:
      - $ref: "#/components/parameters/GrantId"
    get:
      operationId: getAuthorityGrant
      tags:
        - Execution grants
      summary: Read and verify an execution grant without consuming it
      description: |
        The handler of the deprecated alias `POST /v1/execution/verify-token`.
        A GET carries no body, so the execution token is presented in the
        `x-decionis-execution-token` header (required; never logged) and the
        intent hash, optionally, as the `intent_hash` query parameter.

        Verifies the token's Ed25519 signature, issuer and lifetime; that the
        caller is authorised for the organisation the grant names (the caller's
        own organisation for an organisation API key); that the token's `jti`
        is `{grantId}` (otherwise 409 `GRANT_ID_MISMATCH`); and, when
        `intent_hash` is supplied, that the grant is bound to it (otherwise 409
        `GRANT_BINDING_MISMATCH`). The intent hash commits to the tenant,
        actor, action and downstream target the alias checks field by field.
        Reading a grant never authorizes execution: only a claim does.
      parameters:
        - $ref: "#/components/parameters/ExecutionTokenHeader"
        - name: intent_hash
          in: query
          required: false
          schema:
            type: string
            pattern: ^sha256:[0-9a-f]{64}$
      responses:
        "200":
          description: Valid grant
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "400":
          description: Missing `x-decionis-execution-token`, or an invalid grant id or query
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Grant invalid or expired, GRANT_ID_MISMATCH, or GRANT_BINDING_MISMATCH
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Grant verification unavailable; no execution is authorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
  /v1/authority/grants/{grantId}/claims:
    parameters:
      - $ref: "#/components/parameters/GrantId"
    post:
      operationId: createAuthorityGrantClaim
      tags:
        - Execution grants
      summary: Revalidate and atomically claim a grant once, immediately before commit
      description: |
        The handler of the deprecated aliases `POST /v1/execution/claim-token`
        and `POST /v1/execution/consume-token`, with the same body and the same
        responses: execution is authorized only when `should_execute` is
        `true`, `claim_token` is non-null and `claim_lease_expires_at` is still
        live at the downstream boundary, and a live claim returns
        `claim_attestation`. The verified token's `jti` must be `{grantId}`;
        otherwise the answer is 409 `GRANT_ID_MISMATCH` and nothing is claimed.
        When the grant's binding draws on a held allowance (`allowance_draws`),
        the claim converts the grant's reservation in the same transaction
        that consumes the grant and inserts its concurrency scopes. A grant
        whose reservation is not live cannot be claimed: the answer is 409
        `NONCE_REPLAY_DETECTED`, as for any grant that can no longer be
        consumed, and nothing is claimed.

        A live claim must be finalized at `/receipts` (alias
        `/v1/execution/finalize-token`) before `claim_lease_expires_at`, with
        COMMITTED, FAILED or INDETERMINATE; the 200 says so in
        `x-decionis-action-required: FINALIZE_BEFORE_LEASE_EXPIRY`. A claim
        left unfinalized past its lease is recorded INDETERMINATE and keeps
        its concurrency scopes (its execution target and bound material
        signals): every later claim on any of them answers 409 REVIEW
        `CURRENT_STATE_UNRESOLVED` with `evidence.nonce_claim_state`
        INDETERMINATE, and `x-decionis-blocking-grant` names the grant whose
        claim holds the scope, until that attempt is reconciled at
        `/v1/authority/grants/{grantId}/reconciliations`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionClaimTokenRequest"
      responses:
        "200":
          description: Authorization remains valid and the nonce is claimed
          headers:
            x-decionis-action-required:
              $ref: "#/components/headers/DecionisActionRequired"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionClaimTokenResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Structured fail-closed revalidation outcome, including GRANT_ID_MISMATCH and CURRENT_STATE_UNRESOLVED
          headers:
            x-decionis-blocking-grant:
              $ref: "#/components/headers/DecionisBlockingGrant"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Current state cannot be resolved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
  /v1/authority/grants/{grantId}/receipts:
    parameters:
      - $ref: "#/components/parameters/GrantId"
    post:
      operationId: createAuthorityGrantReceipt
      tags:
        - Execution grants
      summary: Record the outcome of a claimed downstream commit attempt
      description: |
        The handler of the deprecated alias `POST /v1/execution/finalize-token`,
        with the same body, rules and responses: COMMITTED, FAILED or
        INDETERMINATE, effect confirmation only from accepted digest-bound
        `effect_evidence`, a verifying provider's `effect_receipt` recorded as
        presented, and lease-expiry recorded as INDETERMINATE. The verified
        token's `jti` must be `{grantId}`; otherwise the answer is 409
        `GRANT_ID_MISMATCH` and nothing is recorded.

        A permit-style platform may add `native_receipt`, what the platform
        itself recorded when it carried the action out. It is recorded as
        `downstream_evidence.native_receipt`, so the claim and its commit
        evidence carry it; it is the executor's report of the attempt and
        never effect confirmation by itself.

        A finalization that contradicts its binding opens an assumption
        breach in the grant's action and target, reported as
        `assumption_breach`: effect evidence naming an observed effect other
        than the expected one (`EFFECT_MISMATCH`), or a verified receipt that
        effected another effect, effected what the executor reports FAILED,
        or refused what it reports COMMITTED (`EFFECT_RECEIPT_CONTRADICTION`).
        An unverified receipt opens nothing. The breach never changes the
        finalization's answer.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionFinalizeRequest"
      responses:
        "200":
          description: Claim finalized and commit evidence recorded or queued for recovery
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionFinalizeResponse"
        "400":
          description: Invalid finalization, native receipt or effect-evidence shape
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Invalid, replayed, non-claimed, or lease-expired authorization, or GRANT_ID_MISMATCH. An expired claim reports outcome INDETERMINATE and CLAIM_LEASE_EXPIRED.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionFinalizeResponse"
  /v1/authority/grants/{grantId}/reconciliations:
    parameters:
      - $ref: "#/components/parameters/GrantId"
    post:
      operationId: createAuthorityGrantReconciliation
      tags:
        - Execution grants
      summary: Report how an INDETERMINATE execution of this grant resolved
      description: |
        An executor holding the grant reports, from its own downstream
        reconciliation, whether an INDETERMINATE execution COMMITTED or
        FAILED. The nonce stays burned and the action is never retried: the
        resolution is an append-only record with digest-bound effect evidence,
        and its commit evidence goes to the Decision Chain. The same evidence
        rules as the platform operator's reconciliation apply.

        The execution token (accepted after its expiry, as at finalization)
        must verify, its `jti` must be `{grantId}` (otherwise 409
        `GRANT_ID_MISMATCH`), its correlation must be `commit_correlation_id`,
        and `claim_token` must be the token of the grant's claim (otherwise
        409 `CLAIM_TOKEN_MISMATCH`). The caller needs `decision:write`,
        `decision:*` or `org:*` in the grant's organisation. The authenticated
        principal is the reconciler and the only trusted observer of the
        effect evidence; it is never named in the body. An organisation API
        key reconciles only when it is on the trusted effect-observer
        allow-list; any other caller is answered 409
        `EFFECT_OBSERVER_PROVENANCE_UNAVAILABLE`. A claim that is not
        INDETERMINATE answers 409 `CLAIM_NOT_INDETERMINATE`.

        Evidence bound to the grant that names an observed effect other than
        the expected one cannot resolve the claim (409
        `EFFECT_EVIDENCE_INSUFFICIENT_FOR_RECONCILIATION`, the claim stays
        INDETERMINATE) and opens an assumption breach in the grant's action
        and target (`RECONCILIATION_CONTRADICTION`), reported as
        `assumption_breach`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionGrantReconciliationRequest"
      responses:
        "200":
          description: Reconciled; commit evidence acknowledged by the Decision Chain
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantReconciliationResponse"
        "202":
          description: Reconciled; commit evidence queued for delivery (COMMIT_EVIDENCE_PENDING)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantReconciliationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          description: No claim of this grant in the organisation (INDETERMINATE_CLAIM_NOT_FOUND)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantReconciliationResponse"
        "409":
          description: Invalid token, GRANT_ID_MISMATCH, EXECUTION_CORRELATION_MISMATCH, CLAIM_TOKEN_MISMATCH, CLAIM_NOT_INDETERMINATE, CLAIM_ALREADY_RECONCILED, or effect evidence that cannot resolve the claim
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantReconciliationResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Reconciliation store unavailable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantReconciliationResponse"
  /v1/authority/allowances:
    get:
      operationId: listAuthorityAllowances
      tags:
        - Allowances
      summary: List the organisation's held allowances, with what each one holds
      description: |
        Every allowance the organisation defines, with its usage now:
        `reserved` by grants not yet claimed and not expired, `held` by
        claims whose outcome is open or unknown (CLAIMED, INDETERMINATE),
        `consumed` by committed claims within the window (all of them when
        `window_seconds` is null), and what is `available` to the next
        grant. Requires policy:read, policy:write or org:* scope.
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: The organisation's allowances, in key order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthorityAllowanceListResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/authority/allowances/{allowanceKey}:
    parameters:
      - name: allowanceKey
        in: path
        required: true
        schema:
          $ref: "#/components/schemas/AuthorityAllowanceKey"
    get:
      operationId: getAuthorityAllowance
      tags:
        - Allowances
      summary: Read one held allowance and what it holds
      description: The allowance and its usage, as listed. Requires policy:read, policy:write or org:* scope.
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: The allowance and its usage now
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthorityAllowance"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    put:
      operationId: putAuthorityAllowance
      tags:
        - Allowances
      summary: Define a held allowance, or change its limit or window
      description: |
        Defines the allowance under `{allowanceKey}`, or replaces its unit,
        limit, window and description. Raising the limit is a top-up: the
        next grant drawing on it sees the room at once. Lowering it below
        what is reserved, held and consumed refuses every new draw until
        enough settles or leaves the window; reservations already made stay
        valid. A policy rule names the key in `then.allowance`, and a draw on
        a key no allowance is defined under is refused as
        `ALLOWANCE_UNDEFINED`. Requires policy:write or org:* scope, so an
        agent's `decision:write` key can never raise the limit it draws on.
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthorityAllowanceRequest"
      responses:
        "200":
          description: The allowance as now defined, with its usage
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthorityAllowance"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/authority/escalations/{escalationId}:
    parameters:
      - name: escalationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: org_id
        in: query
        required: false
        description: |
          Organization UUID. Required for platform-authenticated callers;
          organization API keys derive and enforce their organization from the
          authenticated credential.
        schema:
          type: string
          format: uuid
    get:
      operationId: getManagedAuthorityEscalation
      tags:
        - Escalations
      summary: Read Decionis-managed Presence authorization status
      description: |
        Returns tenant-scoped orchestration state without exposing Presence
        credentials, invitation locators, authentication assertions, or biometric
        material. A normal execution grant is present only at GRANT_READY, after
        Decionis has independently verified Presence evidence and re-evaluated
        current policy for the original exact intent.
      responses:
        "200":
          description: Current managed escalation state
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ManagedEscalationStatus"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    delete:
      operationId: cancelManagedAuthorityEscalation
      tags:
        - Escalations
      summary: Cancel a pending Decionis-managed Presence escalation
      responses:
        "200":
          description: Cancelled or already-terminal managed escalation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ManagedEscalationStatus"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
  /v1/authority/escalations/{escalationId}/approval:
    parameters:
      - name: escalationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: org_id
        in: query
        required: false
        description: |
          Organization UUID. Required for platform-authenticated callers;
          organization API keys derive and enforce their organization from the
          authenticated credential.
        schema:
          type: string
          format: uuid
    get:
      operationId: getManagedAuthorityEscalationApproval
      tags:
        - Escalations
      summary: Read the Presence authority request a managed escalation asks a person to prove
      description: |
        For the caller that opened the escalation, so that a decision case of
        its own can name the same Presence request as its step-up and one
        passkey ceremony answers both. `authority_request_id` is null until
        Presence has the request, and for an approval chain, where each tier
        member has a request of their own. It is never approval evidence and
        carries no invitation, assertion or grant.
      responses:
        "200":
          description: The escalation's Presence authority request, when there is a single one
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ManagedEscalationApproval"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/authority/presence-completions:
    post:
      operationId: notifyManagedPresenceCompletion
      tags:
        - Escalations
      summary: Notify Decionis that signed Presence proof may be ready
      description: |
        Service-to-service recovery hint. The body is never authorization.
        Decionis locates the tenant-bound escalation, fetches the signed Presence
        dossier, verifies it independently, and performs current-policy
        re-authorization before any grant can be issued. Duplicate notifications
        are idempotent.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PresenceAuthorityCompletion"
      responses:
        "202":
          description: Completion hint accepted or idempotently replayed
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
  /v1/authority/plans:
    post:
      operationId: registerGovernedPlan
      tags:
        - Governed plans
      summary: Register a governed plan; it authorizes no step
      description: |
        Registers one change carried out as several governed operations
        (`agent-safe.plan/1`): its steps, a coupling per dependency edge, a
        partial-commit rule and the compensation steps a failure opens. The
        plan is a governance object, not an orchestrator: registering it
        authorizes nothing, and every step is still decided by
        enforce-and-bind and claimed before it commits, with a grant of its
        own. A step's intent names the plan it belongs to in its hashed
        context (`agent_safe.plan`: `plan_id`, `plan_digest`, `step_id`);
        Decionis derives the step's facts from the plan and its own claim
        records and writes them under `agent_safe.plan` for policy to read,
        and binds the step's view of the plan as a material signal the claim
        rechecks. Plans are immutable: the same `plan_id` with another digest
        is refused. One organisation in v1: `tenant_id` must be the caller's.
        Requires decision:write, decision:* or org:*.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GovernedPlan"
      responses:
        "200":
          description: The same plan was already registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GovernedPlanRegistration"
        "201":
          description: Plan registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GovernedPlanRegistration"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/authority/plans/{planId}:
    get:
      operationId: getGovernedPlan
      tags:
        - Governed plans
      summary: Read a governed plan's state and each step's status
      description: |
        The plan as registered, its state and each step's status, derived
        now from the claim records of every grant issued for one of its
        steps: `COMMITTED` only with a confirmed effect. `PARTIAL` (a step
        failed after others committed) stays so once reached and maps to the
        SCITT execution profile's `partially_completed`; `SUSPENDED` (a step's
        outcome is unknown) lasts until reconciliation settles it.
      parameters:
        - name: planId
          in: path
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 128
            pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]*$
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: The plan and its state
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GovernedPlanStatus"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/execution/verify-token:
    post:
      operationId: verifyAgentExecutionToken
      tags:
        - Execution grants
      deprecated: true
      summary: Verify an execution grant without consuming it
      description: |
        Deprecated alias of `GET /v1/authority/grants/{grantId}`: the same
        handler, fed the token and the full intent from a body.

        Verifies the Ed25519 signature, issuer, audience, lifetime, action,
        actor, tenant, and exact intent hash. This endpoint does not authorize
        execution by itself because it does not atomically consume the grant.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionTokenRequest"
      responses:
        "200":
          description: Valid grant
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Grant invalid, expired, or not bound to the supplied intent
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Grant verification unavailable; no execution is authorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
  /v1/execution/consume-token:
    post:
      operationId: consumeAgentExecutionToken
      tags:
        - Execution grants
      deprecated: true
      summary: Compatibility alias for pre-commit claim and revalidation
      description: |
        Deprecated alias of `POST /v1/authority/grants/{grantId}/claims`: the
        same handler.

        The same handler as `/v1/execution/claim-token`, with the same body and
        responses. New adapters should use the explicit claim route and must
        finalize the claim before `claim_lease_expires_at`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionClaimTokenRequest"
      responses:
        "200":
          description: Binding revalidated and nonce claimed; caller may execute once
          headers:
            x-decionis-action-required:
              $ref: "#/components/headers/DecionisActionRequired"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionClaimTokenResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Stale authorization, replay, binding mismatch, or unresolved state
          headers:
            x-decionis-blocking-grant:
              $ref: "#/components/headers/DecionisBlockingGrant"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Revalidation state or claim store unavailable; no execution is authorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
  /v1/execution/claim-token:
    post:
      operationId: claimExecutionBoundDossier
      tags:
        - Execution grants
      deprecated: true
      summary: Revalidate and atomically claim one execution-bound authorization
      description: |
        Deprecated alias of `POST /v1/authority/grants/{grantId}/claims`: the
        same handler.

        Required immediately before the downstream commit. Verifies the dossier
        signature and complete execution binding, resolves current policy,
        signal, and Presence state, then atomically claims the nonce and mutable
        concurrency scope. Execution is authorized only when `should_execute`
        is `true`, `claim_token` is non-null, and `claim_lease_expires_at` is
        still live at the downstream boundary. `valid` alone is diagnostic;
        in SHADOW it may describe hypothetical validity without execution
        authority.

        A live claim also returns `claim_attestation`: a compact EdDSA JWS,
        signed with the execution-grant key, that a downstream system of
        record can verify offline against
        `/.well-known/decionis-execution-grant-jwks.json`. It names the
        grant, the decision, the dossier, the binding the grant carried
        (intent hash, canonical payload digest and its profile, expected
        effect digest, nonce, correlation), a digest of the claim token, and
        an expiry equal to the claim lease. The executor forwards it with the
        downstream request; the provider checks that the request it received
        is the one the attestation describes. See `ClaimAttestationClaims`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionClaimTokenRequest"
      responses:
        "200":
          description: Authorization remains valid and the nonce is claimed
          headers:
            x-decionis-action-required:
              $ref: "#/components/headers/DecionisActionRequired"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionClaimTokenResponse"
        "409":
          description: Structured fail-closed revalidation outcome
          headers:
            x-decionis-blocking-grant:
              $ref: "#/components/headers/DecionisBlockingGrant"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
        "503":
          description: Current state cannot be resolved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionTokenResponse"
  /.well-known/decionis-execution-grant-jwks.json:
    get:
      operationId: getExecutionGrantJwks
      tags:
        - Execution grants
      summary: Public keys for execution grants and claim attestations
      security: []
      description: |
        The Ed25519 public keys, as a JWKS, that sign execution grants and
        claim attestations. A deploy target or a downstream system of record
        verifies either offline against this set; during a signing-key
        rotation the previous key stays listed until the grants signed with
        it have drained. The `kid` in a token's protected header names the
        key to use.
      responses:
        "200":
          description: The current verification keys
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionGrantJwks"
        "404":
          description: Execution-grant signing is not configured for this environment
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/edge/policy-bundles/current:
    get:
      operationId: getCurrentSignedPolicyBundle
      tags:
        - Edge
      summary: Issue the organization's active policy bundle, signed for the edge evaluator
      description: |
        Signs the bundle hosted evaluation would run on right now and returns it
        as a compact JWS for the Decionis edge evaluator (the WebAssembly policy
        core a deployment runs inside its own network). The edge evaluator
        evaluates only bundles Decionis signed: it verifies the signature
        against the keys its release pins (published at
        `/.well-known/decionis-policy-bundle-jwks.json`), the audience against
        its organization, the validity window against the time its host
        supplies, and the bundle against `bundle_digest`.

        Selection is hosted evaluation's own: the newest active bundle whose
        effective window contains now and that passes the maker-checker gate,
        or, when `policy_version` is given, exactly that version among them. An
        unapproved, historical, not-yet-effective or expired bundle is never
        signed; like hosted evaluation, it is treated as not active and the
        answer is `404 POLICY_BUNDLE_NOT_FOUND` with the policy guard's reason.

        The signed bundle lives `ttl_seconds` (default 7 days, at most 30 days
        and at most the organization's plan maximum), never past the bundle's
        own `effective_to`. Every issuance is recorded before it is returned
        (see `GET /v1/edge/policy-bundles/issuances`); one that cannot be
        recorded is not issued. Requires an organization API key with
        `policy:read` (or `policy:*` / `org:*`); keys without explicit scopes
        are refused.

        Only organizations licensed for the edge evaluator receive bundles:
        Enterprise and self-managed plans include it, Premium with the edge
        add-on, and an operator may list an organization for a pilot. Any
        other organization is answered `403 EDGE_EVALUATOR_NOT_ENTITLED`
        (its signed entitlement, `GET /v1/edge/entitlement`, says why).

        The bundle is `core_abi: 3`: it also carries what hosted would decide
        differently for this organization, resolved with hosted's own code —
        `vertical_pack` (its configured pack, or the operator's pack
        override, else null) and `max_mode` / `max_mode_reason` (SHADOW with
        hosted's 403 code for an unclaimed provisional or AWS service
        workspace, else ENFORCEMENT). An edge module older than ABI 3 refuses
        such a bundle rather than decide without them. A bundle whose rules
        compare two facts (`EQ_FACT`, `NEQ_FACT`) is `core_abi: 7`, which an
        edge module older than ABI 7 refuses the same way, and one that
        declares `allowed_transitions` is `core_abi: 8`, which an edge module
        older than ABI 8 refuses.
        A bundle with a rule that draws on a held allowance (`then.allowance`)
        is never signed for an edge: only hosted Decionis holds an allowance,
        and an edge module would approve such a rule with nothing reserved.
      parameters:
        - name: decision_domain
          in: query
          required: false
          description: Recorded with the issuance. The bundle carries the rules of every decision domain; the domain is chosen per evaluation, so it does not change which bundle is signed.
          schema:
            type: string
            minLength: 1
            maxLength: 100
            pattern: ^[A-Za-z0-9_.:-]+$
        - name: policy_version
          in: query
          required: false
          description: Sign exactly this version; it must be active and approved.
          schema:
            type: string
            minLength: 1
            maxLength: 200
        - name: ttl_seconds
          in: query
          required: false
          schema:
            type: integer
            minimum: 60
            maximum: 2592000
            default: 604800
      responses:
        "200":
          description: The signed bundle; private and not cacheable
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignedPolicyBundleResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          description: Not authenticated with an organization API key (`ORG_API_KEY_REQUIRED`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Missing `policy:read` (`FORBIDDEN`), or the organization is not licensed for the edge evaluator (`EDGE_EVALUATOR_NOT_ENTITLED`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: The organization has no active, approved bundle (of the requested version)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyBundleNotFound"
        "409":
          description: "`POLICY_BUNDLE_VALIDITY_WINDOW_EMPTY`: the active bundle's effective window ends before a signed bundle could become valid; or `POLICY_BUNDLE_REQUIRES_HOSTED_ALLOWANCE`: a rule draws on a held allowance, which only hosted Decionis holds, so nothing was signed"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "502":
          description: "`POLICY_BUNDLE_RESOLUTION_FAILED`: the active bundle could not be resolved"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "503":
          description: "`POLICY_BUNDLE_SIGNING_NOT_CONFIGURED`, `POLICY_BUNDLE_ORG_MODE_UNAVAILABLE` (the organization's enforcement mode could not be resolved, so nothing was signed), or `POLICY_BUNDLE_ISSUANCE_UNAVAILABLE` (the issuance could not be recorded, so nothing was issued)"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/edge/policy-bundles/issuances:
    get:
      operationId: listPolicyBundleIssuances
      tags:
        - Edge
      summary: List the signed policy bundles issued to the organization
      description: |
        The record of every signed policy bundle issued to the authenticated
        organization, newest first: its `jti`, bundle, version, digest, signing
        key, validity window and the API key that requested it. Requires an
        organization API key with `policy:read` (or `policy:*` / `org:*`).
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
      responses:
        "200":
          description: The issuances; private and not cacheable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyBundleIssuanceList"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/edge/entitlement:
    get:
      operationId: getEdgeEntitlement
      tags:
        - Edge
      summary: The organization's signed edge-evaluator entitlement
      description: |
        A compact JWS stating what the authenticated organization is licensed
        for: its plan, deployment tier (`hosted` | `dedicated` |
        `self_managed`), included governed actions per month, volume band
        (self-managed only), whether the edge evaluator is included (`edge`),
        and how many days after a month ends its usage report is due. Valid
        35 days. Issued to every organization, entitled or not: an edge
        installation verifies it against the policy-bundle JWKS
        (`/.well-known/decionis-policy-bundle-jwks.json`; same key, its own
        `typ`) and uses it only to warn — a licence problem never stops or
        degrades a decision. Requires an organization API key with
        `policy:read` (or `policy:*` / `org:*`).
      responses:
        "200":
          description: The signed entitlement; private and not cacheable
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeEntitlementResponse"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          description: "`EDGE_ENTITLEMENT_SIGNING_NOT_CONFIGURED`, or `EDGE_ENTITLEMENT_UNAVAILABLE` (the licence could not be read)"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/edge/usage-reports:
    post:
      operationId: submitEdgeUsageReport
      tags:
        - Edge
      summary: Submit an edge installation's signed monthly usage report
      description: |
        An edge installation counts the governed actions it decided per UTC
        month from its hash-chained evidence and reports them as a compact
        JWS (`EdgeUsageReportHeader`, `EdgeUsageReportClaims`) signed with an
        Ed25519 key the organization registered at
        `/v1/execution/provider-keys` with purpose `usage_report` and the
        installation id as its `issuer`.

        Verified like an effect receipt: the header, the key (this
        organization's, this purpose only), the signature, `iss` = the key's
        issuer, `aud` = the organization, `iat` at most 5 minutes ahead, a
        month that has begun, and claims that add up (each breakdown sums to
        `total`, `delegated` <= `total`, the chain range present exactly when
        something was counted, `period_start`/`period_end` the month's
        bounds). A refused report is answered 422 with its code and not
        stored.

        One report per installation and month is current. The same report
        again is answered 200 with the stored record (`replay: true`). A
        different report for the same installation and month is accepted
        only when it counts further along the same chain stream (a higher
        `chain.last_seq`): it supersedes the current one, which stays on
        record pointing at it; otherwise 409.

        A stored report adds `total - delegated` governed actions (minus what
        earlier reports for that installation and month already metered) to
        the organization's usage through the governed-action meter hosted
        decisions use, dated in the reported month when the meter still
        accepts it, so plans, allowances and overage apply unchanged.
        `delegated` decisions were decided by hosted Decionis, which metered
        them already. Metering is fail-open: the report is recorded either
        way, with `meter_status`.

        Requires an organization API key with `policy:read`, `policy:write`,
        `policy:*` or `org:*`: the report's signature, not the API key, is
        what is trusted.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EdgeUsageReportSubmission"
      responses:
        "200":
          description: The same report was already recorded (`replay` true)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeUsageReportAccepted"
        "201":
          description: Recorded (and metered, see `meter_status`)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeUsageReportAccepted"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: The report does not supersede the current one for its installation and month
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeUsageReportConflict"
        "422":
          description: The report was refused; nothing was recorded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeUsageReportRefusal"
        "503":
          description: "`USAGE_REPORT_KEYS_UNAVAILABLE` or `USAGE_REPORT_UNAVAILABLE`: nothing was recorded; send it again"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
    get:
      operationId: listEdgeUsageReports
      tags:
        - Edge
      summary: List the organization's edge usage reports
      description: |
        Every usage report recorded for the authenticated organization,
        newest first, superseded ones included (`superseded_by`), optionally
        for one month. The report JWS itself is kept as evidence and not
        returned. Requires an organization API key with `policy:read`,
        `policy:write`, `policy:*` or `org:*`.
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: period
          in: query
          required: false
          schema:
            type: string
            pattern: ^2[0-9]{3}-(0[1-9]|1[0-2])$
      responses:
        "200":
          description: The reports; private and not cacheable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EdgeUsageReportList"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /.well-known/decionis-policy-bundle-jwks.json:
    get:
      operationId: getPolicyBundleJwks
      tags:
        - Edge
      summary: Public keys for signed policy bundles
      security: []
      description: |
        The Ed25519 public keys, as a JWKS, that sign policy bundles for the
        edge evaluator. An edge evaluator release pins these keys at build
        time; during a signing-key rotation the previous key stays listed until
        the bundles signed with it have expired. The `kid` in a signed bundle's
        protected header names the key to use.
      responses:
        "200":
          description: The current verification keys
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyBundleJwks"
        "404":
          description: Policy bundle signing is not configured for this environment
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/execution/finalize-token:
    post:
      operationId: finalizeExecutionBoundDossier
      tags:
        - Execution grants
      deprecated: true
      summary: Finalize a claimed downstream commit attempt
      description: |
        Deprecated alias of `POST /v1/authority/grants/{grantId}/receipts`:
        the same handler.

        Records COMMITTED, FAILED, or INDETERMINATE. INDETERMINATE effects must
        be reconciled and are never safe for automatic retry. A COMMITTED claim
        proves an attempt was finalized, but an effect is confirmed only when
        digest-bound `effect_evidence` with status CONFIRMED is accepted. If the
        signed grant expires after a successful claim, finalization may continue
        only while the exact persisted claim token, nonce, correlation, and
        database claim lease remain valid. An expired unclaimed grant is never
        execution-eligible. A finalize request at or after the database-clock
        lease boundary fails closed and atomically records the claim as
        INDETERMINATE.

        A verifying provider's signed effect receipt (Verifying Provider
        Profile, VP-3) may accompany the finalization as `effect_receipt`. It
        is verified against the organisation's registered provider keys and
        recorded in the commit evidence as presented, verified or not; it is
        never a reason to refuse the finalization. When the grant named the
        effect it expected and the verified receipt carries an effect digest,
        the receipt is also read as `SIGNED_RECEIPT` effect evidence, and
        confirms the effect only when the digests agree and the outcome is
        COMMITTED. An explicit `effect_evidence` takes precedence.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionFinalizeRequest"
      responses:
        "200":
          description: Claim finalized and commit evidence recorded or queued for recovery
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionFinalizeResponse"
        "400":
          description: Invalid finalization or effect-evidence shape
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          description: Invalid, replayed, non-claimed, or lease-expired authorization. An expired claim reports outcome INDETERMINATE and CLAIM_LEASE_EXPIRED. A corrupt claim missing its claimed scope is also forced INDETERMINATE and reports CLAIM_SCOPE_INVARIANT_VIOLATION.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionFinalizeResponse"
  /v1/execution/provider-keys:
    post:
      operationId: registerExecutionProviderKey
      tags:
        - Provider keys
      summary: Register a public key for effect receipts, presence attestations, edge usage reports or signed signals
      description: |
        Registers only the public half of the Ed25519 key a system of record
        signs effect receipts with, or a presence provider signs presence
        attestations with, under the issuer it names in `iss`. `purpose`
        (default `effect_receipt`) says which: a key only ever verifies its
        own purpose, so an effect-receipt key never verifies an attestation
        and an attestation key never verifies a receipt. An edge
        installation registers its usage-report key with purpose
        `usage_report` and its installation id as `issuer`. A producer of
        signed signals (a card-presence provider's Tap to Authenticate, say)
        registers its key with purpose `signed_signal` and the producer id
        the signals name as `iss` as `issuer`; an admitted presence
        provider's JWKS keys sign its signals without registration.
        Private key material is rejected. Registering the same `kid` again
        replaces the key (and its purpose) and clears its revocation.
        Requires policy:write or org:* scope.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExecutionProviderKeyRegistrationRequest"
      responses:
        "201":
          description: Public verification key registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionProviderKey"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    get:
      operationId: listExecutionProviderKeys
      tags:
        - Provider keys
      summary: List active and revoked provider keys, with their purpose
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Provider-key inventory, public metadata only
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionProviderKeyListResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
  /v1/execution/provider-keys/{kid}:
    delete:
      operationId: revokeExecutionProviderKey
      tags:
        - Provider keys
      summary: Revoke, but retain, a provider key
      description: A revoked key verifies no further receipts or attestations, and a grant admitted by an attestation under it can no longer be claimed. Its metadata remains, so what was recorded against it stays explicable.
      parameters:
        - name: kid
          in: path
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Key revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExecutionProviderKeyRevocationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/presence-providers:
    get:
      operationId: listPresenceProviders
      tags:
        - Presence providers
      summary: The directory of presence providers a policy may name
      description: Third parties that prove a person was present for an intent, such as a card issuer's partner proving the cardholder tapped their own card (method CARD_TAP). Decionis operates the directory; each entry names the provider's attestation `iss` and the JWKS it publishes its Ed25519 keys at. An organisation trusts a provider only once it admits it (PUT /v1/execution/presence-providers/{provider_id}/admission). Requires policy:read, policy:write or org:* scope.
      responses:
        "200":
          description: Active directory entries
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PresenceProviderDirectory"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
  /v1/execution/presence-providers:
    get:
      operationId: listPresenceProviderAdmissions
      tags:
        - Presence providers
      summary: The presence providers this organisation admitted, revoked ones included
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Admissions with their provider's public metadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PresenceProviderAdmissionList"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
  /v1/execution/presence-providers/{provider_id}/admission:
    put:
      operationId: admitPresenceProvider
      tags:
        - Presence providers
      summary: Admit a presence provider for this organisation
      description: From then on an attestation signed under a key the provider's JWKS publishes verifies for this organisation, when the attestation's `iss` is the provider's. The organisation's own registered keys (POST /v1/execution/provider-keys, purpose presence_attestation) are consulted first and remain the way to pin a key by hand. Admitting again clears a revocation. Requires policy:write or org:* scope.
      parameters:
        - name: provider_id
          in: path
          required: true
          schema:
            type: string
            pattern: ^[a-z][a-z0-9_.:-]{0,63}$
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Admitted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PresenceProviderAdmission"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    delete:
      operationId: revokePresenceProviderAdmission
      tags:
        - Presence providers
      summary: Revoke a presence provider's admission, keeping its record
      description: A revoked admission verifies no further attestations from the provider, and a grant admitted by one of its attestations can no longer be claimed. Requires policy:write or org:* scope.
      parameters:
        - name: provider_id
          in: path
          required: true
          schema:
            type: string
            pattern: ^[a-z][a-z0-9_.:-]{0,63}$
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Revoked
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - service
                  - provider_id
                  - revoked
                properties:
                  service:
                    type: string
                    const: decionis
                  provider_id:
                    type: string
                  revoked:
                    type: boolean
                    not:
                      const: false
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/ucp/checkout/authorize:
    post:
      operationId: authorizeUcpCheckout
      tags:
        - UCP
      summary: Evaluate and bind authority for one UCP checkout completion
      description: |
        Accepts a complete UCP checkout response envelope negotiated at either
        2026-04-08 or 2026-08-25. The seven UCP top-level checkout fields are
        required and extension members remain open. August responses must also
        carry ucp.payment_handlers; line items retain their official required
        fields and quantity floor; checkout totals contain exactly one subtotal
        and one total. Historical April callers retain the original adapter's
        optional payment-handler compatibility. Missing, ambiguous, or
        unsupported material fails before policy evaluation.

        Decionis authorizes; the connected merchant system remains responsible
        for execution. An ALLOW decision is not itself an execution grant. An
        authoritative response may carry an exact-action grant that must be
        claimed immediately before the merchant commits the checkout, then
        finalized as COMMITTED, FAILED, or INDETERMINATE.
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UcpCheckoutAuthorizeRequest"
      responses:
        "200":
          description: UCP-shaped authority result; execution authority remains fail-closed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpCheckoutAuthorizeResponse"
        "400":
          description: Invalid or unsupported UCP checkout envelope or mandate evidence
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/UcpCheckoutAuthorizeResponse"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          description: Policy refused the completion or the credential lacks authority
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ErrorResponse"
                  - $ref: "#/components/schemas/UcpCheckoutAuthorizeResponse"
        "409":
          description: The supplied or retained authority material conflicts with the exact checkout action
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpCheckoutAuthorizeResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: Authority unavailable; no execution is authorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpCheckoutAuthorizeResponse"
  /v1/ucp/signing-keys:
    post:
      operationId: registerUcpMerchantSigningKey
      tags:
        - UCP
      summary: Register a merchant public key for UCP terms verification
      description: |
        Registers only the public half of an EC signing key. Private key
        material is rejected. Requires policy:write or org:* scope.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UcpSigningKeyRegistrationRequest"
      responses:
        "201":
          description: Public verification key registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpSigningKey"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    get:
      operationId: listUcpMerchantSigningKeys
      tags:
        - UCP
      summary: List active and revoked UCP merchant verification keys
      parameters:
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Merchant verification-key inventory
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpSigningKeyListResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
  /v1/ucp/signing-keys/{kid}:
    delete:
      operationId: revokeUcpMerchantSigningKey
      tags:
        - UCP
      summary: Revoke, but retain, a UCP merchant verification key
      description: Revoked key metadata remains available for historical evidence verification.
      parameters:
        - name: kid
          in: path
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
        - $ref: "#/components/parameters/UcpOrgId"
      responses:
        "200":
          description: Key revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UcpSigningKeyRevocationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/decisions/evaluate:
    post:
      operationId: evaluateDecisionSdkAlias
      tags:
        - Decisions
      summary: Evaluate captured execution intent through the SDK compatibility route
      deprecated: true
      description: Backwards-compatible alias for SDKs before the canonical protocol route.
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DecisionRequest"
      responses:
        "200":
          description: Policy decision
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
        "500":
          $ref: "#/components/responses/Error"
  /v1/dossiers/{decision_id}:
    get:
      operationId: createDossier
      tags:
        - Dossiers and verification
      summary: Persist or retrieve the Decision Dossier for a decision
      parameters:
        - name: decision_id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Decision Dossier
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionDossier"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/decision-chains/{chain_id}:
    get:
      operationId: getDecisionChain
      tags:
        - Dossiers and verification
      summary: Retrieve workflow lineage for linked Decionis decisions
      description: |
        Returns the protocol-owned Decision Chain for a workflow. Decision
        Chains link evaluated execution intents into a causal graph without
        exposing policy rules or application-side guardrail logic.
      parameters:
        - name: chain_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Decision Chain
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionChain"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/decision-chains/by-evaluation/{evaluation_id}:
    get:
      operationId: getDecisionChainByEvaluation
      tags:
        - Dossiers and verification
      summary: Retrieve authenticated workflow lineage by evaluation
      description: |
        Resolves the tenant-bound Decision Chain containing the specified
        evaluation. The credential organization must match `org_id`.
      parameters:
        - name: evaluation_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Decision Chain
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionChain"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/dossiers/{dossier_id}/proof-packet:
    get:
      operationId: getDossierProofPacket
      tags:
        - Dossiers and verification
      summary: Export a single Decision Dossier as a portable, signed proof packet
      description: |
        Returns an escalation-ready proof packet for one dossier: the dossier
        payload, policy snapshot, ledger anchor, the Ed25519 proof bundle, and a
        cryptographic verification result with verify instructions. Suitable for
        refund/overcharge dispute escalation and audit.
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Signed proof packet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionDossierProofPacket"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/dossiers/{dossier_id}/agent-action-capsule:
    get:
      operationId: exportAgentActionCapsuleV04
      tags:
        - Dossiers and verification
      summary: Export a Decision Dossier execution lifecycle as an Agent Action Capsule
      description: |
        Returns an org-scoped Agent Action Capsule pinned to
        draft-mih-scitt-agent-action-capsule-04. The Capsule is a compatibility
        projection; the Decision Dossier remains the canonical Decionis record.
        Planned, dispatched, and confirmed effects are never inferred from an
        authorization verdict alone. This release is self-attested and does not
        claim SCITT transparency anchoring.
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Draft-04 Agent Action Capsule that passed Class 1 verification
          headers:
            x-decionis-aac-profile:
              schema:
                type: string
                const: draft-mih-scitt-agent-action-capsule-04
            x-decionis-class1-verified:
              schema:
                type: string
                const: "true"
          content:
            application/agent-action-capsule+json:
              schema:
                $ref: "#/components/schemas/AgentActionCapsuleV04"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/dossiers/{dossier_id}/agent-action-capsule/producer-envelopes:
    get:
      operationId: exportAgentActionCapsuleProducerEnvelopesV04
      tags:
        - Dossiers and verification
      summary: Export independent COSE Producer Envelopes over a Capsule ID
      description: |
        Returns a Decionis JSON carrying structure for zero or more independent
        draft-04 Producer Envelopes. Each envelope is a tagged COSE_Sign1 whose
        attached payload is the raw 32-byte Capsule ID. A valid signature
        authenticates the returned public key; authorization of that key for the
        Capsule operator remains caller policy. Producer Envelopes are separate
        from SCITT registration statements and receipts.
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Independent Producer Envelope results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentActionCapsuleProducerEnvelopeResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/dossiers/{dossier_id}/agent-action-capsule/scitt-registration:
    post:
      operationId: registerAgentActionCapsuleWithScitt
      tags:
        - Dossiers and verification
      summary: Asynchronously submit the current Capsule ID to an allowlisted Transparency Service
      description: |
        Creates an RFC 9943 Signed Statement over the raw Capsule ID and queues
        optional registration outside the authority hot path. The operation is
        idempotent by org, Capsule ID, and Transparency Service. A received but
        unverified receipt is persisted as `RECEIPT_UNVERIFIED` and never
        upgrades the record to anchored.
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Existing verified registration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScittCapsuleRegistrationResponse"
        "202":
          description: Registration queued or awaiting receipt-profile verification
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScittCapsuleRegistrationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    get:
      operationId: getAgentActionCapsuleScittRegistration
      tags:
        - Dossiers and verification
      summary: Read optional SCITT registration and receipt-verification status
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: capsule_id
          in: query
          required: false
          description: Immutable historical Capsule ID; defaults to the current lifecycle projection.
          schema:
            type: string
            pattern: ^[0-9a-f]{64}$
      responses:
        "200":
          description: Registration status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScittCapsuleRegistrationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/dossiers/{dossier_id}:
    get:
      operationId: getDecisionDossier
      tags:
        - Dossiers and verification
      summary: Fetch one tenant-bound Decision Dossier
      description: |
        Returns the persisted Decision Dossier for an authenticated tenant. An
        ENFORCEMENT-mode ESCALATE dossier carries `authority_requirement` only
        when a matched policy rule explicitly defines Presence authority and
        the evaluation supplied a valid canonical `context.action_context`.
      parameters:
        - name: dossier_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Tenant-bound Decision Dossier
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProtocolDecisionDossierResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/decision-chains/{chain_id}/proof-packet:
    get:
      operationId: getDecisionChainProofPacket
      tags:
        - Dossiers and verification
      summary: Retrieve an authenticated Decision Chain verification report
      description: |
        Legacy path retained for compatibility. Returns a bounded, point-in-time
        server verification report covering the linked dossiers and chain
        integrity known to Decionis. The compact response does not embed source
        dossier proof bundles or the canonical ledger hash path and has no
        top-level signature. It is therefore not a portable or offline-verifiable
        proof artifact; independently verify the referenced dossiers and ledger
        evidence obtained from their authorized source.
      parameters:
        - name: chain_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Authenticated point-in-time Decision Chain verification report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionChainProofPacket"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/ops/spend-admission/verify:
    post:
      operationId: opsSpendAdmissionVerify
      tags:
        - Decisions
      summary: Govern a spend request (Gate 1 — spend admission)
      description: |
        Evaluates an expense / vendor-payment / refund / credit request against the
        ops spend-control vertical pack (approval threshold + dual authorization,
        vendor verification, refund/credit limits). Runs the full shared
        evaluate-decision pipeline and returns a signed dossier reference.
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OpsGateRequest"
      responses:
        "200":
          description: Ops gate verdict
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpsGateVerdict"
        "401":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
  /v1/protocol/ops/disbursement-authority/verify:
    post:
      operationId: opsDisbursementAuthorityVerify
      tags:
        - Decisions
      summary: Govern a disbursement (Gate 2 — disbursement authority)
      description: |
        Evaluates a vendor payment at release time: authorized role, segregation of
        duties, dual authorization, and duplicate-payment detection (a vendor +
        invoice/amount fingerprint compared against prior org evaluations in the
        lookback window).
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OpsGateRequest"
      responses:
        "200":
          description: Ops gate verdict
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpsGateVerdict"
        "401":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
  /v1/protocol/surfaces/decisions:
    post:
      operationId: federateSurfaceDecision
      tags:
        - Decisions
      summary: Federate a native-surface decision into the shared audit ledger
      description: |
        Records a decision made by a Layer-A commerce surface (Amazon, eBay,
        Shopify) into the cross-surface SHA-256 audit ledger. When the full signed
        dossier is included it is persisted and becomes retrievable + exportable as
        a proof packet; otherwise only a ledger entry is appended (backward
        compatible).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SurfaceDecisionRequest"
      responses:
        "200":
          description: Federation result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SurfaceDecisionResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
  /ebay/marketplace-account-deletion:
    get:
      operationId: ebayAccountDeletionChallenge
      tags:
        - Commerce
      summary: eBay Marketplace Account Deletion validation challenge
      description: |
        Anonymous endpoint required for an eBay PRODUCTION keyset. eBay sends a
        `challenge_code`; the response is the hex SHA-256 of
        challengeCode + verificationToken + endpointURL. Requires
        EBAY_VERIFICATION_TOKEN and EBAY_DELETION_ENDPOINT_URL to be configured.
        No authentication — eBay sends no credentials.
      security: []
      parameters:
        - name: challenge_code
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Challenge response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EbayChallengeResponse"
        "400":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    post:
      operationId: ebayAccountDeletionNotification
      tags:
        - Commerce
      summary: eBay Marketplace Account Deletion notification
      description: |
        Anonymous endpoint that receives an eBay account-deletion notification and
        acknowledges it. Decionis stores no eBay consumer PII, so there is nothing
        to purge beyond acknowledgement.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MarketplaceDeletionNotification"
      responses:
        "200":
          description: Acknowledged
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
  /v1/policies:
    post:
      operationId: createPolicy
      tags:
        - Policies
      summary: Create a policy, or create it MANAGED from a system scaffold
      description: Account session of a writing workspace member; same-site JSON and an Idempotency-Key are required. With content, the caller authors revision 1 and holds POLICY_OWNER and AUTHOR. With governance MANAGED and no content, the system writes revision 1 as a scaffold with no author, the caller holds POLICY_OWNER and RELEASE_APPROVER (never AUTHOR), the named desk analysts receive their bounded roles, and MANAGED governance takes the scaffold as its baseline, all in one journaled command. Alias kept on the same handler /v1/public/account/workspace/policy-platform.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - type: object
                  required:
                    - environment
                    - content
                  additionalProperties: false
                  properties:
                    environment:
                      type: string
                      enum:
                        - sandbox
                        - production
                    content:
                      type: object
                      description: The revision's content. Of its properties, the contract pins the two a release carries into its signed manifest; the rest are the policy document.
                      additionalProperties: true
                      properties:
                        actionManifest:
                          oneOf:
                            - type: "null"
                            - $ref: "#/components/schemas/ActionManifest"
                        assumptions:
                          type: array
                          maxItems: 30
                          items:
                            $ref: "#/components/schemas/PolicyAssumption"
                - type: object
                  required:
                    - environment
                    - governance
                    - desk
                    - reason
                  additionalProperties: false
                  properties:
                    environment:
                      type: string
                      enum:
                        - sandbox
                        - production
                    governance:
                      type: string
                      enum:
                        - MANAGED
                    desk:
                      type: array
                      minItems: 1
                      maxItems: 12
                      description: Desk analysts' grants; at least one AUTHOR, each expiring within 30 days.
                      items:
                        type: object
                        required:
                          - userId
                          - role
                          - expiresAt
                        additionalProperties: false
                        properties:
                          userId:
                            type: string
                            format: uuid
                          role:
                            type: string
                            enum:
                              - AUTHOR
                              - TECHNICAL_REVIEWER
                              - TEST_APPROVER
                          expiresAt:
                            type: string
                            format: date-time
                    reason:
                      type: string
      responses:
        "201":
          description: The policy, in DRAFT, with its first revision.
          content:
            application/json:
              schema:
                type: object
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/policies/validate:
    post:
      operationId: validatePolicy
      tags:
        - Policies
      summary: Validate an encoded policy document
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        "200":
          description: Policy validation result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyValidationResponse"
  /v1/cases:
    get:
      operationId: listCases
      tags:
        - Cases
      summary: List the decisions waiting for a person
      description: "Core's façade over every case owner (Core protocol escalations, procurement referrals, policy proposals and signed findings; Commerce managed cases). Organization API key with decision:read. Case state stays with its owner; Core keeps only the owner reference and delivery receipts. Business Central asserts its signed-in user with `x-decionis-actor: entra:<tenant id>:<object id>` inside the tenant its connection credential proves; an MCP OAuth token names its own user. Without a person every card is listed with `can_decide` false. `GET /v1/protocol/decisions/awaiting-approval` is a deprecated alias on the same handler and keeps its original query and response."
      security:
        - ApiKeyAuth: []
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum:
              - pending
            default: pending
        - name: view
          in: query
          description: card (decionis.delivery.card/1), business-central (flat page payload) or assistant (MCP structured content).
          schema:
            type: string
            enum:
              - card
              - business-central
              - assistant
            default: card
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 50
        - name: x-decionis-actor
          in: header
          required: false
          schema:
            type: string
            pattern: ^entra:[0-9a-f-]{36}:[0-9a-f-]{36}$
      responses:
        "200":
          description: Pending cases in the requested view; `partial` is true when an owner was unreachable.
          content:
            application/json:
              schema:
                type: object
                required:
                  - cases
                  - partial
                properties:
                  cases:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                  partial:
                    type: boolean
        "403":
          $ref: "#/components/responses/Error"
  /v1/cases/{caseId}:
    parameters:
      - name: caseId
        in: path
        required: true
        description: "`<owner>:<kind>:<ref>`, for example `commerce:payment:<uuid>` or `core:escalation:<uuid>`."
        schema:
          type: string
          maxLength: 200
    get:
      operationId: getCase
      tags:
        - Cases
      summary: Read one case as its decision card
      description: Organization API key with decision:read. The card comes from the case's owner.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: view
          in: query
          schema:
            type: string
            enum:
              - card
              - business-central
              - assistant
            default: card
      responses:
        "200":
          description: The decision card (decionis.delivery.card/1) plus can_decide, in the requested view.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "404":
          $ref: "#/components/responses/Error"
  /v1/cases/{caseId}/decisions:
    parameters:
      - name: caseId
        in: path
        required: true
        schema:
          type: string
          maxLength: 200
    post:
      operationId: decideCase
      tags:
        - Cases
      summary: Decide a case (the one inbound decision path)
      description: Every channel resolves here, through DecisionActionResolver. Teams and Slack callbacks, the Business Central extension and the `decionis.cases.*` MCP tools all reach the same steps. The channel identity must belong to the workspace's tenant, resolve to a current Accounts member and hold the case's authority. When the authority requirement asks, Presence must have approved the person's passkey first (428 with `step_up_url`). The transition happens at the case's owner, with a revision check, and is applied once per case revision whichever inbox it came from. Organization API key with decision:write and a person (Business Central `x-decionis-actor` or an MCP OAuth token), or the named recipient's own Account session with the signed email `link`.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: view
          in: query
          schema:
            type: string
            enum:
              - card
              - business-central
              - assistant
            default: card
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - verb
                - revision
              properties:
                verb:
                  type: string
                  enum:
                    - approve
                    - reject
                    - edit
                    - escalate
                revision:
                  type: integer
                  minimum: 0
                decision_id:
                  type: string
                  format: uuid
                choices:
                  type: array
                  maxItems: 16
                  items:
                    type: string
                note:
                  type: string
                  maxLength: 1000
                link:
                  type: string
                  description: Signed email fallback link, for the email channel only.
      responses:
        "200":
          description: "`applied` is false when the same decision was already applied (from this or another inbox)."
          content:
            application/json:
              schema:
                type: object
                required:
                  - applied
                  - card
                properties:
                  applied:
                    type: boolean
                  card:
                    type: object
                    additionalProperties: true
        "400":
          $ref: "#/components/responses/Error"
        "403":
          description: wrong_tenant, not_a_member, not_authorized, actor_required or link_not_yours.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: stale_revision (with the current card), already_decided, decision_in_progress or step_up_unavailable.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "410":
          description: case_expired.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "428":
          description: step_up_required, with `step_up_url` (the Presence passkey hand-off).
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /v1/assessments/{assessmentId}/findings:
    parameters:
      - name: assessmentId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: submitAssessmentFindings
      tags:
        - Assessments
      summary: Submit assessment findings for Core to validate and sign
      description: Organization API key with decision:write (role MEMBER or higher); the organization comes from the key. Core checks record digests, as-of provenance, assessed and total counts, coverage and partial status, and transaction-time amounts in each record's own currency, recomputes the per-currency totals and signs the artifact (decionis.assessments.findings/1) with the dossier Ed25519 key, verifiable offline against /.well-known/decision-dossier-jwks.json. Without a signing key the artifact is stored and labelled unsigned. A partial assessment stays partial. An identical resubmission returns the artifact signed the first time (200).
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AssessmentFindingsSubmission"
      responses:
        "200":
          description: The artifact already signed for this exact submission.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignedAssessmentFindings"
        "201":
          description: Signed (or explicitly unsigned) findings artifact.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignedAssessmentFindings"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
    get:
      operationId: listAssessmentFindings
      tags:
        - Assessments
      summary: Read the signed findings of an assessment
      description: Organization API key with decision:read. Returns every findings artifact signed for the assessment in this organization, each verifiable offline.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Signed findings artifacts for the assessment.
          content:
            application/json:
              schema:
                type: object
                required:
                  - version
                  - assessment_id
                  - items
                properties:
                  version:
                    type: string
                    const: decionis.assessments.findings/1
                  assessment_id:
                    type: string
                    format: uuid
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/SignedAssessmentFindings"
        "403":
          $ref: "#/components/responses/Error"
  /v1/assessments/{assessmentId}/records:
    parameters:
      - name: assessmentId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: submitAssessmentRecords
      tags:
        - Assessments
      summary: Submit transaction, event or audit records for PolicyAgent to author a policy from
      description: The central policy intake for producers holding an organization key (Commerce, the AgentSafe CLI), with decision:write and role MEMBER or higher; the organization comes from the key. Records arrive inline or as one JSON Lines file (decionis.assessments.records/1). Core's assessor for the domain finds the exposures with the production evaluator (commerce today; cards and agents are refused until their assessors exist), reports missing history as a coverage gap, and signs the findings (decionis.assessments.findings/1) like any submitted findings. New findings reach the managed desk, who propose the policy. Identical records return the findings signed the first time (200).
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AssessmentRecords"
      responses:
        "200":
          description: The findings already signed for these exact records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentRecordsResult"
        "201":
          description: Signed findings from the records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentRecordsResult"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "413":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/outcomes/agreements:
    post:
      operationId: createOutcomeAgreement
      tags:
        - Outcomes
      summary: Draft an outcome agreement
      description: "Organization API key with decision:write and role ADMIN or higher; the organization comes from the key. Drafts the agreed outcome meter (decionis.outcomes.agreement/1): workflow, primary metric, scope, baseline, currency and conversion, deductions, who confirms a problem, exclusions, attribution window, monthly close and commercial basis. The agreement becomes ACTIVE only after Decionis signs it with the dossier key and a customer signatory co-signs with a passkey in the delivered case. 503 outcomes_disabled while `DECIONIS_OUTCOMES_ENABLED` is not 1."
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OutcomeAgreementCreate"
      responses:
        "201":
          description: The DRAFT agreement.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OutcomeAgreementRecord"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/agreements/{agreementId}:
    parameters:
      - name: agreementId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getOutcomeAgreement
      tags:
        - Outcomes
      summary: Read an outcome agreement
      description: Organization API key with decision:read and role VIEWER or higher. Returns the agreement, its state and both signatures; an agreement of another organization is not found.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: The agreement.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OutcomeAgreementRecord"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/statements:
    get:
      operationId: listOutcomeStatements
      tags:
        - Outcomes
      summary: List signed outcome statements
      description: Organization API key with decision:read and role VIEWER or higher. Every statement of the key's organization, optionally for one month, each verifiable offline with `decionis-verify outcomes`.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: period
          in: query
          required: false
          schema:
            type: string
            pattern: ^\d{4}-(0[1-9]|1[0-2])$
      responses:
        "200":
          description: The statements.
          content:
            application/json:
              schema:
                type: object
                required:
                  - statements
                properties:
                  statements:
                    type: array
                    items:
                      $ref: "#/components/schemas/SignedOutcomeStatement"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/statements/{statementId}:
    parameters:
      - name: statementId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getOutcomeStatement
      tags:
        - Outcomes
      summary: Read one signed outcome statement
      description: Organization API key with decision:read and role VIEWER or higher.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: The statement.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignedOutcomeStatement"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/statements/{statementId}/charge:
    parameters:
      - name: statementId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getOutcomeStatementCharge
      tags:
        - Outcomes
      summary: Read the outcome fee charged for a statement
      description: Organization API key with decision:read and role VIEWER or higher. The signed monthly fee (decionis.outcomes.charge/1) Decionis computed from this statement and the agreement's commercial terms (a share of the net benefit or a fee on governed value, raised to the floor and limited by the cap), with the marketplace receipt once it was billed. 404 when the agreement charges nothing, the agreement is a sandbox, or the statement is unsigned.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: The charge and its receipt (null until billed).
          content:
            application/json:
              schema:
                type: object
                required:
                  - charge
                  - receipt
                properties:
                  charge:
                    $ref: "#/components/schemas/SignedOutcomeCharge"
                  receipt:
                    oneOf:
                      - $ref: "#/components/schemas/OutcomeChargeReceipt"
                      - type: "null"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/reports/drift:
    get:
      operationId: listOutcomeDriftReports
      tags:
        - Outcomes
      summary: List signed monthly drift reports
      description: "Organization API key with decision:read and role VIEWER or higher. Every drift report of the key's organization (decionis.outcomes.drift/1), optionally for one month: policy releases and activations with their approvals and governance profile, SHADOW and PARALLEL verdicts that disagreed with what was enforced (counts by decision type and verdict, never money), and writes that passed without a binding decision. Every number comes from records; a source Core does not hold is listed as not_reported, never as zero. Closed monthly with the statements, signed with the dossier key or labelled unsigned, and verifiable offline with `decionis-verify outcomes`. 503 outcomes_disabled while the meter is off."
      security:
        - ApiKeyAuth: []
      parameters:
        - name: period
          in: query
          required: false
          schema:
            type: string
            pattern: ^\d{4}-(0[1-9]|1[0-2])$
      responses:
        "200":
          description: The drift reports.
          content:
            application/json:
              schema:
                type: object
                required:
                  - reports
                properties:
                  reports:
                    type: array
                    items:
                      $ref: "#/components/schemas/SignedOutcomeDriftReport"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/reports/drift/{reportId}:
    parameters:
      - name: reportId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getOutcomeDriftReport
      tags:
        - Outcomes
      summary: Read one signed monthly drift report
      description: Organization API key with decision:read and role VIEWER or higher.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: The drift report.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignedOutcomeDriftReport"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/outcomes/disputes:
    post:
      operationId: openOutcomeDispute
      tags:
        - Outcomes
      summary: Dispute an outcome subject
      description: Organization API key with decision:write and role ADMIN or higher. While the dispute is open, or once it is upheld, the subject counts as disputed in every statement and in no charge. A dispute opened after a month closed reaches the next statement as a correction. One open dispute per subject (409 outcome_dispute_open); a subject the meter has never seen is 404.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - subject_digest
                - reason
              additionalProperties: false
              properties:
                subject_digest:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                reason:
                  type: string
                  minLength: 1
                  maxLength: 500
      responses:
        "201":
          description: The open dispute.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OutcomeDispute"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
    get:
      operationId: listOutcomeDisputes
      tags:
        - Outcomes
      summary: List outcome disputes
      description: Organization API key with decision:read and role VIEWER or higher.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: state
          in: query
          required: false
          schema:
            type: string
            enum:
              - open
              - resolved
              - all
            default: all
      responses:
        "200":
          description: The disputes, newest first.
          content:
            application/json:
              schema:
                type: object
                required:
                  - disputes
                properties:
                  disputes:
                    type: array
                    items:
                      $ref: "#/components/schemas/OutcomeDispute"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/decisions/{decisionId}/explanation:
    parameters:
      - name: decisionId
        in: path
        required: true
        description: A protocol decision evaluation id in the key's organization.
        schema:
          type: string
          format: uuid
    get:
      operationId: getDecisionExplanation
      tags:
        - Decisions
      summary: Explain a held decision in customer-safe words
      description: Organization API key with decision:read and role VIEWER or higher; the organization comes from the key. For a HOLD, BLOCK or ESCALATE decision, returns wording a support agent can pass on (no codes, check ids or figures) and an internal part with reason codes, check ids and the dossier id. An approved decision is 409 decision_not_held.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: The explanation.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DecisionExplanation"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/commerce/payments/history:
    get:
      operationId: readCommercePaymentHistory
      tags:
        - Commerce
      summary: Read posted Business Central payment history for an assessment
      description: Default off with the native Business Central reader. Ordinary workspace key with decision:read and decision:write and current native READ authority. Reads the fixed read-only pages for posted vendor payments, vendor invoices and their applications, and the Change Log's vendor bank-account entries, for a window of at most 92 days. Identifiers are company-scoped SHA-256 digests; bank numbers and business identifiers never leave Core. When the Change Log is off or does not log vendor bank accounts, bank_changes.available is false and coverage is incomplete; no change history is inferred. Nothing is written.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connection_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: revision
          in: query
          required: true
          description: The connection revision the caller expects.
          schema:
            type: integer
            minimum: 1
        - name: from
          in: query
          required: true
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: true
          description: Exclusive.
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Posted history and its coverage.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePaymentHistory"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/commerce/sales/history:
    get:
      operationId: readCommerceSalesHistory
      tags:
        - Commerce
      summary: Read Business Central sales history for reconciliation
      description: Default off with the native Business Central reader. Ordinary workspace key with decision:read and decision:write and current native READ authority. Reads the extension's fixed read-only sales pages (1.0.2.4) for open sales orders by Order Date and posted sales invoices by Posting Date, for a window of at most 92 days. Identifiers are company-scoped SHA-256 digests; document numbers, order numbers and External Document No. never leave Core. The External Document No. is digested exactly as Business Central stores it. Amounts exclude tax, in integer minor units of the document currency. A read capped at 4,000 orders or 8,000 invoices sets coverage.truncated with a reason. When the connected extension does not publish a page (older than 1.0.2.4), that list is empty and coverage is incomplete with SALES_ORDER_PAGE_NOT_INSTALLED or SALES_INVOICE_PAGE_NOT_INSTALLED; no sale is inferred. A negative document is left out with NEGATIVE_SALES_DOCUMENTS_EXCLUDED. Nothing is written.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connection_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: revision
          in: query
          required: true
          description: The connection revision the caller expects.
          schema:
            type: integer
            minimum: 1
        - name: from
          in: query
          required: true
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: true
          description: Exclusive.
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Sales documents as digests and their coverage.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceSalesHistory"
        "400":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/drupal/connect/start:
    post:
      operationId: startDrupalConnect
      tags:
        - Commerce
      summary: Start connecting a Drupal Commerce site
      description: |
        The first call of Decionis for Drupal's connect, made by the module with
        no credential. It registers the site's Ed25519 public key and answers a
        one-time challenge for the site to serve, signed, at
        `/.well-known/decionis-challenge` (see `connect/verify`).

        A public HTTPS site on the default port is proven by that challenge. A
        site Decionis cannot reach (a private or local host, plain HTTP or a
        port) is accepted too, and can be proven only by the 6-digit code
        `connect/verify` emails to `billing_email`. A public host over plain
        HTTP or on a port is refused. Nothing is ever fetched from a private
        address.

        Not idempotent: each call starts a new connect with a new challenge,
        valid for `expires_in_seconds`; an unfinished connect expires. Requests
        are limited per address and per site, and a refused one answers 429
        with Retry-After.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalConnectStartRequest"
      responses:
        "201":
          description: The connect and its one-time challenge.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalConnectStarted"
        "400":
          description: INVALID_REQUEST, BAD_REQUEST (malformed JSON) or INPUT_TOO_COMPLEX; or DRUPAL_SITE_URL_INVALID with a fixed `message` saying why the address was refused.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/connect/verify:
    post:
      operationId: verifyDrupalConnect
      tags:
        - Commerce
      summary: Prove a Drupal site by its challenge, or have a code emailed
      description: |
        Signed with the site key: `signature` is the Ed25519 signature, in
        base64url, over the key-sorted canonical JSON of the body without
        `signature`.

        For a reachable site, Decionis fetches
        `https://<site>/.well-known/decionis-challenge` over HTTPS with no
        redirects, a five-second budget and a 16 KB cap. The site answers a JSON
        object with `protocol` (`decionis-drupal-connect/1`), `purpose`
        (`challenge`), `connect_id`, `site_url`, `challenge`, and `signature`:
        the site key's signature over the rest, signed the same way. A match
        claims the challenge, once, and connects the site (200). A site that
        answers without a valid proof is refused (403 DRUPAL_CHALLENGE_FAILED)
        and is not offered a code.

        For a site Decionis cannot reach, or that gives no answer at all, a
        6-digit code is emailed to the billing address instead (202); finish
        with `connect/code`. Until a code sender is configured, that answers 503
        DRUPAL_EMAIL_CODE_UNAVAILABLE.

        Connecting binds the site to one Decionis organization for good,
        creating it the first time, and answers that organization's
        least-privilege key (role MEMBER, scopes decision:read and
        decision:write) exactly once: only its hash is kept. Proving a connected
        site again issues a new key and revokes the one it had. The site starts
        in Shadow.

        The challenge is single-use. A second verify of a used challenge
        answers 409 DRUPAL_CHALLENGE_ALREADY_USED, and a connect that has
        connected, failed or sent a code answers 409 DRUPAL_CONNECT_NOT_PENDING:
        start a new one. When Decionis refuses to bind the site, the answer
        carries that status with UPSTREAM_UNAVAILABLE.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalConnectVerifyRequest"
      responses:
        "200":
          description: Connected. `api_key` is shown here once and never again.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalConnected"
        "202":
          description: The site could not be reached; a 6-digit code was emailed to the billing address.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalConnectCodeSent"
        "400":
          description: INVALID_REQUEST, BAD_REQUEST (malformed JSON), INPUT_TOO_COMPLEX, or UPSTREAM_UNAVAILABLE when Decionis refused the request to bind the site.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: DRUPAL_SIGNATURE_INVALID.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: DRUPAL_CHALLENGE_FAILED, or UPSTREAM_UNAVAILABLE when Decionis refused to bind the site.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: DRUPAL_CONNECT_NOT_FOUND, for an unknown or expired connect.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: DRUPAL_CONNECT_NOT_PENDING, DRUPAL_CHALLENGE_ALREADY_USED, DRUPAL_WORKSPACE_CONFLICT (the site is connected to another organization), or UPSTREAM_UNAVAILABLE when the binding conflicts.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/connect/code:
    post:
      operationId: confirmDrupalConnectCode
      tags:
        - Commerce
      summary: Finish connecting a Drupal site with the emailed code
      description: |
        Signed with the site key, like `connect/verify`. The code lives at most
        300 seconds and allows three attempts: a wrong code answers 400
        DRUPAL_CODE_INVALID, and once three have failed, 410
        DRUPAL_CODE_EXHAUSTED. A correct code is claimed once and connects the
        site, with the same answer and the same binding as `connect/verify`.

        An emailed code proves the billing inbox, not the site: it may connect
        a new site, never take over a connected one (409
        DRUPAL_SITE_ALREADY_CONNECTED). It answers 503
        DRUPAL_EMAIL_CODE_UNAVAILABLE while codes cannot be checked.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalConnectCodeRequest"
      responses:
        "200":
          description: Connected. `api_key` is shown here once and never again.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalConnected"
        "400":
          description: DRUPAL_CODE_INVALID, INVALID_REQUEST, BAD_REQUEST (malformed JSON), INPUT_TOO_COMPLEX, or UPSTREAM_UNAVAILABLE when Decionis refused the request to bind the site.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: DRUPAL_SIGNATURE_INVALID.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: UPSTREAM_UNAVAILABLE when Decionis refused to bind the site.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: DRUPAL_CONNECT_NOT_FOUND, for an unknown or expired connect.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: DRUPAL_SITE_ALREADY_CONNECTED, DRUPAL_WORKSPACE_CONFLICT, or UPSTREAM_UNAVAILABLE when the binding conflicts.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "410":
          description: DRUPAL_CODE_EXHAUSTED. Start a new connect.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/status:
    post:
      operationId: readDrupalSiteStatus
      tags:
        - Commerce
      summary: Read a connected Drupal site's mode
      description: |
        Authenticated with the key the site received when it connected. Every
        site's enforcement entitlement is read through its immutable native
        binding from Accounts when native authority is enabled. With the default
        disabled authority mode, Core still verifies the exact active native
        binding and returns entitlement: null without calling Accounts. A missing
        entitlement grants no enforcement.
        An unknown organization and a wrong key get the same 401. Read-only; safe to
        repeat. Reading status never starts or extends the workspace trial.
      security:
        - DrupalSiteKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalSiteRequest"
      responses:
        "200":
          description: The site's organization, address and mode.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalSiteStatus"
        "400":
          description: INVALID_REQUEST, BAD_REQUEST (malformed JSON) or INPUT_TOO_COMPLEX.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: DRUPAL_AUTH_FAILED.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/disconnect:
    post:
      operationId: disconnectDrupalSite
      tags:
        - Commerce
      summary: Disconnect a Drupal site and revoke its key
      description: |
        Authenticated with the key the site received when it connected.
        Revokes that key in Decionis, for the Drupal provider only, then marks
        the site disconnected. If the key cannot be revoked, the answer is an
        error and the site stays connected, so a retry is safe. Once
        disconnected the key no longer authenticates, and repeating the call
        answers 401. The organization stays: connecting the site again binds it
        to the same one.
      security:
        - DrupalSiteKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalSiteRequest"
      responses:
        "200":
          description: Disconnected; the site's key is revoked.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalSiteDisconnected"
        "400":
          description: INVALID_REQUEST, BAD_REQUEST (malformed JSON) or INPUT_TOO_COMPLEX.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: DRUPAL_AUTH_FAILED.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/entitlement/trial:
    post:
      operationId: startDrupalEnforcementTrial
      tags:
        - Commerce
      summary: Start the workspace's single enforcement trial
      description: |
        Requires the connected site's key and a stable Idempotency-Key. Accounts
        atomically starts a 14-day trial only from trial_available. Repeated and
        concurrent starts return current authority; reconnects and key rotations
        never restart the trial. Paid, grace and expired workspaces retain their
        state. Entitlement state and dates are never supplied by the site.
      security:
        - DrupalSiteKey: []
      parameters:
        - $ref: "#/components/parameters/DrupalMutationKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalSiteRequest"
      responses:
        "200":
          description: Current Accounts-owned workspace entitlement
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalEntitlementResponse"
        "400":
          description: Invalid input or missing idempotency key
        "401":
          description: DRUPAL_AUTH_FAILED
        "403":
          description: The native key is revoked, expired or bound to another workspace
        "409":
          description: Immutable binding or idempotency conflict
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/drupal/policy/limits:
    post:
      operationId: publishDrupalPolicyLimits
      tags:
        - Commerce
      summary: Publish the bounded Drupal policy settings
      description: |
        Requires the connected site's key and a stable Idempotency-Key. Protocol
        compiles the four supported settings into currency-guarded PolicyBundle
        rules, serializes publication per organization and records an immutable
        audit receipt. No supplied YAML, rule text or arbitrary bundle is accepted.
        expected_policy_version is the last acknowledged version; null or omission
        applies only to the untouched Drupal bootstrap. Existing foreign policies
        are never overwritten. A decision-only site key may tighten the current
        limits or remove a configured currency; loosening protection or adding a
        currency requires the owner's policy workflow and answers 403
        DRUPAL_POLICY_OWNER_CONFIRMATION_REQUIRED. Unknown currencies and missing
        cost/refund evidence require review. limits_digest is SHA-256 of the
        recursively key-sorted limits_by_currency JSON, using finite ECMAScript
        number encoding with no whitespace, prefixed sha256:. Signed dossier
        policy_reference identifies the resulting immutable bundle and version.
        An identical command returns its receipt only while that bundle remains
        the latest active policy. If another publisher has superseded it, retry
        returns 409 DRUPAL_POLICY_VERSION_CONFLICT; the original audit bytes remain.
      security:
        - DrupalSiteKey: []
      parameters:
        - $ref: "#/components/parameters/DrupalMutationKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrupalPolicyLimitsRequest"
      responses:
        "200":
          description: Verified published policy receipt; exact retries return the same receipt
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DrupalPolicyReceipt"
        "400":
          description: Invalid limits, unexpected fields or missing idempotency key
        "401":
          description: DRUPAL_AUTH_FAILED
        "403":
          description: DRUPAL_NATIVE_BINDING_INVALID or DRUPAL_POLICY_OWNER_CONFIRMATION_REQUIRED
        "409":
          description: DRUPAL_POLICY_VERSION_CONFLICT or DRUPAL_POLICY_IDEMPOTENCY_CONFLICT
        "413":
          $ref: "#/components/responses/DrupalConnectTooLarge"
        "429":
          $ref: "#/components/responses/DrupalConnectRateLimited"
        "503":
          $ref: "#/components/responses/DrupalConnectUnavailable"
  /v1/policies/{policyId}/records:
    parameters:
      - name: policyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: uploadPolicyRecords
      tags:
        - Policies
      summary: Upload transaction, event or audit records to a policy
      description: The owner's door into the central policy intake. Account session of the policy's POLICY_OWNER or SOURCE_CUSTODIAN; same-site JSON and an Idempotency-Key are required. The records are assessed and signed exactly as on /v1/assessments/{assessmentId}/records, and the upload is recorded on the policy's access chain. The findings stay with this policy, and its authors (the desk on a MANAGED policy) receive the findings case. Uploading changes no revision, so the uploader never becomes an author. A policy_id in the body must name this policy.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AssessmentRecords"
      responses:
        "200":
          description: The findings already signed for these exact records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentRecordsResult"
        "201":
          description: Signed findings from the records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentRecordsResult"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/policies/{policyId}/proposals:
    parameters:
      - name: policyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: listPolicyProposals
      tags:
        - Policies
      summary: List a policy's proposals
      security:
        - AccountSessionCookie: []
      responses:
        "200":
          description: Proposal run metadata, newest first.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
    post:
      operationId: createPolicyProposal
      tags:
        - Policies
      summary: Propose a policy from signed findings or governed documents
      description: Account session of a policy AUTHOR or POLICY_OWNER; same-site JSON and an Idempotency-Key are required. With findingsIds, a deterministic parameter proposer sets commerce-preflight-v2 parameters (P01, P09, P12, P13, P14, P15, P16) from the findings' distributions; every parameter cites the findings behind it and the same findings always produce the same parameters. An approved model, when named, writes only the rationale. With sourceIds, the existing document drafting runs. Alias kept on the same handler /v1/public/account/workspace/policy-platform/{policyId}/proposals.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/PolicyFindingsDraftRequest"
                - $ref: "#/components/schemas/PolicyDocumentDraftRequest"
      responses:
        "202":
          description: The proposal run. A findings proposal is READY or HELD immediately.
          content:
            application/json:
              schema:
                type: object
                required:
                  - policy
                  - run
                properties:
                  policy:
                    type: object
                  run:
                    type: object
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/policies/{policyId}/proposals/{proposalId}:
    parameters:
      - name: policyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: proposalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      operationId: getPolicyProposal
      tags:
        - Policies
      summary: Read a proposal, its candidate revision, findings and cited evidence
      security:
        - AccountSessionCookie: []
      responses:
        "200":
          description: Run metadata and result.
          content:
            application/json:
              schema:
                type: object
                required:
                  - run
                  - result
                properties:
                  run:
                    type: object
                  result:
                    type:
                      - object
                      - "null"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/policies/{policyId}/proposals/{proposalId}/decisions:
    parameters:
      - name: policyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: proposalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: decidePolicyProposal
      tags:
        - Policies
      summary: Accept, split or reject a proposal
      description: Account session of a policy AUTHOR or POLICY_OWNER; same-site JSON and an Idempotency-Key are required. ACCEPT saves the candidate as a new DRAFT revision; for a findings proposal SPLIT accepts only the named checks (ruleIds such as ["P14"]) and returns the others to their previous values. The existing review, assurance and shadow gates carry the revision to APPROVED_FOR_SHADOW; nothing here reaches production. Alias kept on the same handler /v1/public/account/workspace/policy-platform/{policyId}/proposals/{proposalId}/decisions.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyProposalDecision"
      responses:
        "200":
          description: The policy document after the decision.
          content:
            application/json:
              schema:
                type: object
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/policies/{policyId}/proposals/{proposalId}/replays:
    parameters:
      - name: policyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: proposalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      operationId: replayPolicyProposal
      tags:
        - Policies
      summary: Replay current against proposed on the assessed records
      description: Account session with READ access; same-site JSON and an Idempotency-Key are required. Both configurations are evaluated by the production commerce-preflight evaluator on identical records at their transaction time, scoped to the checks the proposal changes. Money is totalled by finding category in each transaction currency without conversion, false holds (held records with no exposure finding) are counted, and caps and coverage are explicit. Nothing is stored, sent or executed.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        "200":
          description: The replay.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyProposalReplay"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/public/account/workspace/policy-platform/{policyId}/proposals:
    post:
      operationId: createPolicyProposalAlias
      tags:
        - Policies
      summary: Deprecated alias of POST /v1/policies/{policyId}/proposals
      deprecated: true
      security:
        - AccountSessionCookie: []
      parameters:
        - name: policyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/PolicyFindingsDraftRequest"
                - $ref: "#/components/schemas/PolicyDocumentDraftRequest"
      responses:
        "202":
          description: Same handler and response as the canonical path.
  /v1/public/account/workspace/policy-platform/{policyId}/proposals/{proposalId}/decisions:
    post:
      operationId: decidePolicyProposalAlias
      tags:
        - Policies
      summary: Deprecated alias of POST /v1/policies/{policyId}/proposals/{proposalId}/decisions
      deprecated: true
      security:
        - AccountSessionCookie: []
      parameters:
        - name: policyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: proposalId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyProposalDecision"
      responses:
        "200":
          description: Same handler and response as the canonical path.
  /v1/public/account/workspace/policy-platform/invariants:
    get:
      operationId: listPolicyInvariants
      tags:
        - Policies
      summary: List the organisation's policy invariants, live and retired
      description: Account session of any workspace member. Every declaration the organisation's owner made for the environment, newest first, each with its digest and, once retired, its retirement.
      security:
        - AccountSessionCookie: []
      parameters:
        - name: environment
          in: query
          required: false
          schema:
            type: string
            enum:
              - sandbox
              - production
            default: sandbox
      responses:
        "200":
          description: The declarations.
          content:
            application/json:
              schema:
                type: object
                required:
                  - invariants
                additionalProperties: false
                properties:
                  invariants:
                    type: array
                    maxItems: 500
                    items:
                      $ref: "#/components/schemas/PolicyInvariantEntry"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
    post:
      operationId: declarePolicyInvariant
      tags:
        - Policies
      summary: Declare an organisation invariant every policy release in its scope must refuse
      description: Account session of the organisation's owner only (`POLICY_INVARIANT_OWNER_REQUIRED`); same-site JSON and an Idempotency-Key are required. The invariant compiles to one scenario per combination of its varied values, each a copy of `input` with `decision_type` set to the invariant's. From the next assurance run on, every candidate of every policy whose runtime scope names the invariant's decision domain and type (or that declares no scope) must REJECT each compiled scenario, or the run fails with `INVARIANT_VIOLATED`; no dataset disposition, review or approval clears it. One live declaration per invariant id (`409 POLICY_INVARIANT_ALREADY_DECLARED`); the live set compiles to at most 500 scenarios per environment (`422 POLICY_INVARIANT_LIMIT`).
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - environment
                - invariant
                - reason
              additionalProperties: false
              properties:
                environment:
                  type: string
                  enum:
                    - sandbox
                    - production
                invariant:
                  $ref: "#/components/schemas/PolicyInvariant"
                reason:
                  type: string
                  minLength: 1
                  maxLength: 4000
      responses:
        "201":
          description: The declaration, as evidence.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyInvariantEntry"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /v1/public/account/workspace/policy-platform/invariants/{invariantId}/retirements:
    post:
      operationId: retirePolicyInvariant
      tags:
        - Policies
      summary: Retire an organisation invariant, naming the exact declaration it ends
      description: Account session of the organisation's owner only; same-site JSON and an Idempotency-Key are required. `invariantDigest` must be the live declaration's digest (`409 POLICY_INVARIANT_DIGEST_MISMATCH`); a declaration is retired once (`409 POLICY_INVARIANT_ALREADY_RETIRED`). The declaration itself never changes; the retirement is recorded beside it, and the next assurance run no longer reads it.
      security:
        - AccountSessionCookie: []
      parameters:
        - name: invariantId
          in: path
          required: true
          description: The declaration's id (`record.id`), not the invariant's name.
          schema:
            type: string
            format: uuid
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - environment
                - invariantDigest
                - reason
              additionalProperties: false
              properties:
                environment:
                  type: string
                  enum:
                    - sandbox
                    - production
                invariantDigest:
                  type: string
                  pattern: ^sha256:[a-f0-9]{64}$
                reason:
                  type: string
                  minLength: 1
                  maxLength: 4000
      responses:
        "200":
          description: The declaration with its retirement.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyInvariantEntry"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
  /v1/protocol/policies/bundles:
    post:
      operationId: encodePolicyBundle
      tags:
        - Policies
      summary: Submit a versioned policy bundle artifact for Decionis encoding
      description: |
        Use this endpoint only when an integration participates in policy
        authoring. The SDK submits a reviewed policy bundle artifact to
        Decionis; it does not evaluate or enforce policy rules locally.
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyBundle"
      responses:
        "202":
          description: Policy bundle accepted for encoding
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ArtifactAcceptedResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
  /v1/protocol/signals/envelopes:
    post:
      operationId: ingestProtocolSignalEnvelope
      tags:
        - Decisions
      summary: Ingest a versioned Protocol signal envelope
      description: |
        Persists an evidence-bearing signal for deterministic policy evaluation
        and material-signal revalidation. Semantic classifier metadata is input
        evidence only and cannot mint an authority verdict or execution grant.
      parameters:
        - $ref: "#/components/parameters/CorrelationId"
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProtocolSignalEnvelope"
      responses:
        "202":
          description: Signal envelope accepted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ArtifactAcceptedResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
  /v1/orgs/{org_id}/policies/strategies/draft:
    post:
      operationId: draftPolicyStrategy
      tags:
        - Policies
      summary: Draft a reviewable policy strategy from unstructured sources
      description: |
        Turns scattered policy material — pasted text and uploaded files
        (PDF, XLSX, XML, HTML, JSON, plain text such as transaction or audit
        logs) plus optional live policy-source connectors (Jira, Confluence,
        Notion, Google Drive, Git repository, SAP) — into a strategy-shaped
        Decionis draft with clauses bucketed for automatic execution,
        escalation, and blocking. The draft is not persisted: review it, then
        encode the accepted version. Drafting is LLM-assisted when a provider
        is configured and falls back to deterministic extraction otherwise;
        `used_llm` reports which path ran. Requires an org API key with the
        ADMIN role and the `autonomous:manage` or `org:*` scope.
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - $ref: "#/components/parameters/CorrelationId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyDraftRequest"
      responses:
        "200":
          description: Non-persistent policy strategy draft
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyStrategyDraftResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
  /v1/orgs/{org_id}/policies/packs/draft:
    post:
      operationId: draftPolicyPack
      tags:
        - Policies
      summary: Draft an executable policy pack from unstructured sources
      description: |
        Same inputs as the strategy draft, but the output is the executable
        Decionis policy pack — `{ name, all|any: [{field, op, value}], action }`
        rules. Every synthesized rule is validated through the rules compiler
        before it is returned; anything that cannot become an executable
        predicate is returned under `review`, never as a broken rule. The
        draft is persisted for the org (`pack_id`) so it can be reviewed,
        edited, and finalized. Requires an org API key with the ADMIN role
        and the `autonomous:manage` or `org:*` scope.
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - $ref: "#/components/parameters/CorrelationId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyDraftRequest"
      responses:
        "200":
          description: Persisted executable policy pack draft
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyPackDraftResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
  /v1/protocol/shadow/evaluate-decision/reports:
    get:
      operationId: listShadowEvaluateDecisionReports
      tags:
        - Decisions
      summary: List shadow-mode decision evaluation reports
      description: |
        Returns protocol-owned shadow reports derived from saved
        evaluate-decision records. Reports summarize what Decionis would
        continue, stop, hand off, or review without exposing policy rules.
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - SHADOW
              - PARALLEL
              - ENFORCEMENT
            default: SHADOW
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 50
        - name: since
          in: query
          required: false
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: Shadow report list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShadowEvaluateDecisionReportsResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
  /v1/protocol/shadow/evaluate-decision/reports/summary:
    get:
      operationId: summarizeShadowEvaluateDecisionReports
      tags:
        - Decisions
      summary: Summarize shadow-mode decision evaluation reports
      description: |
        Returns aggregate protocol-owned shadow report metrics for saved
        evaluate-decision records.
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - SHADOW
              - PARALLEL
              - ENFORCEMENT
            default: SHADOW
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 50
        - name: since
          in: query
          required: false
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: Shadow report summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShadowEvaluateDecisionReportsSummaryResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
  /v1/analytics/events:
    post:
      operationId: recordAnalyticsEvent
      tags:
        - Analytics
      summary: Ingest a public experiment analytics event
      description: |
        Public sink for proof-led A/B exposure and conversion events. Events are
        idempotent on visitor_id, experiment, event, and occurred_at.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsEventRequest"
      responses:
        "202":
          description: Analytics event accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - accepted
                  - event_id
                  - idempotent_replay
                  - experiment
                  - variant
                  - report
                properties:
                  accepted:
                    type: boolean
                  event_id:
                    type: string
                    format: uuid
                  idempotent_replay:
                    type: boolean
                  experiment:
                    type: string
                  variant:
                    type: string
                    enum:
                      - A
                      - B
                  report:
                    $ref: "#/components/schemas/AnalyticsExperimentReport"
        "400":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/compliance/evidence-pack:
    post:
      operationId: createComplianceEvidencePack
      tags:
        - Dossiers and verification
      summary: Generate and persist a signed compliance evidence pack
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ComplianceEvidencePackRequest"
      responses:
        "201":
          description: Signed evidence pack
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ComplianceEvidencePackResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/verify/evidence/{pack_id}:
    get:
      operationId: verifyComplianceEvidencePack
      tags:
        - Dossiers and verification
      summary: Publicly verify a signed compliance evidence pack
      security: []
      parameters:
        - name: pack_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Evidence pack verification result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EvidencePackVerificationResponse"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/public/agents/provision:
    post:
      operationId: provisionAnonymousAgentWorkspace
      tags:
        - Onboarding and auth
      summary: Mint a provisional anonymous workspace and API key
      security: []
      description: |
        Zero-human onboarding entry point. Mints a provisional workspace, its
        org API key, and a seeded shadow-mode default policy — no account, no
        email. Hard caps: 10 requests per minute, 5 provisional workspaces per
        network per 24 hours, and an exploration allowance of 50 governed
        decisions per month. The raw key is returned exactly once. Every
        dossier a provisional workspace mints carries a SIGNED issuer_context
        tier of "provisional_anonymous" inside the dossier claims, so a
        verifier can always distinguish it from an owned org's dossier.
        Claiming (POST /v1/orgs/{org_id}/claim/start then /claim/verify)
        attaches a human owner; the key and the dossier ledger survive the
        claim.
        The workspace is stamped with what the caller's User-Agent says about
        where it came from and nothing else: the product and version, and
        for the open-source runtime's `agent-safe-pipeline/<version>
        (repo=<owner/name>; example=<name>; surface=github)` form and
        Govern's `govern/<version> (example=govern@<version>;
        surface=<runner>; repo=<owner/name>)` form, the repository, example
        and surface. The stamp is accounting for the acquisition funnel; it
        is never decision input and never verified.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgentProvisionRequest"
      responses:
        "201":
          description: Provisional workspace minted; the raw key appears only here
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentProvisionResponse"
        "400":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/public/decision-dossiers/{dossier_id}/verify:
    get:
      operationId: verifyPublicDecisionDossier
      tags:
        - Dossiers and verification
      summary: Verify a Decision Dossier — no account required
      security: []
      description: |
        Runs the real Ed25519 verification against the published public JWKS —
        the same check anyone can reproduce offline with @decionis/verify —
        and returns a share-safe, masked projection of the dossier. The ?sig
        capability comes from a dossier's verification envelope and only gates
        access (it keeps dossier ids from being enumerated); the signatures
        prove authenticity. Every capability failure collapses to the same
        404 — no oracle about which check failed.
      parameters:
        - $ref: "#/components/parameters/PublicDossierId"
        - $ref: "#/components/parameters/ShareLinkSignature"
        - $ref: "#/components/parameters/ShareLinkExpiry"
      responses:
        "200":
          description: Verification result with a masked public dossier projection
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicDossierVerificationResponse"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/public/decision-dossiers/{dossier_id}/proof-bundle:
    get:
      operationId: getPublicDecisionDossierProofBundle
      tags:
        - Dossiers and verification
      summary: Fetch the signed documents and Ed25519 proof bundle
      security: []
      description: |
        Returns only what independent verification needs: the signed documents
        at their JSON-pointer paths, the Ed25519 proof bundle, and the public
        JWKS URL. Same ?sig share-link capability as /verify. Verify offline
        with `npx @decionis/verify "<this URL>"`. Exit 0 means the presented
        proof artifacts are cryptographically valid; it does not by itself
        establish current execution eligibility.
      parameters:
        - $ref: "#/components/parameters/PublicDossierId"
        - $ref: "#/components/parameters/ShareLinkSignature"
        - $ref: "#/components/parameters/ShareLinkExpiry"
      responses:
        "200":
          description: Signed documents plus the proof bundle and JWKS pointer
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicDossierProofBundleResponse"
        "404":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/public/decision-dossiers/{dossier_id}/reproduce:
    get:
      operationId: reproducePublicDecisionDossier
      tags:
        - Dossiers and verification
      summary: Deterministically re-run the recorded decision
      security: []
      description: |
        Re-runs the recorded inputs through the recorded policy bundle in the
        protocol engine — side-effect-free, nothing persisted — and reports
        whether the same verdict comes out. Same ?sig capability as /verify;
        because replay actually runs the policy engine, results are cached for
        about 60 seconds and capped at 20 requests per minute per dossier.
      parameters:
        - $ref: "#/components/parameters/PublicDossierId"
        - $ref: "#/components/parameters/ShareLinkSignature"
        - $ref: "#/components/parameters/ShareLinkExpiry"
      responses:
        "200":
          description: Reproduction outcome for the recorded decision
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicDossierReproduceResponse"
        "404":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
        "502":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/orgs/{org_id}/claim/start:
    post:
      operationId: startOrgClaim
      tags:
        - Onboarding and auth
      summary: Start claiming a provisional workspace (email OTP)
      description: |
        First half of attaching a human owner to an anonymously minted
        workspace. Org-key authed — holding the workspace's key is the
        possession proof that decides who may attach an owner. The org must be
        provisional and unclaimed. Emails a six-digit OTP with a 5-minute
        expiry to owner_email; 10 requests per minute.
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrgClaimStartRequest"
      responses:
        "202":
          description: OTP challenge created and emailed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrgClaimStartResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "404":
          description: Not a provisional workspace (it already has an owner path)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: The workspace is already claimed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "502":
          $ref: "#/components/responses/Error"
        "503":
          $ref: "#/components/responses/Error"
  /v1/orgs/{org_id}/claim/verify:
    post:
      operationId: verifyOrgClaim
      tags:
        - Onboarding and auth
      summary: Finish claiming a provisional workspace
      description: |
        Second half of the claim: org-key authed, with a timing-safe check of
        the emailed OTP (3 attempts per challenge). Attaches an existing
        account by email or creates one — a new account requires a password so
        the claimed identity can sign back in. The claim is atomic; the API
        key and every dossier minted before the claim survive. 10 requests per
        minute.
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrgClaimVerifyRequest"
      responses:
        "200":
          description: Workspace claimed; a signed account session cookie is set
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrgClaimVerifyResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          description: OTP invalid, expired, or attempt cap reached
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: Already claimed, or the OTP was already used
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "503":
          $ref: "#/components/responses/Error"
  /v1/orgs/{org_id}/verification-links/rotate:
    post:
      operationId: rotateOrgVerificationLinks
      tags:
        - Dossiers and verification
      summary: Revoke every outstanding v2 dossier share link for the org
      description: |
        v2 dossier share links are signed with a per-org derived secret;
        bumping the org's secret version invalidates every v2 link the org has
        ever minted — one org, one bump, nothing global. Freshly minted links
        use the new version. Revoking every outstanding share link is an admin
        act: requires an org API key with the ADMIN role. 5 requests per
        minute.
      parameters:
        - name: org_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Secret version bumped; all previously issued v2 links are dead
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrgVerificationLinkRotationResponse"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/public/account/workspace/deployments:
    get:
      operationId: readHostedGatewayDeployment
      tags:
        - Hosted gateway
      summary: Read one of the workspace's hosted gateways and the list of all of them
      description: Account session scoped to the current workspace; reads require membership. The organization comes only from the session. Without deployment_id the answer is the workspace's primary gateway; with it, that gateway, or 404 GATEWAY_NOT_FOUND when the workspace holds no gateway with that id (never the primary). `deployments` lists every gateway the workspace holds and `deployment_limit` the capacity an operator granted it (default 1). Reservation is a name allocation, never evidence of DNS, TLS or runtime readiness.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      responses:
        "200":
          description: Private overview; credentials appear only as prefixes and status.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "400":
          description: INVALID_REQUEST when deployment_id is not a UUID.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "404":
          description: GATEWAY_NOT_FOUND.
    post:
      operationId: reserveHostedGatewayDeployment
      tags:
        - Hosted gateway
      summary: Reserve the workspace's first gateway domain, or an additional one
      description: Signed account session, current workspace ADMIN or OWNER; same-site JSON is mandatory. A body with an optional company_name reserves the workspace's primary gateway, or returns it when one exists. A body with additional:true and tenant_label reserves a further gateway at exactly <tenant_label>.decionisedge.com, needs a verified email, and fits within the capacity an operator granted the workspace; repeating it returns the same gateway. The answer is the reserved gateway's overview. Reservation grants no access to a fleet tenant already serving that label.
      security:
        - AccountSessionCookie: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayDeploymentReservation"
      responses:
        "201":
          description: The reserved gateway's overview.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "400":
          description: INVALID_REQUEST, or GATEWAY_LABEL_INVALID for a malformed or reserved label.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED for an additional gateway.
        "409":
          description: GATEWAY_DEPLOYMENT_LIMIT_REACHED at the workspace's granted capacity, GATEWAY_PRIMARY_REQUIRED before the workspace has its first gateway, or GATEWAY_DOMAIN_UNAVAILABLE when another workspace holds the label.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/activate:
    post:
      operationId: activateHostedGatewayDeployment
      tags:
        - Hosted gateway
      summary: Approve the upstream origin of one of the workspace's gateways and start its setup
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary. Records the consent and queues provisioning; ownership proof, keys and readiness follow in the background. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayDeploymentActivation"
      responses:
        "202":
          description: The gateway's overview, with provisioning queued.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "400":
          description: INVALID_REQUEST or an origin the hosted gateway cannot front.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_RESERVED without a gateway, or GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: The gateway is being provisioned, or its credential needs reconnection.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/mode:
    post:
      operationId: setHostedGatewayMode
      tags:
        - Hosted gateway
      summary: Turn enforcement on or off for one of the workspace's gateways
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary; every gateway has its own mode, upstream credential and named policy. The upstream credential is sealed at once and never logged, echoed or returned. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayModeRequest"
      responses:
        "200":
          description: Nothing to change; the gateway's overview.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "202":
          description: The change is queued; the gateway's overview.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "400":
          description: INVALID_REQUEST, UPSTREAM_CREDENTIAL_HEADER_INVALID or UPSTREAM_CREDENTIAL_INVALID.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, VERIFIED_EMAIL_REQUIRED, HOSTED_GATEWAY_ADMIN_REQUIRED or HOSTED_GATEWAY_ENFORCEMENT_UNAVAILABLE.
        "404":
          description: GATEWAY_NOT_RESERVED without a gateway, or GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_NOT_READY, UPSTREAM_CREDENTIAL_REQUIRED or a provisioning lease in progress.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/credentials/reveal:
    post:
      operationId: revealHostedGatewayTenantKey
      tags:
        - Hosted gateway
      summary: Reveal one gateway's ingress (tenant) key, once
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary. Returns that gateway's AgentSafe-Tenant-Key exactly once, after the fleet verified it; each gateway has its own key. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpEmpty"
      responses:
        "200":
          description: The tenant key; store it at once in a secret manager.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayTenantKey"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_NOT_READY, GATEWAY_CREDENTIAL_INACTIVE or GATEWAY_KEY_ALREADY_REVEALED.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/gateway-token/reveal:
    post:
      operationId: revealHostedGatewayToken
      tags:
        - Hosted gateway
      summary: Reveal one gateway's gateway token, once
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary. Returns the token that gateway sends the tenant's API in AgentSafe-Gateway-Token on every forwarded request, exactly once, after the fleet verified the gateway. Decionis mints it with the tenant key and keeps it sealed for the fleet; a token that was not saved is replaced by regenerating it. sent says whether every pod sends it now. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpEmpty"
      responses:
        "200":
          description: The gateway token; store it at once where the tenant's API reads it.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayToken"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_NOT_READY, GATEWAY_TOKEN_NOT_ISSUED or GATEWAY_TOKEN_ALREADY_REVEALED.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/gateway-token/regenerate:
    post:
      operationId: regenerateHostedGatewayToken
      tags:
        - Hosted gateway
      summary: Make a new gateway token for one gateway, shown once and kept pending
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary, once it has been ready. Returns a new 256-bit token exactly once and keeps it pending, sealed; the gateway goes on sending the token in use until the token is activated, so the tenant's API can accept both first. Regenerating again replaces a pending token not yet activated. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpEmpty"
      responses:
        "201":
          description: The pending gateway token; store it at once where the tenant's API reads it.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayPendingToken"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_NOT_READY.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/gateway-token/activate:
    post:
      operationId: activateHostedGatewayToken
      tags:
        - Hosted gateway
      summary: Switch one gateway to its pending gateway token
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Acts on the gateway deployment_id names, else the primary. api_accepts_token is the administrator's statement that the tenant's API accepts the pending token. The pending token becomes the one in use and a provisioning job delivers it to every pod of the gateway; until the fleet confirms it, gateway_token.sent in the overview is false and pods may still send the previous token. With no token pending, a token in use that the fleet has not confirmed is delivered again. An explicit id the workspace does not hold is 404 GATEWAY_NOT_FOUND.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTokenActivation"
      responses:
        "202":
          description: The switch is queued; the body is the gateway's overview.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeploymentOverview"
        "400":
          description: INVALID_REQUEST without api_accepts_token true.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_NOT_READY, GATEWAY_CONFIGURATION_LOCKED or GATEWAY_TOKEN_NOT_PENDING.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/resources:
    get:
      operationId: listHostedGatewayResources
      tags:
        - Hosted gateway
      summary: Read one gateway's resource inventory and secret-free TCP status
      description: Account session scoped to the current workspace. Reads require workspace membership. Each gateway keeps its own inventory; deployment_id names one, else the primary, and an id the workspace does not hold is 404 GATEWAY_NOT_FOUND. Saving inventory alone does not activate routing. HTTPS connected status requires a verified deployed upstream; TCP connected status requires a fresh authenticated connector lease. TCP metadata is omitted and tcp_enabled is false when the default-off feature is disabled. HTTP and WebSocket forwarding remain unsupported.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      responses:
        "200":
          description: Private bounded result.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayResources"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: Current workspace membership required.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "500":
          description: Resource inventory or database unavailable.
    post:
      operationId: addHostedGatewayResource
      tags:
        - Hosted gateway
      summary: Save a resource to one gateway's inventory
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. Saves to the gateway deployment_id names, else the primary; an id the workspace does not hold is 404 GATEWAY_NOT_FOUND. Saving never activates routing; a repeat returns the saved resource. At most 50 resources per gateway.
      security:
        - AccountSessionCookie: []
      parameters:
        - $ref: "#/components/parameters/HostedGatewayDeploymentSelector"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayResourceInput"
      responses:
        "200":
          description: Already saved; the gateway's inventory.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayResourceAdded"
        "201":
          description: Saved; the gateway's inventory.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayResourceAdded"
        "400":
          description: INVALID_GATEWAY_RESOURCE or INVALID_REQUEST.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, ADMIN or OWNER required, or VERIFIED_EMAIL_REQUIRED.
        "404":
          description: GATEWAY_NOT_FOUND for an id the workspace does not hold.
        "409":
          description: GATEWAY_DEPLOYMENT_REQUIRED before any gateway is reserved, or GATEWAY_RESOURCE_LIMIT_REACHED.
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED.
  /v1/public/account/workspace/deployments/resources/{id}/tcp/activate:
    post:
      operationId: activateHostedGatewayTcp
      tags:
        - Hosted gateway
      summary: "Default off: authorize an opaque TCP connector route"
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. The organization comes only from the session. Requests are closed and limited to 4096 bytes. TCP forwarding is opaque and does not evaluate SQL or API commands. Default off. Explicit accept_terms:true authorizes a saved tcp_ip resource with a numeric IPv4/IPv6 address and explicit port. Current paid active entitlement is required. Queue an identifier-only worker job; the worker probes only the derived tenant gateway capability endpoint. No HTTPS origin is required and the shared fleet never dials the saved target. Idempotent while the current route is ready or provisioning.
      security:
        - AccountSessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          description: Saved resource UUID in the current workspace; also the TCP route UUID.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpActivate"
      responses:
        "202":
          description: Private bounded result.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayResources"
        "400":
          description: TCP_RESOURCE_REQUIRED, TCP_PORT_REQUIRED or ordinary validation refusal.
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: TCP_AUTHORIZATION_REFUSED, HOSTED_GATEWAY_ADMIN_REQUIRED, HOSTED_GATEWAY_PAID_PLAN_REQUIRED or HOSTED_GATEWAY_ENTITLEMENT_INACTIVE. Current authorizing administrator membership and paid active entitlement are rechecked; no fallback authorization. SAME_SITE_REQUEST_REQUIRED or VERIFIED_EMAIL_REQUIRED also refuses the request.
        "404":
          description: TCP_RESOURCE_NOT_FOUND in this workspace.
        "415":
          $ref: "#/components/responses/HostedGatewayTcpJsonRequired"
        "429":
          $ref: "#/components/responses/HostedGatewayTcpRateLimited"
        "503":
          $ref: "#/components/responses/HostedGatewayTcpUnavailable"
  /v1/public/account/workspace/deployments/resources/{id}/tcp/disable:
    post:
      operationId: disableHostedGatewayTcp
      tags:
        - Hosted gateway
      summary: Revoke a TCP route and both role credentials
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. The organization comes only from the session. Requests are closed and limited to 4096 bytes. TCP forwarding is opaque and does not evaluate SQL or API commands. Works while the TCP feature is disabled. Increments generation, clears both role credentials, and removes tickets and live leases. Existing broker legs close by their last valid 30-second lease expiry. Other resources and HTTPS routing are unchanged.
      security:
        - AccountSessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          description: Saved resource UUID in the current workspace; also the TCP route UUID.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpEmpty"
      responses:
        "200":
          description: Private bounded result.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayResources"
        "400":
          $ref: "#/components/responses/HostedGatewayTcpInvalidRequest"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, VERIFIED_EMAIL_REQUIRED or insufficient workspace role.
        "404":
          description: TCP_ROUTE_NOT_FOUND in this workspace.
        "415":
          $ref: "#/components/responses/HostedGatewayTcpJsonRequired"
        "429":
          $ref: "#/components/responses/HostedGatewayTcpRateLimited"
        "503":
          $ref: "#/components/responses/HostedGatewayTcpUnavailable"
  /v1/public/account/workspace/deployments/resources/{id}/tcp/credentials/reveal:
    post:
      operationId: revealHostedGatewayTcpCredentials
      tags:
        - Hosted gateway
      summary: Reveal both TCP credentials once for the expected generation
      description: Signed account session, current workspace ADMIN or OWNER and verified email; same-site JSON is mandatory. The organization comes only from the session. Requests are closed and limited to 4096 bytes. TCP forwarding is opaque and does not evaluate SQL or API commands. Default off. Requires the route to be ready and its current authorizing administrator to retain paid active entitlement. The generation from the latest resource read is compared under the route lock before disclosure is consumed. Stale requests never consume replacement credentials. Do not cache, log or automatically retry a credential disclosure.
      security:
        - AccountSessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          description: Saved resource UUID in the current workspace; also the TCP route UUID.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpReveal"
      responses:
        "200":
          description: Private bounded result.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayTcpCredentials"
        "400":
          $ref: "#/components/responses/HostedGatewayTcpInvalidRequest"
        "401":
          $ref: "#/components/responses/HostedGatewayTcpSessionRequired"
        "403":
          description: TCP_AUTHORIZATION_REFUSED, HOSTED_GATEWAY_ADMIN_REQUIRED, HOSTED_GATEWAY_PAID_PLAN_REQUIRED or HOSTED_GATEWAY_ENTITLEMENT_INACTIVE. Current authorizing administrator membership and paid active entitlement are rechecked; no fallback authorization. SAME_SITE_REQUEST_REQUIRED or VERIFIED_EMAIL_REQUIRED also refuses the request.
        "404":
          description: TCP_ROUTE_NOT_FOUND in this workspace.
        "409":
          description: TCP_GENERATION_CHANGED (no credentials consumed), TCP_NOT_READY, or TCP_CREDENTIALS_ALREADY_REVEALED. Refresh the route before any new request.
        "415":
          $ref: "#/components/responses/HostedGatewayTcpJsonRequired"
        "429":
          $ref: "#/components/responses/HostedGatewayTcpRateLimited"
        "503":
          $ref: "#/components/responses/HostedGatewayTcpUnavailable"
  /v1/public/gateway/tcp/tickets:
    post:
      operationId: issueHostedGatewayTcpTicket
      tags:
        - Hosted gateway
      summary: "Default off: exchange a role credential for a one-use TCP ticket"
      description: Default off. Native connectors and local tunnels supply the matching role credential in Authorization, never an organization API key. Rechecks ready route, current generation, role and the authorizing administrator's current paid active entitlement. A ticket expires in 60 seconds and is redeemed atomically once by the broker. At most 32 outstanding tickets per route, 120 requests/minute and 4096-byte JSON bodies. Compare route_id, tenant_host, gateway_url and the canonical resource/hash against local configuration before CONNECT. The service never receives TCP payloads or chooses a connector target.
      security:
        - HostedGatewayTcpRouteCredential: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayTcpTicketRequest"
      responses:
        "200":
          description: Private bounded result.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayTcpTicketResponse"
        "400":
          $ref: "#/components/responses/HostedGatewayTcpInvalidRequest"
        "401":
          description: "TCP_CREDENTIAL_REQUIRED: a 43-character opaque route bearer is required."
        "403":
          $ref: "#/components/responses/HostedGatewayTcpAuthorizationRefused"
        "415":
          $ref: "#/components/responses/HostedGatewayTcpJsonRequired"
        "429":
          description: TCP_TICKET_LIMIT or request rate limit reached.
        "503":
          $ref: "#/components/responses/HostedGatewayTcpUnavailable"
  /v1/hosted-gateway/authorizations/lookup:
    post:
      operationId: lookupHostedGatewayAuthorization
      tags:
        - Hosted gateway
      summary: Read a hosted gateway sign-on request by its user code (signed-in customer)
      security:
        - AccountSessionCookie: []
      description: |
        What the approval page shows: the tenant and its host, the upstream
        origin, the operator who asked, when it expires, exactly what the
        gateway records (`disclosure`), and the signed-in user's workspaces
        with whether each can take the key by the rules the database answers
        (ADMIN or above, a paid plan, API access); Accounts' entitlement is
        asked at approval. The owner email is shown in full only to that
        owner, and workspaces are listed only for them. Never returns the
        device code.

        A POST so the user code is never in a URL (and so never in a request
        log line), from the page itself: `Sec-Fetch-Site: same-origin` (or,
        without it, the web application's own `Origin`) and a JSON body,
        as approve requires.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayLookupRequest"
      responses:
        "200":
          description: The request as the customer sees it
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayLookup"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED or VERIFIED_EMAIL_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          $ref: "#/components/responses/Error"
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          $ref: "#/components/responses/Error"
  /v1/hosted-gateway/authorizations/approve:
    post:
      operationId: approveHostedGatewayAuthorization
      tags:
        - Hosted gateway
      summary: Approve a hosted gateway sign-on into one of the customer's workspaces
      security:
        - AccountSessionCookie: []
      description: |
        From the page itself: the request must carry `Sec-Fetch-Site:
        same-origin` (`same-site` is refused: the session cookie reaches every
        subdomain) or, without it, an `Origin` that is the web application's
        own (the web proxy forwards the browser's headers), and a JSON body
        (415 JSON_CONTENT_TYPE_REQUIRED otherwise, so no form can send it).
        The session must come from a sign-in that proved its email (an email
        code, a password, Accounts, or an OAuth provider that asserted the
        address verified; otherwise 403 VERIFIED_EMAIL_REQUIRED, sign in
        again), that email must equal the request's owner email
        (case-insensitive), and the user must be ADMIN or above in `org_id`, a
        workspace on a paid plan (`org_entitlements.plan_code`; a Stripe
        subscription in `trialing` counts as its plan) whose entitlement
        Accounts holds active, all read at approval. On success the session
        is bound to `org_id` (a new account-session cookie is set when it was
        bound elsewhere), so the console's key list and billing show the
        workspace that now holds the gateway's key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayApproveRequest"
      responses:
        "200":
          description: Approved; the operator's next poll receives the key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayApproval"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "402":
          description: HOSTED_GATEWAY_PAID_PLAN_REQUIRED, with `plan_code` and `pricing_url`
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayPaidPlanRequired"
        "403":
          description: SAME_SITE_REQUEST_REQUIRED, VERIFIED_EMAIL_REQUIRED, HOSTED_GATEWAY_OWNER_MISMATCH, HOSTED_GATEWAY_ADMIN_REQUIRED or HOSTED_GATEWAY_ENTITLEMENT_INACTIVE (no API access, or Accounts does not hold the plan active; every gateway evaluation would be refused)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: HOSTED_GATEWAY_AUTHORIZATION_NOT_PENDING, with its `status`
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "410":
          description: HOSTED_GATEWAY_AUTHORIZATION_EXPIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "415":
          description: JSON_CONTENT_TYPE_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          $ref: "#/components/responses/Error"
        "503":
          description: ACCOUNT_AUTHORITY_UNAVAILABLE or HOSTED_GATEWAY_RATE_LIMIT_UNAVAILABLE
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/hosted-gateway/authorizations/deny:
    post:
      operationId: denyHostedGatewayAuthorization
      tags:
        - Hosted gateway
      summary: Deny a hosted gateway sign-on request (signed-in owner)
      security:
        - AccountSessionCookie: []
      description: From the page itself (same-origin, JSON body, as approve), by the owner the request names, signed in by a sign-in that proved the email; the operator's next poll answers `access_denied`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HostedGatewayDenyRequest"
      responses:
        "200":
          description: Denied
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                  - authorization_id
                  - tenant_label
                properties:
                  status:
                    type: string
                    const: denied
                  authorization_id:
                    type: string
                    format: uuid
                  tenant_label:
                    type: string
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          $ref: "#/components/responses/Error"
        "410":
          $ref: "#/components/responses/Error"
        "415":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
  /v1/hosted-gateway/keys/{key_id}/revoke:
    post:
      operationId: disconnectHostedGatewayKey
      tags:
        - Hosted gateway
      summary: Disconnect a hosted gateway by revoking its key (workspace admin)
      security:
        - AccountSessionCookie: []
      description: From the page itself (same-origin, a JSON body such as `{}`, as approve). An ADMIN or above of the session's workspace revokes a key that a hosted gateway sign-on issued there (it appears in the workspace key list as `agentsafe-hosted-<tenant_label>` with scopes `["decision:shadow"]`), including one that lapsed undelivered; the gateway records nothing more. Any other key answers 404.
      parameters:
        - name: key_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        "200":
          description: Revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayKeyRevocation"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "415":
          $ref: "#/components/responses/Error"
        "429":
          $ref: "#/components/responses/Error"
  /v1/hosted-gateway/keys/confirm:
    post:
      operationId: confirmHostedGatewayKeyDelivery
      tags:
        - Hosted gateway
      summary: Confirm a just-issued hosted gateway key was received (the key itself)
      description: "Called with the key the token endpoint returned, as Bearer, before `confirm_by`. The key then no longer expires, and in the same transaction the tenant's earlier keys it replaces are revoked (`revoked_key_ids`). Idempotent: a second call revokes nothing more. A key no sign-on issued answers 404 HOSTED_GATEWAY_KEY_NOT_FOUND. A key that is revoked (superseded, disconnected, revoked by itself) or past `confirm_by` is refused by the org-key authentication before this route runs: 401 UNAUTHORIZED (\"Invalid API key\"). The 409s HOSTED_GATEWAY_KEY_RETIRED and HOSTED_GATEWAY_KEY_INACTIVE answer only a race with a concurrent retirement."
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        "200":
          description: Delivery confirmed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayDeliveryConfirmation"
        "401":
          description: "UNAUTHORIZED: the key is revoked, superseded, or past `confirm_by` (or none was presented)"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "409":
          description: HOSTED_GATEWAY_KEY_RETIRED or HOSTED_GATEWAY_KEY_INACTIVE, only in a race with a concurrent retirement (otherwise such a key gets 401)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /v1/hosted-gateway/keys/revoke-self:
    post:
      operationId: revokeOwnApiKey
      tags:
        - Onboarding and auth
      summary: Revoke the calling organization key (offboarding, rotation, failed onboarding)
      description: Any database-backed organization key may revoke itself; a hosted gateway key also stops being its tenant's current key. Protocol and AWS service credentials and platform keys are refused (403). A key already revoked or expired gets 401 UNAUTHORIZED from the org-key authentication.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        "200":
          description: Revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HostedGatewayKeyRevocation"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /v1/protocol/policies/commerce/readiness:
    get:
      operationId: getCommercePreflightReadiness
      tags:
        - Commerce
      summary: Inspect the selected Commerce Gate policy configuration
      description: Source candidate requiring the matching backend. Requires VIEWER access and policy:read, policy:* or org:* scope for the requested organization. Unknown or duplicate query fields are rejected. Reports configuration only; HTTP 200 does not approve an action, activate policy or prove connector or release readiness. Responses are private and must not be cached.
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: policy_version
          in: query
          required: false
          description: Trimmed, nonempty policy version. When omitted, select the newest active bundle.
          schema:
            type: string
            minLength: 1
            maxLength: 100
      responses:
        "200":
          description: Configuration report, including missing, unsupported or unavailable states
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePreflightReadiness"
        "400":
          description: Invalid or duplicate query fields
        "401":
          description: Authentication required
        "403":
          description: Organization, role or policy-read scope denied
        "502":
          description: Policy service unavailable or returned an invalid or mismatched report
  /v1/protocol/commerce/data/sources:
    get:
      operationId: listCommerceErpSources
      tags:
        - Commerce
      summary: List authorized Business Central connections
      description: Default off; requires COMMERCE_MCP_OAUTH_DATA_ACCESS_ENABLED and COMMERCE_MCP_BUSINESS_CENTRAL_ENABLED, a live Accounts Microsoft purchase, current membership and signed v2 or v3 consent. An opaque connection identifies a separately verified company within the purchaser tenant extracted by Accounts. Reads are bounded to eight seconds and 100 documents, return no connector credentials, and cannot execute an ERP action. Connected v3 source discovery reports BC history unavailable; its historical tools cover only Walmart and Adobe. Requires erp:read.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceErpSources"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/protocol/commerce/data/business-central/{connectionId}/orders:
    get:
      operationId: readCommerceErpOrders
      tags:
        - Commerce
      summary: Read bounded current Business Central orders
      description: Default off; requires COMMERCE_MCP_OAUTH_DATA_ACCESS_ENABLED and COMMERCE_MCP_BUSINESS_CENTRAL_ENABLED, a live Accounts Microsoft purchase, current membership and signed v2 or v3 consent. An opaque connection identifies a separately verified company within the purchaser tenant extracted by Accounts. Reads are bounded to eight seconds and 100 documents, return no connector credentials, and cannot execute an ERP action. Connected v3 source discovery reports BC history unavailable; its historical tools cover only Walmart and Adobe. Requires erp:read.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceErpOrders"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/protocol/commerce/history/assessments:
    post:
      operationId: startCommerceHistoryAssessment
      tags:
        - Commerce
      summary: Assess the previous ninety complete dates
      description: Default off; requires COMMERCE_MCP_OAUTH_DATA_ACCESS_ENABLED and COMMERCE_MCP_BUSINESS_CENTRAL_ENABLED, a live Accounts Microsoft purchase, current membership and signed v2 or v3 consent. An opaque connection identifies a separately verified company within the purchaser tenant extracted by Accounts. Reads are bounded to eight seconds and 100 documents, return no connector credentials, and cannot execute an ERP action. Connected v3 source discovery reports BC history unavailable; its historical tools cover only Walmart and Adobe. This preserved BC historical flow admits only v2 erp:read and history:assess consent; v3 grants are refused. COMMERCE_HISTORY_ENABLED and an explicit history_assessment_limit_monthly in the verified publisher/offer/plan mapping are required; a missing limit disables assessments. Compares available historical merchandise margin against the exact selected policy floor over the previous ninety complete UTC dates. Missing costs or provenance are not_assessed; this is not full policy replay, execution authority, or a ninety-day trial. Results disclose partial coverage and are unsigned. One durable allowance reservation per new idempotent report; an exact completed retry returns the original report without another charge. An uncertain attempt is retained and cannot silently rerun.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
            pattern: ^[A-Za-z0-9._:-]+$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceHistoryStart"
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceHistoryAssessment"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "402":
          description: Monthly history assessment allowance exhausted
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/protocol/commerce/history/assessments/{assessmentId}:
    get:
      operationId: getCommerceHistoryAssessment
      tags:
        - Commerce
      summary: Read an immutable historical assessment
      description: Default off; requires COMMERCE_MCP_OAUTH_DATA_ACCESS_ENABLED and COMMERCE_MCP_BUSINESS_CENTRAL_ENABLED, a live Accounts Microsoft purchase, current membership and signed v2 or v3 consent. An opaque connection identifies a separately verified company within the purchaser tenant extracted by Accounts. Reads are bounded to eight seconds and 100 documents, return no connector credentials, and cannot execute an ERP action. Connected v3 source discovery reports BC history unavailable; its historical tools cover only Walmart and Adobe. This preserved BC historical flow admits only v2 erp:read and history:assess consent; v3 grants are refused. COMMERCE_HISTORY_ENABLED and an explicit history_assessment_limit_monthly in the verified publisher/offer/plan mapping are required; a missing limit disables assessments. Compares available historical merchandise margin against the exact selected policy floor over the previous ninety complete UTC dates. Missing costs or provenance are not_assessed; this is not full policy replay, execution authority, or a ninety-day trial. Results disclose partial coverage and are unsigned. Requires the same immutable Accounts user, workspace, membership and source entitlement; current authority and company connection are checked. Reading a saved report consumes no allowance.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: assessmentId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceHistoryAssessment"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/microsoft/business-central/connections:
    get:
      operationId: listCommerceBusinessCentralConnections
      tags:
        - Business Central connections
      summary: List administrable Business Central connections
      description: Default off and outside the MCP OAuth profile. Requires a separate OWNER or ADMIN organization API key with org:integrations:write, org:* or * scope. Accounts must have supplied a fresh signed v2 or v3 purchaser tenant; the customer cannot enter or rebind tenant authority. Administrators authorize an environment/company and dedicated read-only BC application separately. Credentials are encrypted with an explicitly configured integration custody key and never returned. Verification performs bounded reads only; no ERP write is available.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceConnectionsResponse"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
    post:
      operationId: createCommerceBusinessCentralConnection
      tags:
        - Business Central connections
      summary: Register a company connection for verification
      description: Default off and outside the MCP OAuth profile. Requires a separate OWNER or ADMIN organization API key with org:integrations:write, org:* or * scope. Accounts must have supplied a fresh signed v2 or v3 purchaser tenant; the customer cannot enter or rebind tenant authority. Administrators authorize an environment/company and dedicated read-only BC application separately. Credentials are encrypted with an explicitly configured integration custody key and never returned. Verification performs bounded reads only; no ERP write is available.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceConnectionCreate"
      responses:
        "201":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceConnectionResponse"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/microsoft/business-central/connections/{connectionId}/verify:
    post:
      operationId: verifyCommerceBusinessCentralConnection
      tags:
        - Business Central connections
      summary: Verify read access to the company
      description: Default off and outside the MCP OAuth profile. Requires a separate OWNER or ADMIN organization API key with org:integrations:write, org:* or * scope. Accounts must have supplied a fresh signed v2 or v3 purchaser tenant; the customer cannot enter or rebind tenant authority. Administrators authorize an environment/company and dedicated read-only BC application separately. Credentials are encrypted with an explicitly configured integration custody key and never returned. Verification performs bounded reads only; no ERP write is available.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceConnectionRevision"
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceConnectionResponse"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/microsoft/business-central/connections/{connectionId}/credentials:
    post:
      operationId: rotateCommerceBusinessCentralCredentials
      tags:
        - Business Central connections
      summary: Rotate a connection credential and require re-verification
      description: Default off and outside the MCP OAuth profile. Requires a separate OWNER or ADMIN organization API key with org:integrations:write, org:* or * scope. Accounts must have supplied a fresh signed v2 or v3 purchaser tenant; the customer cannot enter or rebind tenant authority. Administrators authorize an environment/company and dedicated read-only BC application separately. Credentials are encrypted with an explicitly configured integration custody key and never returned. Verification performs bounded reads only; no ERP write is available.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceConnectionCredentials"
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceConnectionResponse"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/microsoft/business-central/connections/{connectionId}/disconnect:
    post:
      operationId: disconnectCommerceBusinessCentralConnection
      tags:
        - Business Central connections
      summary: Disconnect a company source and delete its stored credential
      description: Default off and outside the MCP OAuth profile. Requires a separate OWNER or ADMIN organization API key with org:integrations:write, org:* or * scope. Accounts must have supplied a fresh signed v2 or v3 purchaser tenant; the customer cannot enter or rebind tenant authority. Administrators authorize an environment/company and dedicated read-only BC application separately. Credentials are encrypted with an explicitly configured integration custody key and never returned. Verification performs bounded reads only; no ERP write is available.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceConnectionRevision"
      responses:
        "200":
          description: Bounded private result; no downstream action is executed
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceConnectionDisconnected"
        "400":
          description: Invalid or unexpected fields, or mismatched idempotency key
        "401":
          description: Authentication required
        "403":
          description: Current authority, consent, scope or organization denied
        "404":
          description: Authorized source or report unavailable
        "409":
          description: Source revision, policy, idempotency or uncertain attempt conflict
        "429":
          description: Request rate limit reached
        "503":
          description: Feature disabled or required authority, source or policy unavailable
  /v1/protocol/commerce/connected/approvals/evidence:
    post:
      operationId: prepareCommerceConnectedApprovalEvidence
      tags:
        - Commerce
      summary: Read minimized verified evidence for a named approval request
      description: Default off; requires COMMERCE_MCP_OAUTH_CONNECTED_ENABLED, the exact fresh nine-scope v3 consent, current Microsoft purchase and membership, and signed supported-source eligibility. It never upgrades a legacy v1 or v2 grant. Requires approval:request and current Accounts owner/admin. Only exact saved ORDER_ACCEPTANCE or REFUND_REQUEST SHADOW evidence and its current selected policy are admitted. Returns facts, missing/violated checks and verified dossier/action commitments. It neither completes a human approval nor executes an action.
      security:
        - CommerceAccountsOAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceApprovalPrepare"
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceApprovalEvidence"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/protocol/commerce/connected/business-central/{connectionId}/snapshot/{documentId}:
    get:
      operationId: prepareCommerceNativeSnapshot
      tags:
        - Commerce
      summary: Prepare current company-native order evidence and exact policy
      description: Default off; requires COMMERCE_MCP_OAUTH_CONNECTED_ENABLED, the exact fresh nine-scope v3 consent, current Microsoft purchase and membership, and signed supported-source eligibility. It never upgrades a legacy v1 or v2 grant. Also requires COMMERCE_MCP_BUSINESS_CENTRAL_NATIVE_ENABLED and a separately verified current company connection/native read grant within the purchaser tenant extracted by Accounts. No caller-supplied tenant, economics or source URL is accepted. Eight-second deadline and fixed bounded source reads apply. Requires erp:read and erp:validate. Returns an immutable snapshot digest, explicit cost provenance and exact signed policy. Admitted v2 evidence binds complete source cost from the verified effective company profile; v1 retains its native current-estimate provenance and missing landed cost. Preparation does not reserve budget or authorize an ERP write.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: documentId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: policy_version
          in: query
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 100
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceNativeSnapshotResponse"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/protocol/commerce/connected/business-central/{connectionId}/preflight:
    post:
      operationId: evaluateCommerceNativeShadowPreflight
      tags:
        - Commerce
      summary: Record the confirmed current order's full SHADOW policy result
      description: Default off; requires COMMERCE_MCP_OAUTH_CONNECTED_ENABLED, the exact fresh nine-scope v3 consent, current Microsoft purchase and membership, and signed supported-source eligibility. It never upgrades a legacy v1 or v2 grant. Also requires COMMERCE_MCP_BUSINESS_CENTRAL_NATIVE_ENABLED and a separately verified current company connection/native read grant within the purchaser tenant extracted by Accounts. No caller-supplied tenant, economics or source URL is accepted. Eight-second deadline and fixed bounded source reads apply. Requires erp:read and erp:validate, explicit confirmation, snapshot digest, policy digest and matching idempotency header. Re-reads the exact source and executes the canonical sixteen-check Commerce SHADOW workflow with one durable evaluation reservation. Missing landed cost, inventory, promotion or other required facts produce HOLD. The original PROCEED/HOLD/BLOCK/ESCALATE verdict, signed dossier and policy identity remain visible. No callback or integration is dispatched. Commerce may separately request native margin and agent-budget authorization only after unchanged PROCEED.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
            pattern: ^[A-Za-z0-9._:-]+$
          description: Must equal the confirmed body idempotency_key; retries cannot rebind the operation.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceNativePreflightRequest"
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceNativePreflightResponse"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "402":
          description: Monthly evaluation reservation allowance exhausted
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/protocol/commerce/connected/business-central/{connectionId}/safety-settings:
    get:
      operationId: getCommerceNativeSafetySettings
      tags:
        - Commerce
      summary: Read actual company fallback settings and recorded outages
      description: Default off; requires COMMERCE_MCP_OAUTH_CONNECTED_ENABLED, the exact fresh nine-scope v3 consent, current Microsoft purchase and membership, and signed supported-source eligibility. It never upgrades a legacy v1 or v2 grant. Also requires COMMERCE_MCP_BUSINESS_CENTRAL_NATIVE_ENABLED and a separately verified current company connection/native read grant within the purchaser tenant extracted by Accounts. No caller-supplied tenant, economics or source URL is accepted. Eight-second deadline and fixed bounded source reads apply. Requires erp:read. Reads enabled status and provider-observed can_configure; enabled remains read-only.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: org_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceNativeSafetyResponse"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
    patch:
      operationId: setCommerceNativeFallbackMode
      tags:
        - Commerce
      summary: Apply an explicitly confirmed company fallback-mode change
      description: Default off; requires COMMERCE_MCP_OAUTH_CONNECTED_ENABLED, the exact fresh nine-scope v3 consent, current Microsoft purchase and membership, and signed supported-source eligibility. It never upgrades a legacy v1 or v2 grant. Also requires COMMERCE_MCP_BUSINESS_CENTRAL_NATIVE_ENABLED and a separately verified current company connection/native read grant within the purchaser tenant extracted by Accounts. No caller-supplied tenant, economics or source URL is accepted. Eight-second deadline and fixed bounded source reads apply. Requires erp:configure, current Accounts owner/admin, a separately verified native configure grant and provider-observed write permission. Only FAIL_OPEN/FAIL_CLOSED changes are supported. Exact old/new mode, settings ID, connection revision, nonwildcard ETag and idempotency must match the reviewed request. Adapter-proven non-writes are terminal NOT_APPLIED; uncertain outcomes stay reserved and never retry a PATCH. A read can reconcile only the same applied operation UUID. This settings change performs no financial ERP action.
      security:
        - CommerceAccountsOAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
            pattern: ^[A-Za-z0-9._:-]+$
          description: Must equal the confirmed body idempotency_key; retries cannot rebind the operation.
        - name: If-Match
          in: header
          required: true
          schema:
            type: string
            minLength: 3
            maxLength: 256
          description: Exact nonwildcard settings ETag; must match expected_etag in the body.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceNativeFallbackRequest"
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceNativeFallbackResponse"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/microsoft/business-central/connections/{connectionId}/native-grant:
    post:
      operationId: verifyCommerceNativePermissionGrant
      tags:
        - Business Central connections
      summary: Verify and record narrow native company permissions
      description: Default off and outside the MCP OAuth profile. Requires an ordinary OWNER/ADMIN organization key with org:integrations:write, org:* or *; no protocol service or OAuth credential is admitted. Tenant comes only from fresh signed Accounts purchaser evidence. A current verified company connection, unchanged revision and read-only native status proof are required. A configure grant additionally requires provider-observed company write permission. No provider credential is returned or financial ERP action performed.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommerceNativeGrantRequest"
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - org_id
                  - connection_id
                  - connection_revision
                  - permissions
                  - verified_at
                properties:
                  org_id:
                    type: string
                    format: uuid
                  connection_id:
                    type: string
                    format: uuid
                  connection_revision:
                    type: integer
                    minimum: 1
                  permissions:
                    type: array
                    items:
                      enum:
                        - read
                        - configure
                    minItems: 1
                    maxItems: 2
                  verified_at:
                    type: string
                    format: date-time
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/microsoft/business-central/connections/{connectionId}/native-grant/revoke:
    post:
      operationId: revokeCommerceNativePermissionGrant
      tags:
        - Business Central connections
      summary: Revoke native company permission at the expected revision
      description: Default off and outside the MCP OAuth profile. Requires an ordinary OWNER/ADMIN organization key with org:integrations:write, org:* or *; no protocol service or OAuth credential is admitted. Tenant comes only from fresh signed Accounts purchaser evidence. A current verified company connection, unchanged revision and read-only native status proof are required. A configure grant additionally requires provider-observed company write permission. No provider credential is returned or financial ERP action performed.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - org_id
                - expected_revision
              properties:
                org_id:
                  type: string
                  format: uuid
                expected_revision:
                  type: integer
                  minimum: 1
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - revoked
                properties:
                  revoked:
                    const: true
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/auth/credential-context:
    post:
      operationId: getCommerceCredentialContext
      tags:
        - Onboarding and auth
      summary: Resolve the current credential's authoritative product context
      description: Returns the authenticated credential class and exact organization, role and scopes. Accounts owns OAuth and workspace issuance; Core consumes its signed purchased-workspace projection and never turns this response into a new OAuth or organization key. V1 base3 stays unchanged. V2 adds only its recognized profile/consent metadata. V3 privately adds oauth_authority and the existing signed oauth_source_authority for request-scoped product transport. The private evidence is never returned in MCP tools or persisted in reports. Service credentials are refused. Data and connected extensions are default off and require their exact freshly consented profiles.
      security:
        - CommerceAccountsOAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - authority
                  - org_id
                  - role
                  - scopes
                  - api_key_id
                properties:
                  authority:
                    enum:
                      - org_api_key
                      - accounts_oauth
                      - platform
                      - onboarding
                  org_id:
                    type:
                      - string
                      - "null"
                    format: uuid
                  role:
                    enum:
                      - OWNER
                      - ADMIN
                      - MEMBER
                      - VIEWER
                      - null
                  scopes:
                    type: array
                    items:
                      type: string
                  api_key_id:
                    type:
                      - string
                      - "null"
                    format: uuid
                  policy_id:
                    description: The named policy an organization key is bound to; evaluations through it that name no policy are decided by it. Null decides by the workspace default.
                    type:
                      - string
                      - "null"
                    pattern: ^[a-z0-9][a-z0-9._-]{0,99}$
                  onboarding_scope:
                    const: pilot_setup
                  oauth_profile:
                    const: commerce
                  oauth_resource:
                    type: string
                    format: uri
                  oauth_grant_id:
                    type: string
                    format: uuid
                  oauth_profile_version:
                    enum:
                      - 2
                      - 3
                  oauth_consent:
                    type: object
                    additionalProperties: false
                    required:
                      - consent_id
                      - consent_text_version
                      - consent_sha256
                    properties:
                      consent_id:
                        type: string
                        format: uuid
                      consent_text_version:
                        enum:
                          - commerce-data-consent-v1
                          - commerce-connected-consent-v1
                      consent_sha256:
                        type: string
                        pattern: ^[a-f0-9]{64}$
                  oauth_authority:
                    $ref: "#/components/schemas/CommerceConnectedAuthority"
                  oauth_source_authority:
                    $ref: "#/components/schemas/CommerceConnectedSourceAuthority"
                  initial_policy:
                    $ref: "#/components/schemas/CommerceInitialPolicy"
        "400":
          description: Invalid, oversized or conflicting request fields
        "401":
          description: Authentication required
        "403":
          description: Current signed authority, source, scope, role or company permission denied
        "404":
          description: Authorized source, document or evidence unavailable
        "409":
          description: Exact source, policy, evidence or idempotency binding changed; an uncertain write is never retried
        "429":
          description: Request rate limit reached
        "503":
          description: Default-off capability or required dependency unavailable
  /v1/microsoft/business-central/connections/{connectionId}/payment-context:
    get:
      operationId: getCommerceNativePaymentContext
      tags:
        - Business Central connections
      summary: Resolve registered Business Central payment evidence context
      description: A current ordinary organization key with decision:read and decision:write resolves only its synchronized Accounts workspace and exact active verified company connection with a current revision-bound native read grant. No query parameters or body are accepted. Missing configuration is unavailable; client-supplied organization or provider tenant claims grant no authority. The response contains non-secret registration metadata with basis=persisted_connection_and_native_grant, provider_read_authority=not_checked and execution_available=false, or true only for a connection whose payments Core decides with a single-use permit (the permit path); a permit claimed for one exact payment line, never this flag, lets a payment post. It does not read Microsoft payment facts, refresh Accounts provider authority, open provider credential custody or authorize posting. Existing native provider reads and configuration retain their separate fresh Accounts source and permission checks. Commerce binds subsequent queued assertions to all returned workspace/company/revision fields. Both scopes authorize payment evidence use, not a financial action.
      x-release-status: source_candidate
      security:
        - ApiKeyAuth: []
      parameters:
        - name: connectionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
            pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
      responses:
        "200":
          description: Bounded private result
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceNativeContext"
        "400":
          description: Malformed connection id, body or query parameters
        "401":
          description: Current organization API key required
        "403":
          description: Credential class, role, scopes, expiry or revocation denied
        "404":
          description: Exact synchronized workspace, verified connection or native grant unavailable
        "413":
          description: Request body exceeds the bounded limit
        "429":
          description: Request rate limit reached; retry after the returned Retry-After interval
        "503":
          description: Registration metadata dependency unavailable; no provider call is made
  /v1/commerce/payments/workspace:
    post:
      operationId: resolveCommercePaymentWorkspace
      tags:
        - Commerce
      summary: Resolve the current payment workspace mapping
      description: "Default off. Current ordinary workspace API key with decision:read and decision:write; no runtime-key scope expansion. Metadata only: returns the exact SYNCED Accounts mapping after checking the current ordinary key. No provider read, key issuance or payment execution."
      x-commerce-contract:
        id: urn:decionis:commerce:payment:evidence:v1
        sha256: dc7e0634199c349a248c356c81294c80f2fd00514ee5c66893c152c297a338cf
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommercePaymentWorkspaceRequest"
      responses:
        "200":
          description: Bound result. A grant, when one is bound, is a single-use permit for one exact payment line; Core executes nothing.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePaymentWorkspaceResponse"
        "400":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "401":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "402":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "403":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "404":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "409":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "413":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "429":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "503":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
  /v1/commerce/payments/snapshot:
    post:
      operationId: readCommercePaymentSnapshot
      tags:
        - Commerce
      summary: Read the current native payment source snapshot
      description: Default off. Current ordinary workspace API key with decision:read and decision:write; no runtime-key scope expansion. Fixed managed Business Central reader checks current connection/grant/assignment and exact native context, preserving the native observation time. Beneficiary verification remains unverified. Unsupported, stale, changing or locked source fails closed. No payment execution.
      x-commerce-contract:
        id: urn:decionis:commerce:payment:evidence:v1
        sha256: dc7e0634199c349a248c356c81294c80f2fd00514ee5c66893c152c297a338cf
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommercePaymentSnapshotRequest"
      responses:
        "200":
          description: Bound result. A grant, when one is bound, is a single-use permit for one exact payment line; Core executes nothing.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePaymentSnapshotResponse"
        "400":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "401":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "402":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "403":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "404":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "409":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "413":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "429":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "503":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
  /v1/commerce/payments/authorize:
    post:
      operationId: authorizeCommercePaymentEvidenceAlias
      tags:
        - Commerce
      deprecated: true
      summary: Evaluate a bound native payment (deprecated alias)
      description: "Default off. Current ordinary workspace API key with decision:read and decision:write; no runtime-key scope expansion. Deprecated alias of `POST /v1/commerce/payments/authorizations`: the same handler, kept for installed Commerce releases. Requires an immutable Commerce attempt, a fresh matching native snapshot, historical Accounts reviewer evidence plus fresh current authority, and the exact active approved policy pin. The whole Protocol policy and P12-P15 checks run. Transport retries retain the original input and expiry; no lease renewal. A policy result is not consent or an ERP write. Missing authority fails closed; HOLD and BLOCK remain stops. On a connection with the permit path on, a request may name the executor and the exact payment line's agent-safe.intent/1 intent; Core then binds one single-use grant to that intent and answers it under grant, with the permit fields a permit-style executor presents. Nothing executes until that permit is claimed, once."
      x-commerce-contract:
        id: urn:decionis:commerce:payment:evidence:v1
        sha256: dc7e0634199c349a248c356c81294c80f2fd00514ee5c66893c152c297a338cf
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommercePaymentAuthorizationRequest"
      responses:
        "200":
          description: Bound result. A grant, when one is bound, is a single-use permit for one exact payment line; Core executes nothing.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePaymentAuthorizationResponse"
        "400":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "401":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "402":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "403":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "404":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "409":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "413":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "429":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "503":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
  /v1/commerce/payments/authorizations:
    post:
      operationId: authorizeCommercePaymentEvidence
      tags:
        - Commerce
      summary: Evaluate a bound native payment with managed case evidence
      description: Default off. Current ordinary workspace API key with decision:read and decision:write; no runtime-key scope expansion. Requires an immutable Commerce attempt, a fresh matching native snapshot, historical Accounts reviewer evidence plus fresh current authority, and the exact active approved policy pin. The whole Protocol policy and P12-P15 checks run. Transport retries retain the original input and expiry; no lease renewal. A policy result is not consent or an ERP write. Missing authority fails closed; HOLD and BLOCK remain stops. On a connection with the permit path on, a request may name the executor and the exact payment line's agent-safe.intent/1 intent; Core then binds one single-use grant to that intent and answers it under grant, with the permit fields a permit-style executor presents. Nothing executes until that permit is claimed, once.
      x-commerce-contract:
        id: urn:decionis:commerce:payment:evidence:v1
        sha256: dc7e0634199c349a248c356c81294c80f2fd00514ee5c66893c152c297a338cf
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CommercePaymentAuthorizationRequest"
      responses:
        "200":
          description: Bound result. A grant, when one is bound, is a single-use permit for one exact payment line; Core executes nothing.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercePaymentAuthorizationResponse"
        "400":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "401":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "402":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "403":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "404":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "409":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "413":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "429":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
        "503":
          description: Bounded refusal or unavailable dependency; no payment execution.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, no-store
            Retry-After:
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
components:
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: |
        An organization API key. Its scopes decide what it may call;
        `decision:shadow` is the narrowest: SHADOW evaluations through
        POST /v1/authority/grants or its alias
        POST /v1/authority/enforce-and-bind only (DECISION_SHADOW_MODE_DENIED
        in any other mode; DECISION_SHADOW_FIELD_DENIED for a body carrying
        `context.decionis_policy`, `evidence` or `escalation`), with no
        integration dispatch. A key whose only scope is `decision:shadow`
        (an AgentSafe hosted gateway's) reaches exactly those two,
        POST /v1/auth/credential-context, POST /v1/hosted-gateway/keys/confirm
        and POST /v1/hosted-gateway/keys/revoke-self; every other route
        answers 403 HOSTED_GATEWAY_KEY_PATH_DENIED.
        `decision:enforce` is an enforced hosted gateway's key: evaluations
        in SHADOW or ENFORCEMENT through POST /v1/authority/grants or its
        alias (400 DECISION_ENFORCE_FIELD_DENIED for a body carrying
        `context.decionis_policy`; it never holds `policy:write`), and the
        grants and managed escalations they bind. A key whose scopes are
        `decision:enforce` (with or without `decision:shadow`) reaches exactly
        POST /v1/authority/enforce-and-bind, POST /v1/authority/grants,
        GET /v1/authority/grants/{grant_id},
        POST /v1/authority/grants/{grant_id}/claims,
        POST /v1/authority/grants/{grant_id}/receipts,
        POST /v1/authority/grants/{grant_id}/reconciliations,
        POST /v1/execution/verify-token, POST /v1/execution/claim-token,
        POST /v1/execution/consume-token, POST /v1/execution/finalize-token,
        GET /v1/authority/escalations/{escalation_id},
        DELETE /v1/authority/escalations/{escalation_id},
        POST /v1/auth/credential-context, POST /v1/hosted-gateway/keys/confirm
        and POST /v1/hosted-gateway/keys/revoke-self, each id a UUID; every
        other route answers 403 HOSTED_GATEWAY_KEY_PATH_DENIED.
    AccountSessionCookie:
      type: apiKey
      in: cookie
      name: decionis_account_session
      description: The signed HttpOnly account session the web app holds after sign-in (also accepted as a Bearer `acct_` token).
    HostedGatewayTcpRouteCredential:
      type: http
      scheme: bearer
      description: A role-specific opaque 43-character connector or client credential revealed by the verified workspace administrator. Accepted only for TCP ticket issuance, never an organization API key, account session, worker credential or broker credential.
    CommerceAccountsOAuth:
      type: http
      scheme: bearer
      description: Opaque Accounts-issued Commerce OAuth access credential with resource-bound current purchase. Legacy base3, signed v2 ERP/history and fresh signed v3 nine-scope connected grants retain distinct route profiles. Refresh credentials never authenticate. Per-operation connection, current role, proof, quota and confirmation checks remain mandatory.
    DrupalSiteKey:
      type: http
      scheme: bearer
      description: The organization API key a Drupal site received, once, when it connected (connect/verify or connect/code). Only that key is accepted, compared with the hash stored at connect; another key of the same organization is refused.
  parameters:
    DrupalMutationKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Stable nonblank printable ASCII key; repeat the same value only for the same immutable command.
      schema:
        type: string
        minLength: 1
        maxLength: 200
        pattern: ^[ -~]+$
    HostedGatewayDeploymentSelector:
      name: deployment_id
      in: query
      required: false
      description: One of the current workspace's gateways; omitted, the workspace's primary. The organization always comes from the session, never from a parameter.
      schema:
        type: string
        format: uuid
    CorrelationId:
      name: X-Correlation-ID
      in: header
      required: false
      schema:
        type: string
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
    GrantId:
      name: grantId
      in: path
      required: true
      description: "The execution grant's `jti`: the `execution_token_jti` returned when the grant was issued, the `jti` recorded for the grant, and the `jti` claim of the signed execution token. The token remains the bearer proof; a token whose `jti` is not this id is refused with GRANT_ID_MISMATCH."
      schema:
        type: string
        format: uuid
    ExecutionTokenHeader:
      name: x-decionis-execution-token
      in: header
      required: true
      description: The execution token, as issued. Redacted from request logs.
      schema:
        type: string
        minLength: 1
        maxLength: 20000
    UcpOrgId:
      name: org_id
      in: query
      required: false
      description: Optional when the authenticated API key is already bound to an organization.
      schema:
        type: string
        format: uuid
    PublicDossierId:
      name: dossier_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    ShareLinkSignature:
      name: sig
      in: query
      required: true
      description: The share-link capability from a dossier's verification envelope. An access gate, not proof of authenticity — the Ed25519 signatures in the proof bundle are what prove the dossier. A missing or wrong value returns the same 404 as an unknown dossier.
      schema:
        type: string
    ShareLinkExpiry:
      name: exp
      in: query
      required: false
      description: Expiry (epoch seconds) of a v2 org-scoped share link. Bound into the signature — stripping or editing it invalidates the link. Absent only on legacy expiry-less links, which deployments may refuse.
      schema:
        type: string
  headers:
    DecionisWarning:
      description: "Present only when Decionis made the decision but left something the request asked for undone: comma-separated codes, never a reason to treat the decision differently. A header rather than a body field, so a gate that mirrors the decision's closed shape never meets a field it does not know. `POLICY_ENFORCE_SCOPE_MISSING`: the context's `decionis_policy` asked for `enforce: true`, and the key holds none of `policy:write`, `policy:*` or `org:*` (the scopes POST /v1/protocol/policies/bundles requires), so no policy bundle was published; the event `policy.file.enforce_skipped` records it. `EXPECTED_EFFECT_DIGEST_MISSING`: a grant was issued under Protocol 1.1 for an intent that named no `expected_effect_digest`, so its effect can never be confirmed; send one in the intent to make it confirmable."
      schema:
        type: string
        examples:
          - POLICY_ENFORCE_SCOPE_MISSING
          - EXPECTED_EFFECT_DIGEST_MISSING
    DecionisActionRequired:
      description: "On a live claim: what the executor still owes the authority. `FINALIZE_BEFORE_LEASE_EXPIRY`: report the attempt at the grant's `/receipts` before `claim_lease_expires_at`, or the claim is recorded INDETERMINATE and holds its scopes until it is reconciled."
      schema:
        type: string
        enum:
          - FINALIZE_BEFORE_LEASE_EXPIRY
    DecionisBlockingGrant:
      description: "On a claim refused with CURRENT_STATE_UNRESOLVED because an earlier claim on the same scope is INDETERMINATE: that claim's grant id (its `jti`), in the caller's own organisation, for its reconciliation."
      schema:
        type: string
  responses:
    HostedGatewayTcpInvalidRequest:
      description: INVALID_REQUEST or ordinary validation refusal for missing, oversized, invalid or unexpected body fields.
    HostedGatewayTcpSessionRequired:
      description: The signed workspace account session is missing or invalid.
    HostedGatewayTcpAuthorizationRefused:
      description: TCP_AUTHORIZATION_REFUSED, HOSTED_GATEWAY_ADMIN_REQUIRED, HOSTED_GATEWAY_PAID_PLAN_REQUIRED or HOSTED_GATEWAY_ENTITLEMENT_INACTIVE. Current authorizing administrator membership and paid active entitlement are rechecked; no fallback authorization.
    HostedGatewayTcpJsonRequired:
      description: JSON_CONTENT_TYPE_REQUIRED.
    HostedGatewayTcpRateLimited:
      description: Request rate or bounded connection capacity reached.
    HostedGatewayTcpUnavailable:
      description: TCP_UNAVAILABLE when a required dependency is unavailable or a gated operation is disabled. Internal service configuration may return TCP_SERVICE_UNAVAILABLE. Fail closed; no ticket, lease or traffic authority is granted.
    Error:
      description: Structured API error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    DrupalConnectTooLarge:
      description: The body is larger than 16 KiB.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    DrupalConnectRateLimited:
      description: RATE_LIMITED. Requests are limited per address and route, and per site, connect or organization.
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 1
        X-RateLimit-Limit:
          schema:
            type: integer
            minimum: 0
        X-RateLimit-Remaining:
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    DrupalConnectUnavailable:
      description: Nothing is granted. DRUPAL_CONNECT_NOT_CONFIGURED while connect is not configured; DRUPAL_EMAIL_CODE_UNAVAILABLE while no code sender exists (connect/verify and connect/code); COMMERCE_NOT_CONFIGURED or COMMERCE_COMPATIBILITY_UNAVAILABLE when the Commerce service is not configured or cannot be reached; SERVICE_BUSY (with Retry-After), RATE_LIMIT_UNAVAILABLE, MERCHANT_SERVICE_UNAVAILABLE, or UPSTREAM_UNAVAILABLE when Decionis could not bind or revoke. Drupal authority additionally fails closed with DRUPAL_AUTHORITY_UNAVAILABLE, DRUPAL_ACCOUNTS_WORKSPACE_UNAVAILABLE or DRUPAL_ACCOUNTS_ROLLOUT_GATE_CLOSED while Accounts enrollment is unavailable or gated; invalid or expired authority receipts never grant enforcement.
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
  schemas:
    HostedGatewayTcpEmpty:
      type: object
      additionalProperties: false
      required: []
      properties: {}
    HostedGatewayTcpRole:
      type: string
      enum:
        - connector
        - client
    HostedGatewayTcpActivate:
      type: object
      additionalProperties: false
      required:
        - accept_terms
      properties:
        accept_terms:
          type: boolean
          not:
            const: false
    HostedGatewayTcpReveal:
      type: object
      additionalProperties: false
      required:
        - generation
      properties:
        generation:
          type: integer
          minimum: 1
          maximum: 2147483647
          description: Non-secret fencing generation. Discard stale reveals and clear displayed credentials when this changes.
    HostedGatewayTcpTicketRequest:
      type: object
      additionalProperties: false
      required:
        - route_id
        - role
      properties:
        route_id:
          type: string
          format: uuid
        role:
          $ref: "#/components/schemas/HostedGatewayTcpRole"
    HostedGatewayTcpTicketResponse:
      type: object
      additionalProperties: false
      required:
        - ticket
        - expires_at
        - route_id
        - tenant_host
        - gateway_url
        - resource
        - resource_hash
      properties:
        ticket:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
          description: Sensitive opaque capability; never put in a URL, log, analytics event or ordinary resource view.
        expires_at:
          type: string
          format: date-time
          allOf:
            - pattern: Z$
        route_id:
          type: string
          format: uuid
        tenant_host:
          type: string
          maxLength: 253
        gateway_url:
          type: string
          format: uri
        resource:
          type: string
          minLength: 1
          maxLength: 2048
        resource_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: SHA-256 lowercase hex of the canonical saved numeric IP:port resource string, not a customer payload.
      description: A one-use ticket expires in 60 seconds. Verify every returned binding against local configuration before CONNECT; never infer authorization from shape alone. Roles have separate route credentials.
    HostedGatewayTcpCredentials:
      type: object
      additionalProperties: false
      required:
        - route_id
        - tenant_host
        - gateway_url
        - resource
        - resource_hash
        - connector_credential
        - client_credential
      properties:
        route_id:
          type: string
          format: uuid
        tenant_host:
          type: string
          maxLength: 253
        gateway_url:
          type: string
          format: uri
        resource:
          type: string
          minLength: 1
          maxLength: 2048
        resource_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: SHA-256 lowercase hex of the canonical saved numeric IP:port resource string, not a customer payload.
        connector_credential:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
          description: Sensitive opaque capability; never put in a URL, log, analytics event or ordinary resource view.
        client_credential:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
          description: Sensitive opaque capability; never put in a URL, log, analytics event or ordinary resource view.
      description: One-time disclosure after a matching generation and current authority check. Save the separate credentials in local files, never URLs, browser persistence or analytics. Losing this response requires disable and re-enable to replace credentials.
    HostedGatewayTcpView:
      type: object
      additionalProperties: false
      required:
        - route_id
        - generation
        - state
        - gateway_url
        - connector_online
        - last_seen_at
        - credentials_available
        - message
      properties:
        route_id:
          type: string
          format: uuid
        generation:
          type: integer
          minimum: 1
          maximum: 2147483647
          description: Non-secret fencing generation. Discard stale reveals and clear displayed credentials when this changes.
        state:
          type: string
          enum:
            - provisioning
            - awaiting_connector
            - connected
            - offline
            - disabled
            - failed
        gateway_url:
          type: string
          format: uri
        connector_online:
          type: boolean
        last_seen_at:
          type:
            - string
            - "null"
          format: date-time
        credentials_available:
          type: boolean
        message:
          type: string
      description: Secret-free resource metadata, omitted while TCP is disabled. route_id equals the saved resource UUID. Connected means a fresh broker-authenticated connector lease, not a successful application login or application-command inspection.
    HostedGatewayResource:
      type: object
      additionalProperties: false
      required:
        - id
        - type
        - resource
        - label
        - created_at
        - status
        - status_message
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          enum:
            - url
            - tcp_ip
            - hostname
        resource:
          type: string
          maxLength: 2048
        label:
          type: string
          maxLength: 100
        created_at:
          type: string
          format: date-time
        status:
          type: string
          enum:
            - connected
            - pending_connection
            - unsupported_transport
        status_message:
          type: string
        tcp:
          $ref: "#/components/schemas/HostedGatewayTcpView"
    HostedGatewayResources:
      type: object
      additionalProperties: false
      required:
        - resources
        - resource_limit
        - tcp_enabled
      properties:
        resources:
          type: array
          maxItems: 50
          items:
            $ref: "#/components/schemas/HostedGatewayResource"
        resource_limit:
          type: integer
          const: 50
        tcp_enabled:
          type: boolean
          description: Default false. The interface must hide TCP activation controls unless true.
    HostedGatewayDeploymentSummary:
      type: object
      required:
        - id
        - tenant_host
        - is_primary
        - status
        - running_mode
      properties:
        id:
          type: string
          format: uuid
        tenant_host:
          type: string
          examples:
            - acme.decionisedge.com
        is_primary:
          type: boolean
          description: The gateway a request without deployment_id acts on.
        status:
          type: string
          enum:
            - queued
            - provisioning
            - ready
            - failed
            - needs_configuration
        running_mode:
          type:
            - string
            - "null"
          enum:
            - SHADOW
            - ENFORCEMENT
            - null
          description: What the fleet last confirmed it runs; null before it runs.
    HostedGatewayDeploymentOverview:
      type: object
      required:
        - deployment
        - credentials
        - networking
        - activation
      description: One gateway's state, as the Deployments page shows it, and the list of the workspace's gateways.
      properties:
        deployment:
          type:
            - object
            - "null"
          description: The selected gateway; null while the workspace has none.
          required:
            - id
            - tenant_label
            - tenant_host
            - gateway_url
            - status
            - runtime_verified
          properties:
            id:
              type: string
              format: uuid
            tenant_label:
              type: string
            tenant_host:
              type: string
            gateway_url:
              type: string
            status:
              type: string
              enum:
                - reserved
                - awaiting_gateway
                - authorized
                - disconnected
            upstream_origin:
              type:
                - string
                - "null"
            runtime_verified:
              type: boolean
              description: True only after the provisioning worker confirms the hosted runtime.
        deployments:
          type: array
          maxItems: 10
          items:
            $ref: "#/components/schemas/HostedGatewayDeploymentSummary"
        deployment_limit:
          type: integer
          minimum: 1
          maximum: 10
          description: How many gateways an operator granted this workspace; 1 unless raised.
        credentials:
          type: array
          description: The gateway's key to Decionis, by prefix and status only.
          items:
            type: object
        gateway_token:
          oneOf:
            - $ref: "#/components/schemas/HostedGatewayTokenStatus"
            - type: "null"
          description: The token the gateway sends the tenant's API, by state only; null without a gateway.
        enforcement:
          type: object
        networking:
          type: object
        activation:
          type: object
    HostedGatewayDeploymentReservation:
      anyOf:
        - type: object
          additionalProperties: false
          properties:
            company_name:
              type: string
              minLength: 1
              maxLength: 200
              description: Makes the primary gateway's label; the workspace name when omitted.
        - type: object
          additionalProperties: false
          required:
            - additional
            - tenant_label
          properties:
            additional:
              type: boolean
              not:
                const: false
            tenant_label:
              type: string
              pattern: ^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
              description: The exact label of the further gateway, served at <tenant_label>.decionisedge.com.
              examples:
                - sitework
    HostedGatewayDeploymentActivation:
      type: object
      additionalProperties: false
      required:
        - upstream_origin
        - accept_terms
      properties:
        upstream_origin:
          type: string
          maxLength: 2048
          examples:
            - https://api.acme.example
        accept_terms:
          type: boolean
          not:
            const: false
    HostedGatewayModeRequest:
      type: object
      additionalProperties: false
      required:
        - mode
        - accept_terms
      properties:
        mode:
          type: string
          enum:
            - SHADOW
            - ENFORCEMENT
        accept_terms:
          type: boolean
          not:
            const: false
        upstream_credential:
          type: object
          additionalProperties: false
          required:
            - header
            - value
          description: Enforcement only; sealed at once, never returned.
          properties:
            header:
              type: string
              maxLength: 64
            value:
              type: string
              maxLength: 8192
              writeOnly: true
        policy_id:
          type:
            - string
            - "null"
          description: The named policy the gateway is decided by; null is the workspace default, omitted keeps it.
    HostedGatewayTokenStatus:
      type: object
      additionalProperties: false
      required:
        - header
        - issued
        - revealable
        - sent
        - sent_at
        - pending_at
      properties:
        header:
          type: string
          const: AgentSafe-Gateway-Token
        issued:
          type: boolean
          description: A token is in use for this gateway.
        revealable:
          type: boolean
          description: The token in use can be revealed, once, now.
        sent:
          type: boolean
          description: The fleet confirmed every pod sends the token in use.
        sent_at:
          type:
            - string
            - "null"
          format: date-time
        pending_at:
          type:
            - string
            - "null"
          format: date-time
          description: When a regenerated token, not yet activated, was made.
    HostedGatewayToken:
      type: object
      additionalProperties: false
      required:
        - gateway_token
        - header
        - sent
      properties:
        gateway_token:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
        header:
          type: string
          const: AgentSafe-Gateway-Token
        sent:
          type: boolean
    HostedGatewayPendingToken:
      type: object
      additionalProperties: false
      required:
        - gateway_token
        - header
        - pending_at
      properties:
        gateway_token:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
        header:
          type: string
          const: AgentSafe-Gateway-Token
        pending_at:
          type: string
          format: date-time
    HostedGatewayTokenActivation:
      type: object
      additionalProperties: false
      required:
        - api_accepts_token
      properties:
        api_accepts_token:
          type: boolean
          not:
            const: false
          description: The tenant's API accepts the pending token; the gateway switches to it.
    HostedGatewayTenantKey:
      type: object
      additionalProperties: false
      required:
        - tenant_key
        - header
        - gateway_url
      properties:
        tenant_key:
          type: string
        header:
          type: string
          const: AgentSafe-Tenant-Key
        gateway_url:
          type: string
    HostedGatewayResourceInput:
      type: object
      additionalProperties: false
      required:
        - resource
        - type
        - label
      properties:
        resource:
          type: string
          minLength: 1
          maxLength: 2048
        type:
          type: string
          enum:
            - url
            - tcp_ip
            - hostname
        label:
          type: string
          minLength: 1
          maxLength: 100
    HostedGatewayResourceAdded:
      type: object
      additionalProperties: false
      required:
        - resources
        - resource_limit
        - tcp_enabled
        - resource
        - created
      properties:
        resources:
          type: array
          maxItems: 50
          items:
            $ref: "#/components/schemas/HostedGatewayResource"
        resource_limit:
          type: integer
          const: 50
        tcp_enabled:
          type: boolean
        resource:
          $ref: "#/components/schemas/HostedGatewayResource"
        created:
          type: boolean
          description: False when the same resource was already saved to this gateway.
    HostedGatewayDisclosure:
      type: object
      required:
        - statement
        - evaluated_methods
        - recorded
        - json_body_max_bytes
        - header_values_recorded
        - never_recorded
        - key
        - metering
        - refusals
        - disconnect
      properties:
        statement:
          type: string
          description: The paragraph the approval page shows verbatim. It states which requests are evaluated and what each records, that each counts as a governed action on the workspace's plan (`metering`), and that Decionis's shadow verdicts never block or change a request while the gateway itself still refuses requests over its rate or size limits or that it cannot read (`refusals`).
        evaluated_methods:
          type: array
          items:
            type: string
          examples:
            - - POST
              - PUT
              - PATCH
              - DELETE
          description: The methods the gateway evaluates; other requests pass through unrecorded.
        metering:
          type: string
          description: That each evaluated request counts as one governed action on the workspace's plan (within its allowance or billed as overage).
        refusals:
          type: string
          description: What Decionis's verdicts do to a request (nothing, in shadow) and what the gateway itself still refuses (HTTP 429, 413, 400).
        recorded:
          type: array
          items:
            type: string
            enum:
              - method
              - path
              - query
              - json_body
              - body_sha256
              - body_bytes
              - content_type
              - idempotency_key
        json_body_max_bytes:
          type: integer
        header_values_recorded:
          type: array
          items:
            type: string
          examples:
            - - Content-Type
              - Idempotency-Key
        never_recorded:
          type: array
          items:
            type: string
          examples:
            - - other request headers
              - response bodies
        key:
          type: object
          required:
            - name
            - role
            - scopes
            - power
          properties:
            name:
              type: string
            role:
              type: string
            scopes:
              type: array
              items:
                type: string
            power:
              type: string
        disconnect:
          type: string
    HostedGatewayWorkspace:
      type: object
      required:
        - org_id
        - name
        - role
        - plan_code
        - paid
        - eligible
        - refusal
      properties:
        org_id:
          type: string
          format: uuid
        name:
          type: string
        role:
          type: string
          enum:
            - OWNER
            - ADMIN
            - MEMBER
            - VIEWER
        plan_code:
          type: string
        paid:
          type: boolean
        eligible:
          type: boolean
        refusal:
          type:
            - string
            - "null"
          enum:
            - HOSTED_GATEWAY_ADMIN_REQUIRED
            - HOSTED_GATEWAY_PAID_PLAN_REQUIRED
            - HOSTED_GATEWAY_ENTITLEMENT_INACTIVE
            - null
          description: By the rules the database answers (role, plan, API access); Accounts' entitlement is asked at approval and may still refuse with HOSTED_GATEWAY_ENTITLEMENT_INACTIVE.
    HostedGatewayLookupRequest:
      type: object
      additionalProperties: false
      required:
        - user_code
      properties:
        user_code:
          type: string
          maxLength: 32
          examples:
            - BCDF-GHJK
    HostedGatewayLookup:
      type: object
      required:
        - authorization
        - disclosure
        - approver
        - workspaces
        - pricing_url
      properties:
        authorization:
          type: object
          required:
            - authorization_id
            - status
            - user_code
            - tenant_label
            - tenant_host
            - upstream_origin
            - owner_email
            - requested_by
            - requested_at
            - expires_at
            - org_id
          properties:
            authorization_id:
              type: string
              format: uuid
            status:
              type: string
              enum:
                - pending
                - approved
                - denied
                - expired
                - consumed
            user_code:
              type: string
            tenant_label:
              type: string
            tenant_host:
              type: string
            upstream_origin:
              type: string
            owner_email:
              type: string
              description: In full for the owner; masked (`o***@acme.example`) for anyone else.
            requested_by:
              type: object
              required:
                - name
              properties:
                name:
                  type:
                    - string
                    - "null"
                  description: The operator's sign-in name from their verified Entra token.
            requested_at:
              type: string
              format: date-time
            expires_at:
              type: string
              format: date-time
            org_id:
              type:
                - string
                - "null"
              format: uuid
        disclosure:
          $ref: "#/components/schemas/HostedGatewayDisclosure"
        approver:
          type: object
          required:
            - email
            - email_matches
            - session_org_id
          properties:
            email:
              type: string
            email_matches:
              type: boolean
            session_org_id:
              type: string
              format: uuid
        workspaces:
          type: array
          description: The signed-in owner's workspaces; empty for anyone else.
          items:
            $ref: "#/components/schemas/HostedGatewayWorkspace"
        pricing_url:
          type: string
          format: uri
    HostedGatewayApproveRequest:
      type: object
      additionalProperties: false
      required:
        - user_code
        - org_id
      properties:
        user_code:
          type: string
          maxLength: 32
        org_id:
          type: string
          format: uuid
    HostedGatewayDenyRequest:
      type: object
      additionalProperties: false
      required:
        - user_code
      properties:
        user_code:
          type: string
          maxLength: 32
    HostedGatewayApproval:
      type: object
      required:
        - status
        - authorization_id
        - org_id
        - org_name
        - tenant_label
        - tenant_host
        - approved_at
        - session_org_id
        - session_rebound
      properties:
        status:
          type: string
          const: approved
        authorization_id:
          type: string
          format: uuid
        org_id:
          type: string
          format: uuid
        org_name:
          type: string
        tenant_label:
          type: string
        tenant_host:
          type: string
        approved_at:
          type: string
          format: date-time
        session_org_id:
          type: string
          format: uuid
        session_rebound:
          type: boolean
          description: True when a new account-session cookie bound to `org_id` was set.
    HostedGatewayPaidPlanRequired:
      type: object
      required:
        - error
        - plan_code
        - pricing_url
      properties:
        error:
          type: string
          const: HOSTED_GATEWAY_PAID_PLAN_REQUIRED
        message:
          type: string
        plan_code:
          type: string
        pricing_url:
          type: string
          format: uri
    HostedGatewayKeyRevocation:
      type: object
      required:
        - key_id
        - org_id
        - tenant_label
        - revoked_at
        - revoked_reason
      properties:
        key_id:
          type: string
          format: uuid
        org_id:
          type: string
          format: uuid
        tenant_label:
          type:
            - string
            - "null"
        revoked_at:
          type: string
          format: date-time
        revoked_reason:
          type: string
          examples:
            - self_revoked
            - owner_disconnected
    HostedGatewayDeliveryConfirmation:
      type: object
      required:
        - key_id
        - org_id
        - tenant_label
        - delivered_at
        - expires_at
        - already_confirmed
        - revoked_key_ids
      properties:
        key_id:
          type: string
          format: uuid
        org_id:
          type: string
          format: uuid
        tenant_label:
          type: string
        delivered_at:
          type: string
          format: date-time
        expires_at:
          const: null
        already_confirmed:
          type: boolean
        revoked_key_ids:
          type: array
          items:
            type: string
            format: uuid
          description: The tenant's earlier keys this confirmation revoked (the token answer's `replaced_key_ids` still live); empty when already confirmed.
    AnalyticsSegment:
      type:
        - string
        - "null"
      enum:
        - compliance
        - risk
        - finance
        - technical
        - null
    AnalyticsEventRequest:
      type: object
      required:
        - experiment
        - variant
        - event
        - visitor_id
        - page_path
        - occurred_at
      properties:
        experiment:
          type: string
          examples:
            - proof_led_page
        variant:
          type: string
          enum:
            - A
            - B
        event:
          type: string
          examples:
            - exposure
            - qualified_demo
            - signup
        segment:
          $ref: "#/components/schemas/AnalyticsSegment"
        visitor_id:
          type: string
        page_path:
          type: string
          examples:
            - /proof-led
        occurred_at:
          type: string
          format: date-time
        metadata:
          type: object
          additionalProperties: true
      additionalProperties: false
    AnalyticsConversionRate:
      type: object
      required:
        - variant
        - segment
        - exposed_visitors
        - converted_visitors
        - conversion_rate
      properties:
        variant:
          type: string
          enum:
            - A
            - B
        segment:
          $ref: "#/components/schemas/AnalyticsSegment"
        exposed_visitors:
          type: integer
          minimum: 0
        converted_visitors:
          type: integer
          minimum: 0
        conversion_rate:
          type: number
          minimum: 0
      additionalProperties: false
    AnalyticsExperimentReport:
      type: object
      required:
        - generated_at
        - experiment
        - window_days
        - conversion_event
        - variants
        - segments
      properties:
        generated_at:
          type: string
          format: date-time
        experiment:
          type: string
        window_days:
          type: integer
        conversion_event:
          type:
            - string
            - "null"
        variants:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsConversionRate"
        segments:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsConversionRate"
      additionalProperties: false
    ComplianceFrameworkId:
      type: string
      enum:
        - eu_ai_act
        - gdpr
        - soc2
    ComplianceEvidencePackRequest:
      type: object
      required:
        - org_id
        - session_id
        - workflow_label
        - window_days
        - frameworks
      properties:
        org_id:
          type: string
          format: uuid
        session_id:
          type: string
        workflow_label:
          type: string
          examples:
            - Vendor payments
        window_days:
          type: integer
          minimum: 1
          maximum: 365
        frameworks:
          type: array
          items:
            $ref: "#/components/schemas/ComplianceFrameworkId"
      additionalProperties: false
    ComplianceEvidencePackMetrics:
      type: object
      required:
        - decisions
        - blocked
        - escalated
        - human_oversight
        - recordkeeping
      properties:
        decisions:
          type: integer
          minimum: 0
        blocked:
          type: integer
          minimum: 0
          description: Decisions with outcome REJECT in ENFORCEMENT mode, refused before the action ran.
        shadow_blocked:
          type: integer
          minimum: 0
          description: Decisions with outcome REJECT in any other mode, recorded while the action went ahead. Absent from packs signed before it was counted.
        escalated:
          type: integer
          minimum: 0
        human_oversight:
          type: integer
          minimum: 0
        recordkeeping:
          type: integer
          minimum: 0
          description: Decisions a stored, signed Decision Dossier backs.
      additionalProperties: false
    ComplianceEvidenceControl:
      type: object
      required:
        - ref
        - name
        - requirement
        - evidence
        - metric_value
      properties:
        ref:
          type: string
        name:
          type: string
        requirement:
          type: string
        evidence:
          type: string
        metric:
          type: string
          enum:
            - decisions
            - blocked
            - escalated
            - humanOversight
            - recordkeeping
        metric_value:
          description: "The control's headline count: its metric's value, or for a control with measures (SOC 2) the first measure's. Null where the source is not reported."
          type:
            - integer
            - "null"
          minimum: 0
        measures:
          description: The counts behind a SOC 2 control (CC6.1-CC6.3, CC7.2-CC7.3, CC8.1), each naming the record it is counted from. Null where this deployment has no such record.
          type: array
          items:
            $ref: "#/components/schemas/ComplianceEvidenceMeasure"
      additionalProperties: false
    ComplianceEvidenceMeasure:
      type: object
      required:
        - key
        - label
        - source
        - value
      properties:
        key:
          type: string
          examples:
            - api_keys_active
        label:
          type: string
        source:
          type: string
        value:
          type:
            - integer
            - "null"
          minimum: 0
      additionalProperties: false
    ComplianceEvidenceFramework:
      type: object
      required:
        - id
        - name
        - controls
      properties:
        id:
          $ref: "#/components/schemas/ComplianceFrameworkId"
        name:
          type: string
        note:
          type: string
          description: What the mapping is and is not (SOC 2 evidence supports an audit; it is not an attestation).
        controls:
          type: array
          items:
            $ref: "#/components/schemas/ComplianceEvidenceControl"
      additionalProperties: false
    ComplianceEvidencePackResponse:
      type: object
      required:
        - pack_id
        - generated_at
        - signature
        - verification_url
        - metrics
        - frameworks
        - download_url
      properties:
        pack_id:
          type: string
          format: uuid
        generated_at:
          type: string
          format: date-time
        signature:
          type: string
          examples:
            - ed25519:key-id:base64url-signature
        verification_url:
          type: string
          format: uri
        metrics:
          $ref: "#/components/schemas/ComplianceEvidencePackMetrics"
        frameworks:
          type: array
          items:
            $ref: "#/components/schemas/ComplianceEvidenceFramework"
        download_url:
          type: string
          format: uri
      additionalProperties: false
    EvidencePackVerificationResponse:
      type: object
      required:
        - service
        - verified
        - valid
        - checked_at
        - pack
        - signature
      properties:
        service:
          type: string
          enum:
            - decionis
        verified:
          type: boolean
        valid:
          type: boolean
        checked_at:
          type: string
          format: date-time
        pack:
          type: object
          additionalProperties: true
        signature:
          type: object
          additionalProperties: true
      additionalProperties: false
    AuthorityClassification:
      type: string
      enum:
        - AUTHORITATIVE
        - OBSERVATIONAL
      description: Authority possessed by an artifact, independent of its verdict. Only AUTHORITATIVE artifacts may become execution-eligible.
    PolicyReference:
      type: object
      additionalProperties: false
      required:
        - policy_id
        - revision_id
        - version
        - digest
      properties:
        policy_id:
          type: string
          minLength: 1
          maxLength: 500
        revision_id:
          type: string
          minLength: 1
          maxLength: 500
        version:
          type: string
          minLength: 1
          maxLength: 500
        digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
    EvaluationSemantics:
      type: object
      additionalProperties: false
      required:
        - protocol_version
        - evaluator_version
        - policy_schema_version
        - canonicalization
        - digest_algorithm
        - signal_normalization_version
      properties:
        protocol_version:
          type: string
          const: "1.1"
        evaluator_version:
          type: string
          minLength: 1
          maxLength: 500
        policy_schema_version:
          type: string
          minLength: 1
          maxLength: 500
        canonicalization:
          type: string
          const: RFC8785/JCS
        digest_algorithm:
          type: string
          const: SHA-256
        signal_normalization_version:
          type: string
          minLength: 1
          maxLength: 500
    UcpProtocolVersion:
      type: string
      enum:
        - 2026-04-08
        - 2026-08-25
      description: UCP releases whose checkout response envelopes this adapter validates.
    UcpCapabilityReference:
      type: object
      additionalProperties: true
      required:
        - version
      properties:
        version:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
        spec:
          type: string
          format: uri
          maxLength: 2000
        schema:
          type: string
          format: uri
          maxLength: 2000
        id:
          type: string
          minLength: 1
          maxLength: 500
        extends:
          oneOf:
            - type: string
              minLength: 1
              maxLength: 500
            - type: array
              minItems: 1
              maxItems: 50
              items:
                type: string
                minLength: 1
                maxLength: 500
        config:
          type: object
          additionalProperties: true
    UcpPaymentHandlerReference:
      type: object
      additionalProperties: true
      required:
        - version
        - id
      properties:
        version:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
        id:
          type: string
          minLength: 1
          maxLength: 500
        spec:
          type: string
          format: uri
          maxLength: 2000
        schema:
          type: string
          format: uri
          maxLength: 2000
        config:
          type: object
          additionalProperties: true
    UcpCheckoutEnvelope:
      type: object
      additionalProperties: true
      required:
        - version
      properties:
        version:
          $ref: "#/components/schemas/UcpProtocolVersion"
        status:
          type: string
          enum:
            - success
            - error
        capabilities:
          type: object
          propertyNames:
            type: string
            pattern: ^[a-z](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9_])?)+$
          additionalProperties:
            type: array
            maxItems: 50
            items:
              $ref: "#/components/schemas/UcpCapabilityReference"
          description: Negotiated UCP capabilities keyed by reverse-domain identifier. A capability is active only through a matching versioned reference; key presence or an empty array is not negotiation.
        payment_handlers:
          type: object
          propertyNames:
            type: string
            pattern: ^[a-z](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9_])?)+$
          additionalProperties:
            type: array
            maxItems: 50
            items:
              $ref: "#/components/schemas/UcpPaymentHandlerReference"
    UcpCheckoutTotal:
      type: object
      additionalProperties: true
      required:
        - type
        - amount
      properties:
        type:
          type: string
          minLength: 1
          maxLength: 120
        amount:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: ISO 4217 minor units.
        display_text:
          type: string
          minLength: 1
          maxLength: 200
      allOf:
        - if:
            required:
              - type
            properties:
              type:
                enum:
                  - discount
                  - items_discount
          then:
            properties:
              amount:
                maximum: -1
        - if:
            required:
              - type
            properties:
              type:
                enum:
                  - subtotal
                  - fulfillment
                  - tax
                  - fee
          then:
            properties:
              amount:
                minimum: 0
        - if:
            required:
              - type
            properties:
              type:
                not:
                  enum:
                    - subtotal
                    - items_discount
                    - discount
                    - fulfillment
                    - tax
                    - fee
                    - total
          then:
            required:
              - display_text
    UcpCheckoutLineItem:
      type: object
      additionalProperties: true
      required:
        - id
        - item
        - quantity
        - totals
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 200
        quantity:
          type: integer
          minimum: 1
          maximum: 9007199254740991
        item:
          type: object
          additionalProperties: true
          required:
            - id
            - title
            - price
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 200
            title:
              type: string
              minLength: 1
              maxLength: 400
            price:
              type: integer
              minimum: 0
              maximum: 9007199254740991
              description: ISO 4217 minor units.
        totals:
          type: array
          maxItems: 50
          items:
            $ref: "#/components/schemas/UcpCheckoutTotal"
    UcpCheckoutLink:
      type: object
      additionalProperties: true
      required:
        - type
        - url
      properties:
        type:
          type: string
          minLength: 1
          maxLength: 120
        url:
          type: string
          format: uri
          maxLength: 2000
        title:
          type: string
          maxLength: 400
    UcpCheckoutSession:
      type: object
      additionalProperties: true
      description: Validated core checkout response plus any negotiated extensions. The seven top-level required members are common to UCP 2026-04-08 and 2026-08-25; the version conditional below additionally requires the August response payment-handler registry.
      required:
        - ucp
        - id
        - line_items
        - status
        - currency
        - totals
        - links
      properties:
        ucp:
          $ref: "#/components/schemas/UcpCheckoutEnvelope"
        id:
          type: string
          minLength: 1
          maxLength: 200
        line_items:
          type: array
          maxItems: 500
          items:
            $ref: "#/components/schemas/UcpCheckoutLineItem"
        status:
          type: string
          enum:
            - incomplete
            - requires_escalation
            - ready_for_complete
            - complete_in_progress
            - completed
            - canceled
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          description: ISO 4217 List One code with a numeric minor unit, pinned to the maintenance-agency list published 2026-01-01. Unknown codes and entries whose minor unit is N.A. are rejected before evaluation.
        totals:
          type: array
          minItems: 2
          maxItems: 50
          items:
            $ref: "#/components/schemas/UcpCheckoutTotal"
          allOf:
            - contains:
                type: object
                required:
                  - type
                properties:
                  type:
                    const: subtotal
              minContains: 1
              maxContains: 1
            - contains:
                type: object
                required:
                  - type
                properties:
                  type:
                    const: total
              minContains: 1
              maxContains: 1
        links:
          type: array
          maxItems: 100
          items:
            $ref: "#/components/schemas/UcpCheckoutLink"
        signals:
          type: object
          additionalProperties: true
        ap2:
          type: object
          additionalProperties: true
          properties:
            checkout_mandate:
              type: string
              maxLength: 8192
            merchant_authorization:
              type: string
              maxLength: 8192
      allOf:
        - if:
            properties:
              ucp:
                type: object
                required:
                  - version
                properties:
                  version:
                    const: 2026-08-25
          then:
            properties:
              ucp:
                required:
                  - payment_handlers
    UcpCheckoutAuthorizeRequest:
      type: object
      additionalProperties: false
      required:
        - checkout
      properties:
        org_id:
          type: string
          format: uuid
          description: Optional when the authenticated API key is organization-bound.
        checkout:
          $ref: "#/components/schemas/UcpCheckoutSession"
        agent:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
              maxLength: 200
            human_present:
              type: boolean
            environment:
              type: string
              minLength: 1
              maxLength: 120
              pattern: ^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$
              description: Merchant execution environment committed into the signed downstream target, for example base-sepolia or production.
        approval_url:
          type: string
          format: uri
          pattern: ^https://(?![^/?#]*@)
          maxLength: 2000
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
          default: ENFORCEMENT
        grant_ttl_seconds:
          type: integer
          minimum: 1
          maximum: 300
        idempotency_key:
          type: string
          minLength: 1
          maxLength: 180
        degradation_mode:
          type: string
          enum:
            - fail_closed
          default: fail_closed
          description: Compatibility field. Execution authority always fails closed; caller-selected fail-open is rejected.
    UcpMandateVerification:
      type: object
      additionalProperties: false
      required:
        - verified
        - status
        - checked
        - not_checked
      properties:
        verified:
          type: boolean
          deprecated: true
          description: Compatibility rollup; use status to distinguish inapplicable from unverified.
        status:
          type: string
          enum:
            - VERIFIED
            - UNVERIFIED
            - NOT_APPLICABLE
        checked:
          type: array
          items:
            type: string
        not_checked:
          type: array
          items:
            type: string
    UcpExecutionGrant:
      type: object
      additionalProperties: false
      required:
        - token
        - jti
        - key_id
        - expires_at
        - intent_hash
        - execution_binding_digest
        - execution_correlation_id
        - claim_path
        - finalize_path
        - intent
      properties:
        token:
          type: string
        jti:
          type: string
        key_id:
          type: string
        expires_at:
          type: string
          format: date-time
        intent_hash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        execution_binding_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        execution_correlation_id:
          type: string
          minLength: 1
          maxLength: 200
        claim_path:
          type: string
          const: /v1/execution/claim-token
        finalize_path:
          type: string
          const: /v1/execution/finalize-token
        intent:
          $ref: "#/components/schemas/ExecutionIntentBinding"
    UcpExecutionAuthorityPayloadBase:
      type: object
      required:
        - decision
        - authoritative
        - evaluation_id
        - dossier_id
        - policy_version
        - dossier_sha256
        - reason_codes
        - required_presence
        - verification_url
        - evaluated_at
      properties:
        decision:
          type: string
          enum:
            - ALLOW
            - ESCALATE
            - BLOCK
        authoritative:
          type: boolean
          description: Legacy compatibility flag; authority_classification is normative in Protocol 1.1.
        evaluation_id:
          type: string
        dossier_id:
          type: string
        policy_version:
          type: string
        reason_codes:
          type: array
          items:
            type: string
        required_presence:
          type: boolean
        verification_url:
          type:
            - string
            - "null"
          format: uri
        evaluated_at:
          type: string
          format: date-time
    UcpExecutionAuthorityProtocol11Fields:
      type: object
      properties:
        authority_classification:
          $ref: "#/components/schemas/AuthorityClassification"
        evaluation_mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        execution_eligible:
          type: boolean
        policy_reference:
          $ref: "#/components/schemas/PolicyReference"
        evaluation_semantics:
          $ref: "#/components/schemas/EvaluationSemantics"
        input_snapshot_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        execution_binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
      allOf:
        - if:
            required:
              - authority_classification
            properties:
              authority_classification:
                const: OBSERVATIONAL
          then:
            properties:
              authoritative:
                const: false
              execution_eligible:
                const: false
              execution_binding_digest:
                const: null
        - if:
            required:
              - execution_eligible
            properties:
              execution_eligible:
                const: true
          then:
            required:
              - authority_classification
              - evaluation_mode
              - execution_binding_digest
            properties:
              decision:
                const: ALLOW
              authoritative:
                const: true
              authority_classification:
                const: AUTHORITATIVE
              evaluation_mode:
                const: ENFORCEMENT
              execution_binding_digest:
                type: string
                pattern: ^sha256:[0-9a-f]{64}$
        - if:
            required:
              - evaluation_mode
            properties:
              evaluation_mode:
                enum:
                  - SHADOW
                  - PARALLEL
          then:
            properties:
              authority_classification:
                const: OBSERVATIONAL
              execution_eligible:
                const: false
              execution_binding_digest:
                const: null
        - if:
            required:
              - evaluation_mode
            properties:
              evaluation_mode:
                const: ENFORCEMENT
          then:
            properties:
              authoritative:
                const: true
              authority_classification:
                const: AUTHORITATIVE
        - if:
            required:
              - execution_binding_digest
            properties:
              execution_binding_digest:
                type: string
          then:
            required:
              - execution_eligible
            properties:
              execution_eligible:
                const: true
        - if:
            required:
              - authoritative
            properties:
              authoritative:
                const: false
          then:
            properties:
              authority_classification:
                const: OBSERVATIONAL
              execution_eligible:
                const: false
              execution_binding_digest:
                const: null
    UcpExecutionAuthorityPayloadLegacy:
      description: Exact response projection for extension 2026-09-05.
      unevaluatedProperties: false
      allOf:
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadBase"
        - type: object
          properties:
            dossier_sha256:
              type:
                - string
                - "null"
              pattern: ^[0-9a-f]{64}$
    UcpExecutionAuthorityPayloadPrevious:
      description: Additive Protocol 1.1 response projection for extension 2026-09-06.
      unevaluatedProperties: false
      allOf:
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadBase"
        - $ref: "#/components/schemas/UcpExecutionAuthorityProtocol11Fields"
        - type: object
          properties:
            dossier_sha256:
              type:
                - string
                - "null"
              pattern: ^(?:sha256:)?[0-9a-f]{64}$
    UcpExecutionAuthorityPayloadCurrent:
      description: Strict Protocol 1.1 response projection for extension 2026-09-07.
      unevaluatedProperties: false
      allOf:
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadBase"
        - $ref: "#/components/schemas/UcpExecutionAuthorityProtocol11Fields"
        - type: object
          required:
            - authority_classification
            - evaluation_mode
            - execution_eligible
            - policy_reference
            - evaluation_semantics
            - input_snapshot_digest
            - execution_binding_digest
          properties:
            dossier_sha256:
              type:
                - string
                - "null"
              pattern: ^sha256:[0-9a-f]{64}$
    UcpExecutionAuthorityPayload:
      description: Version-dispatched response union. The exact negotiated extension release determines which immutable member schema applies; this union preserves historical 2026-09-05 and additive 2026-09-06 responses while making 2026-09-07 Protocol 1.1 evidence strict.
      anyOf:
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadLegacy"
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadPrevious"
        - $ref: "#/components/schemas/UcpExecutionAuthorityPayloadCurrent"
    UcpCheckoutAuthorizeResponse:
      type: object
      additionalProperties: true
      required:
        - service
        - ucp
      properties:
        service:
          type: string
          const: decionis
        ucp:
          type: object
          additionalProperties: true
          required:
            - version
            - status
          properties:
            version:
              $ref: "#/components/schemas/UcpProtocolVersion"
            status:
              type: string
              enum:
                - success
                - error
        checkout_id:
          type: string
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        enforcing:
          type: boolean
        authority_classification:
          $ref: "#/components/schemas/AuthorityClassification"
        evaluation_mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
          description: Present on some fail-closed evidence errors; normal results use mode.
        execution_eligible:
          type: boolean
          description: True only for an AUTHORITATIVE ALLOW carrying an exact-action execution grant. Signature validity alone does not make a response execution-eligible.
        dossier_id:
          type:
            - string
            - "null"
        status:
          type:
            - string
            - "null"
        continue_url:
          type: string
          format: uri
        error:
          type: object
          additionalProperties: true
        actions:
          $ref: "#/components/schemas/UcpActions"
        messages:
          type: array
          items:
            $ref: "#/components/schemas/UcpMessage"
        fallback:
          $ref: "#/components/schemas/UcpAuthorityFallback"
        com.decionis.commerce.execution_authority:
          $ref: "#/components/schemas/UcpExecutionAuthorityPayload"
        verification:
          $ref: "#/components/schemas/UcpMandateVerification"
        escalation:
          type:
            - object
            - "null"
          additionalProperties: false
          required:
            - override_id
          properties:
            override_id:
              type: string
            status:
              type: string
              enum:
                - PENDING
                - APPROVED
                - REJECTED
                - CANCELLED
                - EXPIRED
        execution_grant:
          oneOf:
            - $ref: "#/components/schemas/UcpExecutionGrant"
            - type: "null"
        requires_human_approval:
          type: boolean
        reason_codes:
          type: array
          items:
            type: string
    UcpAuthorityReviewActionConfig:
      type: object
      additionalProperties: false
      required:
        - continue_url
      properties:
        continue_url:
          type: string
          format: uri
          pattern: ^https://(?![^/?#]*@)
          maxLength: 2000
        reason_codes:
          type: array
          maxItems: 100
          items:
            type: string
            minLength: 1
            maxLength: 500
        expires_at:
          type: string
          format: date-time
    UcpAuthorityReviewAction:
      type: object
      additionalProperties: false
      required:
        - id
        - config
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 500
        config:
          $ref: "#/components/schemas/UcpAuthorityReviewActionConfig"
    UcpActions:
      type: object
      additionalProperties: false
      required:
        - com.decionis.authority.review
      properties:
        com.decionis.authority.review:
          type: array
          minItems: 1
          maxItems: 1
          items:
            $ref: "#/components/schemas/UcpAuthorityReviewAction"
    UcpMessage:
      type: object
      additionalProperties: true
      required:
        - type
        - content_type
        - content
      properties:
        type:
          type: string
          enum:
            - info
            - warning
            - error
        content_type:
          type: string
          enum:
            - plain
            - markdown
        content:
          type: string
          minLength: 1
    UcpAuthorityFallback:
      type: object
      additionalProperties: false
      required:
        - degraded
        - mode
        - reason
        - circuit_open
      properties:
        degraded:
          type: boolean
          not:
            const: false
        mode:
          type: string
          enum:
            - fail_closed
        reason:
          type: string
        circuit_open:
          type: boolean
    UcpPublicEcJwk:
      type: object
      additionalProperties: false
      required:
        - kty
        - crv
        - x
        - y
      properties:
        kty:
          type: string
          const: EC
        crv:
          type: string
          enum:
            - P-256
            - P-384
            - P-521
        x:
          type: string
          minLength: 1
          maxLength: 512
        y:
          type: string
          minLength: 1
          maxLength: 512
        kid:
          type: string
          minLength: 1
          maxLength: 200
        alg:
          type: string
          enum:
            - ES256
            - ES384
            - ES512
        use:
          type: string
          maxLength: 20
    UcpSigningKeyRegistrationRequest:
      type: object
      additionalProperties: false
      required:
        - kid
        - algorithm
        - public_jwk
      properties:
        org_id:
          type: string
          format: uuid
        kid:
          type: string
          minLength: 1
          maxLength: 200
        algorithm:
          type: string
          enum:
            - ES256
            - ES384
            - ES512
        public_jwk:
          $ref: "#/components/schemas/UcpPublicEcJwk"
        label:
          type: string
          maxLength: 200
    UcpSigningKey:
      type: object
      additionalProperties: false
      required:
        - kid
        - algorithm
        - label
        - created_at
      properties:
        service:
          type: string
          const: decionis
        kid:
          type: string
        algorithm:
          type: string
          enum:
            - ES256
            - ES384
            - ES512
        label:
          type:
            - string
            - "null"
        created_at:
          type: string
          format: date-time
        revoked_at:
          type:
            - string
            - "null"
          format: date-time
    UcpSigningKeyListResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - keys
      properties:
        service:
          type: string
          const: decionis
        keys:
          type: array
          items:
            $ref: "#/components/schemas/UcpSigningKey"
    UcpSigningKeyRevocationResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - kid
        - revoked
      properties:
        service:
          type: string
          const: decionis
        kid:
          type: string
        revoked:
          type: boolean
          not:
            const: false
    ExecutionProviderPublicOkpJwk:
      type: object
      additionalProperties: false
      required:
        - kty
        - crv
        - x
      description: The public half of an Ed25519 key. A `d` member is rejected.
      properties:
        kty:
          type: string
          const: OKP
        crv:
          type: string
          const: Ed25519
        x:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
        kid:
          type: string
          minLength: 1
          maxLength: 200
        alg:
          type: string
          const: EdDSA
        use:
          type: string
          const: sig
    ExecutionProviderKeyRegistrationRequest:
      type: object
      additionalProperties: false
      required:
        - kid
        - issuer
        - algorithm
        - public_jwk
      properties:
        org_id:
          type: string
          format: uuid
          description: Optional when the authenticated API key is already bound to an organization.
        kid:
          type: string
          minLength: 1
          maxLength: 200
          description: The `kid` the provider puts in its receipts' protected header.
        issuer:
          type: string
          minLength: 1
          maxLength: 500
          description: The `iss` the provider puts in its receipts or attestations; one under this key with another issuer does not verify.
        algorithm:
          type: string
          const: EdDSA
        public_jwk:
          $ref: "#/components/schemas/ExecutionProviderPublicOkpJwk"
        label:
          type: string
          maxLength: 200
        purpose:
          $ref: "#/components/schemas/ExecutionProviderKeyPurpose"
    ExecutionProviderKey:
      type: object
      additionalProperties: false
      required:
        - service
        - kid
        - issuer
        - algorithm
        - purpose
        - label
        - created_at
        - revoked_at
      properties:
        service:
          type: string
          const: decionis
        kid:
          type: string
        issuer:
          type: string
        algorithm:
          type: string
          const: EdDSA
        purpose:
          $ref: "#/components/schemas/ExecutionProviderKeyPurpose"
        label:
          type:
            - string
            - "null"
        created_at:
          type: string
          format: date-time
        revoked_at:
          type:
            - string
            - "null"
          format: date-time
    PresenceProviderDirectoryEntry:
      type: object
      additionalProperties: false
      required:
        - service
        - provider_id
        - display_name
        - issuer
        - jwks_url
        - methods
        - revoked_at
      properties:
        service:
          type: string
          const: decionis
        provider_id:
          type: string
          pattern: ^[a-z][a-z0-9_.:-]{0,63}$
          description: The id a policy names in verification_requirements.provider.
        display_name:
          type: string
          maxLength: 120
        issuer:
          type: string
          maxLength: 100
          description: The `iss` the provider writes into its attestations.
        jwks_url:
          type: string
          format: uri
          description: Where the provider publishes its Ed25519 public keys; https only.
        methods:
          type: array
          items:
            type: string
            enum:
              - CARD_TAP
        revoked_at:
          type:
            - string
            - "null"
          format: date-time
    PresenceProviderDirectory:
      type: object
      additionalProperties: false
      required:
        - service
        - providers
      properties:
        service:
          type: string
          const: decionis
        providers:
          type: array
          items:
            $ref: "#/components/schemas/PresenceProviderDirectoryEntry"
    PresenceProviderAdmission:
      type: object
      additionalProperties: false
      required:
        - service
        - provider_id
        - display_name
        - issuer
        - methods
        - admitted_at
        - revoked_at
        - provider_revoked_at
      properties:
        service:
          type: string
          const: decionis
        provider_id:
          type: string
        display_name:
          type: string
        issuer:
          type: string
        methods:
          type: array
          items:
            type: string
            enum:
              - CARD_TAP
        admitted_at:
          type: string
          format: date-time
        revoked_at:
          type:
            - string
            - "null"
          format: date-time
        provider_revoked_at:
          type:
            - string
            - "null"
          format: date-time
          description: Set when Decionis retired the provider from the directory, whatever the admission says.
    PresenceProviderAdmissionList:
      type: object
      additionalProperties: false
      required:
        - service
        - admissions
      properties:
        service:
          type: string
          const: decionis
        admissions:
          type: array
          items:
            $ref: "#/components/schemas/PresenceProviderAdmission"
    ExecutionProviderKeyPurpose:
      type: string
      enum:
        - effect_receipt
        - presence_attestation
        - usage_report
        - signed_signal
      default: effect_receipt
      description: "What the key verifies. A key is only ever used for its own purpose. `usage_report`: an edge installation's monthly usage reports (`POST /v1/edge/usage-reports`); register it with the installation id as `issuer`, which the reports name as `iss`. `signed_signal`: a producer's signed standing signals (`evidence.signals` on enforce-and-bind); register it with the producer id as `issuer`, which the signals name as `iss`."
    ExecutionProviderKeyListResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - keys
      properties:
        service:
          type: string
          const: decionis
        keys:
          type: array
          items:
            $ref: "#/components/schemas/ExecutionProviderKey"
    ExecutionProviderKeyRevocationResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - kid
        - revoked
      properties:
        service:
          type: string
          const: decionis
        kid:
          type: string
        revoked:
          type: boolean
          not:
            const: false
    GovernedPlan:
      type: object
      additionalProperties: false
      description: |
        `agent-safe.plan/1`, as AgentSafe defines it (ADR 0008): its digest is
        SHA-256 over the plan's RFC 8785 form. Edges join known, distinct steps
        once and form no cycle; a compensation step stands outside the edges and
        compensates ordinary steps only.
      required:
        - version
        - plan_id
        - tenant_id
        - steps
        - edges
        - partial_commit
      properties:
        version:
          type: string
          const: agent-safe.plan/1
        plan_id:
          type: string
          minLength: 1
          maxLength: 128
          pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]*$
        tenant_id:
          type: string
          format: uuid
        steps:
          type: array
          minItems: 1
          maxItems: 32
          items:
            $ref: "#/components/schemas/GovernedPlanStep"
        edges:
          type: array
          maxItems: 64
          items:
            $ref: "#/components/schemas/GovernedPlanEdge"
        partial_commit:
          type: object
          additionalProperties: false
          description: |
            What stays admissible once a step has FAILED: the listed steps, if
            their edges allow it; every other remaining step takes `otherwise`.
          required:
            - admissible
            - otherwise
          properties:
            admissible:
              type: array
              maxItems: 32
              items:
                $ref: "#/components/schemas/GovernedPlanStepId"
            otherwise:
              type: string
              enum:
                - ESCALATE
                - BLOCK
    GovernedPlanStepId:
      type: string
      minLength: 1
      maxLength: 64
      pattern: ^[a-z][a-z0-9_-]*$
    GovernedPlanStep:
      type: object
      additionalProperties: false
      required:
        - step_id
        - action
        - target
      properties:
        step_id:
          $ref: "#/components/schemas/GovernedPlanStepId"
        action:
          type: string
          minLength: 1
          maxLength: 120
          pattern: ^[a-z][a-z0-9._:-]*$
        target:
          type: string
          minLength: 1
          maxLength: 500
          description: An exact resource, or a prefix followed by one trailing `*`.
        parameters:
          type: object
          additionalProperties: true
          description: Parameters the step pins; each must equal the intent's, canonically.
        compensates:
          type: array
          minItems: 1
          maxItems: 8
          description: |
            Present only on a compensation step: it is admissible only after one
            of these steps FAILED, and never otherwise. It still needs its own
            grant.
          items:
            $ref: "#/components/schemas/GovernedPlanStepId"
    GovernedPlanEdge:
      type: object
      additionalProperties: false
      description: |
        `to` depends on `from`. `ordered`: `to` waits for `from` to commit with
        a confirmed effect, and is refused after it failed. `all_or_escalate`:
        the same wait, and a person decides after it failed. `independent`:
        `from`'s outcome changes nothing for `to`.
      required:
        - from
        - to
        - coupling
      properties:
        from:
          $ref: "#/components/schemas/GovernedPlanStepId"
        to:
          $ref: "#/components/schemas/GovernedPlanStepId"
        coupling:
          type: string
          enum:
            - independent
            - ordered
            - all_or_escalate
    GovernedPlanRegistration:
      type: object
      additionalProperties: false
      required:
        - plan_id
        - plan_digest
        - registered_at
        - authorizes
      properties:
        plan_id:
          type: string
        plan_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        registered_at:
          type: string
          format: date-time
        authorizes:
          type: string
          const: NOTHING
          description: Registering a plan grants no step; each is decided and granted on its own.
    GovernedPlanStatus:
      type: object
      additionalProperties: false
      required:
        - plan_id
        - plan_digest
        - registered_at
        - state
        - scitt_outcome_state
        - steps
        - plan
      properties:
        plan_id:
          type: string
        plan_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        registered_at:
          type: string
          format: date-time
        state:
          type: string
          enum:
            - ACTIVE
            - PARTIAL
            - SUSPENDED
            - COMPLETE
        scitt_outcome_state:
          type:
            - string
            - "null"
          enum:
            - partially_completed
            - pending_confirmation
            - completed
            - null
        steps:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - step_id
              - status
            properties:
              step_id:
                $ref: "#/components/schemas/GovernedPlanStepId"
              status:
                type: string
                enum:
                  - PENDING
                  - IN_FLIGHT
                  - COMMITTED
                  - UNCONFIRMED
                  - INDETERMINATE
                  - FAILED
        plan:
          $ref: "#/components/schemas/GovernedPlan"
    AuthorityAllowanceKey:
      type: string
      description: The name a policy rule's `then.allowance.key` draws on, unique within the organisation.
      pattern: ^[a-z0-9][a-z0-9._:-]{0,127}$
    AuthorityAllowanceRequest:
      type: object
      additionalProperties: false
      required:
        - unit
        - limit
        - window_seconds
      properties:
        unit:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]*$
          description: What one unit counts (replicas, deployments, USD_minor); a label only.
        limit:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: The most the allowance admits across its window.
        window_seconds:
          type:
            - integer
            - "null"
          minimum: 60
          maximum: 31536000
          description: "A rolling window over which committed draws count. Null means no window: a committed draw counts until the limit is raised past it."
        description:
          type:
            - string
            - "null"
          maxLength: 500
    AuthorityAllowanceUsage:
      type: object
      additionalProperties: false
      required:
        - reserved
        - held
        - consumed
        - available
      properties:
        reserved:
          type: integer
          minimum: 0
          description: Reserved by grants not yet claimed and not yet expired.
        held:
          type: integer
          minimum: 0
          description: Held by claims whose outcome is open (CLAIMED) or unknown (INDETERMINATE).
        consumed:
          type: integer
          minimum: 0
          description: Kept by committed claims within the window.
        available:
          type: integer
          minimum: 0
          description: The limit less reserved, held and consumed; never below zero.
    AuthorityAllowance:
      type: object
      additionalProperties: false
      required:
        - service
        - allowance_key
        - unit
        - limit
        - window_seconds
        - description
        - usage
        - created_at
        - updated_at
      properties:
        service:
          type: string
          const: decionis
        allowance_key:
          $ref: "#/components/schemas/AuthorityAllowanceKey"
        unit:
          type: string
        limit:
          type: integer
          minimum: 0
        window_seconds:
          type:
            - integer
            - "null"
        description:
          type:
            - string
            - "null"
        usage:
          $ref: "#/components/schemas/AuthorityAllowanceUsage"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    AuthorityAllowanceListResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - allowances
      properties:
        service:
          type: string
          const: decionis
        allowances:
          type: array
          items:
            $ref: "#/components/schemas/AuthorityAllowance"
    DecisionStatus:
      type: string
      enum:
        - ALLOW
        - BLOCK
        - ESCALATE
        - REVIEW_REQUIRED
        - ERROR
    Actor:
      type: object
      required:
        - id
        - type
      properties:
        id:
          type: string
        type:
          type: string
          examples:
            - AI_AGENT
            - TRADING_BOT
            - HUMAN
            - SERVICE
        role:
          type: string
      additionalProperties: true
    Action:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          examples:
            - TRANSFER_FUNDS
            - OPEN_POSITION
        resource:
          type: string
      additionalProperties: true
    DecisionRequest:
      type: object
      required:
        - tenant_id
        - actor
        - action
      properties:
        tenant_id:
          type: string
        actor:
          $ref: "#/components/schemas/Actor"
        action:
          $ref: "#/components/schemas/Action"
        context:
          type: object
          additionalProperties: true
          properties:
            signals:
              type: object
              additionalProperties: true
              description: |
                Signal values may be existing scalars, legacy
                `{value, source?, observed_at?}` envelopes, or a strict
                SemanticSignalEnvelope. Typed values are digest-checked and
                admitted by the selected policy bundle before rules can use them.
        policy_refs:
          type: array
          items:
            type: string
        idempotency_key:
          type: string
        correlation_id:
          type: string
        shadow_mode:
          type: boolean
          default: false
        enforcement_mode:
          type: string
          enum:
            - enforce
            - shadow
            - dry_run
          default: enforce
      additionalProperties: true
    ExecutionIntentActor:
      type: object
      additionalProperties: false
      required:
        - id
        - type
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 200
        type:
          type: string
          minLength: 1
          maxLength: 200
        runtime:
          type: string
          minLength: 1
          maxLength: 200
        trust_level:
          type: string
          minLength: 1
          maxLength: 80
    ExecutionIntentAction:
      type: object
      additionalProperties: false
      required:
        - type
        - resource
        - parameters
      properties:
        type:
          type: string
          minLength: 1
          maxLength: 120
          pattern: ^[a-z][a-z0-9._:-]*$
        resource:
          type: string
          minLength: 1
          maxLength: 500
        parameters:
          type: object
          additionalProperties: true
    ExecutionDownstreamTarget:
      type: object
      additionalProperties: false
      required:
        - system
        - operation
      properties:
        system:
          type: string
          minLength: 1
          maxLength: 200
        operation:
          type: string
          minLength: 1
          maxLength: 200
        environment:
          type: string
          minLength: 1
          maxLength: 200
          default: production
        endpoint:
          type: string
          minLength: 1
          maxLength: 500
    ExecutionPolicyProjection:
      type: object
      additionalProperties: false
      required:
        - decision_type
        - transaction_type
        - workflow_key
        - channel
      description: Exact policy-routing vocabulary committed into the intent. Protocol adapters use it when their evaluated decision type differs from the executable action type; legacy generic callers may omit it.
      properties:
        decision_type:
          type: string
          minLength: 1
          maxLength: 120
        transaction_type:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 120
        workflow_key:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 120
        channel:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 120
    ExecutionIntentBindingBase:
      type: object
      required:
        - protocol_version
        - tenant_id
        - intent_id
        - captured_at
        - expires_at
        - actor
        - action
        - context
        - downstream_target
      properties:
        protocol_version:
          type: string
          const: agent-safe.intent/1
        tenant_id:
          type: string
          format: uuid
        intent_id:
          type: string
          format: uuid
        captured_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
          description: Must be later than captured_at and no more than five minutes after it.
        actor:
          $ref: "#/components/schemas/ExecutionIntentActor"
        action:
          $ref: "#/components/schemas/ExecutionIntentAction"
        context:
          type: object
          additionalProperties: true
          description: The trusted runtime's context, entirely inside the canonical intent hash. Open by design, with four reserved keys. `idempotency_key` is required and carries the retry identity. `enforcement_boundary` and `workload` are what an enforcement boundary reports about itself and about the software that proposed the action; each is validated against its schema when present, and an absent signal is an answer rather than a placeholder, so a policy that requires provenance refuses on its absence. `agent_safe` is what the runtime states about the action's own circumstances; Decionis reads only the sub-keys named here, each validated when present, into the facts it writes under the same name. `runtime_attribution` is reserved for Decionis, which computes it from those reports, and a request that supplies it is refused.
          properties:
            enforcement_boundary:
              $ref: "#/components/schemas/EnforcementBoundarySignal"
            workload:
              $ref: "#/components/schemas/WorkloadSignal"
            agent_safe:
              type: object
              additionalProperties: true
              properties:
                precondition:
                  $ref: "#/components/schemas/ExecutionTargetPrecondition"
        downstream_target:
          $ref: "#/components/schemas/ExecutionDownstreamTarget"
        policy_projection:
          $ref: "#/components/schemas/ExecutionPolicyProjection"
        expected_effect_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
          description: "Digest-only commitment to the expected downstream state. Part of the hashed intent, so the authority never adds one. A Protocol 1.1 grant bound without it accepts no effect evidence at finalization or reconciliation (EFFECT_EXPECTED_BINDING_UNAVAILABLE), and the grant is issued with `x-decionis-warning: EXPECTED_EFFECT_DIGEST_MISSING`."
    EnforcementBoundarySignal:
      type: object
      additionalProperties: false
      required:
        - boundary_id
        - agentsafe_version
        - protocol_version
        - deployment_type
      description: "Which enforcement boundary admitted the intent. The identity is of the configured logical boundary, not of the process running it: a restart, a rescheduling or a scale-out leaves it unchanged, and the container, pod and node are deliberately absent, so an effect's evidence names the door rather than whichever instance was alive at the time."
      properties:
        boundary_id:
          type: string
          maxLength: 200
          description: What the operator calls this boundary, or a stable id derived from its configuration.
        agentsafe_version:
          type: string
          maxLength: 80
        protocol_version:
          type: string
          const: agent-safe.intent/1
        deployment_type:
          type: string
          maxLength: 200
          description: What the boundary was installed as, for example docker, kubernetes or linux.
        environment:
          type: string
          maxLength: 200
        conformance_version:
          type: string
          maxLength: 120
        placement:
          type: object
          additionalProperties: false
          description: Stable placement only. It survives a restart and is what a policy means by an environment and a region.
          properties:
            cluster_id:
              type: string
              maxLength: 200
            namespace:
              type: string
              maxLength: 200
            region:
              type: string
              maxLength: 200
            workload_id:
              type: string
              maxLength: 200
    WorkloadSignal:
      type: object
      additionalProperties: false
      required:
        - provenance
      description: "What software proposed the action, as a runtime reported it. Decionis records the report and does not establish it: image digests, provenance attestations and publisher verification belong to the container and OCI tooling that produced them. Every field is optional but `provenance`, because a workload cannot be expressed without saying who reported it and how far that report goes."
      properties:
        runtime:
          type: string
          maxLength: 200
        artifact_type:
          type: string
          maxLength: 200
        image:
          type: string
          maxLength: 500
        digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        publisher:
          type: string
          maxLength: 200
        provenance:
          type: object
          additionalProperties: false
          required:
            - source
            - trust_level
          properties:
            source:
              type: string
              maxLength: 200
              description: Who reported it, for example docker, kubernetes or operator.
            trust_level:
              type: string
              enum:
                - unverified
                - supplied
                - observed
                - verified
              description: "How far the producer said its report goes. It is the producer's claim, recorded as such: Decionis neither raises nor lowers it. A policy that means the platform checked something matches on the decision's `runtime_attribution.platform_verified` instead, which Decionis computes and a caller cannot assert."
    ExecutionTargetPrecondition:
      type: object
      additionalProperties: false
      required:
        - version
        - source
        - read_at
      description: "The target's state as the trusted runtime read it immediately before asking: the version the decision is made against, inside the intent hash. Policy reads it as `agent_safe.precondition` (a transition rule reads its `state`), the grant binds `version` as `binding.expected_state_version`, and the claim's attestation carries it to a verifying provider, which effects only while the target is still at that version and otherwise refuses `TARGET_STATE_CHANGED`. Revalidation at the claim catches a policy or a signal that changed; this catches a target that changed underneath an unchanged policy. A malformed precondition is refused with `INTENT_PRECONDITION_INVALID`."
      properties:
        version:
          type: string
          pattern: ^[\x21-\x7e]{1,256}$
          description: "Opaque, compared byte for byte, as a strong `If-Match` compares: an entity tag keeps its quotes and its `W/`, a resource version is its decimal string."
        state:
          type: string
          minLength: 1
          maxLength: 200
          description: The target's state as the read named it, when it names one.
        source:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[a-zA-Z0-9][a-zA-Z0-9_.:/#-]*$
          description: "Which read produced it: `<profile>#<operation>` for an API profile, or the executor's own name for its read."
        read_at:
          type: string
          format: date-time
    ExecutionIntentBinding:
      unevaluatedProperties: false
      allOf:
        - $ref: "#/components/schemas/ExecutionIntentBindingBase"
    PresenceHumanApprovalEvidence:
      type: object
      additionalProperties: false
      required:
        - provider
        - requestId
        - receiptDossierId
      properties:
        provider:
          type: string
          const: presence
        requestId:
          type: string
          maxLength: 200
        receiptDossierId:
          type: string
          maxLength: 200
    AttestedHumanApprovalEvidence:
      type: object
      additionalProperties: false
      description: A presence provider's signed attestation that a person was present for this exact intent (for example, the cardholder tapping their own card), as a compact JWS whose payload is PresenceAttestationClaims.
      required:
        - provider
        - attestation
      properties:
        provider:
          type: string
          const: attestation
        attestation:
          type: string
          minLength: 1
          maxLength: 20000
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
    HumanApprovalEvidence:
      description: A Presence receipt (bank-designated roles, verified with Presence) or a presence provider's attestation (verified against the key the organisation registered for it). Either is evidence for a fresh policy evaluation, never authority by itself.
      oneOf:
        - $ref: "#/components/schemas/PresenceHumanApprovalEvidence"
        - $ref: "#/components/schemas/AttestedHumanApprovalEvidence"
      discriminator:
        propertyName: provider
        mapping:
          presence: "#/components/schemas/PresenceHumanApprovalEvidence"
          attestation: "#/components/schemas/AttestedHumanApprovalEvidence"
    PresenceAttestationRefusal:
      type: object
      additionalProperties: false
      description: A presence attestation that did not verify; no evaluation ran.
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - PRESENCE_ATTESTATION_MALFORMED
            - PRESENCE_ATTESTATION_KEY_UNKNOWN
            - PRESENCE_ATTESTATION_SIGNATURE_INVALID
            - PRESENCE_ATTESTATION_EXPIRED
            - PRESENCE_ATTESTATION_AUDIENCE_MISMATCH
            - PRESENCE_ATTESTATION_INTENT_MISMATCH
            - PRESENCE_ATTESTATION_ISSUER_MISMATCH
            - PRESENCE_ATTESTATION_NOT_VERIFIED
    SignedSignalEvidence:
      type: object
      additionalProperties: false
      description: A producer's signed standing signal about the subject (for example, the cardholder's Tap to Authenticate granting an agent permission to buy on their behalf, within limits, until a date), as a compact JWS whose payload is SignedSignalClaims.
      required:
        - token
      properties:
        token:
          type: string
          minLength: 1
          maxLength: 20000
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
    SignedSignalRefusal:
      type: object
      additionalProperties: false
      description: A signed signal that did not verify; no evaluation ran and no event fired.
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - SIGNED_SIGNAL_MALFORMED
            - SIGNED_SIGNAL_KEY_UNKNOWN
            - SIGNED_SIGNAL_SIGNATURE_INVALID
            - SIGNED_SIGNAL_EXPIRED
            - SIGNED_SIGNAL_AUDIENCE_MISMATCH
            - SIGNED_SIGNAL_ISSUER_MISMATCH
            - SIGNED_SIGNAL_NOT_VERIFIED
            - SIGNED_SIGNAL_DUPLICATE_NAME
    ManagedEscalationApproverConstraints:
      type: object
      additionalProperties: false
      properties:
        principal_id:
          type: string
          minLength: 1
          maxLength: 200
        role_id:
          type: string
          pattern: ^[A-Z][A-Z0-9_]{1,63}$
      anyOf:
        - required:
            - principal_id
        - required:
            - role_id
      description: Optional narrowing constraints. These values do not assign a role; effective identity and role are resolved from trusted tenant identity configuration and verified Presence evidence.
    ManagedEscalationVerificationRequirements:
      type: object
      additionalProperties: false
      required:
        - methods
      properties:
        methods:
          type: array
          minItems: 1
          maxItems: 3
          uniqueItems: true
          items:
            type: string
            enum:
              - WEBAUTHN
              - ACTIVE_LIVENESS
        level:
          type: string
          enum:
            - STANDARD
            - HIGH_CONFIDENCE
      description: Optional equal-or-stronger constraints applied to the policy-issued AuthorityRequirement. They can never downgrade policy requirements.
    ManagedEscalationRequest:
      type: object
      additionalProperties: false
      required:
        - mode
      properties:
        mode:
          type: string
          const: MANAGED
        approver:
          $ref: "#/components/schemas/ManagedEscalationApproverConstraints"
        verification_requirements:
          $ref: "#/components/schemas/ManagedEscalationVerificationRequirements"
      description: Requests Decionis-owned Presence orchestration. This object is outside the canonical ExecutionIntentBinding hash and is included in request replay validation. It is valid only in ENFORCEMENT mode.
    ManagedEscalationLifecycleStatus:
      type: string
      enum:
        - PENDING_PRESENCE
        - PRESENCE_REQUESTED
        - AWAITING_APPROVER
        - PRESENCE_VERIFIED
        - REAUTHORIZING
        - GRANT_READY
        - EXPIRED
        - REJECTED
        - BLOCKED
        - CANCELLED
        - FAILED
    ManagedEscalationOutcome:
      type: string
      enum:
        - ESCALATE_PENDING
        - ALLOW
        - BLOCK
        - ERROR
    ManagedEscalationReference:
      type: object
      additionalProperties: false
      required:
        - outcome
        - escalation_id
        - intent_id
        - status
        - expires_at
        - reason_codes
      properties:
        outcome:
          $ref: "#/components/schemas/ManagedEscalationOutcome"
        escalation_id:
          type: string
          minLength: 8
          maxLength: 200
        intent_id:
          type: string
          format: uuid
        status:
          $ref: "#/components/schemas/ManagedEscalationLifecycleStatus"
        expires_at:
          type: string
          format: date-time
        reason_codes:
          type: array
          maxItems: 50
          items:
            type: string
      description: Non-authorizing status locator. It is not an ExecutionBinding, claim token, invitation, or executable capability.
    ManagedEscalationStatus:
      type: object
      additionalProperties: false
      required:
        - escalation_id
        - intent_id
        - action_hash
        - status
        - outcome
        - expires_at
        - reason_codes
        - decision
      properties:
        escalation_id:
          type: string
          minLength: 8
          maxLength: 200
        intent_id:
          type: string
          format: uuid
        action_hash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        status:
          $ref: "#/components/schemas/ManagedEscalationLifecycleStatus"
        outcome:
          $ref: "#/components/schemas/ManagedEscalationOutcome"
        expires_at:
          type: string
          format: date-time
        reason_codes:
          type: array
          maxItems: 50
          items:
            type: string
        decision:
          oneOf:
            - $ref: "#/components/schemas/ExecutionAuthorityDecision"
            - type: "null"
    ManagedEscalationApproval:
      type: object
      additionalProperties: false
      required:
        - escalation_id
        - status
        - provider
        - authority_request_id
        - expires_at
      properties:
        escalation_id:
          type: string
          minLength: 8
          maxLength: 200
        status:
          $ref: "#/components/schemas/ManagedEscalationLifecycleStatus"
        provider:
          type: string
          enum:
            - presence
        authority_request_id:
          type:
            - string
            - "null"
          pattern: ^aur_[0-9a-f]{24}$
        expires_at:
          type: string
          format: date-time
    PresenceAuthorityCompletion:
      type: object
      additionalProperties: false
      required:
        - version
        - org_id
        - authority_request_id
        - source_decision_id
        - requirement_digest
        - action_digest
        - proof_digest
        - proof_dossier_id
        - verified_at
        - expires_at
      properties:
        version:
          type: string
          const: presence.authority_completion/1
        org_id:
          type: string
          format: uuid
        authority_request_id:
          type: string
          minLength: 8
          maxLength: 200
        source_decision_id:
          type: string
          minLength: 1
          maxLength: 200
        requirement_digest:
          type: string
          pattern: ^[0-9a-f]{64}$
        action_digest:
          type: string
          pattern: ^[0-9a-f]{64}$
        proof_digest:
          type: string
          pattern: ^[0-9a-f]{64}$
        proof_dossier_id:
          type: string
          minLength: 1
          maxLength: 200
        verified_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
    ExecutionAuthorityRequest:
      unevaluatedProperties: false
      allOf:
        - $ref: "#/components/schemas/ExecutionIntentBindingBase"
        - type: object
          required:
            - intent_hash
            - mode
          properties:
            intent_hash:
              type: string
              pattern: ^sha256:[0-9a-f]{64}$
              description: |
                SHA-256 of the UTF-8 canonical JSON ExecutionIntentBinding.
                Objects are recursively key-sorted using ECMAScript's default
                UTF-16 code-unit ordering and serialized with JSON.stringify semantics.
            mode:
              type: string
              enum:
                - SHADOW
                - PARALLEL
                - ENFORCEMENT
            escalation:
              $ref: "#/components/schemas/ManagedEscalationRequest"
            executor:
              $ref: "#/components/schemas/AuthorityExecutor"
            evidence:
              type: object
              additionalProperties: false
              properties:
                humanApproval:
                  $ref: "#/components/schemas/HumanApprovalEvidence"
                signals:
                  type: array
                  minItems: 1
                  maxItems: 8
                  description: Producers' signed standing signals about the subject, each verified against the producer's registered key (purpose `signed_signal`) or an admitted presence provider's JWKS, and written as facts under `agent_safe.signed_signals`. Bound to no intent; presented with or without a human approval, in any mode. Two under one `signal.name` are refused.
                  items:
                    $ref: "#/components/schemas/SignedSignalEvidence"
    ExecutionAuthorityDecision:
      type: object
      additionalProperties: false
      required:
        - decision_id
        - chain_id
        - status
        - should_execute
        - authority_classification
        - execution_eligible
        - execution_binding_digest
        - reason_codes
        - action_hash
        - policy_version
        - mode
        - execution_token
        - execution_token_jti
        - execution_token_key_id
        - execution_token_expires_at
        - dossier_id
        - dossier_sha256
        - dossier_url
        - approval_request_id
        - ledger_entry_id
      properties:
        decision_id:
          type: string
        chain_id:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - ALLOW
            - BLOCK
            - ESCALATE
            - REVIEW_REQUIRED
            - ERROR
        should_execute:
          type: boolean
        authority_classification:
          $ref: "#/components/schemas/AuthorityClassification"
        execution_eligible:
          type: boolean
          description: True only for an AUTHORITATIVE ALLOW carrying an exact-action ExecutionBinding and executable grant.
        execution_binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        reason_codes:
          type: array
          items:
            type: string
        action_hash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        policy_version:
          type:
            - string
            - "null"
        mode:
          type:
            - string
            - "null"
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
            - null
        execution_token:
          type:
            - string
            - "null"
          description: Present only when status is ALLOW and should_execute is true.
        execution_token_jti:
          type:
            - string
            - "null"
          description: Single-use identifier of the issued execution token.
        execution_token_key_id:
          type:
            - string
            - "null"
          description: Identifier of the key that signed the issued execution token.
        execution_token_expires_at:
          type:
            - string
            - "null"
          format: date-time
        dossier_id:
          type:
            - string
            - "null"
        dossier_sha256:
          type:
            - string
            - "null"
        dossier_url:
          type:
            - string
            - "null"
        approval_request_id:
          type:
            - string
            - "null"
        ledger_entry_id:
          type:
            - string
            - "null"
        managed_escalation:
          oneOf:
            - $ref: "#/components/schemas/ManagedEscalationReference"
            - type: "null"
        verification:
          $ref: "#/components/schemas/DecisionDossierVerificationEnvelope"
          description: Present only for a client that identifies itself as agent-safe-pipeline/0.2.0 or later, or as govern/2.0.0 or later; absent for every other client.
        escalation_requirement:
          $ref: "#/components/schemas/EscalationRequirement"
          description: Present only on an ESCALATE, and only for a client that identifies itself as agent-safe-pipeline/0.3.7 or later; absent for every other client. Routing, never authority.
        action_manifest_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
          description: "Present only for a client that identifies itself as agent-safe-pipeline/0.5.1 or later; absent for every other client, and when the release could not be read. The `actionManifestDigest` the signed policy release whose bundle decided records: the `agent-safe.actions/1` action space (ActionManifest) its assurance was checked against, as SHA-256 over its RFC 8785 form. Null when the deciding policy came from no governed release, or its release attached no action manifest. The runtime compares it with the digest of the action space it loaded and reports a difference. Never decision input, and never authority."
        permit_id:
          type: string
          format: uuid
          description: "Present only when the request named a `permit` executor and a grant was issued: the grant's jti (`execution_token_jti`), the `{grantId}` of `/v1/authority/grants/{grantId}`."
        intent_sha256:
          type: string
          pattern: ^[0-9a-f]{64}$
          description: "Present with `permit_id`: the intent hash (`action_hash`) as bare lowercase hex, written as `dossier_sha256` is."
        expires_at:
          type: string
          format: date-time
          description: "Present with `permit_id`: when the grant stops being claimable (`execution_token_expires_at`)."
    AuthorityExecutor:
      type: object
      additionalProperties: false
      required:
        - platform
        - style
        - version
      description: "Who will carry out a granted action, and how it takes authority: a `dispatch` executor presents the execution token at the claim; a `permit` executor runs inside a platform that holds a single-use permit and reports its own native receipt. Delivery information only: never part of the canonical intent, its hash, or the grant's binding, and it changes nothing about the decision."
      properties:
        platform:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z0-9][a-z0-9._-]*$
        style:
          type: string
          enum:
            - dispatch
            - permit
        version:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[0-9A-Za-z][0-9A-Za-z.+_-]*$
    EscalationRequirement:
      type: object
      additionalProperties: false
      description: "Where an ESCALATE goes: which authority the policy requires (its kind and role, never a person) and who proves that person, by which method. The runtime holding the intent hands the cardholder's tap to the provider named here and resumes with the attestation; a bank role goes to Decionis Presence. Only a fresh evaluation with the proof as evidence can turn the hold into a grant."
      required:
        - requirement_id
        - expires_at
        - selector
        - verification
      properties:
        requirement_id:
          type:
            - string
            - "null"
          description: The issued Presence requirement's id when one was issued (a managed escalation); null for a direct one.
        expires_at:
          type: string
          format: date-time
        selector:
          type:
            - object
            - "null"
          additionalProperties: false
          required:
            - kind
          properties:
            kind:
              type: string
              enum:
                - ROLE
                - PRINCIPAL
            role_id:
              type: string
        verification:
          type:
            - object
            - "null"
          additionalProperties: false
          required:
            - provider
            - methods
            - level
          properties:
            provider:
              type: string
              description: "`decionis` for Decionis Presence; otherwise the admitted presence provider's id."
            methods:
              type: array
              items:
                type: string
                enum:
                  - WEBAUTHN
                  - MOBILE_DEVICE
                  - ACTIVE_LIVENESS
                  - CARD_TAP
            level:
              type: string
              enum:
                - STANDARD
                - HIGH_CONFIDENCE
    DecisionDossierVerificationEnvelope:
      type: object
      description: "The share-safe way to verify a Decision Dossier without an account: a page and an API URL carrying an expiring share-link capability (`?sig=`, `&exp=`) that gates access, and the pointers to the Ed25519 proof that establishes authenticity. The capability is an access gate, never proof; the signatures in the proof bundle are the proof."
      required:
        - verification_page_url
        - verification_url
        - signature
      properties:
        verification_page_url:
          type: string
          format: uri
          description: The public page that runs the verification for anyone who opens it.
        verification_url:
          type: string
          format: uri
          description: The public verify route, `/v1/public/decision-dossiers/{dossier_id}/verify`, with its capability.
        verification_api_path:
          type: string
        signature:
          type: string
        signature_algorithm:
          type: string
          examples:
            - HMAC-SHA256
        signature_scheme:
          type: string
          enum:
            - hmac-v1
            - hmac-v2-org-scoped
        link_expires_at:
          type:
            - string
            - "null"
          format: date-time
        link_exp:
          type:
            - string
            - "null"
          description: The expiry in epoch seconds, as it appears in the link.
        asymmetric_proof:
          type:
            - object
            - "null"
          additionalProperties: true
        asymmetric_proof_bundle:
          type:
            - object
            - "null"
          additionalProperties: true
      additionalProperties: true
    ExecutionTokenRequest:
      type: object
      additionalProperties: false
      required:
        - execution_token
        - intent_hash
        - intent
      properties:
        execution_token:
          type: string
          minLength: 1
          maxLength: 20000
        intent_hash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        intent:
          $ref: "#/components/schemas/ExecutionIntentBinding"
        evidence:
          type: object
          additionalProperties: false
          description: Action-bound authority evidence presented again at the claim boundary. Required when the bound policy requires Presence. An attested approval is recorded in the signed binding and is not presented again; the claim re-checks that the attesting key is still registered and active. A signed signal is recorded the same way; the claim re-checks its key and that it has not expired.
          properties:
            humanApproval:
              $ref: "#/components/schemas/HumanApprovalEvidence"
        consumed_by:
          type: string
          minLength: 1
          maxLength: 200
        commit_correlation_id:
          type: string
          minLength: 1
          maxLength: 200
    ExecutionClaimTokenRequest:
      type: object
      additionalProperties: false
      required:
        - execution_token
        - intent_hash
        - intent
      properties:
        execution_token:
          type: string
          minLength: 1
          maxLength: 20000
        intent_hash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        intent:
          $ref: "#/components/schemas/ExecutionIntentBinding"
        consumed_by:
          type: string
          minLength: 1
          maxLength: 200
        commit_correlation_id:
          type: string
          minLength: 1
          maxLength: 200
        claim_lease_seconds:
          type: integer
          minimum: 5
          maximum: 300
          default: 30
          description: Pre-commit lease duration. This does not extend the signed execution grant lifetime.
    ExecutionTokenClaims:
      type: object
      additionalProperties: true
      required:
        - iss
        - org_id
        - dossier_id
        - decision_id
        - action
        - decision
        - scope
        - binding
        - jti
        - iat
        - nbf
        - exp
      properties:
        iss:
          type: string
        sub:
          type: string
        aud:
          type: string
        org_id:
          type: string
          format: uuid
        dossier_id:
          type: string
        decision_id:
          type: string
        chain_id:
          type: string
        action:
          type: string
        decision:
          type: string
          const: allow
        scope:
          type: string
          const: execute
        binding:
          type: object
          required:
            - intent_hash
          properties:
            intent_hash:
              type: string
              pattern: ^sha256:[0-9a-f]{64}$
            execution_binding_digest:
              type: string
              pattern: ^sha256:[0-9a-f]{64}$
            execution_payload_digest:
              type: string
              pattern: ^sha256:[0-9a-f]{64}$
              description: Signed digest of the exact downstream request parameters.
            execution_payload_canonicalization_profile:
              type: string
              description: Canonicalization profile used for execution_payload_digest.
            execution_nonce:
              type: string
              pattern: ^[A-Za-z0-9_-]{43,128}$
            execution_correlation_id:
              type: string
            expected_effect_digest:
              type: string
              pattern: ^sha256:[0-9a-f]{64}$
              description: Expected downstream effect commitment carried by the grant.
            expected_state_version:
              type: string
              pattern: ^[\x21-\x7e]{1,256}$
              description: The target's version the grant was decided against, from the intent's `context.agent_safe.precondition.version`, verbatim.
            authority_protocol_version:
              type: string
              enum:
                - "1.0"
                - 1.0.0
                - "1.1"
              description: Protocol semantics governing execution eligibility and effect evidence validation for this grant. Protocol 1.1 grants reject the deprecated legacy effect-evidence shape.
        jti:
          type: string
        iat:
          type: integer
        nbf:
          type: integer
        exp:
          type: integer
    ExecutionTokenResponse:
      type: object
      additionalProperties: false
      required:
        - valid
        - reason_codes
        - claims
      properties:
        valid:
          type: boolean
        should_execute:
          type: boolean
          description: Present on pre-commit claim responses. Only true after current-state and Presence revalidation, an atomic nonce claim with durable evidence, and a final database-time claim-lease check.
        would_block:
          type: boolean
          description: Present on pre-commit claim responses for Shadow diagnostics.
        verdict:
          type: string
          enum:
            - APPROVE
            - ESCALATE
            - REJECT
            - REVIEW
          description: Deterministic pre-commit revalidation verdict.
        reason_codes:
          type: array
          items:
            type: string
        claims:
          oneOf:
            - $ref: "#/components/schemas/ExecutionTokenClaims"
            - type: "null"
        claim_token:
          type:
            - string
            - "null"
          pattern: ^[A-Za-z0-9_-]{43,128}$
        claim_validated_at:
          type:
            - string
            - "null"
          format: date-time
          description: Database time of the final execution-eligibility confirmation. Qualifying effect observations must not predate this boundary.
        claim_lease_expires_at:
          type:
            - string
            - "null"
          format: date-time
          description: End of the claim's lease. The claim must be finalized before it; after it, the claim is recorded INDETERMINATE and holds its scopes until it is reconciled.
        claim_attestation:
          type:
            - string
            - "null"
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
          description: Present only on a live claim. A compact EdDSA JWS over `ClaimAttestationClaims`, verifiable against the execution-grant JWKS. Absent or null whenever `should_execute` is not true.
        evidence:
          type: object
          additionalProperties: true
        evidence_durably_queued:
          type: boolean
          description: True when the canonical revalidation evidence is durably queued in the same transaction as the nonce transition. This does not by itself mean the Protocol Decision Chain append has completed.
        decision_chain_evidence_recorded:
          type: boolean
          description: True when the queued evidence has already been acknowledged by the Protocol Decision Chain. False evidence remains recoverable when evidence_durably_queued is true.
    ExecutionClaimTokenResponse:
      description: Successful pre-commit claim response. All three execution-bound fields are required; `valid` alone never authorizes execution.
      allOf:
        - $ref: "#/components/schemas/ExecutionTokenResponse"
        - type: object
          required:
            - should_execute
            - claim_token
            - claim_validated_at
            - claim_lease_expires_at
            - claim_attestation
          properties:
            should_execute:
              type: boolean
              not:
                const: false
            claim_token:
              type: string
              pattern: ^[A-Za-z0-9_-]{43,128}$
            claim_validated_at:
              type: string
              format: date-time
            claim_lease_expires_at:
              type: string
              format: date-time
            claim_attestation:
              type: string
              pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
              description: Compact EdDSA JWS over `ClaimAttestationClaims`.
    ExecutionGrantJwks:
      type: object
      required:
        - keys
      properties:
        keys:
          type: array
          items:
            type: object
            required:
              - kty
              - crv
              - x
              - kid
              - alg
              - use
            properties:
              kty:
                type: string
                const: OKP
              crv:
                type: string
                const: Ed25519
              x:
                type: string
              kid:
                type: string
              alg:
                type: string
                const: EdDSA
              use:
                type: string
                const: sig
            additionalProperties: true
    SignedPolicyBundleResponse:
      type: object
      additionalProperties: false
      required:
        - signed_bundle
        - bundle_id
        - policy_version
        - kid
        - issued_at
        - not_before
        - expires_at
      properties:
        signed_bundle:
          type: string
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
          description: Compact JWS. Protected header `{"alg":"EdDSA","typ":"decionis-policy-bundle+jwt","kid":"<kid>"}`; payload `SignedPolicyBundleClaims`.
        bundle_id:
          type: string
        policy_version:
          type: string
        kid:
          type: string
          maxLength: 128
        issued_at:
          type: string
          format: date-time
        not_before:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
    PolicyBundleNotFound:
      type: object
      required:
        - error
        - reason
      properties:
        error:
          type: string
          const: POLICY_BUNDLE_NOT_FOUND
        reason:
          type: string
          enum:
            - missing_org_policy_bundle
            - no_active_org_policy_bundle
            - requested_policy_bundle_not_found
          description: The hosted policy guard's reason. An unapproved bundle (maker-checker) is not active, so it reads `no_active_org_policy_bundle`, or `requested_policy_bundle_not_found` when it was named.
        message:
          type: string
    PolicyBundleIssuance:
      type: object
      additionalProperties: false
      required:
        - jti
        - bundle_id
        - policy_version
        - bundle_digest
        - kid
        - decision_domain
        - issued_at
        - not_before
        - expires_at
        - api_key_id
      properties:
        jti:
          type: string
          format: uuid
        bundle_id:
          type: string
        policy_version:
          type: string
        bundle_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        kid:
          type: string
        decision_domain:
          type:
            - string
            - "null"
        issued_at:
          type: string
          format: date-time
        not_before:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        api_key_id:
          type:
            - string
            - "null"
          format: uuid
          description: The API key that requested it; null once that key is deleted.
    PolicyBundleIssuanceList:
      type: object
      additionalProperties: false
      required:
        - issuances
      properties:
        issuances:
          type: array
          items:
            $ref: "#/components/schemas/PolicyBundleIssuance"
    PolicyBundleJwks:
      type: object
      required:
        - keys
      properties:
        keys:
          type: array
          items:
            type: object
            required:
              - kty
              - crv
              - x
              - kid
              - alg
              - use
            properties:
              kty:
                type: string
                const: OKP
              crv:
                type: string
                const: Ed25519
              x:
                type: string
              kid:
                type: string
              alg:
                type: string
                const: EdDSA
              use:
                type: string
                const: sig
            additionalProperties: false
    EdgeEntitlementResponse:
      type: object
      additionalProperties: false
      required:
        - entitlement
        - kid
        - edge
        - issued_at
        - expires_at
      properties:
        entitlement:
          type: string
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
          description: "Compact JWS: protected header `EdgeEntitlementHeader`, payload `EdgeEntitlementClaims`, verified with the policy-bundle JWKS."
        kid:
          type: string
          maxLength: 128
        edge:
          type: boolean
        issued_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
    EdgeUsageReportSubmission:
      type: object
      additionalProperties: false
      required:
        - report
      properties:
        report:
          type: string
          minLength: 1
          maxLength: 524288
          description: The usage report as a compact JWS.
    EdgeUsageCounts:
      type: object
      additionalProperties: false
      required:
        - by_mode
        - by_verdict
        - total
      properties:
        by_mode:
          type: object
          additionalProperties: false
          required:
            - ENFORCEMENT
            - SHADOW
          properties:
            ENFORCEMENT:
              type: integer
              minimum: 0
            SHADOW:
              type: integer
              minimum: 0
            PARALLEL:
              type: integer
              minimum: 0
        by_verdict:
          type: object
          additionalProperties: false
          required:
            - ALLOW
            - ESCALATE
            - BLOCK
          properties:
            ALLOW:
              type: integer
              minimum: 0
            ESCALATE:
              type: integer
              minimum: 0
            BLOCK:
              type: integer
              minimum: 0
        total:
          type: integer
          minimum: 0
          description: Every edge decision in the month; `by_mode` and `by_verdict` each sum to it.
    EdgeUsageChain:
      type: object
      additionalProperties: false
      required:
        - stream
        - first_seq
        - last_seq
        - first_hash
        - last_hash
      description: The evidence-chain range the counts were taken from; the four bounds are null exactly when nothing was counted.
      properties:
        stream:
          type: string
          minLength: 1
          maxLength: 200
        first_seq:
          type:
            - integer
            - "null"
          minimum: 0
        last_seq:
          type:
            - integer
            - "null"
          minimum: 0
        first_hash:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        last_hash:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
    EdgeUsageReport:
      type: object
      additionalProperties: false
      required:
        - id
        - installation_id
        - kid
        - jti
        - period
        - period_start
        - period_end
        - issued_at
        - counts
        - delegated
        - billable
        - chain
        - bundles
        - report_digest
        - supersedes
        - superseded_by
        - metered_actions
        - meter_status
        - received_at
      properties:
        id:
          type: string
          format: uuid
        installation_id:
          type: string
        kid:
          type: string
        jti:
          type: string
        period:
          type: string
        period_start:
          type: string
          format: date-time
        period_end:
          type: string
          format: date-time
        issued_at:
          type: string
          format: date-time
        counts:
          $ref: "#/components/schemas/EdgeUsageCounts"
        delegated:
          type: integer
          minimum: 0
        billable:
          type: integer
          minimum: 0
          description: "`total - delegated`."
        chain:
          $ref: "#/components/schemas/EdgeUsageChain"
        bundles:
          type: array
          items:
            type: string
        report_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        supersedes:
          type:
            - string
            - "null"
          format: uuid
        superseded_by:
          type:
            - string
            - "null"
          format: uuid
        metered_actions:
          type: integer
          minimum: 0
          description: What this report added to the meter (beyond earlier reports for its month).
        meter_status:
          type: string
          enum:
            - pending
            - recorded
            - not_recorded
            - not_metered
          description: "`not_metered`: the plan is not metered (the hard-capped exploration default); `not_recorded`: the meter did not take it (no billing customer, or the meter was unavailable)."
        received_at:
          type: string
          format: date-time
    EdgeUsageReportAccepted:
      type: object
      additionalProperties: false
      required:
        - replay
        - report
      properties:
        replay:
          type: boolean
        report:
          $ref: "#/components/schemas/EdgeUsageReport"
    EdgeUsageReportList:
      type: object
      additionalProperties: false
      required:
        - reports
      properties:
        reports:
          type: array
          items:
            $ref: "#/components/schemas/EdgeUsageReport"
    EdgeUsageReportRefusal:
      type: object
      additionalProperties: false
      required:
        - error
        - message
      properties:
        error:
          type: string
          enum:
            - USAGE_REPORT_MALFORMED
            - USAGE_REPORT_KEY_UNKNOWN
            - USAGE_REPORT_SIGNATURE_INVALID
            - USAGE_REPORT_ISSUER_MISMATCH
            - USAGE_REPORT_AUDIENCE_MISMATCH
            - USAGE_REPORT_ISSUED_IN_FUTURE
            - USAGE_REPORT_PERIOD_IN_FUTURE
            - USAGE_REPORT_INCONSISTENT
        message:
          type: string
        kid:
          type: string
    EdgeUsageReportConflict:
      type: object
      additionalProperties: false
      required:
        - error
        - message
      properties:
        error:
          type: string
          enum:
            - USAGE_REPORT_DUPLICATE
            - USAGE_REPORT_JTI_REUSED
            - USAGE_REPORT_STREAM_CHANGED
            - USAGE_REPORT_CONCURRENT
        message:
          type: string
        current:
          $ref: "#/components/schemas/EdgeUsageReport"
    ExecutionEffectEvidence:
      type: object
      additionalProperties: false
      deprecated: true
      description: Deployed pre-Protocol-1.1 effect record. It remains accepted and verifiable for grants issued under its original request/outcome-binding rules. Protocol 1.1 grants reject this shape to prevent an evidence semantics downgrade. New integrations should emit EffectEvidence.
      allOf:
        - if:
            properties:
              status:
                const: CONFIRMED
            required:
              - status
          then:
            properties:
              response_digest:
                type: string
                pattern: ^sha256:[0-9a-f]{64}$
      required:
        - effect_schema_version
        - status
        - request_digest
        - response_digest
        - digest_algorithm
        - canonicalization_profile
        - external_reference
        - observation_mode
        - observer
        - observed_at
        - metadata_digest
      properties:
        effect_schema_version:
          type: string
          const: "1.0"
        status:
          type: string
          enum:
            - CONFIRMED
            - FAILED
            - INDETERMINATE
          description: CONFIRMED means the execution gate directly observed a digestible response.
        request_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
          description: Must equal the execution payload digest signed into the grant.
        response_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
          description: Required when status is CONFIRMED; null otherwise.
        digest_algorithm:
          type: string
          const: SHA-256
        canonicalization_profile:
          type: string
          minLength: 1
          maxLength: 500
          description: Canonicalization profile for the response digest when present; otherwise the request digest profile.
        external_reference:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 2000
        observation_mode:
          type: string
          enum:
            - GATE_OBSERVED
            - RUNTIME_REPORTED
        observer:
          type: object
          additionalProperties: false
          required:
            - id
            - version
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 500
            version:
              type: string
              minLength: 1
              maxLength: 200
        observed_at:
          type: string
          format: date-time
        metadata_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
    EffectObservationMethod:
      type: string
      enum:
        - DOWNSTREAM_ACK
        - READ_AFTER_WRITE
        - EVENT_CONFIRMATION
        - STATE_RECONCILIATION
        - SIGNED_RECEIPT
        - EXTERNAL_ATTESTATION
        - HUMAN_VALIDATION
      description: Versioned identifier for how the downstream effect was observed. DOWNSTREAM_ACK is weak evidence and cannot independently confirm an effect.
    EffectEvidence:
      type: object
      additionalProperties: false
      description: Optional Protocol 1.1 observation evidence. COMMITTED remains an executor-reported finalization state and is not CONFIRMED without a qualifying record. Raw provider responses should remain outside the evidence artifact; use commitments and immutable references.
      required:
        - version
        - status
        - observation_method
        - observer
        - expected_effect_digest
        - observed_effect_digest
        - observed_at
        - evidence_digest
        - evidence_reference
        - execution_correlation_id
      allOf:
        - if:
            properties:
              status:
                const: CONFIRMED
            required:
              - status
          then:
            required:
              - observer
              - observed_effect_digest
              - observed_at
            allOf:
              - not:
                  properties:
                    observation_method:
                      const: DOWNSTREAM_ACK
                  required:
                    - observation_method
              - properties:
                  observer:
                    type: object
                    required:
                      - id
                      - version
                    properties:
                      id:
                        type: string
                        minLength: 1
                        maxLength: 500
                        pattern: .*\S.*
                      version:
                        type: string
                        minLength: 1
                        maxLength: 500
                        pattern: .*\S.*
                  observed_effect_digest:
                    type: string
                    pattern: ^sha256:[0-9a-f]{64}$
                  observed_at:
                    type: string
                    format: date-time
              - anyOf:
                  - properties:
                      evidence_digest:
                        type: string
                        pattern: ^sha256:[0-9a-f]{64}$
                    required:
                      - evidence_digest
                  - properties:
                      evidence_reference:
                        type: string
                        minLength: 1
                        maxLength: 500
                    required:
                      - evidence_reference
      properties:
        version:
          type: string
          const: "1.0"
        status:
          type: string
          enum:
            - CONFIRMED
            - UNCONFIRMED
        observation_method:
          $ref: "#/components/schemas/EffectObservationMethod"
        observer:
          type:
            - object
            - "null"
          additionalProperties: false
          required:
            - id
            - version
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 500
              pattern: .*\S.*
            version:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 500
              pattern: .*\S.*
        expected_effect_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        observed_effect_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
          description: For CONFIRMED evidence, must equal expected_effect_digest.
        observed_at:
          type:
            - string
            - "null"
          format: date-time
        evidence_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        evidence_reference:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 500
        execution_correlation_id:
          type: string
          minLength: 1
          maxLength: 500
          description: Must exactly equal the bound commit correlation identifier.
    ExecutionFinalizeRequest:
      type: object
      additionalProperties: false
      required:
        - execution_token
        - claim_token
        - outcome
        - commit_correlation_id
      properties:
        execution_token:
          type: string
          minLength: 1
          maxLength: 20000
        claim_token:
          type: string
          pattern: ^[A-Za-z0-9_-]{43,128}$
        outcome:
          type: string
          enum:
            - COMMITTED
            - FAILED
            - INDETERMINATE
        commit_correlation_id:
          type: string
          minLength: 1
          maxLength: 200
        downstream_evidence:
          type: object
          additionalProperties: true
          description: Free-form legacy evidence; never interpreted as effect confirmation.
        native_receipt:
          $ref: "#/components/schemas/NativeReceipt"
        effect_evidence:
          anyOf:
            - $ref: "#/components/schemas/EffectEvidence"
            - $ref: "#/components/schemas/ExecutionEffectEvidence"
          description: When effect evidence is present for a Protocol 1.1 grant it must use the Protocol 1.1 shape. Effect confirmation remains optional. The legacy shape remains accepted only for historical grants and keeps its original verification semantics.
        effect_receipt:
          type: string
          minLength: 1
          maxLength: 20000
          pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
          description: "A verifying provider's effect receipt, forwarded by the executor exactly as the provider returned it: a compact EdDSA JWS whose protected header `typ` is `decionis-effect-receipt+jwt` and whose payload is `EffectReceiptClaims`. Verified against the organisation's registered provider keys and recorded whatever the verdict; never a reason to refuse the finalization."
    NativeReceipt:
      type: object
      additionalProperties: false
      required:
        - platform
        - kind
        - reference
        - status
        - observed_at
      description: What a permit-style platform recorded when it carried the action out (a posted journal, an acknowledged order). Recorded as `downstream_evidence.native_receipt`, replacing any value the executor put there; the executor's report of the attempt, never effect confirmation by itself.
      properties:
        platform:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z0-9][a-z0-9._-]*$
        kind:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z][a-z0-9._-]*$
        reference:
          type: string
          minLength: 1
          maxLength: 500
        status:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[A-Za-z][A-Za-z0-9._-]*$
        observed_at:
          type: string
          format: date-time
        digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
    ExecutionGrantReconciliationRequest:
      type: object
      additionalProperties: false
      required:
        - execution_token
        - claim_token
        - commit_correlation_id
        - outcome
        - effect_evidence
      properties:
        execution_token:
          type: string
          minLength: 1
          maxLength: 20000
        claim_token:
          type: string
          pattern: ^[A-Za-z0-9_-]{43,128}$
          description: The claim token the grant's claim returned.
        commit_correlation_id:
          type: string
          minLength: 1
          maxLength: 200
        outcome:
          type: string
          enum:
            - COMMITTED
            - FAILED
        reconciliation_note:
          type: string
          minLength: 1
          maxLength: 2000
          description: Free-form context; never identity. A fixed note naming the grant is recorded when absent.
        downstream_evidence:
          type: object
          additionalProperties: true
        effect_evidence:
          anyOf:
            - $ref: "#/components/schemas/EffectEvidence"
            - $ref: "#/components/schemas/ExecutionEffectEvidence"
          description: Protocol 1.1 evidence must be CONFIRMED to resolve COMMITTED, and cannot resolve FAILED; legacy evidence must name the reconciling principal as its observer.
    ExecutionGrantReconciliationResponse:
      type: object
      additionalProperties: false
      required:
        - reconciled
        - reason_codes
      properties:
        reconciled:
          type: boolean
        resolution:
          type: string
          enum:
            - FINALIZED
            - FAILED
        reconciliation_id:
          type: string
          format: uuid
        evidence_hash:
          type: string
        decision_chain_evidence_recorded:
          type: boolean
        assumption_breach:
          $ref: "#/components/schemas/AssumptionBreachOpened"
        reason_codes:
          type: array
          items:
            type: string
    AssumptionBreachOpened:
      type: object
      additionalProperties: false
      required:
        - breach_id
        - trigger
        - created
      description: "The assumption breach this report opened, or had already opened: an observed outcome that contradicts what the grant was bound to. While it is open the authority supplies it to policy, at enforce-and-bind and at every claim in the same action and target, as the fact `history.assumption_breach`; it is not a material signal and adds no claim concurrency scope. It clears only through a governed policy release or an independent recovery review that cites it and every piece of its evidence. Present only when a breach was opened; the report's own answer is unchanged by it."
      properties:
        breach_id:
          type: string
          format: uuid
        trigger:
          type: string
          enum:
            - EFFECT_MISMATCH
            - EFFECT_RECEIPT_CONTRADICTION
            - RECONCILIATION_CONTRADICTION
        created:
          type: boolean
          description: False when an earlier report of the same evidence already opened it.
    ExecutionFinalizeResponse:
      type: object
      additionalProperties: false
      required:
        - finalized
        - reason_codes
      properties:
        finalized:
          type: boolean
        outcome:
          type: string
          enum:
            - COMMITTED
            - FAILED
            - INDETERMINATE
        evidence_recorded:
          type: boolean
          description: Compatibility field reporting immediate Decision Chain acknowledgement.
        evidence_durably_queued:
          type: boolean
          description: True when commit evidence was persisted transactionally with the terminal claim state, including lease-expiry INDETERMINATE.
        decision_chain_evidence_recorded:
          type: boolean
          description: True when the Protocol Decision Chain had already acknowledged the commit evidence when this response was formed; false is delivered asynchronously from the durable outbox.
        effect_evidence_recorded:
          type: boolean
        effect_confirmation:
          type: string
          enum:
            - CONFIRMED
            - UNCONFIRMED
        effect_receipt:
          type: object
          additionalProperties: false
          required:
            - verified
            - verification_code
            - provider_key_id
            - recorded
          description: Present when the request carried an `effect_receipt`.
          properties:
            verified:
              type: boolean
              description: True when the receipt's signature verified under a registered provider key and its claims describe this grant and this claim.
            verification_code:
              type: string
              enum:
                - EFFECT_RECEIPT_VERIFIED
                - EFFECT_RECEIPT_MALFORMED
                - EFFECT_RECEIPT_KEY_UNKNOWN
                - EFFECT_RECEIPT_SIGNATURE_INVALID
                - EFFECT_RECEIPT_BINDING_MISMATCH
                - EFFECT_RECEIPT_KEYS_UNAVAILABLE
            provider_key_id:
              type:
                - string
                - "null"
              description: The `kid` the receipt named, when it named one.
            recorded:
              type: boolean
              description: True when the receipt was persisted in the commit evidence, which is whenever the claim finalized.
        assumption_breach:
          $ref: "#/components/schemas/AssumptionBreachOpened"
        reason_codes:
          type: array
          items:
            type: string
    ProtocolEvaluateDecisionRequest:
      type: object
      required:
        - decision_type
      properties:
        org_id:
          type: string
          format: uuid
          description: Optional when authenticated with an organization API key.
        decision_type:
          type: string
        amount:
          type: number
        risk_score:
          type: number
          minimum: 0
          maximum: 1
        channel:
          type: string
        policy_version:
          type: string
          description: The exact active policy bundle version to decide under. A named version the organization does not hold fails closed (policy_guard.reason requested_policy_bundle_not_found, outcome ESCALATE); it is never silently substituted. Omit it to decide under the newest active bundle — the response's policy_bundle_resolution says which happened.
        require_exact_policy_version:
          type: boolean
          description: Accepted for compatibility. Exact matching is now the default whenever policy_version is named.
        objective_profile:
          type: string
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
          description: Absent means SHADOW. The spellings enforce and enforced are accepted as ENFORCEMENT; any other value is a 400, never a silent SHADOW.
        decision_band:
          type: string
        transaction_type:
          type: string
        workflow_key:
          type: string
        vertical_pack:
          type: string
        agent_attribution:
          type: object
          additionalProperties: false
          minProperties: 1
          description: "What the calling agent reported about producing the action: agent, model, provider, tokens and cost. Recorded on the Decision Dossier's inputs snapshot as client-reported (reported_by client, platform_verified false); never verified, never a policy fact. Absent is fine; present but malformed is a 400."
          properties:
            agent_id:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]*$
            provider:
              type: string
              minLength: 1
              maxLength: 120
            model:
              type: string
              minLength: 1
              maxLength: 200
              pattern: ^[\w.:/@-]+$
            input_tokens:
              type: integer
              minimum: 0
              maximum: 1000000000
            output_tokens:
              type: integer
              minimum: 0
              maximum: 1000000000
            reported_cost:
              type: object
              additionalProperties: false
              required:
                - amount
                - currency
              properties:
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
        context:
          type: object
          additionalProperties: true
          description: |
            Arbitrary evaluated facts. A matched ESCALATE rule can issue a
            Presence Authority Requirement only when `action_context` conforms
            to `PresenceActionContext`; the digest binds that complete canonical
            object and unknown action fields are excluded from the binding.
            `context.authority_requirement` is reserved and rejected; callers
            cannot promote their own JSON into trusted authority policy.
            `context.decionis_policy` describes the repository's policy file
            (the workflow gate's `DECIONIS_POLICY.md`) and is recorded with the
            decision. Its `sha256` must be the SHA-256 of its UTF-8 `content`:
            Decionis hashes the content itself, and from a descriptor claiming
            another hash it neither versions nor publishes anything (the event
            `policy.file.encode_rejected` records it). With `enforce: true`,
            its `decionis` rules block is published as the workspace's ACTIVE
            enforced bundle only when the key holds `policy:write`, `policy:*`
            or `org:*`; for any other key the decision is unaffected, nothing
            is published, and the response carries
            `x-decionis-warning: POLICY_ENFORCE_SCOPE_MISSING`.
        idempotency_key:
          type: string
        decision_chain:
          $ref: "#/components/schemas/DecisionChainRequest"
      additionalProperties: true
    ProtocolEvaluateDecisionResponse:
      type: object
      allOf:
        - if:
            properties:
              protocol_version:
                const: "1.1"
            required:
              - protocol_version
          then:
            required:
              - verdict
              - authority_classification
              - execution_eligible
              - policy_reference
              - evaluation_semantics
              - input_snapshot_digest
              - execution_binding_digest
      required:
        - outcome
        - confidence
        - policy_version
        - objective_profile
        - dossier_id
        - evaluation_id
        - mode
        - fallback_to_legacy
        - governance_metrics
        - idempotent_replay
      properties:
        protocol_version:
          type: string
          const: "1.1"
        outcome:
          type: string
          enum:
            - APPROVE
            - ESCALATE
            - REJECT
            - REVIEW
        verdict:
          type: string
          enum:
            - ALLOW
            - ESCALATE
            - BLOCK
        authority_classification:
          $ref: "#/components/schemas/AuthorityClassification"
        execution_eligible:
          type: boolean
        policy_reference:
          $ref: "#/components/schemas/PolicyReference"
        evaluation_semantics:
          $ref: "#/components/schemas/EvaluationSemantics"
        input_snapshot_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        execution_binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
          description: Commitment to the exact-action ExecutionBinding when one is present. Null on observational or otherwise non-execution-eligible Protocol 1.1 evaluations.
        confidence:
          type: number
        policy_version:
          type: string
        objective_profile:
          type: string
        dossier_id:
          type: string
          format: uuid
        dossier_sha256:
          type:
            - string
            - "null"
        evaluation_id:
          type: string
          format: uuid
        decision_resolution_id:
          type:
            - string
            - "null"
          format: uuid
        ledger_entry_id:
          type:
            - string
            - "null"
          format: uuid
        ledger_entry_hash:
          type:
            - string
            - "null"
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        fallback_to_legacy:
          type: boolean
        fallback_reason:
          type:
            - string
            - "null"
          description: The rollout's reason for a legacy fallback, or the policy guard's reason when the guard blocked. In SHADOW this reads mode_not_enforcement by design; enforcement_effect states the mode's effect on its own.
        enforcement_effect:
          type: object
          description: What this mode does with the verdict. The outcome is the same function of policy and request in every mode; ENFORCEMENT binds it (BINDING), SHADOW and PARALLEL observe it (OBSERVED).
          properties:
            effective_mode:
              type: string
              enum:
                - SHADOW
                - PARALLEL
                - ENFORCEMENT
            verdict_effect:
              type: string
              enum:
                - BINDING
                - OBSERVED
            reason:
              type: string
              enum:
                - enforcement_mode
                - shadow_mode_observes_only
                - parallel_mode_observes_only
                - policy_guard_blocked
        policy_bundle_resolution:
          type: object
          description: How the deciding bundle was chosen, on every response, so a default is never mistaken for the version the caller named.
          properties:
            requested_policy_version:
              type:
                - string
                - "null"
            resolved_policy_version:
              type:
                - string
                - "null"
            status:
              type: string
              enum:
                - exact_match
                - newest_active
                - requested_not_found
                - policy_guard
        governance_metrics:
          type: object
          additionalProperties: true
        policy_guard:
          type: object
          additionalProperties: true
        policy_evaluation:
          type: object
          additionalProperties: true
        decision_chain:
          $ref: "#/components/schemas/DecisionChainSummary"
        policy_snapshot:
          type: object
          additionalProperties: true
          description: Hash-backed reference to the encoded policy bundle evaluated by the protocol.
        execution_binding:
          type: object
          additionalProperties: true
          description: Exact-action ExecutionBinding v1.0. Absent on observational or otherwise non-execution-eligible evaluations.
        authority_requirement:
          $ref: "#/components/schemas/AuthorityRequirement"
          description: |
            Present only for an ENFORCEMENT-mode matched ESCALATE rule with
            explicit policy-owned authority settings and a valid canonical action_context. Human
            approval is evidence; callers must keep execution held until a later
            Decionis re-evaluation authorizes release.
        idempotent_replay:
          type: boolean
        verification:
          $ref: "#/components/schemas/DecisionDossierVerificationEnvelope"
          description: Attached when the evaluation left a dossier and the envelope could be built; a failure to build it is logged and omitted, never a failed decision.
      additionalProperties: true
    AuthoritySelector:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - kind
            - role_id
          properties:
            kind:
              type: string
              const: ROLE
            role_id:
              type: string
              pattern: ^[A-Z][A-Z0-9_]{1,63}$
            principal_id:
              type: string
              minLength: 1
              maxLength: 200
              description: Optional exact-human narrowing for managed role selection. The selected principal must still hold the trusted human role.
        - type: object
          additionalProperties: false
          required:
            - kind
            - principal_id
          properties:
            kind:
              type: string
              const: PRINCIPAL
            principal_id:
              type: string
              minLength: 1
              maxLength: 200
            role_id:
              type: string
              pattern: ^[A-Z][A-Z0-9_]{1,63}$
              description: Trusted effective human approval role. Optional for DIRECT requirements and required when orchestration.mode is MANAGED.
    AuthorityVerificationRequirements:
      type: object
      additionalProperties: false
      required:
        - level
        - methods
        - hardware_pki_required
        - disallow_virtual_cameras
      properties:
        level:
          type: string
          enum:
            - STANDARD
            - HIGH_CONFIDENCE
        methods:
          type: array
          minItems: 1
          maxItems: 3
          uniqueItems: true
          items:
            type: string
            enum:
              - WEBAUTHN
              - MOBILE_DEVICE
              - ACTIVE_LIVENESS
              - CARD_TAP
          description: WEBAUTHN, MOBILE_DEVICE and ACTIVE_LIVENESS are ceremonies Decionis Presence runs. CARD_TAP is the cardholder tapping the physical card on their own phone inside the issuer's app, proved by a third-party presence provider named in `provider`; a requirement never mixes the two kinds.
        hardware_pki_required:
          type: boolean
        disallow_virtual_cameras:
          type: boolean
        mobile_device_policy:
          type: string
          enum:
            - WEB_OR_JIT_DEVICE
            - MANAGED_DEVICE_REQUIRED
        trusted_ip_regions:
          type: array
          minItems: 1
          maxItems: 100
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 64
        provider:
          type: string
          pattern: ^[a-z][a-z0-9_.:-]{0,63}$
          description: Who proves the person. Absent, or `decionis`, Decionis Presence runs the ceremony. Any other id names a presence provider from the directory (GET /v1/presence-providers) that the organisation admitted; its signed presence attestation (`evidence.humanApproval` of provider `attestation`, `presence.method` `card_tap`) is the proof. `presence` is reserved and refused.
    AuthorityResolutionPolicy:
      type: object
      additionalProperties: false
      required:
        - quorum
        - delegation
        - fallback_role_ids
      properties:
        quorum:
          type: integer
          const: 1
        delegation:
          type: string
          enum:
            - DISALLOWED
            - REQUIREMENT_REFRESH
        fallback_role_ids:
          type: array
          maxItems: 10
          uniqueItems: true
          items:
            type: string
            pattern: ^[A-Z][A-Z0-9_]{1,63}$
    AuthorityOriginator:
      type: object
      additionalProperties: false
      required:
        - organization_id
        - organization_name
        - provenance
      properties:
        organization_id:
          type: string
          minLength: 1
          maxLength: 200
        organization_name:
          type: string
          minLength: 1
          maxLength: 160
        actor_id:
          type: string
          minLength: 1
          maxLength: 200
        display_name:
          type: string
          minLength: 1
          maxLength: 160
        role:
          type: string
          minLength: 1
          maxLength: 120
        provenance:
          type: string
          enum:
            - AUTHENTICATED_TENANT
            - VERIFIED_CONNECTOR
            - CALLER_DECLARED
    AuthorityPresentation:
      type: object
      additionalProperties: false
      required:
        - locale
        - title
        - description
        - display_fields
      properties:
        locale:
          type: string
          minLength: 2
          maxLength: 35
          pattern: ^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$
        title:
          type: string
          minLength: 1
          maxLength: 160
        description:
          type: string
          minLength: 1
          maxLength: 1000
        display_fields:
          type: array
          maxItems: 20
          items:
            type: object
            additionalProperties: false
            required:
              - key
              - label
              - value
            properties:
              key:
                type: string
                pattern: ^[a-z][a-z0-9_]{0,63}$
              label:
                type: string
                minLength: 1
                maxLength: 120
              value:
                type: string
                minLength: 1
                maxLength: 500
    ManagedAuthorityOrchestration:
      type: object
      additionalProperties: false
      required:
        - mode
        - escalation_id
      properties:
        mode:
          type: string
          const: MANAGED
        escalation_id:
          type: string
          minLength: 8
          maxLength: 200
      description: Server-issued routing metadata. It identifies managed orchestration but is not execution authority and does not create an ExecutionBinding.
    AuthorityRequirement:
      type: object
      additionalProperties: false
      required:
        - requirement_version
        - requirement_id
        - source_decision_id
        - source_dossier_id
        - policy_version
        - policy_reason_codes
        - action_digest
        - selector
        - verification_requirements
        - resolution
        - originator
        - presentation
        - nonce
        - issued_at
        - expires_at
      properties:
        requirement_version:
          type: string
          const: decionis.authority_requirement/1
        requirement_id:
          type: string
          minLength: 8
          maxLength: 200
        source_decision_id:
          type: string
          minLength: 1
          maxLength: 200
        source_dossier_id:
          type: string
          minLength: 1
          maxLength: 200
        policy_version:
          type: string
          minLength: 1
          maxLength: 120
        policy_reason_codes:
          type: array
          minItems: 1
          maxItems: 20
          items:
            type: string
            pattern: ^[A-Z][A-Z0-9_]{1,119}$
        action_digest:
          type: string
          pattern: ^[0-9a-f]{64}$
        selector:
          $ref: "#/components/schemas/AuthoritySelector"
        verification_requirements:
          $ref: "#/components/schemas/AuthorityVerificationRequirements"
        resolution:
          $ref: "#/components/schemas/AuthorityResolutionPolicy"
        originator:
          $ref: "#/components/schemas/AuthorityOriginator"
        presentation:
          $ref: "#/components/schemas/AuthorityPresentation"
        nonce:
          type: string
          pattern: ^[A-Za-z0-9_-]{43,128}$
        issued_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
          description: Must be later than issued_at.
        orchestration:
          $ref: "#/components/schemas/ManagedAuthorityOrchestration"
    ProtocolDecisionDossierResponse:
      type: object
      additionalProperties: true
      required:
        - service
        - protocol_version
        - dossier
      properties:
        service:
          type: string
        protocol_version:
          type: string
        dossier:
          type: object
          additionalProperties: false
          required:
            - dossier_id
            - org_id
            - decision_evaluation_id
            - dossier_payload
            - evidence_hashes
            - created_at
            - updated_at
          properties:
            dossier_id:
              type: string
              format: uuid
            org_id:
              type: string
              format: uuid
            decision_evaluation_id:
              type: string
              format: uuid
            dossier_payload:
              type: object
              additionalProperties: true
            evidence_hashes:
              type: array
              items:
                type: string
                pattern: ^[0-9a-f]{64}$
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
    AgentActionCapsuleV04:
      type: object
      description: Agent Action Capsule compatibility profile pinned to draft-mih-scitt-agent-action-capsule-04, format 4, using plain RFC 8785/JCS.
      required:
        - spec_version
        - format_version
        - canonicalization_id
        - capsule_id
        - action_id
        - action_type
        - operator
        - developer
        - timestamp
        - disposition
        - assurance
      properties:
        spec_version:
          type: string
          const: draft-mih-scitt-agent-action-capsule-04
        format_version:
          type: string
          const: "4"
        canonicalization_id:
          type: string
          const: jcs
        capsule_id:
          type: string
          pattern: ^[0-9a-f]{64}$
        action_id:
          type: string
          minLength: 1
        decision_id:
          type: string
          minLength: 1
        action_type:
          type: string
          enum:
            - fyi
            - decide
        operator:
          type: string
          minLength: 1
        developer:
          type: string
          minLength: 1
        timestamp:
          type: string
          format: date-time
        epoch_id:
          type: string
          minLength: 1
        disposition:
          type: object
          required:
            - decision
            - approver
            - human_disposed
          properties:
            decision:
              type: string
            approver:
              type: string
              enum:
                - human
                - policy
                - counterparty
            human_disposed:
              type: boolean
            authority:
              type: string
            verdict_class:
              type: string
            reason_digest:
              type: string
              pattern: ^[0-9a-f]{64}$
          additionalProperties: true
        effect:
          type: object
          required:
            - type
            - status
            - irreversibility_class
          properties:
            type:
              type: string
            status:
              type: string
              enum:
                - planned
                - dispatched
                - confirmed
                - failed
                - reverted
            request_digest:
              type: string
              pattern: ^[0-9a-f]{64}$
            response_digest:
              type: string
              pattern: ^[0-9a-f]{64}$
            external_ref:
              type: string
            irreversibility_class:
              type: string
            effect_attestation:
              type: string
          additionalProperties: true
        assurance:
          type: object
          additionalProperties: false
          required:
            - attestation_mode
            - effect_mode
            - ledger_mode
          properties:
            attestation_mode:
              type: string
              enum:
                - self_attested
                - anchored
            effect_mode:
              type: string
              enum:
                - not_applicable
                - dispatched_unconfirmed
                - confirmed
            ledger_mode:
              type: string
              enum:
                - standalone
                - chained
                - anchored
        constraints:
          type: array
          items:
            type: object
            required:
              - id
              - result
              - severity
              - blocking
            properties:
              id:
                type: string
              check_type:
                type: string
              method:
                type: string
              result:
                type: string
                enum:
                  - pass
                  - fail
                  - n/a
              severity:
                type: string
              blocking:
                type: boolean
              evidence_digest:
                type: string
                pattern: ^[0-9a-f]{64}$
            additionalProperties: false
        chain:
          type: object
          additionalProperties: false
          required:
            - parent_capsule_id
            - relation
          properties:
            parent_capsule_id:
              type: string
              pattern: ^[0-9a-f]{64}$
            relation:
              type: string
        references:
          type: array
          items:
            type: object
            required:
              - type
              - digest_alg
              - digest
            properties:
              type:
                type: string
              digest_alg:
                type: string
              digest:
                type: string
                pattern: ^[0-9a-f]{64}$
              citation_purpose:
                type: string
            additionalProperties: true
      additionalProperties: true
    AgentActionCapsuleProducerEnvelopeResponse:
      type: object
      additionalProperties: false
      required:
        - service
        - protocol_version
        - capsule_id
        - payload_encoding
        - signing_available
        - envelopes
      properties:
        service:
          type: string
        protocol_version:
          type: string
        capsule_id:
          type: string
          pattern: ^[0-9a-f]{64}$
        payload_encoding:
          type: string
          const: raw-32-byte-capsule-id
        signing_available:
          type: boolean
        envelopes:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - media_type
              - profile
              - content_type
              - key_id
              - cose_sign1_base64url
              - verification
            properties:
              media_type:
                type: string
                const: application/cose
              profile:
                type: string
                const: draft-mih-scitt-agent-action-capsule-04
              content_type:
                type: string
                const: application/agent-action-capsule-id
              key_id:
                type: string
              cose_sign1_base64url:
                type: string
                pattern: ^[A-Za-z0-9_-]+$
              verification:
                type: object
                additionalProperties: true
    ScittCapsuleRegistrationResponse:
      type: object
      additionalProperties: true
      required:
        - capsule_id
        - anchored
        - registration
      properties:
        service:
          type: string
        protocol_version:
          type: string
        capsule_id:
          type: string
          pattern: ^[0-9a-f]{64}$
        idempotent:
          type: boolean
        anchored:
          type: boolean
          description: True only when both the Signed Statement and receipt profile verify.
        status_path:
          type: string
        registration:
          type: object
          additionalProperties: false
          required:
            - org_id
            - dossier_id
            - capsule_id
            - transparency_service
            - status
            - registration_statement_base64url
            - statement_verified
            - receipt_verified
            - attempt_count
            - created_at
            - updated_at
          properties:
            org_id:
              type: string
              format: uuid
            dossier_id:
              type: string
              format: uuid
            capsule_id:
              type: string
              pattern: ^[0-9a-f]{64}$
            transparency_service:
              type: string
              format: uri
            status:
              type: string
              enum:
                - PENDING
                - REGISTERING
                - RECEIPT_UNVERIFIED
                - ANCHORED
                - FAILED
            registration_statement_base64url:
              type: string
            statement_verified:
              type: boolean
            receipt_base64url:
              type:
                - string
                - "null"
            receipt_profile:
              type:
                - string
                - "null"
            receipt_verified:
              type: boolean
            service_key_id:
              type:
                - string
                - "null"
            attempt_count:
              type: integer
              minimum: 0
            last_error:
              type:
                - string
                - "null"
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
    DecisionChainRequest:
      type: object
      properties:
        chain_id:
          type: string
          format: uuid
          description: Existing chain to append to. Optional when parent references are supplied.
        workflow_id:
          type: string
          description: Customer workflow or execution instance identifier.
        step_id:
          type: string
          description: Current workflow step being evaluated.
        sequence:
          type: integer
          minimum: 0
        parent_evaluation_ids:
          type: array
          maxItems: 20
          items:
            type: string
            format: uuid
        parent_dossier_ids:
          type: array
          maxItems: 20
          items:
            type: string
            format: uuid
        metadata:
          type: object
          additionalProperties: true
      additionalProperties: true
    DecisionChainSummary:
      type: object
      required:
        - chain_id
        - workflow_id
        - step_id
        - root_evaluation_id
        - parent_evaluation_ids
        - parent_dossier_ids
        - lineage_depth
        - integrity_hash
        - chain_api_path
      properties:
        chain_id:
          type: string
          format: uuid
        workflow_id:
          type: string
        step_id:
          type: string
        sequence:
          type:
            - integer
            - "null"
        root_evaluation_id:
          type: string
          format: uuid
        parent_evaluation_ids:
          type: array
          items:
            type: string
            format: uuid
        parent_dossier_ids:
          type: array
          items:
            type: string
            format: uuid
        lineage_depth:
          type: integer
        integrity_hash:
          type: string
        chain_api_path:
          type: string
        authority_classification:
          $ref: "#/components/schemas/AuthorityClassification"
        verdict:
          type: string
          enum:
            - ALLOW
            - ESCALATE
            - BLOCK
        execution_binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
      additionalProperties: false
    DecisionChainLink:
      type: object
      required:
        - id
        - chain_id
        - workflow_id
        - step_id
        - decision_evaluation_id
        - dossier_id
        - parent_evaluation_ids
        - parent_dossier_ids
        - root_evaluation_id
        - lineage_depth
        - integrity_hash
        - integrity_verified
        - dossier_api_path
        - created_at
      properties:
        id:
          type: string
          format: uuid
        chain_id:
          type: string
          format: uuid
        workflow_id:
          type: string
        step_id:
          type: string
        sequence:
          type:
            - integer
            - "null"
        decision_evaluation_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        parent_evaluation_ids:
          type: array
          items:
            type: string
            format: uuid
        parent_dossier_ids:
          type: array
          items:
            type: string
            format: uuid
        root_evaluation_id:
          type: string
          format: uuid
        lineage_depth:
          type: integer
        integrity_hash:
          type: string
        integrity_verified:
          type: boolean
        outcome:
          type: string
        policy_version:
          type: string
        authority_classification:
          type:
            - string
            - "null"
          enum:
            - AUTHORITATIVE
            - OBSERVATIONAL
            - null
        verdict:
          type:
            - string
            - "null"
          enum:
            - ALLOW
            - ESCALATE
            - BLOCK
            - null
        execution_binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        dossier_api_path:
          type: string
        created_at:
          type: string
          format: date-time
      additionalProperties: false
    DecisionChainEvidenceReference:
      type: object
      additionalProperties: false
      description: Privacy-safe reference to append-only execution evidence correlated with a Decision Chain. The audit ledger remains the evidence store; this object carries commitments and provenance, never raw provider payloads. DISPATCH appears only when a connected executor records dispatch evidence.
      required:
        - stage
        - evaluation_id
        - dossier_id
        - status
        - occurred_at
        - ledger_entry_id
        - ledger_entry_hash
        - evidence_digest
        - evidence_hash_verified
        - execution_correlation_id
        - binding_digest
        - observed_at
        - observation_method
        - observer
        - expected_effect_digest
        - observed_effect_digest
        - evidence_reference
      properties:
        stage:
          type: string
          enum:
            - CLAIM
            - DISPATCH
            - FINALIZATION
            - EFFECT
        evaluation_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        status:
          type: string
          minLength: 1
          maxLength: 120
        occurred_at:
          type: string
          format: date-time
        ledger_entry_id:
          type: string
          format: uuid
        ledger_entry_hash:
          type: string
          pattern: ^[0-9a-f]{64}$
        evidence_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        evidence_hash_verified:
          type: boolean
          description: True when the evidence hash recorded in the ledger payload matches the canonical evidence fields projected into this reference.
        execution_correlation_id:
          type: string
          minLength: 1
          maxLength: 500
        binding_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        observed_at:
          type:
            - string
            - "null"
          format: date-time
        observation_method:
          type:
            - string
            - "null"
          maxLength: 120
        observer:
          type:
            - object
            - "null"
          additionalProperties: false
          required:
            - id
            - version
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 500
            version:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 500
        expected_effect_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        observed_effect_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        evidence_reference:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 2000
    DecisionChain:
      type: object
      required:
        - service
        - protocol_version
        - org_id
        - chain_id
        - count
        - max_lineage_depth
        - integrity_verified
        - ledger_verification
        - links
        - link_limit
        - links_truncated
        - evidence_lineage
        - evidence_lineage_limit
        - evidence_lineage_truncated
      properties:
        service:
          type: string
        protocol_version:
          type: string
        org_id:
          type: string
          format: uuid
        chain_id:
          type: string
          format: uuid
        workflow_id:
          type:
            - string
            - "null"
        root_evaluation_id:
          type:
            - string
            - "null"
          format: uuid
        count:
          type: integer
        max_lineage_depth:
          type: integer
        integrity_verified:
          type: boolean
        ledger_verification:
          type: object
          additionalProperties: false
          required:
            - valid
            - complete
            - checked
            - max_entries
          description: "Bounded canonical-ledger verification performed for this response. `complete: false` means the response must not be treated as verified, even when the checked prefix contained no broken link."
          properties:
            valid:
              type: boolean
            complete:
              type: boolean
            checked:
              type: integer
              minimum: 0
            max_entries:
              type: integer
              minimum: 1
              maximum: 50000
        links:
          type: array
          items:
            $ref: "#/components/schemas/DecisionChainLink"
        link_limit:
          type: integer
          minimum: 1
          maximum: 500
          description: Maximum Decision Chain links returned in this bounded projection.
        links_truncated:
          type: boolean
          description: True when additional Decision Chain links exist. A truncated response must not be interpreted as verification of the complete chain.
        evidence_lineage:
          type: array
          description: Claim, optional dispatch, finalization, and effect-evidence commitments correlated from canonical append-only audit-ledger membership and a cryptographically verified ExecutionBinding.
          items:
            $ref: "#/components/schemas/DecisionChainEvidenceReference"
        evidence_lineage_limit:
          type: integer
          minimum: 1
          maximum: 500
          description: Maximum canonical audit-ledger entries considered by this projection.
        evidence_lineage_truncated:
          type: boolean
          description: True when additional chain-correlated ledger entries exist. In that case evidence_lineage is withheld so a bounded prefix is not presented as complete authoritative lineage.
      additionalProperties: false
    ShadowEvaluateDecisionReport:
      type: object
      required:
        - evaluation_id
        - dossier_id
        - created_at
        - decision_type
        - policy_version
        - mode
        - outcome
        - confidence
        - would_execute
        - execution_action
        - reason
        - dossier_api_path
      properties:
        evaluation_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        decision_type:
          type: string
        decision_domain:
          type:
            - string
            - "null"
        amount:
          type:
            - number
            - "null"
        risk_score:
          type:
            - number
            - "null"
        channel:
          type:
            - string
            - "null"
        policy_version:
          type: string
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        outcome:
          type: string
          enum:
            - APPROVE
            - ESCALATE
            - REJECT
            - REVIEW
        confidence:
          type: number
        would_execute:
          type: boolean
        execution_action:
          type: string
          enum:
            - CONTINUE
            - STOP
            - HAND_OFF
            - REVIEW
        reason:
          type: string
        policy_guard_reason:
          type:
            - string
            - "null"
        policy_evaluation_resolution:
          type:
            - string
            - "null"
        selected_rule_id:
          type:
            - string
            - "null"
        dossier_api_path:
          type: string
      additionalProperties: false
    ShadowEvaluateDecisionReportSummary:
      type: object
      required:
        - total_evaluations
        - would_approve_count
        - would_block_count
        - would_escalate_count
        - review_required_count
        - non_approve_count
        - non_approve_rate
        - policy_mismatch_count
        - policy_mismatch_rate
        - near_miss_count
        - near_miss_rate
      properties:
        total_evaluations:
          type: integer
        would_approve_count:
          type: integer
        would_block_count:
          type: integer
        would_escalate_count:
          type: integer
        review_required_count:
          type: integer
        non_approve_count:
          type: integer
        non_approve_rate:
          type: number
        policy_mismatch_count:
          type: integer
        policy_mismatch_rate:
          type: number
        near_miss_count:
          type: integer
        near_miss_rate:
          type: number
        outcome_counts:
          type: object
          additionalProperties:
            type: integer
        top_decision_types:
          type: array
          items:
            type: object
            additionalProperties: true
        top_reason_patterns:
          type: array
          items:
            type: object
            additionalProperties: true
      additionalProperties: false
    ShadowEvaluateDecisionReportsResponse:
      type: object
      required:
        - service
        - protocol_version
        - generated_at
        - org_id
        - mode
        - count
        - reports
        - summary
      properties:
        service:
          type: string
        protocol_version:
          type: string
        generated_at:
          type: string
          format: date-time
        org_id:
          type: string
          format: uuid
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        since:
          type:
            - string
            - "null"
          format: date-time
        count:
          type: integer
        reports:
          type: array
          items:
            $ref: "#/components/schemas/ShadowEvaluateDecisionReport"
        summary:
          $ref: "#/components/schemas/ShadowEvaluateDecisionReportSummary"
      additionalProperties: false
    ShadowEvaluateDecisionReportsSummaryResponse:
      type: object
      required:
        - service
        - protocol_version
        - generated_at
        - org_id
        - mode
        - summary
      properties:
        service:
          type: string
        protocol_version:
          type: string
        generated_at:
          type: string
          format: date-time
        org_id:
          type: string
          format: uuid
        mode:
          type: string
          enum:
            - SHADOW
            - PARALLEL
            - ENFORCEMENT
        since:
          type:
            - string
            - "null"
          format: date-time
        summary:
          $ref: "#/components/schemas/ShadowEvaluateDecisionReportSummary"
      additionalProperties: false
    DecisionSignature:
      type: object
      required:
        - algorithm
        - value
      properties:
        algorithm:
          type: string
          enum:
            - Ed25519
        value:
          type: string
          description: Base64, base64url, or hex encoded signature bytes.
    DecisionResponse:
      type: object
      required:
        - decision_id
        - status
        - reason_codes
        - explanation
      properties:
        decision_id:
          type: string
        status:
          $ref: "#/components/schemas/DecisionStatus"
        reason_codes:
          type: array
          items:
            type: string
        explanation:
          type: string
        dossier_url:
          type: string
          format: uri
        signature:
          $ref: "#/components/schemas/DecisionSignature"
        latency_ms:
          type: integer
          minimum: 0
      additionalProperties: true
    DecisionDossier:
      type: object
      properties:
        decision_id:
          type: string
        dossier_url:
          type: string
          format: uri
        status:
          $ref: "#/components/schemas/DecisionStatus"
        audit_events:
          type: array
          items:
            type: object
            additionalProperties: true
      additionalProperties: true
    PolicyValidationResponse:
      type: object
      required:
        - valid
      properties:
        valid:
          type: boolean
        errors:
          type: array
          items:
            type: string
        warnings:
          type: array
          items:
            type: string
      additionalProperties: true
    PolicyBundle:
      type: object
      required:
        - protocol_version
        - bundle_id
        - org_id
        - version
        - effective_from
        - rules
      properties:
        protocol_version:
          type: string
          pattern: ^1\.[0-9]+(\.[0-9]+)?$
        bundle_id:
          type: string
          format: uuid
        org_id:
          type: string
        version:
          type: string
          minLength: 1
          maxLength: 100
        effective_from:
          type: string
          format: date-time
        effective_to:
          type: string
          format: date-time
        rules:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/PolicyRule"
        allowed_transitions:
          type: array
          maxItems: 50
          description: "Which states a decision type's target may move between, checked before any rule. For a decision of `decision_type`, the move from the state at the fact path `from` (typically `agent_safe.precondition.state`) to the state at `to` must be one of `allowed`, exactly as written, or the evaluation resolves `transition_not_allowed` and the outcome is REJECT. No value at `to` asks for no state, and `to` equal to `from` is no transition. A `from` or `to` that is not a string fails safe to ESCALATE as `missing_required_signals`. A bundle declaring any is signed for the edge as `core_abi: 8`."
          items:
            type: object
            additionalProperties: false
            required:
              - transition_id
              - decision_type
              - from
              - to
              - allowed
            properties:
              transition_id:
                type: string
                minLength: 1
                maxLength: 120
              name:
                type: string
                minLength: 1
                maxLength: 200
              decision_type:
                type: string
                minLength: 1
                maxLength: 120
              from:
                type: string
                minLength: 1
                maxLength: 200
              to:
                type: string
                minLength: 1
                maxLength: 200
              allowed:
                type: array
                minItems: 1
                maxItems: 200
                items:
                  type: object
                  additionalProperties: false
                  required:
                    - from
                    - to
                  properties:
                    from:
                      type: string
                      maxLength: 200
                    to:
                      type: string
                      maxLength: 200
              rationale:
                type: string
                maxLength: 4000
        metadata:
          type: object
          properties:
            author:
              type: string
            source:
              type: string
            change_ticket:
              type: string
            signal_admission:
              $ref: "#/components/schemas/SemanticSignalAdmissionPolicy"
            requires_approval:
              type: boolean
            drupal:
              type: object
              additionalProperties: false
              required:
                - template
                - revision
                - limits_by_currency
                - limits_digest
              properties:
                template:
                  const: drupal-commerce-v2
                revision:
                  type: integer
                  minimum: 0
                  maximum: 2147483647
                limits_digest:
                  type: string
                  pattern: ^sha256:[a-f0-9]{64}$
                limits_by_currency:
                  type: object
                  minProperties: 1
                  maxProperties: 32
                  propertyNames:
                    pattern: ^[A-Z]{3}$
                  additionalProperties:
                    $ref: "#/components/schemas/DrupalCurrencyLimits"
          additionalProperties: false
        signature:
          type: object
          properties:
            algo:
              type: string
            digest:
              type: string
            signed_at:
              type: string
              format: date-time
            signed_by:
              type: string
          additionalProperties: false
        commerce_preflight:
          type: object
          properties:
            version:
              type: string
              const: commerce-preflight-v2
            max_fact_age_seconds:
              type: integer
              minimum: 1
              maximum: 86400
            allowed_sources:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 120
                pattern: ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$
              minItems: 1
              maxItems: 100
            checks:
              type: object
              properties:
                P01:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        floor_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - floor_percent
                      additionalProperties: false
                P02:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        tolerance_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - tolerance_percent
                      additionalProperties: false
                P03:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        minimum_available:
                          type: integer
                          minimum: 0
                          maximum: 1000000000
                      required:
                        - enabled
                        - minimum_available
                      additionalProperties: false
                P04:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        mode:
                          type: string
                          enum:
                            - allow
                            - block
                        countries:
                          type: array
                          items:
                            type: string
                            pattern: ^[A-Z]{2}$
                          maxItems: 250
                      required:
                        - enabled
                        - mode
                        - countries
                      additionalProperties: false
                P05:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_concurrent_discounts:
                          type: integer
                          minimum: 0
                          maximum: 32
                      required:
                        - enabled
                        - max_concurrent_discounts
                      additionalProperties: false
                P06:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        tolerance_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - tolerance_percent
                      additionalProperties: false
                P07:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_redemptions:
                          type: integer
                          minimum: 1
                          maximum: 1000000000
                        new_account_age_days:
                          type: number
                          minimum: 0
                          maximum: 100000
                      required:
                        - enabled
                        - max_redemptions
                        - new_account_age_days
                      additionalProperties: false
                P08:
                  type: object
                  properties:
                    enabled:
                      type: boolean
                  required:
                    - enabled
                  additionalProperties: false
                P09:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        amount:
                          type: number
                          minimum: 0
                          maximum: 1000000000000
                        currency:
                          type: string
                          pattern: ^[A-Z]{3}$
                      required:
                        - enabled
                        - amount
                        - currency
                      additionalProperties: false
                P10:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_prior_refunds:
                          type: integer
                          minimum: 0
                          maximum: 1000000000
                      required:
                        - enabled
                        - max_prior_refunds
                      additionalProperties: false
                P11:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        return_window_days:
                          type: integer
                          minimum: 0
                          maximum: 3650
                      required:
                        - enabled
                        - return_window_days
                      additionalProperties: false
                P12:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        unattended_limit:
                          type: object
                          properties:
                            amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            currency:
                              type: string
                              pattern: ^[A-Z]{3}$
                          required:
                            - amount
                            - currency
                          additionalProperties: false
                      required:
                        - enabled
                        - unattended_limit
                      additionalProperties: false
                P13:
                  type: object
                  properties:
                    enabled:
                      type: boolean
                  required:
                    - enabled
                  additionalProperties: false
                P14:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        window_days:
                          type: integer
                          minimum: 0
                          maximum: 3650
                      required:
                        - enabled
                        - window_days
                      additionalProperties: false
                P15:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        floor:
                          type: object
                          properties:
                            amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            currency:
                              type: string
                              pattern: ^[A-Z]{3}$
                          required:
                            - amount
                            - currency
                          additionalProperties: false
                      required:
                        - enabled
                        - floor
                      additionalProperties: false
                P16:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        minimum_annualized_yield_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - minimum_annualized_yield_percent
                      additionalProperties: false
              additionalProperties: false
          required:
            - version
            - max_fact_age_seconds
            - allowed_sources
            - checks
          additionalProperties: false
        commerce_history:
          type: object
          properties:
            version:
              type: string
              const: commerce-marketplace-history-policy-v1
            price_reference:
              type: object
              properties:
                kind:
                  type: string
                  const: recorded_order_original_price
                max_markdown_percent:
                  type: number
                  minimum: 0
                  maximum: 100
              required:
                - kind
                - max_markdown_percent
              additionalProperties: false
          required:
            - version
            - price_reference
          additionalProperties: false
      additionalProperties: false
    SemanticSignalAdmissionPolicy:
      type: object
      additionalProperties: false
      description: Deterministic trust gate for typed semantic evidence.
      properties:
        allowed_producers:
          type: array
          maxItems: 100
          uniqueItems: true
          items:
            type: string
        allowed_detector_versions:
          type: array
          maxItems: 100
          uniqueItems: true
          items:
            type: string
        require_evidence_digest:
          type: boolean
        minimum_confidence_basis_points:
          type: integer
          minimum: 0
          maximum: 10000
        required_signal_paths:
          type: array
          maxItems: 50
          uniqueItems: true
          items:
            type: string
        on_failure:
          type: string
          enum:
            - ESCALATE
            - AUTO_REJECT
    PersistedSemanticSignalMetadata:
      type: object
      additionalProperties: false
      required:
        - schema_version
        - signal_id
        - kind
        - detector_version
        - observed_at
        - confidence_basis_points
        - evidence_digest
        - value_digest
        - material
      properties:
        schema_version:
          type: string
          const: "1.0"
        signal_id:
          type: string
          minLength: 1
          maxLength: 200
        kind:
          type: string
          pattern: ^(intent_risk|scope_drift|data_sensitivity|suspected_exfiltration|[a-z0-9][a-z0-9.-]{0,62}:[a-z0-9][a-z0-9._-]{0,119})$
        detector_version:
          type: string
          minLength: 1
          maxLength: 200
        observed_at:
          type: string
          format: date-time
        confidence_basis_points:
          type: integer
          minimum: 0
          maximum: 10000
        evidence_digest:
          type:
            - string
            - "null"
          pattern: ^sha256:[0-9a-f]{64}$
        value_digest:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        material:
          type: boolean
    ProtocolSignalEnvelope:
      type: object
      additionalProperties: false
      required:
        - protocol_version
        - envelope_id
        - org_id
        - source
        - domain
        - metric_name
        - metric_type
        - value
        - recorded_at
        - ingested_at
      properties:
        protocol_version:
          type: string
          pattern: ^1\.[0-9]+(\.[0-9]+)?$
        envelope_id:
          type: string
          format: uuid
        org_id:
          type: string
        source:
          type: object
          additionalProperties: false
          required:
            - provider
            - mode
          properties:
            provider:
              type: string
            connector_id:
              type: string
            mode:
              type: string
              enum:
                - DIRECT_API
                - CUSTOMER_INFRA
                - WEBHOOK
                - MANUAL
        domain:
          type: string
        metric_name:
          type: string
        metric_type:
          type: string
          enum:
            - gauge
            - counter
            - event
            - categorical
        value: {}
        unit:
          type: string
        recorded_at:
          type: string
          format: date-time
        ingested_at:
          type: string
          format: date-time
        dimensions:
          type: object
          additionalProperties: true
        semantic:
          $ref: "#/components/schemas/PersistedSemanticSignalMetadata"
        evidence:
          type: array
          maxItems: 100
          items:
            type: string
        trace:
          type: object
          additionalProperties: true
        hash:
          type: string
          pattern: ^[A-Fa-f0-9]{64}$
    PolicyRule:
      type: object
      required:
        - rule_id
        - name
        - decision_domain
        - when
        - then
        - priority
        - enabled
      properties:
        rule_id:
          type: string
        name:
          type: string
        decision_domain:
          type: string
        when:
          type: object
          additionalProperties: true
        then:
          type: object
          required:
            - action
          properties:
            action:
              type: string
              enum:
                - REQUIRE_REVIEW
                - AUTO_APPROVE
                - AUTO_REJECT
                - ESCALATE
                - REQUEST_INFO
            severity:
              type: string
              enum:
                - routine
                - elevated
                - urgent
            assignee_role:
              type: string
            sla_minutes:
              type: integer
              minimum: 1
            authority:
              type: object
              additionalProperties: false
              required:
                - reason_codes
                - selector
                - verification_requirements
                - resolution
                - expires_in_seconds
              properties:
                reason_codes:
                  type: array
                  minItems: 1
                  maxItems: 20
                  uniqueItems: true
                  items:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{1,119}$
                selector:
                  $ref: "#/components/schemas/AuthoritySelector"
                verification_requirements:
                  $ref: "#/components/schemas/AuthorityVerificationRequirements"
                resolution:
                  $ref: "#/components/schemas/AuthorityResolutionPolicy"
                expires_in_seconds:
                  type: integer
                  minimum: 60
                  maximum: 3600
          additionalProperties: false
        priority:
          type: integer
        enabled:
          type: boolean
        rationale:
          type: string
      additionalProperties: false
    PolicyDraftSource:
      type: object
      required:
        - label
        - source_type
      description: |
        One manual policy source. Provide `content` (inline text) or
        `content_base64` (file bytes; text is extracted server-side from PDF,
        XLSX, XML, HTML, JSON, and plain-text documents such as transaction
        or audit logs).
      properties:
        label:
          type: string
          maxLength: 200
        source_type:
          type: string
          maxLength: 80
          description: Caller-chosen tag, e.g. upload, jira, confluence, audit_log.
        content:
          type: string
          maxLength: 250000
        content_base64:
          type: string
          maxLength: 10000000
        content_type:
          type: string
          maxLength: 200
        file_name:
          type: string
          maxLength: 300
        external_reference:
          type: string
          maxLength: 500
      additionalProperties: false
    PolicyDraftRequest:
      type: object
      description: |
        Provide manual sources, live connector ids, or both — at least one of the two is required.
      properties:
        suggested_name:
          type: string
          maxLength: 160
        workflow_key:
          type: string
          maxLength: 120
        sources:
          type: array
          maxItems: 20
          items:
            $ref: "#/components/schemas/PolicyDraftSource"
        live_connector_ids:
          type: array
          maxItems: 6
          description: |
            Org policy-source connectors to pull live at draft time (Jira, Confluence, Notion, Google Drive, Git repository, SAP).
          items:
            type: string
            format: uuid
      additionalProperties: false
    PolicyStrategyDraftResponse:
      type: object
      required:
        - org
        - generated_at
        - draft
      properties:
        org:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
        generated_at:
          type: string
          format: date-time
        draft:
          type: object
          required:
            - used_llm
            - suggested_name
            - workflow_key
            - summary
            - strategy
          properties:
            used_llm:
              type: boolean
            suggested_name:
              type: string
            workflow_key:
              type: string
            summary:
              type: string
            strategy:
              type: object
              description: |
                The strategy-shaped draft, including `strategy_rules` with clauses bucketed for automatic execution, escalation, and blocking.
              additionalProperties: true
            extracted_sources:
              type: array
              items: {}
            review_checklist:
              type: array
              items: {}
            open_questions:
              type: array
              items: {}
            warnings:
              type: array
              items: {}
          additionalProperties: true
      additionalProperties: false
    PolicyPackDraftResponse:
      type: object
      required:
        - org
        - generated_at
        - pack_id
        - draft
      properties:
        org:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
        generated_at:
          type: string
          format: date-time
        pack_id:
          type: string
          format: uuid
          description: The persisted draft pack, ready for review and finalization.
        draft:
          type: object
          required:
            - used_llm
            - suggested_name
            - workflow_key
            - pack
            - review
          properties:
            status:
              type: string
            used_llm:
              type: boolean
            suggested_name:
              type: string
            workflow_key:
              type: string
            pack:
              type: object
              description: |
                The executable pack: compiler-validated rules of the shape `{ name, all|any: [{field, op, value}], action }` with action one of allow, block, restrain, escalate.
              properties:
                rules:
                  type: array
                  items:
                    type: object
                    additionalProperties: true
              additionalProperties: true
            source_summary:
              type: array
              items: {}
            review:
              type: array
              description: |
                Clauses that could not become executable predicates — returned for human review instead of being synthesized into rules.
              items: {}
          additionalProperties: true
      additionalProperties: false
    ArtifactAcceptedResponse:
      type: object
      required:
        - accepted
        - service
        - protocol_version
        - artifact
        - artifact_id
        - org_id
        - received_at
      properties:
        accepted:
          type: boolean
        service:
          type: string
        protocol_version:
          type: string
        artifact:
          type: string
          enum:
            - policy_bundle
            - signal_envelope
        artifact_id:
          type: string
        org_id:
          type: string
        received_at:
          type: string
          format: date-time
      additionalProperties: true
    HealthResponse:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          examples:
            - ok
        version:
          type: string
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
        message:
          type: string
        request_id:
          type: string
        status:
          type: integer
    DrupalConnectStartRequest:
      type: object
      additionalProperties: false
      required:
        - site_url
        - site_uuid
        - business_name
        - billing_email
        - public_key
        - terms_accepted
      properties:
        site_url:
          type: string
          format: uri
          maxLength: 2048
          description: The site's base URL.
        site_uuid:
          type: string
          minLength: 1
          maxLength: 128
          description: The Drupal site UUID (system.site uuid). A site Decionis cannot reach is bound by it, as drupal://site/<uuid>.
        business_name:
          type: string
          minLength: 1
          maxLength: 200
        billing_email:
          type: string
          format: email
          maxLength: 320
          description: Where the 6-digit code is sent if the site cannot be reached.
        public_key:
          type: string
          pattern: ^[A-Za-z0-9_-]{43}$
          description: The site key's raw 32-byte Ed25519 public key, base64url without padding.
        terms_accepted:
          type: boolean
          not:
            const: false
    DrupalConnectStarted:
      type: object
      additionalProperties: false
      required:
        - connect_id
        - challenge
        - expires_in_seconds
      properties:
        connect_id:
          type: string
          format: uuid
        challenge:
          type: string
          description: Single-use. The site serves it, signed, at /.well-known/decionis-challenge.
        expires_in_seconds:
          type: integer
          minimum: 1
    DrupalConnectVerifyRequest:
      type: object
      additionalProperties: false
      required:
        - protocol
        - purpose
        - connect_id
        - signature
      properties:
        protocol:
          type: string
          const: decionis-drupal-connect/1
        purpose:
          type: string
          const: verify
        connect_id:
          type: string
          format: uuid
        signature:
          $ref: "#/components/schemas/DrupalSiteSignature"
    DrupalConnectCodeRequest:
      type: object
      additionalProperties: false
      required:
        - protocol
        - purpose
        - connect_id
        - code
        - signature
      properties:
        protocol:
          type: string
          const: decionis-drupal-connect/1
        purpose:
          type: string
          const: code
        connect_id:
          type: string
          format: uuid
        code:
          type: string
          pattern: ^[0-9]{6}$
        signature:
          $ref: "#/components/schemas/DrupalSiteSignature"
    DrupalSiteSignature:
      type: string
      pattern: ^[A-Za-z0-9_-]{86}$
      description: The site key's Ed25519 signature, base64url without padding, over the key-sorted canonical JSON of the body without `signature`.
    DrupalConnected:
      type: object
      additionalProperties: false
      required:
        - status
        - org_id
        - api_key
        - mode
        - entitlement
      properties:
        status:
          type: string
          const: connected
        org_id:
          type: string
          format: uuid
        api_key:
          type: string
          description: The site's least-privilege key (MEMBER; decision:read, decision:write). Shown once; only its hash is kept.
        mode:
          type: string
          const: shadow
        entitlement:
          $ref: "#/components/schemas/DrupalEntitlement"
        initial_policy:
          $ref: "#/components/schemas/DrupalPolicyReceipt"
        billing_contact_confirmed:
          type: boolean
          description: Accounts confirmed the designated billing mailbox; this alone grants no membership or billing permission.
    DrupalConnectCodeSent:
      type: object
      additionalProperties: false
      required:
        - status
      properties:
        status:
          type: string
          const: code_sent
    DrupalSiteRequest:
      type: object
      additionalProperties: false
      required:
        - org_id
      properties:
        org_id:
          type: string
          format: uuid
    DrupalSiteStatus:
      type: object
      additionalProperties: false
      required:
        - org_id
        - site_url
        - mode
        - entitlement
      properties:
        org_id:
          type: string
          format: uuid
        site_url:
          type: string
          description: What the organization is bound to, the public URL or drupal://site/<uuid>.
        mode:
          type: string
          const: shadow
        entitlement:
          $ref: "#/components/schemas/DrupalEntitlement"
    DrupalEntitlement:
      description: Accounts-owned authority. Null is explicit absence and grants no enforcement. Trial and grace require a future ends_at; other states omit it.
      oneOf:
        - type: "null"
        - type: object
          additionalProperties: false
          required:
            - state
            - enforcement
          properties:
            state:
              type: string
              enum:
                - trial_available
                - trial
                - paid
                - grace
                - expired
            enforcement:
              type: boolean
            ends_at:
              type: string
              format: date-time
            subscribe_url:
              type: string
              format: uri
              pattern: ^https://
              description: Trusted authorized Build billing continuation, when available.
          allOf:
            - if:
                properties:
                  state:
                    enum:
                      - trial
                      - grace
              then:
                required:
                  - ends_at
                properties:
                  enforcement:
                    const: true
              else:
                not:
                  required:
                    - ends_at
            - if:
                properties:
                  state:
                    const: paid
              then:
                properties:
                  enforcement:
                    const: true
            - if:
                properties:
                  state:
                    enum:
                      - trial_available
                      - expired
              then:
                properties:
                  enforcement:
                    const: false
    DrupalEntitlementResponse:
      type: object
      additionalProperties: false
      required:
        - org_id
        - entitlement
      properties:
        org_id:
          type: string
          format: uuid
        entitlement:
          $ref: "#/components/schemas/DrupalEntitlement"
    DrupalCurrencyLimits:
      type: object
      additionalProperties: false
      required:
        - refund_limit
        - margin_floor
        - stacking_ceiling
        - repeat_limit
      properties:
        refund_limit:
          type: number
          minimum: 0
          maximum: 1000000000000
        margin_floor:
          type: number
          minimum: 0
          maximum: 100
        stacking_ceiling:
          type: number
          minimum: 0
          maximum: 100
        repeat_limit:
          type: integer
          minimum: 1
          maximum: 1000000000
    DrupalPolicyLimitsRequest:
      type: object
      additionalProperties: false
      required:
        - org_id
        - limits_by_currency
      properties:
        org_id:
          type: string
          format: uuid
        expected_policy_version:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 120
          description: Null or omitted only for the untouched Drupal bootstrap.
        limits_by_currency:
          type: object
          minProperties: 1
          maxProperties: 32
          propertyNames:
            pattern: ^[A-Z]{3}$
          additionalProperties:
            $ref: "#/components/schemas/DrupalCurrencyLimits"
    DrupalPolicyReceipt:
      type: object
      additionalProperties: false
      required:
        - org_id
        - policy_version
        - bundle_id
        - limits_digest
      properties:
        org_id:
          type: string
          format: uuid
        policy_version:
          type: string
          minLength: 1
          maxLength: 120
        bundle_id:
          type: string
          format: uuid
        limits_digest:
          type: string
          pattern: ^sha256:[a-f0-9]{64}$
    DrupalSiteDisconnected:
      type: object
      additionalProperties: false
      required:
        - disconnected
        - org_id
      properties:
        disconnected:
          type: boolean
          not:
            const: false
        org_id:
          type: string
          format: uuid
    OpsGateRequest:
      type: object
      description: A spend/disbursement payload for the ops spend-control vertical pack.
      properties:
        object_type:
          type: string
          examples:
            - Expense
            - VendorPayment
            - Refund
            - Credit
        object_id:
          type: string
        action:
          type: string
        proposed_state:
          type: object
          description: amount, currency, vendor_id, invoice_number, vendor_status, expense_threshold, refund_limit, credit_limit, etc.
          additionalProperties: true
        actor:
          type: object
          description: The acting principal and its role (e.g. role Controller or CFO).
          additionalProperties: true
        context:
          type: object
          description: requested_by, approved_by, second_approver, org_id, etc.
          additionalProperties: true
      additionalProperties: true
    OpsGateVerdict:
      type: object
      properties:
        decision:
          type: string
          enum:
            - ALLOW
            - BLOCK
            - ESCALATE
            - DELAY
        outcome:
          type: string
          enum:
            - APPROVE
            - REJECT
            - ESCALATE
            - REVIEW
        reason:
          type: string
        required_action:
          type:
            - string
            - "null"
        gate:
          type: string
          enum:
            - spend_admission
            - disbursement_authority
        decision_domain:
          type: string
          enum:
            - OPS_SPEND_ADMISSION
            - OPS_DISBURSEMENT_AUTHORITY
        rule_id:
          type:
            - string
            - "null"
        duplicate_suspected:
          type: boolean
        policy_version:
          type: string
        dossier_id:
          type:
            - string
            - "null"
        dossier_sha256:
          type:
            - string
            - "null"
        ledger_entry_id:
          type:
            - string
            - "null"
        ledger_entry_hash:
          type:
            - string
            - "null"
        federated:
          type: boolean
        pipeline:
          type: boolean
        idempotent_replay:
          type: boolean
      additionalProperties: true
    SurfaceDecisionRequest:
      type: object
      required:
        - surface
        - decision
        - dossier_id
        - dossier_sha256
      properties:
        surface:
          type: string
          examples:
            - amazon
            - ebay
            - shopify
        decision:
          type: string
          enum:
            - authorize
            - block
            - review
        dossier_id:
          type: string
        dossier_sha256:
          type: string
        org_id:
          type: string
          format: uuid
        mode:
          type: string
          enum:
            - shadow
            - enforced
        dossier:
          type: object
          description: The full signed surface dossier. When present it is persisted and made exportable as a proof packet; when omitted only a ledger entry is appended.
          additionalProperties: true
      additionalProperties: true
    SurfaceDecisionResponse:
      type: object
      properties:
        federated:
          type: boolean
        persisted:
          type: boolean
        surface:
          type: string
        org_id:
          type: string
        dossier_id:
          type: string
        ledger_entry_id:
          type:
            - string
            - "null"
        ledger_entry_hash:
          type:
            - string
            - "null"
        ledger_error:
          type:
            - string
            - "null"
      additionalProperties: true
    EbayChallengeResponse:
      type: object
      required:
        - challengeResponse
      properties:
        challengeResponse:
          type: string
          description: Hex SHA-256 of challengeCode + verificationToken + endpointURL.
    MarketplaceDeletionNotification:
      type: object
      description: eBay account-deletion notification payload (subset Decionis reads).
      properties:
        metadata:
          type: object
          properties:
            topic:
              type: string
            schemaVersion:
              type: string
          additionalProperties: true
        notification:
          type: object
          properties:
            notificationId:
              type: string
            data:
              type: object
              properties:
                username:
                  type: string
                userId:
                  type: string
                eiasToken:
                  type: string
              additionalProperties: true
          additionalProperties: true
      additionalProperties: true
    DecisionDossierProofPacket:
      type: object
      properties:
        service:
          type: string
        protocol_version:
          type: string
        packet_type:
          type: string
          examples:
            - decionis.decision_dossier.proof_packet
        packet_version:
          type: string
        issued_at:
          type: string
          format: date-time
        subject:
          type: object
          properties:
            org_id:
              type: string
            dossier_id:
              type: string
        dossier:
          type: object
          additionalProperties: true
        policy_snapshot:
          type:
            - object
            - "null"
          additionalProperties: true
        ledger_anchor:
          type: object
          additionalProperties: true
        proof_bundle:
          type:
            - object
            - "null"
          additionalProperties: true
        verification:
          type: object
          description: signature_verified, policy_snapshot_verified, chain_integrity_verified, proof_bundle_verified, and overall (VERIFIED | PARTIAL | UNVERIFIED).
          additionalProperties: true
        verify_instructions:
          type: object
          additionalProperties: true
      additionalProperties: true
    DecisionChainProofPacket:
      type: object
      description: Backward-compatible schema name for the authenticated Decision Chain verification report. The response is not signed, portable, or independently verifiable offline because source dossier and ledger bytes are not embedded.
      properties:
        service:
          type: string
        protocol_version:
          type: string
        packet_type:
          type: string
          examples:
            - decionis.decision_chain.proof_packet
        packet_version:
          type: string
        report_semantics:
          type: object
          additionalProperties: false
          required:
            - verification_mode
            - response_signed
            - source_evidence_embedded
            - portable
            - offline_verifiable
            - steps
          properties:
            verification_mode:
              type: string
              const: SERVER_STATE_AT_ISSUED_AT
            response_signed:
              type: boolean
              not:
                const: true
            source_evidence_embedded:
              type: boolean
              not:
                const: true
            portable:
              type: boolean
              not:
                const: true
            offline_verifiable:
              type: boolean
              not:
                const: true
            steps:
              type: array
              items:
                type: string
        issued_at:
          type: string
          format: date-time
        subject:
          type: object
          properties:
            org_id:
              type: string
            chain_id:
              type: string
        chain:
          type: object
          additionalProperties: true
        ledger_anchor:
          type: object
          additionalProperties: true
        links:
          type: array
          items:
            type: object
            additionalProperties: true
        overall:
          type: string
          description: Point-in-time server verification result, not a signature over this response.
          enum:
            - VERIFIED
            - PARTIAL
            - UNVERIFIED
        verify_instructions:
          type: object
          description: Explains the server-report boundary and how to obtain source evidence.
          additionalProperties: true
      additionalProperties: true
    AgentProvisionRequest:
      type: object
      properties:
        agent_name:
          type: string
          maxLength: 64
          description: Optional display name for the workspace, shown to the claiming owner.
      additionalProperties: false
    AgentProvisionLimits:
      type: object
      description: The caps on the anonymous lane, echoed so agents plan around them.
      properties:
        requests_per_minute:
          type: integer
          examples:
            - 10
        workspaces_per_network_per_day:
          type: integer
          examples:
            - 5
        governed_decisions_per_month:
          type: integer
          examples:
            - 50
        workspaces_service_wide_per_day:
          type: integer
          description: Service-wide daily ceiling across every network (present only when the deployment enables one). When minting answers 429 with PROVISION_LIMIT_REACHED and Retry-After, claim an existing workspace instead of retrying from a new address.
      additionalProperties: true
    AgentProvisionResponse:
      type: object
      required:
        - org_id
        - raw_key
        - provisional
        - limits
        - claim
        - next
      properties:
        org_id:
          type: string
          format: uuid
        raw_key:
          type: string
          description: The workspace's org API key. Returned exactly once — store it.
        provisional:
          type: boolean
          description: Always true at mint; the workspace stays provisional until claimed.
        limits:
          $ref: "#/components/schemas/AgentProvisionLimits"
        claim:
          type: object
          description: How to attach a human owner — the claim/start and claim/verify endpoints prefilled for this org, plus the note to surface to your operator. The key and dossier ledger survive the claim.
          additionalProperties: true
        next:
          type: object
          description: Suggested next calls, starting with a shadow-mode evaluate-decision.
          additionalProperties: true
      additionalProperties: true
    PublicDossierVerificationResponse:
      type: object
      required:
        - service
        - verified
        - cryptographically_verified
        - execution_eligible
        - execution_authority
        - generated_at
        - verification_status
        - proof_bundle
        - dossier
        - integrity
      properties:
        service:
          type: string
          examples:
            - decionis
        verified:
          type: boolean
          description: Compatibility result. Protocol 1.0 artifacts retain their original share-link verification semantics. When an Ed25519 proof bundle is present this equals its cryptographic signature result. This field is not an execution-eligibility statement.
        cryptographically_verified:
          type: boolean
          description: True only when every listed proof artifact verified against the published Ed25519 JWKS. This does not by itself establish execution eligibility.
        execution_eligible:
          type: boolean
          description: True only for a cryptographically valid Protocol 1.1 authoritative ALLOW whose required execution-authority artifacts and semantic commitments are proof-covered.
        execution_authority:
          type: object
          required:
            - protocol_version
            - required_artifact_coverage_verified
            - authority_classification
            - execution_eligible
          properties:
            protocol_version:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 120
              description: Signed protocol declaration when present. Historical, future, or otherwise unsupported values are echoed for diagnosis but never promoted to Protocol 1.1 execution eligibility.
            required_artifact_coverage_verified:
              type: boolean
            authority_classification:
              oneOf:
                - $ref: "#/components/schemas/AuthorityClassification"
                - type: "null"
            execution_eligible:
              type: boolean
          additionalProperties: false
        generated_at:
          type: string
          format: date-time
        verification_status:
          type: object
          description: Per-check breakdown — signature, policy snapshot, ledger chain, proof bundle — each with verified, severity, and detail.
          additionalProperties: true
        proof_bundle:
          type: object
          description: Ed25519 verification detail, the JWKS URL, and a self_verify command anyone can run offline with @decionis/verify.
          additionalProperties: true
        dossier:
          type: object
          description: Share-safe public projection. Categorical tokens pass; caller- minted values and identifiers are masked server-side; the policy snapshot is proven and pinned by hash but never shipped.
          additionalProperties: true
        integrity:
          type: object
          additionalProperties: true
        verification:
          type: object
          description: Fresh expiring share links for this dossier (v2, org-scoped).
          additionalProperties: true
        signal_trace:
          type: array
          items:
            type: object
            additionalProperties: true
        overrides:
          type: object
          additionalProperties: true
        message:
          type: string
      additionalProperties: true
    PublicDossierProofBundleResponse:
      type: object
      required:
        - service
        - dossier_id
        - dossier_payload
        - jwks_url
      properties:
        service:
          type: string
          examples:
            - decionis
        dossier_id:
          type: string
          format: uuid
        dossier_payload:
          type: object
          description: Only what verification needs — the signed documents at their JSON-pointer paths plus integrity.proof_bundle. Nothing else from the dossier payload.
          additionalProperties: true
        jwks_url:
          type: string
          format: uri
        jwks_path:
          type: string
        verify_with:
          type: object
          description: The exact npx @decionis/verify command for this bundle.
          additionalProperties: true
        message:
          type: string
      additionalProperties: true
    PublicDossierReproduceResponse:
      type: object
      required:
        - service
        - dossier_id
        - reproduction
      properties:
        service:
          type: string
          examples:
            - decionis
        dossier_id:
          type: string
          format: uuid
        reproduction:
          type: object
          description: The deterministic re-run result — same inputs plus same policy bundle, compared against the recorded verdict.
          additionalProperties: true
        message:
          type: string
      additionalProperties: true
    OrgClaimStartRequest:
      type: object
      required:
        - owner_email
      properties:
        owner_email:
          type: string
          format: email
          maxLength: 200
      additionalProperties: false
    OrgClaimStartResponse:
      type: object
      required:
        - verification
      properties:
        verification:
          type: object
          required:
            - channel
            - owner_email
            - expires_at
          properties:
            channel:
              type: string
              enum:
                - email
            owner_email:
              type: string
              format: email
            expires_at:
              type: string
              format: date-time
            email_sent:
              type: boolean
            email_delivery_mode:
              type: string
          additionalProperties: true
      additionalProperties: true
    OrgClaimVerifyRequest:
      type: object
      required:
        - owner_email
        - otp_code
      properties:
        owner_email:
          type: string
          format: email
          maxLength: 200
        otp_code:
          type: string
          pattern: ^\d{6}$
        password:
          type: string
          minLength: 8
          maxLength: 256
          description: Required only when the email has no existing account — it becomes sign-in.
        name:
          type: string
          maxLength: 200
      additionalProperties: false
    OrgClaimVerifyResponse:
      type: object
      required:
        - claimed
        - org
        - user
      properties:
        claimed:
          type: boolean
        org:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type:
                - string
                - "null"
          additionalProperties: true
        user:
          type: object
          properties:
            id:
              type: string
            email:
              type: string
              format: email
            name:
              type:
                - string
                - "null"
          additionalProperties: true
        existing_user:
          type: boolean
        next:
          type: object
          description: Workspace and onboarding paths for the newly attached owner.
          additionalProperties: true
      additionalProperties: true
    OrgVerificationLinkRotationResponse:
      type: object
      required:
        - rotated
        - verification_link_secret_version
      properties:
        rotated:
          type: boolean
        verification_link_secret_version:
          type: integer
          description: The new per-org secret version; freshly minted links use it.
        message:
          type: string
      additionalProperties: true
    CommercePreflightReadiness:
      type: object
      properties:
        version:
          type: string
          const: commerce-preflight-readiness-v1
        org_id:
          type: string
          format: uuid
        checked_at:
          type: string
          format: date-time
          maxLength: 40
          allOf:
            - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$
        preflight_version:
          type: string
          const: commerce-preflight-v2
        evaluator_version:
          type: string
          const: policy-graph/1.1+commerce-preflight/2.0
        policy_resolution:
          type: object
          properties:
            requested_policy_version:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 100
            resolved_policy_version:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 100
            status:
              type: string
              enum:
                - exact_match
                - newest_active
                - requested_not_found
                - policy_guard
          required:
            - requested_policy_version
            - resolved_policy_version
            - status
          additionalProperties: false
        selected_policy:
          type:
            - object
            - "null"
          properties:
            bundle_id:
              type: string
              format: uuid
            version:
              type: string
              minLength: 1
              maxLength: 100
            effective_from:
              type:
                - string
                - "null"
              format: date-time
              maxLength: 40
              allOf:
                - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$
            effective_to:
              type:
                - string
                - "null"
              format: date-time
              maxLength: 40
              allOf:
                - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$
            rules_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            parameters_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            commerce_preflight_digest:
              type:
                - string
                - "null"
              pattern: ^sha256:[a-f0-9]{64}$
          required:
            - bundle_id
            - version
            - effective_from
            - effective_to
            - rules_sha256
            - parameters_sha256
            - commerce_preflight_digest
          additionalProperties: false
        configuration:
          type:
            - object
            - "null"
          properties:
            version:
              type: string
              const: commerce-preflight-v2
            max_fact_age_seconds:
              type: integer
              minimum: 1
              maximum: 86400
            allowed_sources:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 120
                pattern: ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$
              minItems: 1
              maxItems: 100
            checks:
              type: object
              properties:
                P01:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        floor_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - floor_percent
                      additionalProperties: false
                P02:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        tolerance_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - tolerance_percent
                      additionalProperties: false
                P03:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        minimum_available:
                          type: integer
                          minimum: 0
                          maximum: 1000000000
                      required:
                        - enabled
                        - minimum_available
                      additionalProperties: false
                P04:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        mode:
                          type: string
                          enum:
                            - allow
                            - block
                        countries:
                          type: array
                          items:
                            type: string
                            pattern: ^[A-Z]{2}$
                          maxItems: 250
                      required:
                        - enabled
                        - mode
                        - countries
                      additionalProperties: false
                P05:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_concurrent_discounts:
                          type: integer
                          minimum: 0
                          maximum: 32
                      required:
                        - enabled
                        - max_concurrent_discounts
                      additionalProperties: false
                P06:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        tolerance_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - tolerance_percent
                      additionalProperties: false
                P07:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_redemptions:
                          type: integer
                          minimum: 1
                          maximum: 1000000000
                        new_account_age_days:
                          type: number
                          minimum: 0
                          maximum: 100000
                      required:
                        - enabled
                        - max_redemptions
                        - new_account_age_days
                      additionalProperties: false
                P08:
                  type: object
                  properties:
                    enabled:
                      type: boolean
                  required:
                    - enabled
                  additionalProperties: false
                P09:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        amount:
                          type: number
                          minimum: 0
                          maximum: 1000000000000
                        currency:
                          type: string
                          pattern: ^[A-Z]{3}$
                      required:
                        - enabled
                        - amount
                        - currency
                      additionalProperties: false
                P10:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        max_prior_refunds:
                          type: integer
                          minimum: 0
                          maximum: 1000000000
                      required:
                        - enabled
                        - max_prior_refunds
                      additionalProperties: false
                P11:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        return_window_days:
                          type: integer
                          minimum: 0
                          maximum: 3650
                      required:
                        - enabled
                        - return_window_days
                      additionalProperties: false
                P12:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        unattended_limit:
                          type: object
                          properties:
                            amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            currency:
                              type: string
                              pattern: ^[A-Z]{3}$
                          required:
                            - amount
                            - currency
                          additionalProperties: false
                      required:
                        - enabled
                        - unattended_limit
                      additionalProperties: false
                P13:
                  type: object
                  properties:
                    enabled:
                      type: boolean
                  required:
                    - enabled
                  additionalProperties: false
                P14:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        window_days:
                          type: integer
                          minimum: 0
                          maximum: 3650
                      required:
                        - enabled
                        - window_days
                      additionalProperties: false
                P15:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        floor:
                          type: object
                          properties:
                            amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            currency:
                              type: string
                              pattern: ^[A-Z]{3}$
                          required:
                            - amount
                            - currency
                          additionalProperties: false
                      required:
                        - enabled
                        - floor
                      additionalProperties: false
                P16:
                  anyOf:
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: true
                      required:
                        - enabled
                      additionalProperties: false
                    - type: object
                      properties:
                        enabled:
                          type: boolean
                          not:
                            const: false
                        minimum_annualized_yield_percent:
                          type: number
                          minimum: 0
                          maximum: 100
                      required:
                        - enabled
                        - minimum_annualized_yield_percent
                      additionalProperties: false
              additionalProperties: false
          required:
            - version
            - max_fact_age_seconds
            - allowed_sources
            - checks
          additionalProperties: false
        checks:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                enum:
                  - P01
                  - P02
                  - P03
                  - P04
                  - P05
                  - P06
                  - P07
                  - P08
                  - P09
                  - P10
                  - P11
                  - P12
                  - P13
                  - P14
                  - P15
                  - P16
              status:
                type: string
                enum:
                  - enabled
                  - disabled
                  - missing
                  - unsupported
                  - unavailable
            required:
              - id
              - status
            additionalProperties: false
          minItems: 16
          maxItems: 16
        counts:
          type: object
          properties:
            enabled:
              type: integer
              minimum: 0
              maximum: 16
            disabled:
              type: integer
              minimum: 0
              maximum: 16
            missing:
              type: integer
              minimum: 0
              maximum: 16
            unsupported:
              type: integer
              minimum: 0
              maximum: 16
            unavailable:
              type: integer
              minimum: 0
              maximum: 16
          required:
            - enabled
            - disabled
            - missing
            - unsupported
            - unavailable
          additionalProperties: false
        configuration_complete:
          type: boolean
        all_disabled:
          type: boolean
        diagnostics:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
                enum:
                  - MISSING_ORG_POLICY_BUNDLE
                  - NO_ACTIVE_ORG_POLICY_BUNDLE
                  - REQUESTED_POLICY_BUNDLE_NOT_FOUND
                  - COMMERCE_POLICY_MISSING
                  - COMMERCE_POLICY_UNSUPPORTED
                  - CHECK_POLICY_MISSING
                  - ALL_CHECKS_DISABLED
              path:
                type: string
                minLength: 1
                maxLength: 200
                pattern: ^[A-Za-z0-9_.]+$
            required:
              - code
              - path
            additionalProperties: false
          maxItems: 32
      required:
        - version
        - org_id
        - checked_at
        - preflight_version
        - evaluator_version
        - policy_resolution
        - selected_policy
        - configuration
        - checks
        - counts
        - configuration_complete
        - all_disabled
        - diagnostics
      additionalProperties: false
    CommerceErpSources:
      type: object
      properties:
        version:
          type: string
          const: commerce-erp-sources-v1
        org_id:
          type: string
          format: uuid
        connections:
          type: array
          items:
            type: object
            properties:
              connection_id:
                type: string
                format: uuid
              platform:
                type: string
                const: business-central
              display_name:
                type: string
                minLength: 1
                maxLength: 80
              environment_name:
                type: string
                minLength: 1
                maxLength: 80
              revision:
                type: integer
                exclusiveMinimum: 0
                minimum: -9007199254740991
                maximum: 9007199254740991
              views:
                type: array
                minItems: 2
                maxItems: 2
                prefixItems:
                  - type: string
                    const: current_orders
                  - type: string
                    const: posted_invoices
                items:
                  type: string
                  enum:
                    - current_orders
                    - posted_invoices
              history_available:
                type: boolean
            required:
              - connection_id
              - platform
              - display_name
              - environment_name
              - revision
              - views
              - history_available
            additionalProperties: false
          maxItems: 20
        coverage:
          type: object
          properties:
            connection_limit:
              type: number
              const: 20
            truncated:
              type: boolean
          required:
            - connection_limit
            - truncated
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connections
        - coverage
        - execution_available
      additionalProperties: false
    CommerceErpOrders:
      type: object
      properties:
        version:
          type: string
          const: commerce-erp-orders-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        data:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.read.v1
            platform:
              type: string
              const: business-central
            view:
              type: string
              enum:
                - posted_invoices
                - current_orders
            observed_at:
              type: string
              format: date-time
            window:
              type:
                - object
                - "null"
              properties:
                days:
                  type: number
                  const: 90
                start_date:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                end_date_exclusive:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                date_field:
                  type: string
                  const: postingDate
                anchor:
                  type: string
                  const: server_utc_date
              required:
                - days
                - start_date
                - end_date_exclusive
                - date_field
                - anchor
              additionalProperties: false
            documents:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  transaction_date:
                    type: string
                    pattern: ^\d{4}-\d{2}-\d{2}$
                  date_precision:
                    type: string
                    const: day
                  date_field:
                    type: string
                    enum:
                      - postingDate
                      - orderDate
                  status:
                    type: string
                    enum:
                      - Draft
                      - In Review
                      - Open
                      - Paid
                  currency:
                    type:
                      - string
                      - "null"
                    pattern: ^[A-Z]{3}$
                  currency_source:
                    type: string
                    enum:
                      - document
                      - company
                      - unavailable
                  net_amount_excluding_tax:
                    type:
                      - number
                      - "null"
                    minimum: 0
                    maximum: 1000000000000
                  cost_basis:
                    const: null
                  cost_currency:
                    const: null
                  cost_provenance:
                    type: string
                    const: unavailable
                  lines:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        quantity:
                          type:
                            - number
                            - "null"
                          minimum: 0
                          maximum: 1000000000000
                        net_amount_excluding_tax:
                          type:
                            - number
                            - "null"
                          minimum: 0
                          maximum: 1000000000000
                      required:
                        - id
                        - quantity
                        - net_amount_excluding_tax
                      additionalProperties: false
                    maxItems: 100
                  lines_complete:
                    type: boolean
                required:
                  - id
                  - transaction_date
                  - date_precision
                  - date_field
                  - status
                  - currency
                  - currency_source
                  - net_amount_excluding_tax
                  - cost_basis
                  - cost_currency
                  - cost_provenance
                  - lines
                  - lines_complete
                additionalProperties: false
              maxItems: 100
            coverage:
              type: object
              properties:
                document_limit:
                  type: number
                  const: 100
                complete:
                  type: boolean
                truncated:
                  type: boolean
                lines_complete:
                  type: boolean
                reasons:
                  type: array
                  items:
                    type: string
                    enum:
                      - historical_cost_unavailable
                      - document_limit
                      - line_limit
                      - page_limit
                      - duplicate_document
                      - duplicate_line
                      - date_excluded
                      - status_excluded
                      - currency_unavailable
                      - amount_unavailable
                      - response_limit
                  maxItems: 12
              required:
                - document_limit
                - complete
                - truncated
                - lines_complete
                - reasons
              additionalProperties: false
            summary:
              type: object
              properties:
                documents_scanned:
                  type: integer
                  minimum: 0
                  maximum: 100
                documents_returned:
                  type: integer
                  minimum: 0
                  maximum: 100
                missing_cost:
                  type: integer
                  minimum: 0
                  maximum: 100
                missing_currency:
                  type: integer
                  minimum: 0
                  maximum: 100
                excluded_date:
                  type: integer
                  minimum: 0
                  maximum: 100
                excluded_status:
                  type: integer
                  minimum: 0
                  maximum: 100
                invalid_amount:
                  type: integer
                  minimum: 0
                  maximum: 100
                excluded_lines:
                  type: integer
                  minimum: 0
                  maximum: 10000
              required:
                - documents_scanned
                - documents_returned
                - missing_cost
                - missing_currency
                - excluded_date
                - excluded_status
                - invalid_amount
                - excluded_lines
              additionalProperties: false
          required:
            - version
            - platform
            - view
            - observed_at
            - window
            - documents
            - coverage
            - summary
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - data
        - execution_available
      additionalProperties: false
    CommerceHistoryStart:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        policy_version:
          type: string
          minLength: 1
          maxLength: 100
        idempotency_key:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[A-Za-z0-9._:-]+$
      required:
        - org_id
        - connection_id
        - policy_version
        - idempotency_key
      additionalProperties: false
    CommerceHistoryAssessment:
      type: object
      properties:
        version:
          type: string
          const: commerce-history-assessment-v1
        status:
          type: string
          const: completed
        mode:
          type: string
          const: historical_only
        org_id:
          type: string
          format: uuid
        assessment_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        assessed_at:
          type: string
          format: date-time
        observed_at:
          type: string
          format: date-time
        window:
          type: object
          properties:
            days:
              type: number
              const: 90
            start_date:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            end_date_exclusive:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            date_field:
              type: string
              const: postingDate
            anchor:
              type: string
              const: server_utc_date
          required:
            - days
            - start_date
            - end_date_exclusive
            - date_field
            - anchor
          additionalProperties: false
        policy:
          type: object
          properties:
            bundle_id:
              type: string
              format: uuid
            version:
              type: string
              minLength: 1
              maxLength: 100
            policy_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            floor_percent:
              type: number
              minimum: 0
              maximum: 100
            comparison:
              type: string
              const: merchandise_margin_against_selected_floor
            full_policy_evaluated:
              type: boolean
              not:
                const: true
          required:
            - bundle_id
            - version
            - policy_digest
            - floor_percent
            - comparison
            - full_policy_evaluated
          additionalProperties: false
        source:
          type: string
          const: business-central
        cost_scope:
          type: string
          const: merchandise_margin
        summary:
          type: object
          properties:
            documents_scanned:
              type: integer
              minimum: 0
              maximum: 100
            documents_assessed:
              type: integer
              minimum: 0
              maximum: 100
            within_floor:
              type: integer
              minimum: 0
              maximum: 100
            below_floor:
              type: integer
              minimum: 0
              maximum: 100
            not_assessed:
              type: integer
              minimum: 0
              maximum: 100
            missing_cost:
              type: integer
              minimum: 0
              maximum: 100
            missing_currency:
              type: integer
              minimum: 0
              maximum: 100
          required:
            - documents_scanned
            - documents_assessed
            - within_floor
            - below_floor
            - not_assessed
            - missing_cost
            - missing_currency
          additionalProperties: false
        findings:
          type: array
          items:
            type: object
            properties:
              record_id:
                type: string
                pattern: ^[a-f0-9]{64}$
              transaction_date:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              date_precision:
                type: string
                const: day
              currency:
                type:
                  - string
                  - "null"
                pattern: ^[A-Z]{3}$
              finding:
                type: string
                enum:
                  - within_floor
                  - below_floor
                  - not_assessed
              reason_codes:
                type: array
                items:
                  type: string
                  enum:
                    - MARGIN_WITHIN_FLOOR
                    - MARGIN_BELOW_FLOOR
                    - HISTORICAL_COST_UNAVAILABLE
                    - CURRENCY_UNAVAILABLE
                    - COST_CURRENCY_MISMATCH
                    - AMOUNT_UNAVAILABLE
                    - LINES_INCOMPLETE
                    - DATE_OUTSIDE_WINDOW
                    - DUPLICATE_RECORD
                    - MARGIN_UNAVAILABLE
                minItems: 1
                maxItems: 8
              net_margin_percent:
                type:
                  - number
                  - "null"
              proof_ref:
                const: null
            required:
              - record_id
              - transaction_date
              - date_precision
              - currency
              - finding
              - reason_codes
              - net_margin_percent
              - proof_ref
            additionalProperties: false
          maxItems: 100
        coverage:
          type: object
          properties:
            record_limit:
              type: number
              const: 100
            complete:
              type: boolean
            truncated:
              type: boolean
            reasons:
              type: array
              items:
                type: string
                enum:
                  - historical_cost_unavailable
                  - document_limit
                  - line_limit
                  - page_limit
                  - duplicate_document
                  - duplicate_line
                  - date_excluded
                  - status_excluded
                  - currency_unavailable
                  - amount_unavailable
                  - response_limit
              maxItems: 12
          required:
            - record_limit
            - complete
            - truncated
            - reasons
          additionalProperties: false
        proof_ref:
          const: null
        evidence_verification:
          type: string
          const: unsigned
        execution_available:
          type: boolean
          not:
            const: true
        no_downstream_action_executed:
          type: boolean
          not:
            const: false
      required:
        - version
        - status
        - mode
        - org_id
        - assessment_id
        - connection_id
        - connection_revision
        - assessed_at
        - observed_at
        - window
        - policy
        - source
        - cost_scope
        - summary
        - findings
        - coverage
        - proof_ref
        - evidence_verification
        - execution_available
        - no_downstream_action_executed
      additionalProperties: false
    CommerceConnectionCreate:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        display_name:
          type: string
          minLength: 1
          maxLength: 80
        environment_name:
          type: string
          pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
        company_id:
          type: string
          format: uuid
        client_id:
          type: string
          format: uuid
        client_secret:
          type: string
          pattern: ^[!-~]{16,512}$
          writeOnly: true
      required:
        - org_id
        - display_name
        - environment_name
        - company_id
        - client_id
        - client_secret
      additionalProperties: false
    CommerceConnectionRevision:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        expected_revision:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483646
      required:
        - org_id
        - expected_revision
      additionalProperties: false
    CommerceConnectionCredentials:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        expected_revision:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483646
        client_secret:
          type: string
          pattern: ^[!-~]{16,512}$
          writeOnly: true
      required:
        - org_id
        - expected_revision
        - client_secret
      additionalProperties: false
    CommerceConnectionResponse:
      type: object
      properties:
        connection:
          type: object
          properties:
            connection_id:
              type: string
              format: uuid
            org_id:
              type: string
              format: uuid
            display_name:
              type: string
              minLength: 1
              maxLength: 80
            environment_name:
              type: string
              minLength: 1
              maxLength: 80
            company_id:
              type: string
              format: uuid
            revision:
              type: integer
              exclusiveMinimum: 0
              maximum: 2147483647
            status:
              type: string
              enum:
                - PENDING
                - ACTIVE
                - DISCONNECTED
            verified_at:
              type:
                - string
                - "null"
              format: date-time
          required:
            - connection_id
            - org_id
            - display_name
            - environment_name
            - company_id
            - revision
            - status
            - verified_at
          additionalProperties: false
      required:
        - connection
      additionalProperties: false
    CommerceConnectionsResponse:
      type: object
      properties:
        connections:
          type: array
          items:
            type: object
            properties:
              connection_id:
                type: string
                format: uuid
              org_id:
                type: string
                format: uuid
              display_name:
                type: string
                minLength: 1
                maxLength: 80
              environment_name:
                type: string
                minLength: 1
                maxLength: 80
              company_id:
                type: string
                format: uuid
              revision:
                type: integer
                exclusiveMinimum: 0
                maximum: 2147483647
              status:
                type: string
                enum:
                  - PENDING
                  - ACTIVE
                  - DISCONNECTED
              verified_at:
                type:
                  - string
                  - "null"
                format: date-time
            required:
              - connection_id
              - org_id
              - display_name
              - environment_name
              - company_id
              - revision
              - status
              - verified_at
            additionalProperties: false
          maxItems: 20
      required:
        - connections
      additionalProperties: false
    CommerceConnectionDisconnected:
      type: object
      properties:
        disconnected:
          type: boolean
          not:
            const: false
      required:
        - disconnected
      additionalProperties: false
    CommerceNativeSnapshotResponse:
      type: object
      properties:
        version:
          type: string
          const: commerce-native-bc-snapshot-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        data:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.guard.snapshot.v1
            connection_id:
              type: string
              format: uuid
            document_id:
              type: string
              format: uuid
            document_etag:
              type: string
              minLength: 3
              maxLength: 256
              pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
            configuration_etag:
              type: string
              minLength: 3
              maxLength: 256
              pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
            source_revision:
              type: string
              minLength: 1
              maxLength: 160
              pattern: ^[\u0020-\u007e\u0080-\uffff]+$
            snapshot_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            observed_at:
              type: string
              format: date-time
            complete:
              type: boolean
              not:
                const: false
            cost_provenance:
              type: string
              enum:
                - native_sales_line_current_estimate
                - native_complete_cost_profile
            revenue_provenance:
              type: string
              const: sales_line_amount_excluding_vat_after_discounts
            preflight_facts:
              anyOf:
                - type: object
                  properties:
                    version:
                      type: string
                      const: commerce.business_central.native.preflight.v1
                    facts:
                      type: object
                      properties:
                        currency:
                          type: string
                          pattern: ^[A-Z]{3}$
                        region:
                          type: object
                          properties:
                            country:
                              type: string
                              pattern: ^[A-Z]{2}$
                          required:
                            - country
                          additionalProperties: false
                        inventory:
                          type: object
                          properties:
                            requested_quantity:
                              type: number
                              exclusiveMinimum: 0
                              maximum: 1000000000000
                          required:
                            - requested_quantity
                          additionalProperties: false
                        order_totals:
                          type: object
                          properties:
                            gross_amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            discount_amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            net_amount_excluding_tax:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                          required:
                            - gross_amount
                            - discount_amount
                            - net_amount_excluding_tax
                          additionalProperties: false
                      required:
                        - currency
                      additionalProperties: false
                    provenance:
                      type: object
                      properties:
                        currency:
                          type: string
                          const: Sales Header.Currency Code or General Ledger Setup.LCY Code
                        region:
                          type: string
                          const: Sales Header.Ship-to Country/Region Code mapped through Country/Region.ISO Code
                        inventory.requested_quantity:
                          type: string
                          const: Sales Line.Quantity (Base); one item line only
                        order_totals:
                          type: string
                          const: Sales Line.Line Amount + Line Discount Amount; Line Discount Amount + Inv. Discount Amount; Amount; Prices Including VAT=false
                      required:
                        - currency
                      additionalProperties: false
                    unavailable:
                      type: array
                      items:
                        type: string
                        enum:
                          - country_mapping
                          - inventory_requested_quantity_across_items
                          - gross_discount_allocation
                          - cost_basis_distinct_sources
                          - full_landed_cost
                          - inventory_on_hand_and_reservations
                          - promotion_chain_and_redemptions
                          - effective_contract_and_account_type
                          - lifecycle_mapping
                          - refund_ledger_and_eligibility
                      maxItems: 10
                  required:
                    - version
                    - facts
                    - provenance
                    - unavailable
                  additionalProperties: false
                - type: object
                  properties:
                    version:
                      type: string
                      const: commerce.business_central.native.preflight.v2
                    facts:
                      type: object
                      properties:
                        currency:
                          type: string
                          pattern: ^[A-Z]{3}$
                        region:
                          type: object
                          properties:
                            country:
                              type: string
                              pattern: ^[A-Z]{2}$
                          required:
                            - country
                          additionalProperties: false
                        order_totals:
                          type: object
                          properties:
                            gross_amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            discount_amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            net_amount_excluding_tax:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                          required:
                            - gross_amount
                            - discount_amount
                            - net_amount_excluding_tax
                          additionalProperties: false
                        cost_basis:
                          type: object
                          properties:
                            source_cost:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            system_of_record_cost:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                          required:
                            - source_cost
                            - system_of_record_cost
                          additionalProperties: false
                        inventory:
                          type: object
                          properties:
                            source_on_hand:
                              type: integer
                              minimum: 0
                              maximum: 1000000000
                            system_on_hand:
                              type: integer
                              minimum: 0
                              maximum: 1000000000
                            reserved_quantity:
                              type: integer
                              minimum: 0
                              maximum: 1000000000
                            requested_quantity:
                              type: integer
                              minimum: 0
                              maximum: 1000000000
                              exclusiveMinimum: 0
                          required:
                            - source_on_hand
                            - system_on_hand
                            - reserved_quantity
                            - requested_quantity
                          additionalProperties: false
                        discounts:
                          type: object
                          properties:
                            count:
                              type: integer
                              minimum: 0
                              maximum: 2
                            sources:
                              type: array
                              items:
                                type: string
                                enum:
                                  - sales_line_discount
                                  - sales_invoice_discount
                              maxItems: 2
                          required:
                            - count
                            - sources
                          additionalProperties: false
                        contract:
                          type: object
                          properties:
                            account_type:
                              type: string
                              const: b2b
                            contract_price:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                          required:
                            - account_type
                            - contract_price
                          additionalProperties: false
                        promotion:
                          type: object
                          properties:
                            discount_codes:
                              type: array
                              minItems: 0
                              maxItems: 0
                              prefixItems: []
                          required:
                            - discount_codes
                          additionalProperties: false
                        lifecycle:
                          type: object
                          properties:
                            current_state:
                              type: string
                              const: created
                          required:
                            - current_state
                          additionalProperties: false
                      required:
                        - currency
                        - region
                        - order_totals
                        - cost_basis
                        - inventory
                        - discounts
                        - contract
                        - promotion
                        - lifecycle
                      additionalProperties: false
                    provenance:
                      type: object
                      properties:
                        currency:
                          type: string
                          const: Sales Header.Currency Code or General Ledger Setup.LCY Code
                        region:
                          type: string
                          const: Sales Header.Ship-to Country/Region Code mapped through Country/Region.ISO Code
                        order_totals:
                          type: string
                          const: Sales Line.Line Amount + Line Discount Amount; Line Discount Amount + Inv. Discount Amount; Amount; Prices Including VAT=false
                        cost_basis:
                          type: string
                          const: sales_line_and_item_unit_cost_plus_explicit_complete_company_cost_profile
                        inventory:
                          type: string
                          const: warehouse_entry_and_item_ledger_entry_with_reservation_pairs
                        discounts:
                          type: string
                          const: observed_native_line_and_invoice_discounts
                        contract:
                          type: string
                          const: explicit_b2b_profile_and_effective_native_customer_price_list
                        promotion:
                          type: string
                          const: complete_native_pricing_sources_without_governed_codes
                        lifecycle:
                          type: string
                          const: open_sales_order_without_posting_or_warehouse_processing
                      required:
                        - currency
                        - region
                        - order_totals
                        - cost_basis
                        - inventory
                        - discounts
                        - contract
                        - promotion
                        - lifecycle
                      additionalProperties: false
                    unavailable:
                      type: array
                      minItems: 1
                      maxItems: 1
                      prefixItems:
                        - type: string
                          const: refund_ledger_and_eligibility
                      items:
                        type: string
                        enum:
                          - refund_ledger_and_eligibility
                    proof:
                      type: object
                      properties:
                        cohort:
                          type: string
                          const: bc_native_b2b_single_item_lcy_v1
                        profile_id:
                          type: string
                          format: uuid
                        profile_revision:
                          type: string
                          pattern: ^[1-9][0-9]{0,19}$
                        valid_from:
                          type: string
                          format: date-time
                        valid_until:
                          type: string
                          format: date-time
                        source_revisions:
                          type: object
                          properties:
                            cost:
                              type: string
                              pattern: ^[a-f0-9]{64}$
                            inventory:
                              type: string
                              pattern: ^[a-f0-9]{64}$
                            pricing:
                              type: string
                              pattern: ^[a-f0-9]{64}$
                            lifecycle:
                              type: string
                              pattern: ^[a-f0-9]{64}$
                          required:
                            - cost
                            - inventory
                            - pricing
                            - lifecycle
                          additionalProperties: false
                        complete_additional_costs:
                          type: boolean
                          not:
                            const: false
                        complete_native_pricing:
                          type: boolean
                          not:
                            const: false
                        consistent_reads:
                          type: boolean
                          not:
                            const: false
                        cost_components:
                          type: object
                          properties:
                            quantity_base:
                              type: integer
                              minimum: 0
                              maximum: 1000000000
                              exclusiveMinimum: 0
                            retained_unit_cost:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                              exclusiveMinimum: 0
                            current_item_unit_cost:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                              exclusiveMinimum: 0
                            additional_landed_unit_cost:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            outbound_shipping:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            fixed_fees:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            variable_fee_percent:
                              type: number
                              minimum: 0
                              maximum: 100
                            variable_fee_amount:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            nonrecoverable_tax:
                              type: number
                              minimum: 0
                              maximum: 1000000000000
                            variable_fee_basis:
                              type: string
                              const: net_revenue_excluding_tax
                          required:
                            - quantity_base
                            - retained_unit_cost
                            - current_item_unit_cost
                            - additional_landed_unit_cost
                            - outbound_shipping
                            - fixed_fees
                            - variable_fee_percent
                            - variable_fee_amount
                            - nonrecoverable_tax
                            - variable_fee_basis
                          additionalProperties: false
                      required:
                        - cohort
                        - profile_id
                        - profile_revision
                        - valid_from
                        - valid_until
                        - source_revisions
                        - complete_additional_costs
                        - complete_native_pricing
                        - consistent_reads
                        - cost_components
                      additionalProperties: false
                  required:
                    - version
                    - facts
                    - provenance
                    - unavailable
                    - proof
                  additionalProperties: false
            request:
              type: object
              properties:
                transaction_id:
                  type: string
                  minLength: 1
                  maxLength: 160
                  pattern: ^[\u0020-\u007e\u0080-\uffff]+$
                erp_type:
                  type: string
                  const: D365_BC
                tenant_id:
                  type: string
                  format: uuid
                timestamp:
                  type: string
                  format: date-time
                agent_id:
                  type: string
                  minLength: 1
                  maxLength: 160
                  pattern: ^[\u0020-\u007e\u0080-\uffff]+$
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                lines:
                  type: array
                  items:
                    type: object
                    properties:
                      line_id:
                        type: integer
                        exclusiveMinimum: 0
                        minimum: -9007199254740991
                        maximum: 9007199254740991
                      sku:
                        type: string
                        minLength: 1
                        maxLength: 160
                        pattern: ^[\u0020-\u007e\u0080-\uffff]+$
                      quantity:
                        type: number
                        exclusiveMinimum: 0
                        maximum: 1000000000000
                      unit_price:
                        type: number
                        minimum: 0
                        maximum: 1000000000000
                      cost_base:
                        type: number
                        minimum: 0
                        maximum: 1000000000000
                    required:
                      - line_id
                      - sku
                      - quantity
                      - unit_price
                      - cost_base
                    additionalProperties: false
                  minItems: 1
                  maxItems: 200
              required:
                - transaction_id
                - erp_type
                - tenant_id
                - timestamp
                - agent_id
                - currency
                - lines
              additionalProperties: false
          required:
            - version
            - connection_id
            - document_id
            - document_etag
            - configuration_etag
            - source_revision
            - snapshot_sha256
            - observed_at
            - complete
            - cost_provenance
            - revenue_provenance
            - preflight_facts
            - request
          additionalProperties: false
        policy:
          type: object
          properties:
            version:
              type: string
              const: commerce-native-policy-v1
            org_id:
              type: string
              format: uuid
            policy:
              type: object
              properties:
                bundle_id:
                  type: string
                  format: uuid
                version:
                  type: string
                  minLength: 1
                  maxLength: 100
                policy_digest:
                  type: string
                  pattern: ^sha256:[a-f0-9]{64}$
              required:
                - bundle_id
                - version
                - policy_digest
              additionalProperties: false
            snapshot:
              type: object
              properties:
                policyVersion:
                  type: string
                  minLength: 1
                  maxLength: 100
                issuedAt:
                  type: string
                  format: date-time
                expiresAt:
                  type: string
                  format: date-time
                failClosed:
                  type: boolean
                  not:
                    const: false
                degradationMode:
                  type: string
                  const: fail_closed
                margin:
                  type: object
                  properties:
                    key:
                      type: string
                      const: net_margin_floor
                    enabled:
                      type: boolean
                      not:
                        const: false
                    floorPercent:
                      type: number
                      minimum: 0
                      maximum: 100
                  required:
                    - key
                    - enabled
                    - floorPercent
                  additionalProperties: false
                inventory:
                  type: object
                  properties:
                    key:
                      type: string
                      const: inventory_floor
                    enabled:
                      type: boolean
                      not:
                        const: true
                    minimumAvailable:
                      type: number
                      const: 0
                  required:
                    - key
                    - enabled
                    - minimumAvailable
                  additionalProperties: false
                starterRules:
                  type: array
                  items:
                    not: {}
                  maxItems: 0
                metadataMappings:
                  type: array
                  items:
                    not: {}
                  maxItems: 0
                commerce_binding:
                  type: object
                  properties:
                    org_id:
                      type: string
                      format: uuid
                    purpose:
                      type: string
                      const: business_central_margin_guard
                    policy:
                      type: object
                      properties:
                        bundle_id:
                          type: string
                          format: uuid
                        version:
                          type: string
                          minLength: 1
                          maxLength: 100
                        policy_digest:
                          type: string
                          pattern: ^sha256:[a-f0-9]{64}$
                      required:
                        - bundle_id
                        - version
                        - policy_digest
                      additionalProperties: false
                    evaluated_checks:
                      type: array
                      minItems: 1
                      maxItems: 1
                      prefixItems:
                        - type: string
                          const: margin
                      items:
                        type: string
                        enum:
                          - margin
                    full_policy_evaluated:
                      type: boolean
                      not:
                        const: true
                  required:
                    - org_id
                    - purpose
                    - policy
                    - evaluated_checks
                    - full_policy_evaluated
                  additionalProperties: false
                signature:
                  type: object
                  properties:
                    algorithm:
                      type: string
                      const: Ed25519
                    keyId:
                      type: string
                      minLength: 1
                      maxLength: 128
                    value:
                      type: string
                      pattern: ^[A-Za-z0-9_-]{86}$
                  required:
                    - algorithm
                    - keyId
                    - value
                  additionalProperties: false
              required:
                - policyVersion
                - issuedAt
                - expiresAt
                - failClosed
                - degradationMode
                - margin
                - inventory
                - starterRules
                - metadataMappings
                - commerce_binding
                - signature
              additionalProperties: false
            snapshot_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            evaluated_checks:
              type: array
              minItems: 1
              maxItems: 1
              prefixItems:
                - type: string
                  const: margin
              items:
                type: string
                enum:
                  - margin
            full_policy_evaluated:
              type: boolean
              not:
                const: true
          required:
            - version
            - org_id
            - policy
            - snapshot
            - snapshot_sha256
            - evaluated_checks
            - full_policy_evaluated
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - connection_revision
        - data
        - policy
        - execution_available
      additionalProperties: false
    CommerceNativeSafetyResponse:
      type: object
      properties:
        version:
          type: string
          const: commerce-native-bc-safety-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        status:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.guard.status.v1
            connection_id:
              type: string
              format: uuid
            settings_id:
              type: string
              format: uuid
            etag:
              type: string
              minLength: 3
              maxLength: 256
              pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
            observed_at:
              type: string
              format: date-time
            enabled:
              type: boolean
            fallback_mode:
              type: string
              enum:
                - FAIL_OPEN
                - FAIL_CLOSED
            default_fallback_mode:
              type: string
              const: FAIL_OPEN
            configured:
              type: boolean
            can_configure:
              type: boolean
            preflight_readiness:
              type: object
              properties:
                version:
                  type: string
                  const: bc_native_preflight_readiness_v1
                profile_configured:
                  type: boolean
                missing:
                  type: array
                  items:
                    type: string
                    enum:
                      - evidence_profile
                      - profile_disabled
                      - profile_validity
                      - cost_profile
                      - pricing_authority
                      - customer_classification
                      - customer_binding
                      - item_binding
                      - location_binding
                      - effective_price_list
                      - native_read_permission
                  maxItems: 11
                document_evidence_required:
                  type: boolean
                  not:
                    const: false
              required:
                - version
                - profile_configured
                - missing
                - document_evidence_required
              additionalProperties: false
            consecutive_failures:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            circuit_open_until:
              type:
                - string
                - "null"
              format: date-time
            last_configuration_operation_id:
              type:
                - string
                - "null"
              format: uuid
            timeout_ms:
              type: number
              const: 150
            intercepts:
              type: array
              minItems: 2
              maxItems: 2
              prefixItems:
                - type: string
                  const: sales_release
                - type: string
                  const: sales_post
              items:
                type: string
                enum:
                  - sales_release
                  - sales_post
            outage_scope:
              type: string
              const: fail_open_availability_only
          required:
            - version
            - connection_id
            - settings_id
            - etag
            - observed_at
            - enabled
            - fallback_mode
            - default_fallback_mode
            - configured
            - can_configure
            - consecutive_failures
            - circuit_open_until
            - last_configuration_operation_id
            - timeout_ms
            - intercepts
            - outage_scope
          additionalProperties: false
        outages:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.guard.outages.v1
            connection_id:
              type: string
              format: uuid
            observed_at:
              type: string
              format: date-time
            scope:
              type: string
              const: fail_open_availability_only
            records:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  created_at:
                    type: string
                    format: date-time
                  failure_type:
                    type: string
                    enum:
                      - HTTP_5XX
                      - CIRCUIT_OPEN
                      - TRANSPORT_FAILURE
                  attempts:
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                  processed:
                    type: boolean
                required:
                  - id
                  - created_at
                  - failure_type
                  - attempts
                  - processed
                additionalProperties: false
              maxItems: 50
            coverage:
              type: object
              properties:
                limit:
                  type: number
                  const: 50
                complete:
                  type: boolean
                truncated:
                  type: boolean
              required:
                - limit
                - complete
                - truncated
              additionalProperties: false
          required:
            - version
            - connection_id
            - observed_at
            - scope
            - records
            - coverage
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - connection_revision
        - status
        - outages
        - execution_available
      additionalProperties: false
    CommerceNativeFallbackRequest:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        settings_id:
          type: string
          format: uuid
        expected_connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        expected_etag:
          type: string
          minLength: 3
          maxLength: 256
          pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
        expected_fallback_mode:
          type: string
          enum:
            - FAIL_OPEN
            - FAIL_CLOSED
        fallback_mode:
          type: string
          enum:
            - FAIL_OPEN
            - FAIL_CLOSED
        idempotency_key:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[A-Za-z0-9._:-]+$
        confirmation:
          type: boolean
          not:
            const: false
      required:
        - org_id
        - settings_id
        - expected_connection_revision
        - expected_etag
        - expected_fallback_mode
        - fallback_mode
        - idempotency_key
        - confirmation
      additionalProperties: false
    CommerceNativeFallbackResponse:
      type: object
      properties:
        version:
          type: string
          const: commerce-native-bc-configuration-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        operation_id:
          type: string
          format: uuid
        outcome:
          type: string
          const: applied
        before:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.guard.status.v1
            connection_id:
              type: string
              format: uuid
            settings_id:
              type: string
              format: uuid
            etag:
              type: string
              minLength: 3
              maxLength: 256
              pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
            observed_at:
              type: string
              format: date-time
            enabled:
              type: boolean
            fallback_mode:
              type: string
              enum:
                - FAIL_OPEN
                - FAIL_CLOSED
            default_fallback_mode:
              type: string
              const: FAIL_OPEN
            configured:
              type: boolean
            can_configure:
              type: boolean
            preflight_readiness:
              type: object
              properties:
                version:
                  type: string
                  const: bc_native_preflight_readiness_v1
                profile_configured:
                  type: boolean
                missing:
                  type: array
                  items:
                    type: string
                    enum:
                      - evidence_profile
                      - profile_disabled
                      - profile_validity
                      - cost_profile
                      - pricing_authority
                      - customer_classification
                      - customer_binding
                      - item_binding
                      - location_binding
                      - effective_price_list
                      - native_read_permission
                  maxItems: 11
                document_evidence_required:
                  type: boolean
                  not:
                    const: false
              required:
                - version
                - profile_configured
                - missing
                - document_evidence_required
              additionalProperties: false
            consecutive_failures:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            circuit_open_until:
              type:
                - string
                - "null"
              format: date-time
            last_configuration_operation_id:
              type:
                - string
                - "null"
              format: uuid
            timeout_ms:
              type: number
              const: 150
            intercepts:
              type: array
              minItems: 2
              maxItems: 2
              prefixItems:
                - type: string
                  const: sales_release
                - type: string
                  const: sales_post
              items:
                type: string
                enum:
                  - sales_release
                  - sales_post
            outage_scope:
              type: string
              const: fail_open_availability_only
          required:
            - version
            - connection_id
            - settings_id
            - etag
            - observed_at
            - enabled
            - fallback_mode
            - default_fallback_mode
            - configured
            - can_configure
            - consecutive_failures
            - circuit_open_until
            - last_configuration_operation_id
            - timeout_ms
            - intercepts
            - outage_scope
          additionalProperties: false
        after:
          type: object
          properties:
            version:
              type: string
              const: decionis.business_central.guard.status.v1
            connection_id:
              type: string
              format: uuid
            settings_id:
              type: string
              format: uuid
            etag:
              type: string
              minLength: 3
              maxLength: 256
              pattern: ^(?:W\/)?"[\x21\x23-\x7e]+"$
            observed_at:
              type: string
              format: date-time
            enabled:
              type: boolean
            fallback_mode:
              type: string
              enum:
                - FAIL_OPEN
                - FAIL_CLOSED
            default_fallback_mode:
              type: string
              const: FAIL_OPEN
            configured:
              type: boolean
            can_configure:
              type: boolean
            preflight_readiness:
              type: object
              properties:
                version:
                  type: string
                  const: bc_native_preflight_readiness_v1
                profile_configured:
                  type: boolean
                missing:
                  type: array
                  items:
                    type: string
                    enum:
                      - evidence_profile
                      - profile_disabled
                      - profile_validity
                      - cost_profile
                      - pricing_authority
                      - customer_classification
                      - customer_binding
                      - item_binding
                      - location_binding
                      - effective_price_list
                      - native_read_permission
                  maxItems: 11
                document_evidence_required:
                  type: boolean
                  not:
                    const: false
              required:
                - version
                - profile_configured
                - missing
                - document_evidence_required
              additionalProperties: false
            consecutive_failures:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            circuit_open_until:
              type:
                - string
                - "null"
              format: date-time
            last_configuration_operation_id:
              type:
                - string
                - "null"
              format: uuid
            timeout_ms:
              type: number
              const: 150
            intercepts:
              type: array
              minItems: 2
              maxItems: 2
              prefixItems:
                - type: string
                  const: sales_release
                - type: string
                  const: sales_post
              items:
                type: string
                enum:
                  - sales_release
                  - sales_post
            outage_scope:
              type: string
              const: fail_open_availability_only
          required:
            - version
            - connection_id
            - settings_id
            - etag
            - observed_at
            - enabled
            - fallback_mode
            - default_fallback_mode
            - configured
            - can_configure
            - consecutive_failures
            - circuit_open_until
            - last_configuration_operation_id
            - timeout_ms
            - intercepts
            - outage_scope
          additionalProperties: false
        financial_action_executed:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - connection_revision
        - operation_id
        - outcome
        - before
        - after
        - financial_action_executed
      additionalProperties: false
    CommerceNativePreflightRequest:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        document_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        policy_version:
          type: string
          minLength: 1
          maxLength: 100
        policy_digest:
          type: string
          pattern: ^sha256:[a-f0-9]{64}$
        snapshot_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        idempotency_key:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[A-Za-z0-9._:-]+$
        confirmation:
          type: boolean
          not:
            const: false
      required:
        - org_id
        - document_id
        - connection_revision
        - policy_version
        - policy_digest
        - snapshot_sha256
        - idempotency_key
        - confirmation
      additionalProperties: false
    CommerceNativePreflightResponse:
      type: object
      properties:
        version:
          type: string
          const: commerce-native-bc-preflight-v1
        input_version:
          type: string
          const: commerce-preflight-partial-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        document_id:
          type: string
          format: uuid
        snapshot_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        policy:
          type: object
          properties:
            bundle_id:
              type: string
              format: uuid
            version:
              type: string
              minLength: 1
              maxLength: 100
            policy_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
          required:
            - bundle_id
            - version
            - policy_digest
          additionalProperties: false
        mode:
          type: string
          const: SHADOW
        outcome:
          type: string
          enum:
            - APPROVE
            - REJECT
            - ESCALATE
            - REVIEW
        verdict:
          type: string
          enum:
            - PROCEED
            - HOLD
            - BLOCK
            - ESCALATE
        preflight:
          type: object
          properties:
            version:
              type: string
              const: commerce-preflight-v2
            action_type:
              type: string
              enum:
                - PRICE_CHANGE
                - INVENTORY_MUTATION
                - ORDER_ACCEPTANCE
                - FULFILLMENT_ACTION
                - PROMOTION_CHANGE
                - REFUND_REQUEST
                - RETURN_AUTHORIZATION
                - PAYMENT_RELEASE
                - VENDOR_BANK_CHANGE
                - EARLY_PAYMENT_DISCOUNT
                - CREDIT_HOLD_RELEASE
            action_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            facts_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            policy_version:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
            evaluated_at:
              type: string
              format: date-time
              maxLength: 40
            disposition:
              type: string
              enum:
                - PROCEED
                - HOLD
                - BLOCK
            execution_available:
              type: boolean
              not:
                const: true
            checks:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    enum:
                      - P01
                      - P02
                      - P03
                      - P04
                      - P05
                      - P06
                      - P07
                      - P08
                      - P09
                      - P10
                      - P11
                      - P12
                      - P13
                      - P14
                      - P15
                      - P16
                  status:
                    type: string
                    enum:
                      - evaluated
                      - not_applicable
                      - disabled
                      - missing_facts
                      - unsupported
                  verdict:
                    type:
                      - string
                      - "null"
                    enum:
                      - PROCEED
                      - HOLD
                      - BLOCK
                      - null
                  reason_codes:
                    type: array
                    items:
                      type: string
                      pattern: ^[A-Z][A-Z0-9_]{0,119}$
                    minItems: 1
                    maxItems: 20
                  missing_facts:
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 180
                    maxItems: 30
                  measurements:
                    type: object
                    additionalProperties:
                      type: number
                required:
                  - id
                  - status
                  - verdict
                  - reason_codes
                  - missing_facts
                additionalProperties: false
              minItems: 16
              maxItems: 16
          required:
            - version
            - action_type
            - action_digest
            - facts_digest
            - policy_version
            - idempotency_key
            - evaluated_at
            - disposition
            - execution_available
            - checks
          additionalProperties: false
        evaluation_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        dossier_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        idempotent_replay:
          type: boolean
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - input_version
        - org_id
        - connection_id
        - connection_revision
        - document_id
        - snapshot_sha256
        - policy
        - mode
        - outcome
        - verdict
        - preflight
        - evaluation_id
        - dossier_id
        - dossier_sha256
        - idempotent_replay
        - execution_available
      additionalProperties: false
    CommerceNativeGrantRequest:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        expected_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        permissions:
          type: array
          minItems: 1
          maxItems: 2
          prefixItems:
            - type: string
              const: read
            - type: string
              const: configure
          items:
            type: string
            enum:
              - read
              - configure
        confirmation:
          type: boolean
          not:
            const: false
      required:
        - org_id
        - expected_revision
        - permissions
        - confirmation
      additionalProperties: false
    CommerceApprovalPrepare:
      type: object
      properties:
        org_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        policy_version:
          type: string
          minLength: 1
          maxLength: 100
      required:
        - org_id
        - dossier_id
        - policy_version
      additionalProperties: false
    CommerceApprovalEvidence:
      type: object
      properties:
        version:
          type: string
          const: commerce-approval-evidence-v1
        org_id:
          type: string
          format: uuid
        dossier_id:
          type: string
          format: uuid
        dossier_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        evaluation_id:
          type: string
          format: uuid
        action_type:
          type: string
          enum:
            - ORDER_ACCEPTANCE
            - REFUND_REQUEST
        action_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        platform:
          type: string
          enum:
            - business-central
            - walmart-marketplace
            - adobe-commerce
        order_id:
          type: string
          minLength: 1
          maxLength: 200
        amount:
          type: number
          minimum: 0
          maximum: 1000000000000
        currency:
          type: string
          pattern: ^[A-Z]{3}$
        policy:
          type: object
          properties:
            bundle_id:
              type: string
              format: uuid
            version:
              type: string
              minLength: 1
              maxLength: 100
            policy_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
          required:
            - bundle_id
            - version
            - policy_digest
          additionalProperties: false
        mode:
          type: string
          const: SHADOW
        outcome:
          type: string
          enum:
            - APPROVE
            - ESCALATE
            - REJECT
            - REVIEW
        preflight:
          type: object
          properties:
            version:
              type: string
              const: commerce-preflight-v2
            action_type:
              type: string
              enum:
                - PRICE_CHANGE
                - INVENTORY_MUTATION
                - ORDER_ACCEPTANCE
                - FULFILLMENT_ACTION
                - PROMOTION_CHANGE
                - REFUND_REQUEST
                - RETURN_AUTHORIZATION
                - PAYMENT_RELEASE
                - VENDOR_BANK_CHANGE
                - EARLY_PAYMENT_DISCOUNT
                - CREDIT_HOLD_RELEASE
            action_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            facts_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            policy_version:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
            evaluated_at:
              type: string
              format: date-time
              maxLength: 40
            disposition:
              type: string
              enum:
                - PROCEED
                - HOLD
                - BLOCK
            execution_available:
              type: boolean
              not:
                const: true
            checks:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    enum:
                      - P01
                      - P02
                      - P03
                      - P04
                      - P05
                      - P06
                      - P07
                      - P08
                      - P09
                      - P10
                      - P11
                      - P12
                      - P13
                      - P14
                      - P15
                      - P16
                  status:
                    type: string
                    enum:
                      - evaluated
                      - not_applicable
                      - disabled
                      - missing_facts
                      - unsupported
                  verdict:
                    type:
                      - string
                      - "null"
                    enum:
                      - PROCEED
                      - HOLD
                      - BLOCK
                      - null
                  reason_codes:
                    type: array
                    items:
                      type: string
                      pattern: ^[A-Z][A-Z0-9_]{0,119}$
                    minItems: 1
                    maxItems: 20
                  missing_facts:
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 180
                    maxItems: 30
                  measurements:
                    type: object
                    additionalProperties:
                      type: number
                required:
                  - id
                  - status
                  - verdict
                  - reason_codes
                  - missing_facts
                additionalProperties: false
              minItems: 16
              maxItems: 16
          required:
            - version
            - action_type
            - action_digest
            - facts_digest
            - policy_version
            - idempotency_key
            - evaluated_at
            - disposition
            - execution_available
            - checks
          additionalProperties: false
        source_evidence:
          type: object
          properties:
            provenance:
              type: string
              enum:
                - supplied_evidence
                - native_snapshot
            connection_id:
              type:
                - string
                - "null"
              format: uuid
            revision:
              type:
                - integer
                - "null"
              exclusiveMinimum: 0
              minimum: -9007199254740991
              maximum: 9007199254740991
            snapshot_sha256:
              type:
                - string
                - "null"
              pattern: ^[a-f0-9]{64}$
          required:
            - provenance
            - connection_id
            - revision
            - snapshot_sha256
          additionalProperties: false
        review:
          type: object
          properties:
            summary:
              type: string
              minLength: 1
              maxLength: 1000
            facts:
              type: array
              items:
                type: object
                properties:
                  key:
                    type: string
                    enum:
                      - resource_id
                      - amount
                      - currency
                      - requested_quantity
                      - gross_amount
                      - discount_amount
                      - estimated_cost
                      - remaining_refundable
                      - lifecycle_state
                  value:
                    anyOf:
                      - type: string
                        maxLength: 200
                      - type: number
                      - type: "null"
                required:
                  - key
                  - value
                additionalProperties: false
              maxItems: 9
          required:
            - summary
            - facts
          additionalProperties: false
        verification:
          type: object
          properties:
            signature_verified:
              type: boolean
              not:
                const: false
            inputs_commitment_verified:
              type: boolean
              not:
                const: false
            policy_current:
              type: boolean
              not:
                const: false
          required:
            - signature_verified
            - inputs_commitment_verified
            - policy_current
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - dossier_id
        - dossier_sha256
        - evaluation_id
        - action_type
        - action_sha256
        - platform
        - order_id
        - amount
        - currency
        - policy
        - mode
        - outcome
        - preflight
        - source_evidence
        - review
        - verification
        - execution_available
      additionalProperties: false
    CommerceConnectedSourceAuthority:
      type: object
      properties:
        payload:
          type: object
          properties:
            version:
              type: string
              const: accounts-commerce-source-v3
            purpose:
              type: string
              const: commerce_oauth_projection
            resource:
              type: string
              format: uri
              maxLength: 2048
            oauth_grant_id:
              type: string
              format: uuid
            account_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            source_org_id:
              type: string
              format: uuid
            provider:
              type: string
              const: microsoft
            subscription_id:
              type: string
              format: uuid
            publisher_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
            offer_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
            plan_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
            source_entitlement:
              type: object
              properties:
                entitlement_id:
                  type: string
                  pattern: ^ent_[a-f0-9]{24}$
                product:
                  type: string
                  pattern: ^commerce_ms_[a-f0-9]{24}$
                product_plan:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
                revision:
                  type: integer
                  exclusiveMinimum: 0
                  minimum: -9007199254740991
                  maximum: 9007199254740991
                environment:
                  type: string
                  const: production
                status:
                  type: string
                  const: active
              required:
                - entitlement_id
                - product
                - product_plan
                - revision
                - environment
                - status
              additionalProperties: false
            issued_at:
              type: string
              format: date-time
            expires_at:
              type: string
              format: date-time
            provider_tenant_id:
              type: string
              format: uuid
            authorization:
              type: object
              properties:
                profile_version:
                  type: number
                  const: 3
                client_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: ^[A-Za-z0-9._-]+$
                scopes:
                  type: array
                  minItems: 9
                  maxItems: 9
                  prefixItems:
                    - type: string
                      const: decision:read
                    - type: string
                      const: decision:run
                    - type: string
                      const: policy:read
                    - type: string
                      const: erp:read
                    - type: string
                      const: history:assess
                    - type: string
                      const: marketplace:read
                    - type: string
                      const: erp:validate
                    - type: string
                      const: approval:request
                    - type: string
                      const: erp:configure
                  items:
                    type: string
                    enum:
                      - decision:read
                      - decision:run
                      - policy:read
                      - erp:read
                      - history:assess
                      - marketplace:read
                      - erp:validate
                      - approval:request
                      - erp:configure
                consent_id:
                  type: string
                  format: uuid
                consent_text_version:
                  type: string
                  const: commerce-connected-consent-v1
                consent_sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                consented_at:
                  type: string
                  format: date-time
                account_role:
                  type: string
                  enum:
                    - owner
                    - admin
                    - developer
                supported_sources:
                  type: array
                  items:
                    type: string
                    enum:
                      - business-central
                      - walmart-marketplace
                      - adobe-commerce
                  minItems: 1
                  maxItems: 3
              required:
                - profile_version
                - client_id
                - scopes
                - consent_id
                - consent_text_version
                - consent_sha256
                - consented_at
                - account_role
                - supported_sources
              additionalProperties: false
          required:
            - version
            - purpose
            - resource
            - oauth_grant_id
            - account_sha256
            - source_org_id
            - provider
            - subscription_id
            - publisher_id
            - offer_id
            - plan_id
            - source_entitlement
            - issued_at
            - expires_at
            - provider_tenant_id
            - authorization
          additionalProperties: false
        evidence:
          type: object
          properties:
            algorithm:
              type: string
              const: Ed25519
            key_id:
              type: string
              pattern: ^[A-Za-z0-9._-]{1,128}$
            payload_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            signature:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - key_id
            - payload_sha256
            - signature
          additionalProperties: false
      required:
        - payload
        - evidence
      additionalProperties: false
    CommerceConnectedAuthority:
      type: object
      properties:
        version:
          type: string
          const: commerce-connected-authority-v1
        account_user_id:
          type: string
          pattern: ^usr_[a-f0-9]{24}$
        account_org_id:
          type: string
          pattern: ^org_[a-f0-9]{20}$
        workspace_id:
          type: string
          pattern: ^ten_[a-f0-9]{20}$
        membership_id:
          type: string
          pattern: ^mem_[a-f0-9]{24}$
        entitlement_id:
          type: string
          pattern: ^ent_[a-f0-9]{24}$
        account_role:
          type: string
          enum:
            - owner
            - admin
            - developer
        provider_tenant_id:
          type: string
          format: uuid
        subscription_id:
          type: string
          format: uuid
        source_revision:
          type: integer
          exclusiveMinimum: 0
          minimum: -9007199254740991
          maximum: 9007199254740991
        source_plan:
          type: object
          properties:
            publisher_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
            offer_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
            plan_id:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
          required:
            - publisher_id
            - offer_id
            - plan_id
          additionalProperties: false
        supported_sources:
          type: array
          items:
            type: string
            enum:
              - business-central
              - walmart-marketplace
              - adobe-commerce
          minItems: 1
          maxItems: 3
        expires_at:
          type: string
          format: date-time
        history_assessment_limit_monthly:
          type:
            - integer
            - "null"
          minimum: 0
          maximum: 2147483647
      required:
        - version
        - account_user_id
        - account_org_id
        - workspace_id
        - membership_id
        - entitlement_id
        - account_role
        - provider_tenant_id
        - subscription_id
        - source_revision
        - source_plan
        - supported_sources
        - expires_at
      additionalProperties: false
    CommerceInitialPolicy:
      type: object
      properties:
        version:
          type: string
          const: commerce-onboarding-shadow-v1
        bundle_id:
          type: string
          format: uuid
        mode:
          type: string
          const: SHADOW
        source:
          type: string
          const: accounts_commerce_onboarding
        policy_digest:
          type: string
          pattern: ^sha256:[a-f0-9]{64}$
      required:
        - version
        - bundle_id
        - mode
        - source
        - policy_digest
      additionalProperties: false
    CommerceNativeContext:
      type: object
      properties:
        version:
          type: string
          const: commerce-native-context-v1
        org_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        workspace_environment:
          type: string
          enum:
            - sandbox
            - production
        erp_type:
          type: string
          const: D365_BC
        tenant_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        connection_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        expected_revision:
          type: integer
          minimum: 1
          maximum: 2147483647
        environment_name:
          type: string
          pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
        company_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        basis:
          type: string
          const: persisted_connection_and_native_grant
        provider_read_authority:
          type: string
          const: not_checked
        execution_available:
          type: boolean
      required:
        - version
        - org_id
        - workspace_environment
        - erp_type
        - tenant_id
        - connection_id
        - expected_revision
        - environment_name
        - company_id
        - basis
        - provider_read_authority
        - execution_available
      additionalProperties: false
    CommercePaymentWorkspaceRequest:
      type: object
      additionalProperties: false
      required:
        - version
      properties:
        version:
          type: string
          const: commerce-payment-workspace-request-v1
    CommercePaymentWorkspaceResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - workspace
      properties:
        version:
          type: string
          const: commerce-payment-workspace-v1
        workspace:
          type: object
          additionalProperties: false
          required:
            - org_id
            - workspace_id
            - environment
            - source_org_id
          properties:
            org_id:
              type: string
              pattern: ^org_[A-Za-z0-9_-]{1,196}$
            workspace_id:
              type: string
              pattern: ^ten_[A-Za-z0-9_-]{1,196}$
            environment:
              type: string
              enum:
                - sandbox
                - production
            source_org_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
    CommercePaymentSnapshotRequest:
      type: object
      additionalProperties: false
      required:
        - version
        - native_context
        - tenant_id
        - journal_id
      properties:
        version:
          type: string
          const: commerce-payment-snapshot-request-v1
        native_context:
          type: object
          additionalProperties: false
          required:
            - version
            - org_id
            - workspace_environment
            - connection_id
            - expected_revision
            - environment_name
            - company_id
          properties:
            version:
              type: string
              const: commerce-native-context-v1
            org_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            workspace_environment:
              type: string
              enum:
                - sandbox
                - production
            connection_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            expected_revision:
              type: integer
              minimum: 1
              maximum: 2147483647
            environment_name:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
            company_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        tenant_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        journal_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
    CommercePaymentSnapshotResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - workspace
        - snapshot
      properties:
        version:
          type: string
          const: commerce-payment-snapshot-response-v1
        workspace:
          type: object
          additionalProperties: false
          required:
            - org_id
            - workspace_id
            - environment
            - source_org_id
          properties:
            org_id:
              type: string
              pattern: ^org_[A-Za-z0-9_-]{1,196}$
            workspace_id:
              type: string
              pattern: ^ten_[A-Za-z0-9_-]{1,196}$
            environment:
              type: string
              enum:
                - sandbox
                - production
            source_org_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        snapshot:
          type: object
          additionalProperties: false
          required:
            - version
            - tenant_id
            - native_context
            - payment
            - facts
            - payment_evidence
          properties:
            version:
              type: string
              const: commerce-payment-snapshot-v1
            tenant_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            native_context:
              type: object
              additionalProperties: false
              required:
                - version
                - org_id
                - workspace_environment
                - connection_id
                - expected_revision
                - environment_name
                - company_id
              properties:
                version:
                  type: string
                  const: commerce-native-context-v1
                org_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                workspace_environment:
                  type: string
                  enum:
                    - sandbox
                    - production
                connection_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                expected_revision:
                  type: integer
                  minimum: 1
                  maximum: 2147483647
                environment_name:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
                company_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            payment:
              type: object
              additionalProperties: false
              required:
                - payment_id
                - vendor_id
                - amount
                - currency
              properties:
                payment_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                invoice_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                due_at:
                  type: string
                  format: date-time
                  maxLength: 40
                rail:
                  type: string
                  enum:
                    - ach
                    - wire
                    - card
                    - stablecoin
                    - other
            facts:
              type: object
              additionalProperties: false
              required:
                - observed_at
                - payment
                - beneficiary
                - treasury
              properties:
                observed_at:
                  type: string
                  format: date-time
                  maxLength: 40
                payment:
                  type: object
                  additionalProperties: false
                  properties:
                    prior_payment_count:
                      type: integer
                      minimum: 0
                      maximum: 1000000000
                  required:
                    - prior_payment_count
                treasury:
                  type: object
                  additionalProperties: false
                  properties:
                    cash_position:
                      type: number
                      minimum: 0
                      maximum: 1000000000000
                    run_total:
                      type: number
                      minimum: 0
                      maximum: 1000000000000
                  required:
                    - cash_position
                    - run_total
                beneficiary:
                  type: object
                  additionalProperties: false
                  properties:
                    changed_at:
                      type:
                        - string
                        - "null"
                      format: date-time
                      maxLength: 40
                    verification:
                      type: string
                      const: unverified
                  required:
                    - changed_at
                    - verification
            payment_evidence:
              type: object
              additionalProperties: false
              required:
                - version
                - method
                - journal_id
                - journal_revision
                - batch_id
                - batch_revision
                - invoice_entry_id
                - invoice_revision
                - invoice_remaining_amount
                - funding_bank_id
                - funding_bank_revision
                - beneficiary_bank_id
                - beneficiary_bank_revision
                - source_revisions
                - snapshot_sha256
              properties:
                version:
                  type: string
                  const: commerce-payment-evidence-v1
                method:
                  type: string
                  const: ledger_cash_same_currency_single_payment_v1
                source:
                  type: object
                  additionalProperties: false
                  required:
                    - sandbox
                    - evaluation_company
                  properties:
                    sandbox:
                      type: boolean
                    evaluation_company:
                      type: boolean
                journal_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                journal_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                batch_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                batch_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                invoice_entry_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                invoice_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                invoice_remaining_amount:
                  type: number
                  exclusiveMinimum: 0
                  maximum: 1000000000000
                funding_bank_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                funding_bank_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                beneficiary_bank_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                beneficiary_bank_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                source_revisions:
                  type: object
                  additionalProperties: false
                  required:
                    - run
                    - invoice
                    - treasury
                  properties:
                    run:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                    invoice:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                    treasury:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                snapshot_sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
    CommercePaymentAuthorizationRequest:
      type: object
      additionalProperties: false
      required:
        - version
        - attempt_id
        - request
      dependentRequired:
        executor:
          - intent
        intent:
          - executor
      properties:
        version:
          type: string
          const: commerce-payment-authorization-v1
        attempt_id:
          type: string
          format: uuid
          pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
        request:
          type: object
          additionalProperties: false
          required:
            - transaction_id
            - erp_type
            - tenant_id
            - timestamp
            - agent_id
            - mode
            - payment
            - facts
            - native_context
            - payment_evidence
          properties:
            transaction_id:
              type: string
              minLength: 1
              maxLength: 160
            erp_type:
              type: string
              const: D365_BC
            tenant_id:
              type: string
              format: uuid
            native_context:
              type: object
              additionalProperties: false
              required:
                - version
                - org_id
                - workspace_environment
                - connection_id
                - expected_revision
                - environment_name
                - company_id
              properties:
                version:
                  type: string
                  const: commerce-native-context-v1
                org_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                workspace_environment:
                  type: string
                  enum:
                    - sandbox
                    - production
                connection_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                expected_revision:
                  type: integer
                  minimum: 1
                  maximum: 2147483647
                environment_name:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
                company_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            timestamp:
              type: string
              format: date-time
            agent_id:
              type: string
              minLength: 1
              maxLength: 160
            mode:
              type: string
              const: ENFORCE
            payment:
              type: object
              additionalProperties: false
              required:
                - payment_id
                - vendor_id
                - amount
                - currency
              properties:
                payment_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                invoice_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                due_at:
                  type: string
                  format: date-time
                  maxLength: 40
                rail:
                  type: string
                  enum:
                    - ach
                    - wire
                    - card
                    - stablecoin
                    - other
            facts:
              type: object
              additionalProperties: false
              required:
                - observed_at
              properties:
                observed_at:
                  type: string
                  format: date-time
                  maxLength: 40
                payment:
                  type: object
                  additionalProperties: false
                  properties:
                    prior_payment_count:
                      type: integer
                      minimum: 0
                      maximum: 1000000000
                treasury:
                  type: object
                  additionalProperties: false
                  properties:
                    cash_position:
                      type: number
                      minimum: 0
                      maximum: 1000000000000
                    run_total:
                      type: number
                      minimum: 0
                      maximum: 1000000000000
                beneficiary:
                  type: object
                  additionalProperties: false
                  properties:
                    changed_at:
                      type:
                        - string
                        - "null"
                      format: date-time
                      maxLength: 40
                    verification:
                      type: string
                      enum:
                        - verified
                        - unverified
                        - pending
            payment_evidence:
              type: object
              additionalProperties: false
              required:
                - version
                - method
                - journal_id
                - journal_revision
                - batch_id
                - batch_revision
                - invoice_entry_id
                - invoice_revision
                - invoice_remaining_amount
                - funding_bank_id
                - funding_bank_revision
                - beneficiary_bank_id
                - beneficiary_bank_revision
                - source_revisions
                - snapshot_sha256
              properties:
                version:
                  type: string
                  const: commerce-payment-evidence-v1
                method:
                  type: string
                  const: ledger_cash_same_currency_single_payment_v1
                source:
                  type: object
                  additionalProperties: false
                  required:
                    - sandbox
                    - evaluation_company
                  properties:
                    sandbox:
                      type: boolean
                    evaluation_company:
                      type: boolean
                journal_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                journal_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                batch_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                batch_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                invoice_entry_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                invoice_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                invoice_remaining_amount:
                  type: number
                  exclusiveMinimum: 0
                  maximum: 1000000000000
                funding_bank_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                funding_bank_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                beneficiary_bank_id:
                  type: string
                  format: uuid
                  pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
                beneficiary_bank_revision:
                  type: string
                  pattern: ^[1-9][0-9]{0,18}$
                  maxLength: 19
                source_revisions:
                  type: object
                  additionalProperties: false
                  required:
                    - run
                    - invoice
                    - treasury
                  properties:
                    run:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                    invoice:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                    treasury:
                      type: string
                      pattern: ^[a-f0-9]{64}$
                snapshot_sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
            posted:
              type: object
              additionalProperties: false
              required:
                - entry_id
                - vendor_id
                - amount
                - currency
                - posted_at
              properties:
                entry_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                posted_at:
                  type: string
                  format: date-time
                  maxLength: 40
          allOf:
            - if:
                required:
                  - payment_evidence
              then:
                properties:
                  erp_type:
                    const: D365_BC
                  facts:
                    type: object
                    required:
                      - treasury
                    properties:
                      treasury:
                        type: object
                        required:
                          - cash_position
                          - run_total
            - if:
                properties:
                  erp_type:
                    const: D365_BC
                required:
                  - erp_type
              then:
                required:
                  - native_context
              else:
                not:
                  required:
                    - native_context
          not:
            required:
              - posted
        executor:
          type: object
          additionalProperties: false
          required:
            - platform
            - style
            - version
          properties:
            platform:
              type: string
              const: business-central
            style:
              type: string
              const: permit
            version:
              type: string
              maxLength: 64
              pattern: ^[0-9A-Za-z][0-9A-Za-z.+_-]*$
        intent:
          type: object
          additionalProperties: false
          required:
            - protocol_version
            - tenant_id
            - intent_id
            - captured_at
            - expires_at
            - actor
            - action
            - context
            - downstream_target
            - intent_hash
          properties:
            protocol_version:
              type: string
              const: agent-safe.intent/1
            tenant_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            intent_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            captured_at:
              type: string
              format: date-time
              maxLength: 40
            expires_at:
              type: string
              format: date-time
              maxLength: 40
            actor:
              type: object
              maxProperties: 4
            action:
              type: object
              additionalProperties: false
              required:
                - type
                - resource
                - parameters
              properties:
                type:
                  type: string
                  const: payment.release
                resource:
                  type: string
                  minLength: 1
                  maxLength: 500
                parameters:
                  type: object
                  maxProperties: 20
            context:
              type: object
              required:
                - idempotency_key
              maxProperties: 20
            downstream_target:
              type: object
              additionalProperties: false
              required:
                - system
                - operation
              properties:
                system:
                  type: string
                  const: business-central
                operation:
                  type: string
                  minLength: 1
                  maxLength: 200
                environment:
                  type: string
                  enum:
                    - sandbox
                    - production
                endpoint:
                  type: string
                  minLength: 1
                  maxLength: 500
            correlation_id:
              type: string
              minLength: 1
              maxLength: 200
            expected_effect_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            intent_hash:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
    CommercePaymentAuthorizationResponse:
      type: object
      additionalProperties: false
      required:
        - mode
        - enforced
        - transaction_id
        - disposition
        - reason_code
        - message
        - policy_version
        - dossier_id
        - checks
        - execution_time_ms
        - native_context
        - authorization
      properties:
        authorization:
          type: object
          additionalProperties: false
          required:
            - attempt_id
            - expires_at
            - source_snapshot_sha256
          properties:
            attempt_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            expires_at:
              type: string
              format: date-time
              maxLength: 40
            source_snapshot_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
        mode:
          type: string
          const: ENFORCE
        enforced:
          type: boolean
          not:
            const: false
        transaction_id:
          type: string
          minLength: 1
          maxLength: 160
        disposition:
          type: string
          enum:
            - PROCEED
            - HOLD
            - BLOCK
        reason_code:
          type: string
          minLength: 1
          maxLength: 100
        message:
          type: string
          minLength: 1
          maxLength: 500
        policy_version:
          type: string
          minLength: 1
          maxLength: 120
        dossier_id:
          type: string
          format: uuid
        checks:
          type: array
          maxItems: 16
          items:
            type: object
            additionalProperties: false
            required:
              - id
              - status
              - verdict
              - reason_codes
              - missing_facts
            properties:
              id:
                type: string
                pattern: ^P[0-9]{2}$
              status:
                type: string
                enum:
                  - evaluated
                  - missing_facts
                  - unsupported
              verdict:
                type: string
                enum:
                  - PROCEED
                  - HOLD
                  - BLOCK
              reason_codes:
                type: array
                minItems: 1
                maxItems: 20
                items:
                  type: string
                  pattern: ^[A-Z][A-Z0-9_]{0,119}$
              missing_facts:
                type: array
                maxItems: 30
                items:
                  type: string
                  minLength: 1
                  maxLength: 180
        execution_time_ms:
          type: number
          minimum: 0
        native_context:
          type: object
          additionalProperties: false
          required:
            - version
            - org_id
            - workspace_environment
            - connection_id
            - expected_revision
            - environment_name
            - company_id
            - erp_type
            - tenant_id
            - basis
            - provider_read_authority
            - execution_available
          properties:
            version:
              type: string
              const: commerce-native-context-v1
            org_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            workspace_environment:
              type: string
              enum:
                - sandbox
                - production
            connection_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            expected_revision:
              type: integer
              minimum: 1
              maximum: 2147483647
            environment_name:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$
            company_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            erp_type:
              type: string
              const: D365_BC
            tenant_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            basis:
              type: string
              const: persisted_connection_and_native_grant
            provider_read_authority:
              type: string
              const: not_checked
            execution_available:
              type: boolean
        grant:
          type: object
          additionalProperties: false
          required:
            - decision_id
            - status
            - should_execute
            - reason_codes
            - action_hash
            - execution_token
            - execution_token_jti
            - execution_token_expires_at
            - dossier_id
          properties:
            decision_id:
              type: string
              minLength: 1
              maxLength: 200
            status:
              type: string
              enum:
                - ALLOW
                - BLOCK
                - ESCALATE
                - REVIEW_REQUIRED
                - ERROR
            should_execute:
              type: boolean
            reason_codes:
              type: array
              maxItems: 50
              items:
                type: string
                pattern: ^[!-~]{1,200}$
            action_hash:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            execution_token:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 20000
            execution_token_jti:
              type:
                - string
                - "null"
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            execution_token_expires_at:
              type:
                - string
                - "null"
              format: date-time
              maxLength: 40
            dossier_id:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 200
            permit_id:
              type: string
              format: uuid
              pattern: ^(?!00000000-0000-0000-0000-000000000000$)[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$
            intent_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            expires_at:
              type: string
              format: date-time
              maxLength: 40
    CommercePreflightAction:
      anyOf:
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: PRICE_CHANGE
            payload:
              type: object
              properties:
                sku:
                  type: string
                  minLength: 1
                  maxLength: 200
                from_price:
                  type:
                    - number
                    - "null"
                  minimum: 0
                  maximum: 1000000000000
                to_price:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                estimated_cost:
                  type:
                    - number
                    - "null"
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
              required:
                - sku
                - from_price
                - to_price
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: INVENTORY_MUTATION
            payload:
              type: object
              properties:
                sku:
                  type: string
                  minLength: 1
                  maxLength: 200
                from:
                  type:
                    - integer
                    - "null"
                  minimum: 0
                  maximum: 1000000000
                to:
                  type: integer
                  minimum: 0
                  maximum: 1000000000
                location_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
              required:
                - sku
                - from
                - to
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: ORDER_ACCEPTANCE
            payload:
              type: object
              properties:
                order_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
                gross_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                discount_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                estimated_cost:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
              required:
                - order_id
                - gross_amount
                - discount_amount
                - estimated_cost
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: FULFILLMENT_ACTION
            payload:
              type: object
              properties:
                order_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                action:
                  type: string
                  enum:
                    - acknowledge
                    - ship
                    - cancel
                    - hold
              required:
                - order_id
                - action
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: PROMOTION_CHANGE
            payload:
              type: object
              properties:
                promotion_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
                percentage_fraction:
                  type:
                    - number
                    - "null"
                  minimum: 0
                  maximum: 1
                ends_at:
                  type:
                    - string
                    - "null"
                  format: date-time
                  maxLength: 40
                status:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 80
                combines_with:
                  type:
                    - object
                    - "null"
                  properties:
                    order_discounts:
                      type: boolean
                    product_discounts:
                      type: boolean
                    shipping_discounts:
                      type: boolean
                  required:
                    - order_discounts
                    - product_discounts
                    - shipping_discounts
                  additionalProperties: false
              required:
                - promotion_id
                - percentage_fraction
                - ends_at
                - status
                - combines_with
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: REFUND_REQUEST
            payload:
              type: object
              properties:
                order_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                reason_code:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
                remaining_refundable:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                prior_refund_count:
                  type: integer
                  minimum: 0
                  maximum: 1000000000
              required:
                - order_id
                - amount
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: RETURN_AUTHORIZATION
            payload:
              type: object
              properties:
                order_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                rma_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
                amount:
                  type:
                    - number
                    - "null"
                  minimum: 0
                  maximum: 1000000000000
              required:
                - order_id
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: PAYMENT_RELEASE
            payload:
              type: object
              properties:
                payment_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                invoice_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                due_at:
                  type: string
                  format: date-time
                  maxLength: 40
                rail:
                  type: string
                  enum:
                    - ach
                    - wire
                    - card
                    - stablecoin
                    - other
              required:
                - payment_id
                - vendor_id
                - amount
                - currency
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: VENDOR_BANK_CHANGE
            payload:
              type: object
              properties:
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                change_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                account_hash:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                account_last4:
                  type: string
                  pattern: ^[0-9]{4}$
                previous_account_hash:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - vendor_id
                - change_id
                - account_hash
                - account_last4
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: EARLY_PAYMENT_DISCOUNT
            payload:
              type: object
              properties:
                payment_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                vendor_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                discount_percent:
                  type: number
                  minimum: 0
                  maximum: 100
                days_early:
                  type: integer
                  minimum: 0
                  maximum: 365
              required:
                - payment_id
                - vendor_id
                - amount
                - currency
                - discount_percent
                - days_early
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
        - type: object
          properties:
            actor:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - HUMAN
                    - ERP
                    - REPRICER
                    - WORKFLOW
                    - AGENT
                    - UNKNOWN
                id:
                  type: string
                  minLength: 1
                  maxLength: 200
              required:
                - type
                - id
              additionalProperties: false
            platform:
              type: string
              minLength: 1
              maxLength: 120
            idempotency_key:
              type: string
              minLength: 1
              maxLength: 180
              pattern: ^[a-z0-9][\w.:/-]{0,179}$
            action_type:
              type: string
              const: CREDIT_HOLD_RELEASE
            payload:
              type: object
              properties:
                customer_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                order_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                exposure_after_release:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
              required:
                - customer_id
                - amount
                - currency
              additionalProperties: false
          required:
            - actor
            - platform
            - idempotency_key
            - action_type
            - payload
          additionalProperties: false
    CommercePreflightFacts:
      type: object
      properties:
        observed_at:
          type: string
          format: date-time
          maxLength: 40
        source:
          type: string
          minLength: 1
          maxLength: 120
          pattern: ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$
        currency:
          type: string
          pattern: ^[A-Z]{3}$
        pricing:
          type: object
          properties:
            gross_amount:
              type: number
              minimum: 0
              maximum: 1000000000000
            discount_amount:
              type: number
              minimum: 0
              maximum: 1000000000000
            estimated_cost:
              type: number
              minimum: 0
              maximum: 1000000000000
          additionalProperties: false
        cost_basis:
          type: object
          properties:
            source_cost:
              type: number
              minimum: 0
              maximum: 1000000000000
            system_of_record_cost:
              type: number
              minimum: 0
              maximum: 1000000000000
          additionalProperties: false
        inventory:
          type: object
          properties:
            source_on_hand:
              type: integer
              minimum: 0
              maximum: 1000000000
            system_on_hand:
              type: integer
              minimum: 0
              maximum: 1000000000
            reserved_quantity:
              type: integer
              minimum: 0
              maximum: 1000000000
            requested_quantity:
              type: integer
              minimum: 0
              maximum: 1000000000
          additionalProperties: false
        region:
          type: object
          properties:
            country:
              type: string
              pattern: ^[A-Z]{2}$
          additionalProperties: false
        discounts:
          type: object
          properties:
            count:
              type: integer
              minimum: 0
              maximum: 32
            sources:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 120
                pattern: ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$
              maxItems: 32
          additionalProperties: false
        contract:
          type: object
          properties:
            account_type:
              type: string
              enum:
                - retail
                - b2b
            offered_price:
              type: number
              minimum: 0
              maximum: 1000000000000
            contract_price:
              type: number
              minimum: 0
              maximum: 1000000000000
          additionalProperties: false
        promotion:
          type: object
          properties:
            discount_codes:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 120
                pattern: ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$
              maxItems: 32
            prior_redemptions:
              type: integer
              minimum: 0
              maximum: 1000000000
            account_age_days:
              type: number
              minimum: 0
              maximum: 100000
            identity_hash:
              type: string
              pattern: ^[a-f0-9]{64}$
          additionalProperties: false
        refund:
          type: object
          properties:
            remaining_refundable:
              type: number
              minimum: 0
              maximum: 1000000000000
            prior_refund_count:
              type: integer
              minimum: 0
              maximum: 1000000000
          additionalProperties: false
        lifecycle:
          type: object
          properties:
            current_state:
              type: string
              enum:
                - created
                - acknowledged
                - shipped
                - delivered
                - cancelled
                - refunded
                - return_authorized
                - returned
            delivered_at:
              type: string
              format: date-time
              maxLength: 40
            return_eligible:
              type: boolean
          additionalProperties: false
        payment:
          type: object
          properties:
            prior_payment_count:
              type: integer
              minimum: 0
              maximum: 1000000000
            approver_authority_limit:
              type: number
              minimum: 0
              maximum: 1000000000000
          additionalProperties: false
        beneficiary:
          type: object
          properties:
            changed_at:
              type:
                - string
                - "null"
              format: date-time
              maxLength: 40
            verification:
              type: string
              enum:
                - verified
                - unverified
                - pending
          additionalProperties: false
        treasury:
          type: object
          properties:
            cash_position:
              type: number
              minimum: 0
              maximum: 1000000000000
            run_total:
              type: number
              minimum: 0
              maximum: 1000000000000
            cost_of_funds_percent:
              type: number
              minimum: 0
              maximum: 100
          additionalProperties: false
      additionalProperties: false
    AssessmentRecords:
      type: object
      description: decionis.assessments.records/1. Records inline or one JSON Lines file, never both. A commerce record is a commerce-preflight-v2 action with its facts as they stood, its time and its transaction-time money; identifiers in the action should be opaque digests.
      required:
        - version
        - assessment_id
        - domain
        - kind
        - platform
        - producer
        - as_of
        - window
        - total
        - truncated
      additionalProperties: false
      properties:
        version:
          type: string
          const: decionis.assessments.records/1
        assessment_id:
          type: string
          format: uuid
        domain:
          type: string
          enum:
            - commerce
            - cards
            - agents
        kind:
          type: string
          enum:
            - transaction
            - event
            - audit
        platform:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{0,99}$
        producer:
          type: object
          required:
            - product
            - surface
            - version
          additionalProperties: false
          properties:
            product:
              type: string
              enum:
                - agentsafe
                - commerce
                - core
            surface:
              type: string
              enum:
                - cli
                - assistant
                - dashboard
                - service
                - upload
            version:
              type: string
        as_of:
          type: string
          format: date-time
        window:
          type: object
          required:
            - from
            - to
          properties:
            from:
              type: string
              format: date-time
            to:
              type: string
              format: date-time
        policy_id:
          type: string
          format: uuid
          description: The policy the findings are for; its desk receives them. Without it they go to the workspace's commerce draft (a policy created MANAGED first, then a MANAGED one). Must name a commerce policy in the organization.
        total:
          type:
            - integer
            - "null"
          minimum: 0
        truncated:
          type: boolean
        records:
          type: array
          minItems: 1
          maxItems: 5000
          items:
            type: object
        file:
          type: object
          required:
            - format
            - content
          additionalProperties: false
          properties:
            format:
              type: string
              const: jsonl
            name:
              type: string
            content:
              type: string
              maxLength: 4000000
    AssessmentRecordsResult:
      type: object
      required:
        - version
        - assessment_id
        - domain
        - policy_id
        - received
        - assessed
        - findings
      properties:
        version:
          type: string
          const: decionis.assessments.records/1
        assessment_id:
          type: string
          format: uuid
        domain:
          type: string
          enum:
            - commerce
            - cards
            - agents
        policy_id:
          type:
            - string
            - "null"
          format: uuid
          description: The policy the findings went to; null for the workspace's commerce draft.
        received:
          type: integer
          description: Records received, before duplicates were dropped.
        assessed:
          type: integer
        findings:
          $ref: "#/components/schemas/SignedAssessmentFindings"
    AssessmentFindingsSubmission:
      type: object
      properties:
        version:
          type: string
          const: decionis.assessments.submission/1
        assessment_id:
          type: string
          format: uuid
        platform:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{0,99}$
        evaluator:
          type: object
          properties:
            platform:
              type: string
              pattern: ^[a-z0-9][a-z0-9-]{0,99}$
            methodology:
              type: string
              minLength: 1
              maxLength: 120
          required:
            - platform
            - methodology
          additionalProperties: false
        source:
          type: object
          properties:
            kind:
              type: string
              enum:
                - connected_history
                - recorded_evidence
            connection_id:
              type:
                - string
                - "null"
              format: uuid
            company_id:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 120
            revision:
              type: string
              minLength: 1
              maxLength: 120
            as_of:
              type: string
              format: date-time
              maxLength: 40
            window:
              type: object
              properties:
                from:
                  type: string
                  format: date-time
                  maxLength: 40
                to:
                  type: string
                  format: date-time
                  maxLength: 40
              required:
                - from
                - to
              additionalProperties: false
          required:
            - kind
            - connection_id
            - company_id
            - revision
            - as_of
            - window
          additionalProperties: false
        status:
          type: string
          enum:
            - complete
            - partial
        coverage:
          type: object
          properties:
            assessed:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            total:
              type:
                - integer
                - "null"
              minimum: 0
              maximum: 9007199254740991
            limit:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            truncated:
              type: boolean
            complete:
              type: boolean
            reasons:
              type: array
              items:
                type: string
                pattern: ^[A-Z][A-Z0-9_]{0,119}$
              maxItems: 30
            gaps:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{0,119}$
                  finding_types:
                    type: array
                    items:
                      type: string
                      pattern: ^[A-Z][A-Za-z0-9]{2,79}$
                    maxItems: 20
                required:
                  - code
                  - finding_types
                additionalProperties: false
              maxItems: 30
          required:
            - assessed
            - total
            - limit
            - truncated
            - complete
            - reasons
            - gaps
          additionalProperties: false
        findings:
          type: array
          items:
            type: object
            properties:
              finding_id:
                type: string
                minLength: 1
                maxLength: 120
                pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
              type:
                type: string
                pattern: ^[A-Z][A-Za-z0-9]{2,79}$
              check_id:
                type: string
                enum:
                  - P01
                  - P02
                  - P03
                  - P04
                  - P05
                  - P06
                  - P07
                  - P08
                  - P09
                  - P10
                  - P11
                  - P12
                  - P13
                  - P14
                  - P15
                  - P16
              record_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              occurred_at:
                type: string
                format: date-time
                maxLength: 40
              amount:
                type: object
                properties:
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  amount_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - currency
                  - scale
                  - amount_minor
                additionalProperties: false
              measurements:
                type: object
                additionalProperties:
                  type: number
                propertyNames:
                  pattern: ^[a-z][a-z0-9_]{0,63}$
              basis:
                type: string
                enum:
                  - source_record
                  - recorded_observation
            required:
              - finding_id
              - type
              - check_id
              - record_digest
              - occurred_at
              - amount
              - measurements
              - basis
            additionalProperties: false
          maxItems: 5000
        records:
          type: array
          items:
            type: object
            properties:
              record_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              occurred_at:
                type: string
                format: date-time
                maxLength: 40
              amount:
                type:
                  - object
                  - "null"
                properties:
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  amount_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - currency
                  - scale
                  - amount_minor
                additionalProperties: false
              replay:
                type:
                  - object
                  - "null"
                properties:
                  action:
                    $ref: "#/components/schemas/CommercePreflightAction"
                  facts:
                    $ref: "#/components/schemas/CommercePreflightFacts"
                required:
                  - action
                  - facts
                additionalProperties: false
            required:
              - record_digest
              - occurred_at
              - amount
              - replay
            additionalProperties: false
          maxItems: 5000
      required:
        - version
        - assessment_id
        - platform
        - evaluator
        - source
        - status
        - coverage
        - findings
        - records
      additionalProperties: false
    SignedAssessmentFindings:
      type: object
      properties:
        artifact:
          type: object
          properties:
            assessment_id:
              type: string
              format: uuid
            platform:
              type: string
              pattern: ^[a-z0-9][a-z0-9-]{0,99}$
            evaluator:
              type: object
              properties:
                platform:
                  type: string
                  pattern: ^[a-z0-9][a-z0-9-]{0,99}$
                methodology:
                  type: string
                  minLength: 1
                  maxLength: 120
              required:
                - platform
                - methodology
              additionalProperties: false
            source:
              type: object
              properties:
                kind:
                  type: string
                  enum:
                    - connected_history
                    - recorded_evidence
                connection_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                company_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 120
                revision:
                  type: string
                  minLength: 1
                  maxLength: 120
                as_of:
                  type: string
                  format: date-time
                  maxLength: 40
                window:
                  type: object
                  properties:
                    from:
                      type: string
                      format: date-time
                      maxLength: 40
                    to:
                      type: string
                      format: date-time
                      maxLength: 40
                  required:
                    - from
                    - to
                  additionalProperties: false
              required:
                - kind
                - connection_id
                - company_id
                - revision
                - as_of
                - window
              additionalProperties: false
            status:
              type: string
              enum:
                - complete
                - partial
            coverage:
              type: object
              properties:
                assessed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                total:
                  type:
                    - integer
                    - "null"
                  minimum: 0
                  maximum: 9007199254740991
                limit:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                truncated:
                  type: boolean
                complete:
                  type: boolean
                reasons:
                  type: array
                  items:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{0,119}$
                  maxItems: 30
                gaps:
                  type: array
                  items:
                    type: object
                    properties:
                      code:
                        type: string
                        pattern: ^[A-Z][A-Z0-9_]{0,119}$
                      finding_types:
                        type: array
                        items:
                          type: string
                          pattern: ^[A-Z][A-Za-z0-9]{2,79}$
                        maxItems: 20
                    required:
                      - code
                      - finding_types
                    additionalProperties: false
                  maxItems: 30
              required:
                - assessed
                - total
                - limit
                - truncated
                - complete
                - reasons
                - gaps
              additionalProperties: false
            findings:
              type: array
              items:
                type: object
                properties:
                  finding_id:
                    type: string
                    minLength: 1
                    maxLength: 120
                    pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
                  type:
                    type: string
                    pattern: ^[A-Z][A-Za-z0-9]{2,79}$
                  check_id:
                    type: string
                    enum:
                      - P01
                      - P02
                      - P03
                      - P04
                      - P05
                      - P06
                      - P07
                      - P08
                      - P09
                      - P10
                      - P11
                      - P12
                      - P13
                      - P14
                      - P15
                      - P16
                  record_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  occurred_at:
                    type: string
                    format: date-time
                    maxLength: 40
                  amount:
                    type: object
                    properties:
                      currency:
                        type: string
                        pattern: ^[A-Z]{3}$
                      scale:
                        type: integer
                        minimum: 0
                        maximum: 6
                      amount_minor:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                    required:
                      - currency
                      - scale
                      - amount_minor
                    additionalProperties: false
                  measurements:
                    type: object
                    additionalProperties:
                      type: number
                    propertyNames:
                      pattern: ^[a-z][a-z0-9_]{0,63}$
                  basis:
                    type: string
                    enum:
                      - source_record
                      - recorded_observation
                required:
                  - finding_id
                  - type
                  - check_id
                  - record_digest
                  - occurred_at
                  - amount
                  - measurements
                  - basis
                additionalProperties: false
              maxItems: 5000
            records:
              type: array
              items:
                type: object
                properties:
                  record_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  occurred_at:
                    type: string
                    format: date-time
                    maxLength: 40
                  amount:
                    type:
                      - object
                      - "null"
                    properties:
                      currency:
                        type: string
                        pattern: ^[A-Z]{3}$
                      scale:
                        type: integer
                        minimum: 0
                        maximum: 6
                      amount_minor:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                    required:
                      - currency
                      - scale
                      - amount_minor
                    additionalProperties: false
                  replay:
                    type:
                      - object
                      - "null"
                    properties:
                      action:
                        $ref: "#/components/schemas/CommercePreflightAction"
                      facts:
                        $ref: "#/components/schemas/CommercePreflightFacts"
                    required:
                      - action
                      - facts
                    additionalProperties: false
                required:
                  - record_digest
                  - occurred_at
                  - amount
                  - replay
                additionalProperties: false
              maxItems: 5000
            version:
              type: string
              const: decionis.assessments.findings/1
            findings_id:
              type: string
              format: uuid
            org_id:
              type: string
              format: uuid
            submitted_at:
              type: string
              format: date-time
              maxLength: 40
            submission_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            totals:
              type: array
              items:
                type: object
                properties:
                  type:
                    type: string
                    pattern: ^[A-Z][A-Za-z0-9]{2,79}$
                  check_id:
                    type: string
                    enum:
                      - P01
                      - P02
                      - P03
                      - P04
                      - P05
                      - P06
                      - P07
                      - P08
                      - P09
                      - P10
                      - P11
                      - P12
                      - P13
                      - P14
                      - P15
                      - P16
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  amount_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  count:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - type
                  - check_id
                  - currency
                  - scale
                  - amount_minor
                  - count
                additionalProperties: false
              maxItems: 5000
          required:
            - assessment_id
            - platform
            - evaluator
            - source
            - status
            - coverage
            - findings
            - records
            - version
            - findings_id
            - org_id
            - submitted_at
            - submission_sha256
            - totals
          additionalProperties: false
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        canonicalization:
          type: string
          const: RFC8785/JCS
        verification:
          type: string
          enum:
            - signed
            - unsigned
        signature:
          type:
            - object
            - "null"
          properties:
            algorithm:
              type: string
              const: Ed25519
            keyId:
              type: string
              pattern: ^[A-Za-z0-9_.:-]{1,128}$
            value:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - keyId
            - value
          additionalProperties: false
        public_jwks_path:
          type: string
          const: /.well-known/decision-dossier-jwks.json
      required:
        - artifact
        - artifact_sha256
        - canonicalization
        - verification
        - signature
        - public_jwks_path
      additionalProperties: false
    OutcomeAgreementCreate:
      type: object
      properties:
        environment:
          type: string
          enum:
            - sandbox
            - production
        terms:
          type: object
          properties:
            version:
              type: string
              const: decionis.outcomes.agreement/1
            workflow:
              type: string
              enum:
                - PAYMENT_SAFETY
                - MARGIN_OVERSELL
                - SUPPORT
                - ENGINEERING
            primary_metric:
              type: string
              enum:
                - CONFIRMED_PREVENTED_LOSS
                - GOVERNED_VALUE
            scope:
              type: object
              properties:
                platforms:
                  type: array
                  items:
                    type: string
                    pattern: ^[a-z0-9][a-z0-9-]{0,99}$
                  minItems: 1
                  maxItems: 10
                action_types:
                  type: array
                  items:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{0,119}$
                  minItems: 1
                  maxItems: 30
                connection_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 50
                policy:
                  type:
                    - object
                    - "null"
                  properties:
                    policy_id:
                      type: string
                      format: uuid
                    revision_digest:
                      type: string
                      pattern: ^sha256:[a-f0-9]{64}$
                  required:
                    - policy_id
                    - revision_digest
                  additionalProperties: false
              required:
                - platforms
                - action_types
                - connection_ids
                - policy
              additionalProperties: false
            baseline:
              type: object
              properties:
                method:
                  type: string
                  enum:
                    - SHADOW_COMPARISON
                    - MATCHED_COHORT
                    - BEFORE_AFTER
                from:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                to:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                description:
                  type: string
                  minLength: 1
                  maxLength: 2000
              required:
                - method
                - from
                - to
                - description
              additionalProperties: false
            currency:
              type: object
              properties:
                reporting:
                  type: string
                  pattern: ^[A-Z]{3}$
                reporting_scale:
                  type: integer
                  minimum: 0
                  maximum: 6
                conversion:
                  type: string
                  enum:
                    - NONE
                    - FIXED_RATES
                rates:
                  type: array
                  items:
                    type: object
                    properties:
                      currency:
                        type: string
                        pattern: ^[A-Z]{3}$
                      rate_micros:
                        type: integer
                        exclusiveMinimum: 0
                        maximum: 1000000000000000
                    required:
                      - currency
                      - rate_micros
                    additionalProperties: false
                  maxItems: 30
                source:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 200
              required:
                - reporting
                - reporting_scale
                - conversion
                - rates
                - source
              additionalProperties: false
            deductions:
              type: object
              properties:
                false_hold_minor:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                delay_hour_minor:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                analyst_minute_minor:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
              required:
                - false_hold_minor
                - delay_hour_minor
                - analyst_minute_minor
              additionalProperties: false
            confirmation:
              type: string
              enum:
                - REVIEWER
                - CUSTOMER
            exclusions:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{0,119}$
                  description:
                    type: string
                    minLength: 1
                    maxLength: 500
                required:
                  - code
                  - description
                additionalProperties: false
              maxItems: 30
            attribution_days:
              type: integer
              minimum: 1
              maximum: 365
            period:
              type: object
              properties:
                cadence:
                  type: string
                  const: MONTHLY
                close_after_days:
                  type: integer
                  minimum: 0
                  maximum: 60
              required:
                - cadence
                - close_after_days
              additionalProperties: false
            commercial:
              type: object
              properties:
                basis:
                  type: string
                  enum:
                    - NONE
                    - NET_BENEFIT_SHARE
                    - GOVERNED_VALUE_FEE
                rate_bps:
                  type: integer
                  minimum: 0
                  maximum: 10000
                floor_minor:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                cap_minor:
                  type:
                    - integer
                    - "null"
                  minimum: 0
                  maximum: 9007199254740991
              required:
                - basis
                - rate_bps
                - floor_minor
                - cap_minor
              additionalProperties: false
            effective_from:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            effective_to:
              type:
                - string
                - "null"
              pattern: ^\d{4}-\d{2}-\d{2}$
          required:
            - version
            - workflow
            - primary_metric
            - scope
            - baseline
            - currency
            - deductions
            - confirmation
            - exclusions
            - attribution_days
            - period
            - commercial
            - effective_from
            - effective_to
          additionalProperties: false
        supersedes:
          default: null
          type:
            - string
            - "null"
          format: uuid
      required:
        - environment
        - terms
      additionalProperties: false
    OutcomeAgreementRecord:
      type: object
      properties:
        artifact:
          type: object
          properties:
            version:
              type: string
              const: decionis.outcomes.agreement/1
            agreement_id:
              type: string
              format: uuid
            org_id:
              type: string
              format: uuid
            environment:
              type: string
              enum:
                - sandbox
                - production
            terms:
              type: object
              properties:
                version:
                  type: string
                  const: decionis.outcomes.agreement/1
                workflow:
                  type: string
                  enum:
                    - PAYMENT_SAFETY
                    - MARGIN_OVERSELL
                    - SUPPORT
                    - ENGINEERING
                primary_metric:
                  type: string
                  enum:
                    - CONFIRMED_PREVENTED_LOSS
                    - GOVERNED_VALUE
                scope:
                  type: object
                  properties:
                    platforms:
                      type: array
                      items:
                        type: string
                        pattern: ^[a-z0-9][a-z0-9-]{0,99}$
                      minItems: 1
                      maxItems: 10
                    action_types:
                      type: array
                      items:
                        type: string
                        pattern: ^[A-Z][A-Z0-9_]{0,119}$
                      minItems: 1
                      maxItems: 30
                    connection_ids:
                      type: array
                      items:
                        type: string
                        format: uuid
                      maxItems: 50
                    policy:
                      type:
                        - object
                        - "null"
                      properties:
                        policy_id:
                          type: string
                          format: uuid
                        revision_digest:
                          type: string
                          pattern: ^sha256:[a-f0-9]{64}$
                      required:
                        - policy_id
                        - revision_digest
                      additionalProperties: false
                  required:
                    - platforms
                    - action_types
                    - connection_ids
                    - policy
                  additionalProperties: false
                baseline:
                  type: object
                  properties:
                    method:
                      type: string
                      enum:
                        - SHADOW_COMPARISON
                        - MATCHED_COHORT
                        - BEFORE_AFTER
                    from:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}$
                    to:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}$
                    description:
                      type: string
                      minLength: 1
                      maxLength: 2000
                  required:
                    - method
                    - from
                    - to
                    - description
                  additionalProperties: false
                currency:
                  type: object
                  properties:
                    reporting:
                      type: string
                      pattern: ^[A-Z]{3}$
                    reporting_scale:
                      type: integer
                      minimum: 0
                      maximum: 6
                    conversion:
                      type: string
                      enum:
                        - NONE
                        - FIXED_RATES
                    rates:
                      type: array
                      items:
                        type: object
                        properties:
                          currency:
                            type: string
                            pattern: ^[A-Z]{3}$
                          rate_micros:
                            type: integer
                            exclusiveMinimum: 0
                            maximum: 1000000000000000
                        required:
                          - currency
                          - rate_micros
                        additionalProperties: false
                      maxItems: 30
                    source:
                      type:
                        - string
                        - "null"
                      minLength: 1
                      maxLength: 200
                  required:
                    - reporting
                    - reporting_scale
                    - conversion
                    - rates
                    - source
                  additionalProperties: false
                deductions:
                  type: object
                  properties:
                    false_hold_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    delay_hour_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    analyst_minute_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                  required:
                    - false_hold_minor
                    - delay_hour_minor
                    - analyst_minute_minor
                  additionalProperties: false
                confirmation:
                  type: string
                  enum:
                    - REVIEWER
                    - CUSTOMER
                exclusions:
                  type: array
                  items:
                    type: object
                    properties:
                      code:
                        type: string
                        pattern: ^[A-Z][A-Z0-9_]{0,119}$
                      description:
                        type: string
                        minLength: 1
                        maxLength: 500
                    required:
                      - code
                      - description
                    additionalProperties: false
                  maxItems: 30
                attribution_days:
                  type: integer
                  minimum: 1
                  maximum: 365
                period:
                  type: object
                  properties:
                    cadence:
                      type: string
                      const: MONTHLY
                    close_after_days:
                      type: integer
                      minimum: 0
                      maximum: 60
                  required:
                    - cadence
                    - close_after_days
                  additionalProperties: false
                commercial:
                  type: object
                  properties:
                    basis:
                      type: string
                      enum:
                        - NONE
                        - NET_BENEFIT_SHARE
                        - GOVERNED_VALUE_FEE
                    rate_bps:
                      type: integer
                      minimum: 0
                      maximum: 10000
                    floor_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    cap_minor:
                      type:
                        - integer
                        - "null"
                      minimum: 0
                      maximum: 9007199254740991
                  required:
                    - basis
                    - rate_bps
                    - floor_minor
                    - cap_minor
                  additionalProperties: false
                effective_from:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                effective_to:
                  type:
                    - string
                    - "null"
                  pattern: ^\d{4}-\d{2}-\d{2}$
              required:
                - version
                - workflow
                - primary_metric
                - scope
                - baseline
                - currency
                - deductions
                - confirmation
                - exclusions
                - attribution_days
                - period
                - commercial
                - effective_from
                - effective_to
              additionalProperties: false
            supersedes:
              type:
                - string
                - "null"
              format: uuid
            created_at:
              type: string
              format: date-time
              maxLength: 40
          required:
            - version
            - agreement_id
            - org_id
            - environment
            - terms
            - supersedes
            - created_at
          additionalProperties: false
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        canonicalization:
          type: string
          const: RFC8785/JCS
        state:
          type: string
          enum:
            - DRAFT
            - AWAITING_CUSTOMER
            - ACTIVE
            - SUPERSEDED
            - TERMINATED
        decionis_signature:
          type:
            - object
            - "null"
          properties:
            algorithm:
              type: string
              const: Ed25519
            keyId:
              type: string
              pattern: ^[A-Za-z0-9_.:-]{1,128}$
            value:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - keyId
            - value
          additionalProperties: false
        customer_signature:
          type:
            - object
            - "null"
          properties:
            user_id:
              type: string
              format: uuid
            method:
              type: string
              const: WEBAUTHN
            proof_reference:
              type: string
              minLength: 1
              maxLength: 200
            proof_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            signed_at:
              type: string
              format: date-time
              maxLength: 40
          required:
            - user_id
            - method
            - proof_reference
            - proof_sha256
            - signed_at
          additionalProperties: false
        public_jwks_path:
          type: string
          const: /.well-known/decision-dossier-jwks.json
      required:
        - artifact
        - artifact_sha256
        - canonicalization
        - state
        - decionis_signature
        - customer_signature
        - public_jwks_path
      additionalProperties: false
    SignedOutcomeStatement:
      type: object
      properties:
        artifact:
          type: object
          properties:
            version:
              type: string
              const: decionis.outcomes.statement/1
            statement_id:
              type: string
              format: uuid
            agreement_id:
              type: string
              format: uuid
            agreement_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            org_id:
              type: string
              format: uuid
            environment:
              type: string
              enum:
                - sandbox
                - production
            period:
              type: string
              pattern: ^\d{4}-(0[1-9]|1[0-2])$
            window:
              type: object
              properties:
                from:
                  type: string
                  format: date-time
                  maxLength: 40
                to:
                  type: string
                  format: date-time
                  maxLength: 40
              required:
                - from
                - to
              additionalProperties: false
            closed_at:
              type: string
              format: date-time
              maxLength: 40
            calculator:
              type: object
              properties:
                version:
                  type: string
                  minLength: 1
                  maxLength: 80
              required:
                - version
              additionalProperties: false
            totals:
              type: array
              items:
                type: object
                properties:
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  governed_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  prevented_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  held_unconfirmed_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  false_hold_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  pending_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  coverage_gap_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - currency
                  - scale
                  - governed_minor
                  - prevented_minor
                  - held_unconfirmed_minor
                  - false_hold_minor
                  - pending_minor
                  - coverage_gap_minor
                additionalProperties: false
              maxItems: 30
            reporting:
              type: object
              properties:
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                scale:
                  type: integer
                  minimum: 0
                  maximum: 6
                prevented_minor:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                corrections_minor:
                  type: integer
                deductions:
                  type: object
                  properties:
                    false_holds_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    delay_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    analyst_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    total_minor:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                  required:
                    - false_holds_minor
                    - delay_minor
                    - analyst_minor
                    - total_minor
                  additionalProperties: false
                net_benefit_minor:
                  type:
                    - integer
                    - "null"
                unconverted_currencies:
                  type: array
                  items:
                    type: string
                    pattern: ^[A-Z]{3}$
                  maxItems: 30
              required:
                - currency
                - scale
                - prevented_minor
                - corrections_minor
                - deductions
                - net_benefit_minor
                - unconverted_currencies
              additionalProperties: false
            counts:
              type: object
              properties:
                evaluated:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                governed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                prevented:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                held_unconfirmed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                false_holds:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                pending:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                coverage_gaps:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                estimates:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                excluded:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                disputed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
              required:
                - evaluated
                - governed
                - prevented
                - held_unconfirmed
                - false_holds
                - pending
                - coverage_gaps
                - estimates
                - excluded
                - disputed
              additionalProperties: false
            estimates:
              type: array
              items:
                type: object
                properties:
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  would_hold_minor:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  count:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - currency
                  - scale
                  - would_hold_minor
                  - count
                additionalProperties: false
              maxItems: 30
            corrections:
              type: array
              items:
                type: object
                properties:
                  subject_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  original_period:
                    type: string
                    pattern: ^\d{4}-(0[1-9]|1[0-2])$
                  from:
                    type: string
                    enum:
                      - GOVERNED
                      - PREVENTED
                      - HELD_UNCONFIRMED
                      - FALSE_HOLD
                      - PENDING
                      - COVERAGE_GAP
                      - ESTIMATE
                      - EXCLUDED
                      - DISPUTED
                  to:
                    type: string
                    enum:
                      - GOVERNED
                      - PREVENTED
                      - HELD_UNCONFIRMED
                      - FALSE_HOLD
                      - PENDING
                      - COVERAGE_GAP
                      - ESTIMATE
                      - EXCLUDED
                      - DISPUTED
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                  scale:
                    type: integer
                    minimum: 0
                    maximum: 6
                  prevented_delta_minor:
                    type: integer
                required:
                  - subject_digest
                  - original_period
                  - from
                  - to
                  - currency
                  - scale
                  - prevented_delta_minor
                additionalProperties: false
              maxItems: 5000
            process_map:
              type: array
              items:
                type: object
                properties:
                  platform:
                    type: string
                    pattern: ^[a-z0-9][a-z0-9-]{0,99}$
                  action_type:
                    type: string
                    pattern: ^[A-Z][A-Z0-9_]{0,119}$
                  total:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  governed:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  held:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  desk_reviews:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  customer_reviews:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  median_cycle_minutes:
                    type:
                      - integer
                      - "null"
                    minimum: 0
                    maximum: 9007199254740991
                  p90_cycle_minutes:
                    type:
                      - integer
                      - "null"
                    minimum: 0
                    maximum: 9007199254740991
                required:
                  - platform
                  - action_type
                  - total
                  - governed
                  - held
                  - desk_reviews
                  - customer_reviews
                  - median_cycle_minutes
                  - p90_cycle_minutes
                additionalProperties: false
              maxItems: 200
            narrative:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 400
              maxItems: 12
            entries:
              type: object
              properties:
                count:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - count
                - sha256
              additionalProperties: false
          required:
            - version
            - statement_id
            - agreement_id
            - agreement_sha256
            - org_id
            - environment
            - period
            - window
            - closed_at
            - calculator
            - totals
            - reporting
            - counts
            - estimates
            - corrections
            - process_map
            - narrative
            - entries
          additionalProperties: false
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        canonicalization:
          type: string
          const: RFC8785/JCS
        verification:
          type: string
          enum:
            - signed
            - unsigned
        signature:
          type:
            - object
            - "null"
          properties:
            algorithm:
              type: string
              const: Ed25519
            keyId:
              type: string
              pattern: ^[A-Za-z0-9_.:-]{1,128}$
            value:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - keyId
            - value
          additionalProperties: false
        public_jwks_path:
          type: string
          const: /.well-known/decision-dossier-jwks.json
      required:
        - artifact
        - artifact_sha256
        - canonicalization
        - verification
        - signature
        - public_jwks_path
      additionalProperties: false
    SignedOutcomeDriftReport:
      type: object
      properties:
        artifact:
          type: object
          properties:
            version:
              type: string
              const: decionis.outcomes.drift/1
            report_id:
              type: string
              format: uuid
            org_id:
              type: string
              format: uuid
            period:
              type: string
              pattern: ^\d{4}-(0[1-9]|1[0-2])$
            window:
              type: object
              properties:
                from:
                  type: string
                  format: date-time
                  maxLength: 40
                to:
                  type: string
                  format: date-time
                  maxLength: 40
              required:
                - from
                - to
              additionalProperties: false
            closed_at:
              type: string
              format: date-time
              maxLength: 40
            policy_changes:
              type: object
              properties:
                releases:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                activations:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                managed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                standard:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                changes:
                  type: array
                  items:
                    type: object
                    properties:
                      kind:
                        type: string
                        enum:
                          - RELEASE
                          - ACTIVATION
                      policy_id:
                        type: string
                        format: uuid
                      environment:
                        type: string
                        enum:
                          - sandbox
                          - production
                      action:
                        type: string
                        enum:
                          - TESTING
                          - SHADOW
                          - PRODUCTION
                          - ROLLBACK
                          - RETIREMENT
                      from:
                        type:
                          - object
                          - "null"
                        properties:
                          revision_id:
                            type: string
                            format: uuid
                          number:
                            type: integer
                            minimum: 1
                          digest:
                            type: string
                            pattern: ^sha256:[a-f0-9]{64}$
                        required:
                          - revision_id
                          - number
                          - digest
                        additionalProperties: false
                      to:
                        type: object
                        properties:
                          revision_id:
                            type: string
                            format: uuid
                          number:
                            type: integer
                            minimum: 1
                          digest:
                            type: string
                            pattern: ^sha256:[a-f0-9]{64}$
                        required:
                          - revision_id
                          - number
                          - digest
                        additionalProperties: false
                      release_id:
                        type: string
                        format: uuid
                      release_digest:
                        type: string
                        pattern: ^sha256:[a-f0-9]{64}$
                      deployment_id:
                        type:
                          - string
                          - "null"
                        format: uuid
                      deployment_digest:
                        type:
                          - string
                          - "null"
                        pattern: ^sha256:[a-f0-9]{64}$
                      approvals:
                        type: array
                        items:
                          type: object
                          properties:
                            user_id:
                              type: string
                              format: uuid
                            role:
                              type: string
                              pattern: ^[A-Z][A-Z_]{0,63}$
                            at:
                              type: string
                              format: date-time
                              maxLength: 40
                          required:
                            - user_id
                            - role
                            - at
                          additionalProperties: false
                        maxItems: 50
                      activated_by:
                        type:
                          - string
                          - "null"
                        format: uuid
                      governance_profile:
                        type: string
                        enum:
                          - MANAGED
                          - STANDARD
                      at:
                        type: string
                        format: date-time
                        maxLength: 40
                    required:
                      - kind
                      - policy_id
                      - environment
                      - action
                      - from
                      - to
                      - release_id
                      - release_digest
                      - deployment_id
                      - deployment_digest
                      - approvals
                      - activated_by
                      - governance_profile
                      - at
                    additionalProperties: false
                  maxItems: 500
                truncated:
                  type: boolean
              required:
                - releases
                - activations
                - managed
                - standard
                - changes
                - truncated
              additionalProperties: false
            shadow:
              type: object
              properties:
                basis:
                  type: string
                  const: ESTIMATE
                observations:
                  type: object
                  properties:
                    evaluations:
                      type: object
                      properties:
                        SHADOW:
                          type: integer
                          minimum: 0
                          maximum: 9007199254740991
                        PARALLEL:
                          type: integer
                          minimum: 0
                          maximum: 9007199254740991
                      required:
                        - SHADOW
                        - PARALLEL
                      additionalProperties: false
                    disagreements:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    by_type:
                      type: array
                      items:
                        type: object
                        properties:
                          decision_type:
                            type: string
                            minLength: 1
                            maxLength: 1000
                          mode:
                            type: string
                            enum:
                              - SHADOW
                              - PARALLEL
                          shadow_verdict:
                            type: string
                            enum:
                              - ESCALATE
                              - REJECT
                              - REVIEW
                          verdict_effect:
                            type:
                              - string
                              - "null"
                            enum:
                              - OBSERVED
                              - BINDING
                              - null
                          count:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                        required:
                          - decision_type
                          - mode
                          - shadow_verdict
                          - verdict_effect
                          - count
                        additionalProperties: false
                      maxItems: 500
                    truncated:
                      type: boolean
                  required:
                    - evaluations
                    - disagreements
                    - by_type
                    - truncated
                  additionalProperties: false
                replays:
                  type: object
                  properties:
                    compared:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    differing:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    by_type:
                      type: array
                      items:
                        type: object
                        properties:
                          decision_type:
                            type: string
                            minLength: 1
                            maxLength: 1000
                          enforced_verdict:
                            type: string
                            enum:
                              - APPROVE
                              - ESCALATE
                              - REJECT
                              - REVIEW
                          shadow_verdict:
                            type:
                              - string
                              - "null"
                            enum:
                              - APPROVE
                              - ESCALATE
                              - REJECT
                              - REVIEW
                              - null
                          count:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                        required:
                          - decision_type
                          - enforced_verdict
                          - shadow_verdict
                          - count
                        additionalProperties: false
                      maxItems: 500
                    truncated:
                      type: boolean
                  required:
                    - compared
                    - differing
                    - by_type
                    - truncated
                  additionalProperties: false
              required:
                - basis
                - observations
                - replays
              additionalProperties: false
            coverage:
              type: object
              properties:
                ungoverned:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                observed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                sources:
                  type: array
                  items:
                    anyOf:
                      - type: object
                        properties:
                          source:
                            type: string
                            pattern: ^[a-z][a-z0-9_.:-]{0,99}$
                          status:
                            type: string
                            const: reported
                          description:
                            type: string
                            minLength: 1
                            maxLength: 500
                          records:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          ungoverned:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          observed:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          gaps:
                            type: array
                            items:
                              type: object
                              properties:
                                platform:
                                  type: string
                                  pattern: ^[a-z0-9][a-z0-9-]{0,99}$
                                action_type:
                                  type: string
                                  pattern: ^[A-Z][A-Z0-9_]{0,119}$
                                coverage:
                                  type: string
                                  enum:
                                    - UNGOVERNED
                                    - OBSERVED
                                count:
                                  type: integer
                                  minimum: 0
                                  maximum: 9007199254740991
                              required:
                                - platform
                                - action_type
                                - coverage
                                - count
                              additionalProperties: false
                            maxItems: 500
                        required:
                          - source
                          - status
                          - description
                          - records
                          - ungoverned
                          - observed
                          - gaps
                        additionalProperties: false
                      - type: object
                        properties:
                          source:
                            type: string
                            pattern: ^[a-z][a-z0-9_.:-]{0,99}$
                          status:
                            type: string
                            const: not_reported
                          description:
                            type: string
                            minLength: 1
                            maxLength: 500
                        required:
                          - source
                          - status
                          - description
                        additionalProperties: false
                  maxItems: 100
              required:
                - ungoverned
                - observed
                - sources
              additionalProperties: false
            narrative:
              type: array
              items:
                type: string
                minLength: 1
                maxLength: 400
              maxItems: 12
            inputs:
              type: object
              properties:
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                sources:
                  type: array
                  items:
                    type: object
                    properties:
                      source:
                        type: string
                        pattern: ^[a-z][a-z0-9_.:-]{0,99}$
                      records:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      sha256:
                        type: string
                        pattern: ^[a-f0-9]{64}$
                    required:
                      - source
                      - records
                      - sha256
                    additionalProperties: false
                  maxItems: 100
              required:
                - sha256
                - sources
              additionalProperties: false
          required:
            - version
            - report_id
            - org_id
            - period
            - window
            - closed_at
            - policy_changes
            - shadow
            - coverage
            - narrative
            - inputs
          additionalProperties: false
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        canonicalization:
          type: string
          const: RFC8785/JCS
        verification:
          type: string
          enum:
            - signed
            - unsigned
        signature:
          type:
            - object
            - "null"
          properties:
            algorithm:
              type: string
              const: Ed25519
            keyId:
              type: string
              pattern: ^[A-Za-z0-9_.:-]{1,128}$
            value:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - keyId
            - value
          additionalProperties: false
        public_jwks_path:
          type: string
          const: /.well-known/decision-dossier-jwks.json
      required:
        - artifact
        - artifact_sha256
        - canonicalization
        - verification
        - signature
        - public_jwks_path
      additionalProperties: false
    SignedOutcomeCharge:
      type: object
      properties:
        artifact:
          type: object
          properties:
            version:
              type: string
              const: decionis.outcomes.charge/1
            charge_id:
              type: string
              format: uuid
            statement_id:
              type: string
              format: uuid
            statement_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            agreement_id:
              type: string
              format: uuid
            agreement_sha256:
              type: string
              pattern: ^[a-f0-9]{64}$
            org_id:
              type: string
              format: uuid
            period:
              type: string
              pattern: ^\d{4}-(0[1-9]|1[0-2])$
            basis:
              type: string
              enum:
                - NET_BENEFIT_SHARE
                - GOVERNED_VALUE_FEE
            currency:
              type: string
              pattern: ^[A-Z]{3}$
            scale:
              type: integer
              minimum: 0
              maximum: 6
            carried_in_minor:
              type: integer
              maximum: 0
            base_minor:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            rate_bps:
              type: integer
              minimum: 0
              maximum: 10000
            computed_minor:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            floor_minor:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            cap_minor:
              type:
                - integer
                - "null"
              minimum: 0
              maximum: 9007199254740991
            amount_minor:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            above_floor_minor:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            carried_out_minor:
              type: integer
              maximum: 0
            disputed:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            issued_at:
              type: string
              format: date-time
              maxLength: 40
          required:
            - version
            - charge_id
            - statement_id
            - statement_sha256
            - agreement_id
            - agreement_sha256
            - org_id
            - period
            - basis
            - currency
            - scale
            - carried_in_minor
            - base_minor
            - rate_bps
            - computed_minor
            - floor_minor
            - cap_minor
            - amount_minor
            - above_floor_minor
            - carried_out_minor
            - disputed
            - issued_at
          additionalProperties: false
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        canonicalization:
          type: string
          const: RFC8785/JCS
        signature:
          type: object
          properties:
            algorithm:
              type: string
              const: Ed25519
            keyId:
              type: string
              pattern: ^[A-Za-z0-9_.:-]{1,128}$
            value:
              type: string
              pattern: ^[A-Za-z0-9_-]{86}$
          required:
            - algorithm
            - keyId
            - value
          additionalProperties: false
        public_jwks_path:
          type: string
          const: /.well-known/decision-dossier-jwks.json
      required:
        - artifact
        - artifact_sha256
        - canonicalization
        - signature
        - public_jwks_path
      additionalProperties: false
    OutcomeChargeReceipt:
      type: object
      properties:
        version:
          type: string
          const: decionis.outcomes.receipt/1
        platform:
          type: string
          enum:
            - microsoft
            - aws
        subscription_id:
          type: string
          minLength: 1
          maxLength: 200
        plan_id:
          type: string
          minLength: 1
          maxLength: 200
        dimension:
          type: string
          pattern: ^[A-Za-z0-9_.-]{1,100}$
        quantity:
          type: number
          minimum: 0
          maximum: 1000000000
        unit_minor:
          type: integer
          minimum: 1
          maximum: 1000000000
        status:
          type: string
          enum:
            - ACCEPTED
            - DUPLICATE
            - NOTHING_TO_BILL
        usage_reference:
          type:
            - string
            - "null"
          minLength: 1
          maxLength: 200
        reported_at:
          type: string
          format: date-time
          maxLength: 40
      required:
        - version
        - platform
        - subscription_id
        - plan_id
        - dimension
        - quantity
        - unit_minor
        - status
        - usage_reference
        - reported_at
      additionalProperties: false
    OutcomeDispute:
      type: object
      additionalProperties: false
      required:
        - dispute_id
        - subject_digest
        - reason
        - opened_at
        - state
        - resolution_note
        - resolved_at
      properties:
        dispute_id:
          type: string
          format: uuid
        subject_digest:
          type: string
          pattern: ^[a-f0-9]{64}$
        reason:
          type: string
          minLength: 1
          maxLength: 500
        opened_at:
          type: string
          format: date-time
        state:
          type: string
          enum:
            - OPEN
            - UPHELD
            - REJECTED
        resolution_note:
          type:
            - string
            - "null"
          maxLength: 500
        resolved_at:
          type:
            - string
            - "null"
          format: date-time
    DecisionExplanation:
      type: object
      properties:
        version:
          type: string
          const: decionis.decisions.explanation/1
        decision_id:
          type: string
          minLength: 1
          maxLength: 120
        disposition:
          type: string
          enum:
            - HOLD
            - BLOCK
            - ESCALATE
        customer_safe:
          type: object
          properties:
            summary:
              type: string
              minLength: 1
              maxLength: 500
            next_step:
              type: string
              minLength: 1
              maxLength: 300
          required:
            - summary
            - next_step
          additionalProperties: false
        internal:
          type: object
          properties:
            reason_codes:
              type: array
              items:
                type: string
                pattern: ^[A-Z][A-Z0-9_]{0,119}$
              maxItems: 60
            check_ids:
              type: array
              items:
                type: string
                enum:
                  - P01
                  - P02
                  - P03
                  - P04
                  - P05
                  - P06
                  - P07
                  - P08
                  - P09
                  - P10
                  - P11
                  - P12
                  - P13
                  - P14
                  - P15
                  - P16
              maxItems: 16
            dossier_id:
              type:
                - string
                - "null"
              minLength: 1
              maxLength: 200
          required:
            - reason_codes
            - check_ids
            - dossier_id
          additionalProperties: false
        generated_by:
          type: string
          const: decionis.explanations.catalog/1
      required:
        - version
        - decision_id
        - disposition
        - customer_safe
        - internal
        - generated_by
      additionalProperties: false
    CommercePaymentHistory:
      type: object
      properties:
        version:
          type: string
          const: commerce-payment-history-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          minimum: 1
        company_id:
          type: string
          format: uuid
        observed_at:
          type: string
          format: date-time
          maxLength: 40
        window:
          type: object
          properties:
            from:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            to:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
          required:
            - from
            - to
          additionalProperties: false
        payments:
          type: array
          items:
            type: object
            properties:
              payment_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              vendor_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              document_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              posting_date:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              currency:
                type: string
                pattern: ^[A-Z]{3}$
              scale:
                type: integer
                minimum: 0
                maximum: 6
              amount_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              recipient_account_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
            required:
              - payment_digest
              - vendor_digest
              - document_digest
              - posting_date
              - currency
              - scale
              - amount_minor
              - recipient_account_digest
            additionalProperties: false
          maxItems: 2000
        invoices:
          type: array
          items:
            type: object
            properties:
              invoice_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              vendor_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              external_document_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
              posting_date:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              due_date:
                type:
                  - string
                  - "null"
                pattern: ^\d{4}-\d{2}-\d{2}$
              currency:
                type: string
                pattern: ^[A-Z]{3}$
              scale:
                type: integer
                minimum: 0
                maximum: 6
              amount_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              discount_date:
                type:
                  - string
                  - "null"
                pattern: ^\d{4}-\d{2}-\d{2}$
              discount_possible_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              discount_taken_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              closed_at:
                type:
                  - string
                  - "null"
                pattern: ^\d{4}-\d{2}-\d{2}$
            required:
              - invoice_digest
              - vendor_digest
              - external_document_digest
              - posting_date
              - due_date
              - currency
              - scale
              - amount_minor
              - discount_date
              - discount_possible_minor
              - discount_taken_minor
              - closed_at
            additionalProperties: false
          maxItems: 4000
        applications:
          type: array
          items:
            type: object
            properties:
              payment_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              invoice_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              applied_on:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              amount_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
            required:
              - payment_digest
              - invoice_digest
              - applied_on
              - amount_minor
            additionalProperties: false
          maxItems: 8000
        bank_changes:
          type: object
          properties:
            available:
              type: boolean
            reason:
              type:
                - string
                - "null"
              enum:
                - CHANGE_LOG_DISABLED
                - VENDOR_BANK_ACCOUNTS_NOT_LOGGED
                - CHANGE_LOG_UNREADABLE
                - null
            logged_from:
              type:
                - string
                - "null"
              format: date-time
              maxLength: 40
            entries:
              type: array
              items:
                type: object
                properties:
                  vendor_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  account_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  changed_at:
                    type: string
                    format: date-time
                    maxLength: 40
                  change:
                    type: string
                    enum:
                      - INSERTED
                      - MODIFIED
                required:
                  - vendor_digest
                  - account_digest
                  - changed_at
                  - change
                additionalProperties: false
              maxItems: 2000
          required:
            - available
            - reason
            - logged_from
            - entries
          additionalProperties: false
        coverage:
          type: object
          properties:
            complete:
              type: boolean
            truncated:
              type: boolean
            reasons:
              type: array
              items:
                type: string
                pattern: ^[A-Z][A-Z0-9_]{0,119}$
              maxItems: 20
          required:
            - complete
            - truncated
            - reasons
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - connection_revision
        - company_id
        - observed_at
        - window
        - payments
        - invoices
        - applications
        - bank_changes
        - coverage
        - execution_available
      additionalProperties: false
    CommerceSalesHistory:
      type: object
      properties:
        version:
          type: string
          const: commerce-sales-history-v1
        org_id:
          type: string
          format: uuid
        connection_id:
          type: string
          format: uuid
        connection_revision:
          type: integer
          minimum: 1
        company_id:
          type: string
          format: uuid
        observed_at:
          type: string
          format: date-time
          maxLength: 40
        window:
          type: object
          properties:
            from:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            to:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
          required:
            - from
            - to
          additionalProperties: false
        orders:
          type: array
          items:
            type: object
            properties:
              document_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              order_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
              external_document_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
              document_date:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              currency:
                type: string
                pattern: ^[A-Z]{3}$
              scale:
                type: integer
                minimum: 0
                maximum: 6
              amount_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
            required:
              - document_digest
              - order_digest
              - external_document_digest
              - document_date
              - currency
              - scale
              - amount_minor
            additionalProperties: false
          maxItems: 4000
        invoices:
          type: array
          items:
            type: object
            properties:
              document_digest:
                type: string
                pattern: ^[a-f0-9]{64}$
              order_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
              external_document_digest:
                type:
                  - string
                  - "null"
                pattern: ^[a-f0-9]{64}$
              document_date:
                type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
              currency:
                type: string
                pattern: ^[A-Z]{3}$
              scale:
                type: integer
                minimum: 0
                maximum: 6
              amount_minor:
                type: integer
                minimum: 0
                maximum: 9007199254740991
            required:
              - document_digest
              - order_digest
              - external_document_digest
              - document_date
              - currency
              - scale
              - amount_minor
            additionalProperties: false
          maxItems: 8000
        coverage:
          type: object
          properties:
            complete:
              type: boolean
            truncated:
              type: boolean
            reasons:
              type: array
              items:
                type: string
                pattern: ^[A-Z][A-Z0-9_]{0,119}$
              maxItems: 20
          required:
            - complete
            - truncated
            - reasons
          additionalProperties: false
        execution_available:
          type: boolean
          not:
            const: true
      required:
        - version
        - org_id
        - connection_id
        - connection_revision
        - company_id
        - observed_at
        - window
        - orders
        - invoices
        - coverage
        - execution_available
      additionalProperties: false
    PolicyDocumentDraftRequest:
      type: object
      properties:
        expectedSequence:
          type: integer
          exclusiveMinimum: 0
        modelId:
          type: string
          minLength: 1
          maxLength: 120
        modelVersion:
          type: string
          minLength: 1
          maxLength: 120
        sourceIds:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          maxItems: 20
        intent:
          type: string
          minLength: 1
          maxLength: 12000
      required:
        - expectedSequence
        - modelId
        - modelVersion
        - sourceIds
        - intent
      additionalProperties: false
    PolicyFindingsDraftRequest:
      type: object
      properties:
        expectedSequence:
          type: integer
          exclusiveMinimum: 0
        findingsIds:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          maxItems: 20
        modelId:
          type: string
          minLength: 1
          maxLength: 120
        modelVersion:
          type: string
          minLength: 1
          maxLength: 120
        intent:
          type: string
          minLength: 1
          maxLength: 12000
      required:
        - expectedSequence
        - findingsIds
      additionalProperties: false
    PolicyProposalDecision:
      type: object
      properties:
        expectedSequence:
          type: integer
          exclusiveMinimum: 0
        action:
          type: string
          enum:
            - ACCEPT
            - REJECT
            - SPLIT
        reason:
          type: string
          minLength: 1
          maxLength: 4000
        ruleIds:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 120
          maxItems: 120
          default: []
      required:
        - expectedSequence
        - action
        - reason
      additionalProperties: false
    ActionManifest:
      type: object
      description: "`agent-safe.actions/1`: the actions an executor can run, as AgentSafe's `agentsafe actions manifest` exports them from its handler registry and its API and MCP profiles. Actions are unique and sorted in code-point order, so one manifest has one digest (SHA-256 over its RFC 8785 form). A policy revision carries it as `content.actionManifest`; a release cut from the revision records `actionManifestDigest`, and assurance fails with `ACTION_COVERAGE_INCOMPLETE` while a manifest action has no scenario naming it (`context.agent_safe.action.type`) that a rule other than the default matches."
      required:
        - manifest
        - actions
      additionalProperties: false
      properties:
        manifest:
          type: string
          const: agent-safe.actions/1
        actions:
          type: array
          minItems: 1
          maxItems: 500
          items:
            $ref: "#/components/schemas/ActionManifestEntry"
    ActionManifestEntry:
      type: object
      required:
        - action
        - source
        - parameters
        - targets
        - effect_type
      additionalProperties: false
      properties:
        action:
          type: string
          maxLength: 120
          pattern: ^[a-z][a-z0-9._:-]*$
        source:
          anyOf:
            - type: object
              required:
                - kind
                - family
              additionalProperties: false
              properties:
                kind:
                  type: string
                  const: registry
                family:
                  type: string
                  pattern: ^[a-z][a-z0-9]{0,39}$
            - type: object
              required:
                - kind
                - profile
                - operations
              additionalProperties: false
              properties:
                kind:
                  type: string
                  const: api
                profile:
                  type: string
                  minLength: 1
                  maxLength: 200
                operations:
                  type: array
                  minItems: 1
                  maxItems: 200
                  items:
                    type: string
                    minLength: 1
                    maxLength: 200
            - type: object
              required:
                - kind
                - profile
                - tool
              additionalProperties: false
              properties:
                kind:
                  type: string
                  const: mcp
                profile:
                  type: string
                  minLength: 1
                  maxLength: 200
                tool:
                  type: string
                  minLength: 1
                  maxLength: 200
        parameters:
          type: object
          description: The JSON Schema the executor's admission holds the intent's parameters to.
          additionalProperties: true
        targets:
          type: array
          description: Target scope templates with `{name}` placeholders; empty when the proposal names the target.
          maxItems: 64
          items:
            type: string
            minLength: 1
            maxLength: 500
        effect_type:
          type:
            - string
            - "null"
          description: The effect the action produces, when its source declares one.
          pattern: ^[A-Z][A-Z0-9_]{0,119}$
    PolicyAssumption:
      type: object
      description: An interpretation the encoded rules rest on, recorded with the draft and carried, as written, into the signed release manifest (`assumptions`). `invalidatedBy` names the material signal whose open value says the assumption no longer holds.
      required:
        - id
        - text
        - invalidatedBy
      additionalProperties: false
      properties:
        id:
          type: string
          maxLength: 120
          pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]*$
        text:
          type: string
          minLength: 1
          maxLength: 2000
        invalidatedBy:
          type:
            - string
            - "null"
          pattern: ^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,199}$
    PolicyInvariant:
      type: object
      description: 'An organisation invariant ("no production administrative port is opened to 0.0.0.0/0"): compiled to one scenario per combination of the `vary` values, each a copy of `input` with `decision_type` set to `decisionType` and each varied field written at its dotted path. At most 100 scenarios; a field is varied once, never inside another, never `decision_type`, and never through a prototype name.'
      required:
        - id
        - statement
        - decisionDomain
        - decisionType
        - input
        - vary
      additionalProperties: false
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]*$
        statement:
          type: string
          minLength: 1
          maxLength: 2000
        decisionDomain:
          type: string
          pattern: ^[A-Z][A-Z0-9_]{0,99}$
        decisionType:
          type: string
          minLength: 1
          maxLength: 120
        input:
          type: object
          additionalProperties: true
        vary:
          type: array
          maxItems: 6
          items:
            type: object
            required:
              - field
              - values
            additionalProperties: false
            properties:
              field:
                type: string
                maxLength: 200
                pattern: ^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$
              values:
                type: array
                minItems: 1
                maxItems: 20
                items:
                  type:
                    - string
                    - number
                    - boolean
                    - "null"
                  maxLength: 500
    PolicyInvariantEntry:
      type: object
      required:
        - record
        - digest
        - retirement
      additionalProperties: false
      properties:
        record:
          type: object
          required:
            - schemaVersion
            - kind
            - id
            - orgId
            - environment
            - invariant
            - declaredBy
            - declaredAt
            - reason
          additionalProperties: false
          properties:
            schemaVersion:
              type: integer
              const: 1
            kind:
              type: string
              const: decionis.policy-invariant/v1
            id:
              type: string
              format: uuid
            orgId:
              type: string
              format: uuid
            environment:
              type: string
              enum:
                - sandbox
                - production
            invariant:
              $ref: "#/components/schemas/PolicyInvariant"
            declaredBy:
              type: string
              format: uuid
            declaredAt:
              type: string
              format: date-time
            reason:
              type: string
        digest:
          type: string
          pattern: ^sha256:[a-f0-9]{64}$
        retirement:
          type:
            - object
            - "null"
          required:
            - record
            - digest
          additionalProperties: false
          properties:
            record:
              type: object
              required:
                - schemaVersion
                - kind
                - invariantRecordId
                - invariantDigest
                - retiredBy
                - retiredAt
                - reason
              additionalProperties: false
              properties:
                schemaVersion:
                  type: integer
                  const: 1
                kind:
                  type: string
                  const: decionis.policy-invariant-retirement/v1
                invariantRecordId:
                  type: string
                  format: uuid
                invariantDigest:
                  type: string
                  pattern: ^sha256:[a-f0-9]{64}$
                retiredBy:
                  type: string
                  format: uuid
                retiredAt:
                  type: string
                  format: date-time
                reason:
                  type: string
            digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
    PolicyProposalReplay:
      type: object
      properties:
        version:
          type: string
          const: decionis.policy.proposal.replay/1
        policy_id:
          type: string
          format: uuid
        proposal_id:
          type: string
          format: uuid
        replayed_at:
          type: string
          format: date-time
        findings:
          type: array
          items:
            type: object
            properties:
              findings_id:
                type: string
                format: uuid
              assessment_id:
                type: string
                format: uuid
              verification:
                type: string
                enum:
                  - signed
                  - unsigned
              status:
                type: string
                enum:
                  - complete
                  - partial
              gaps:
                type: array
                items:
                  type: string
                maxItems: 30
            required:
              - findings_id
              - assessment_id
              - verification
              - status
              - gaps
            additionalProperties: false
          maxItems: 20
        replay:
          type: object
          properties:
            version:
              type: string
              const: decionis.assessments.replay/1
            evaluator_version:
              type: string
              minLength: 1
              maxLength: 120
            current_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            proposed_digest:
              type: string
              pattern: ^sha256:[a-f0-9]{64}$
            identical_configuration:
              type: boolean
            scope:
              type: array
              items:
                type: string
                enum:
                  - P01
                  - P02
                  - P03
                  - P04
                  - P05
                  - P06
                  - P07
                  - P08
                  - P09
                  - P10
                  - P11
                  - P12
                  - P13
                  - P14
                  - P15
                  - P16
              maxItems: 16
            assumptions:
              type: array
              items:
                type: string
                pattern: ^[A-Z][A-Z0-9_]{0,119}$
              maxItems: 10
            categories:
              type: array
              items:
                type: object
                properties:
                  category:
                    type: string
                    minLength: 1
                    maxLength: 80
                  totals:
                    type: array
                    items:
                      type: object
                      properties:
                        currency:
                          type: string
                          pattern: ^[A-Z]{3}$
                        scale:
                          type: integer
                          minimum: 0
                          maximum: 6
                        records:
                          type: integer
                          minimum: 0
                          maximum: 9007199254740991
                        amount_minor:
                          type: integer
                          minimum: 0
                          maximum: 9007199254740991
                        current:
                          type: object
                          properties:
                            stopped:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            stopped_amount_minor:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            held:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            blocked:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                          required:
                            - stopped
                            - stopped_amount_minor
                            - held
                            - blocked
                          additionalProperties: false
                        proposed:
                          type: object
                          properties:
                            stopped:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            stopped_amount_minor:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            held:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            blocked:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                          required:
                            - stopped
                            - stopped_amount_minor
                            - held
                            - blocked
                          additionalProperties: false
                      required:
                        - currency
                        - scale
                        - records
                        - amount_minor
                        - current
                        - proposed
                      additionalProperties: false
                required:
                  - category
                  - totals
                additionalProperties: false
              maxItems: 40
            false_holds:
              type: object
              properties:
                basis:
                  type: string
                  const: held_without_exposure_finding
                current:
                  type: array
                  items:
                    type: object
                    properties:
                      currency:
                        type: string
                        pattern: ^[A-Z]{3}$
                      scale:
                        type: integer
                        minimum: 0
                        maximum: 6
                      count:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      amount_minor:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                    required:
                      - currency
                      - scale
                      - count
                      - amount_minor
                    additionalProperties: false
                proposed:
                  type: array
                  items:
                    type: object
                    properties:
                      currency:
                        type: string
                        pattern: ^[A-Z]{3}$
                      scale:
                        type: integer
                        minimum: 0
                        maximum: 6
                      count:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      amount_minor:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                    required:
                      - currency
                      - scale
                      - count
                      - amount_minor
                    additionalProperties: false
              required:
                - basis
                - current
                - proposed
              additionalProperties: false
            changes:
              type: array
              items:
                type: object
                properties:
                  record_digest:
                    type: string
                    pattern: ^[a-f0-9]{64}$
                  categories:
                    type: array
                    items:
                      type: string
                    maxItems: 20
                  currency:
                    type:
                      - string
                      - "null"
                    pattern: ^[A-Z]{3}$
                  amount_minor:
                    type:
                      - integer
                      - "null"
                    minimum: 0
                    maximum: 9007199254740991
                  current:
                    type: string
                    enum:
                      - PROCEED
                      - HOLD
                      - BLOCK
                  proposed:
                    type: string
                    enum:
                      - PROCEED
                      - HOLD
                      - BLOCK
                required:
                  - record_digest
                  - categories
                  - currency
                  - amount_minor
                  - current
                  - proposed
                additionalProperties: false
              maxItems: 200
            coverage:
              type: object
              properties:
                assessed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                replayed:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                out_of_scope:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                not_replayable:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                record_limit:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                change_limit:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                changes_truncated:
                  type: boolean
                truncated:
                  type: boolean
                complete:
                  type: boolean
              required:
                - assessed
                - replayed
                - out_of_scope
                - not_replayable
                - record_limit
                - change_limit
                - changes_truncated
                - truncated
                - complete
              additionalProperties: false
            no_downstream_action_executed:
              type: boolean
              not:
                const: false
          required:
            - version
            - evaluator_version
            - current_digest
            - proposed_digest
            - identical_configuration
            - scope
            - assumptions
            - categories
            - false_holds
            - changes
            - coverage
            - no_downstream_action_executed
          additionalProperties: false
      required:
        - version
        - policy_id
        - proposal_id
        - replayed_at
        - findings
        - replay
      additionalProperties: false
