{
  "openapi": "3.0.3",
  "info": {
    "title": "AGLedger API",
    "description": "AGLedger is a self-hosted cryptographic notary for automated work — built for audit, governance, and org scale.\n\nAGLedger records what AI agents are authorized to do, how they delegate, and what they report back. Every authorization, delegation, and completion is captured in a cryptographically signed, tamper-evident Audit Chain (SHA-256 hash chain with optional Ed25519 per-entry signatures over RFC 8785 JCS canonical JSON). When an incident occurs, the full decision chain is reconstructable.\n\nThe **Compliance Export** assembles org-wide audit data for regulators, auditors, and GRC tooling.\n\n**Key capabilities:** customer-defined Types via `POST /v1/schemas` (the engine ships zero built-in types — register your own), an 11-state customer-facing record lifecycle, delegation chains (default depth 5, configurable up to 10) with cascading gates, A2A protocol support (AgentCard discovery + JSON-RPC 2.0), dual operating modes (cleartext where the server can evaluate gates, encrypted where the principal evaluates), three-tier dispute resolution, and agent reputation scores.\n\n## Authentication\n\nAll authenticated endpoints require a Bearer token in the `Authorization` header. API keys are hashed with HMAC-SHA256 server-side and never stored in plaintext. Three roles exist:\n\n- **admin** -- governs a org: provisions agents, manages schemas/webhooks/policy, can act on records (signed as admin)\n- **agent** -- acts: creates records as principal by default, delivers completions, delegates\n- **platform** -- cross-org; unrestricted; every action signed as platform\n\nAGLedger is self-hosted only. Accounts are provisioned by an operator via `POST /v1/admin/orgs` + `POST /v1/admin/api-keys` (or via the `provisioning/` YAML config-as-code directory).\n\nPublic endpoints (`/health`, `/docs/*`, `/schemas/*`) do not require authentication. Protocol endpoints (`/.well-known/*`, `/a2a`) are also at root. All business routes are under `/v1`.\n\n## Webhook Signatures\n\nA subscription is signed with one of two schemes, fixed at create time via `signingAlg` and reported on every response. You receive an asymmetric RFC 9421 signature iff the subscription was created with an asymmetric `signingAlg` (`ed25519`, or `ecdsa-p256-sha256` on a Server opted into ES256; the value must match the active vault key) or is a settlement subscription on a key-bearing Server; otherwise `hmac`.\n\n**`hmac` (default).** HMAC-SHA256 with the per-subscription shared secret:\n\n```\nX-AGLedger-Signature: t=<unix_timestamp>,v1=<hex_hmac>\n```\n\nThe signed input is `<unix_timestamp>.<rawBody>` — the literal `t=` is a parser prefix, NOT part of the HMAC input. Recompute the HMAC over `${timestamp}.${rawBody}` with your secret and compare constant-time. Reject deliveries where `t` is more than 300 seconds old (replay protection). Right for the private, receiver-only case.\n\n**Asymmetric (opt-in, non-repudiable).** RFC 9421 HTTP Message Signatures signed with the Server vault key — the receiver holds no secret and verifies against the published public key, so a Settlement Signal is provable to a third party (the same trust root as the chain). The wire `alg` parameter is the active key's RFC 9421 name (`ed25519` by default). Headers:\n\n```\nContent-Digest: sha-256=:<base64(sha256(body))>:\nSignature-Input: sig1=(\"content-digest\" \"x-agledger-idempotency-key\");created=<unix>;keyid=\"<kid>\";alg=\"<active key alg, ed25519 by default>\"\nSignature: sig1=:<base64>:\n```\n\nVerify with any RFC 9421 library (e.g. the `http-message-signatures` package): resolve `keyid` against `GET /v1/verification-keys` (feed `publicKey`, the SPKI-DER form RFC 9421 libraries expect; `publicKeyRaw` is the raw 32-byte form for raw-key libraries like libsodium), check the signature over the RFC 9421 signature base, and enforce the `created` 300s replay window. No derived components (`@method`/`@target-uri`) are signed, so proxy/LB rewrites do not break verification.\n\nDedup on the `X-AGLedger-Idempotency-Key: <uuid>` header — the event id, stable across retries (and, for asymmetric subscriptions, covered by the signature). The `X-AGLedger-Delivery: <uuid>` header is a per-attempt correlation id and changes on each retry, so do not dedup on it.\n\n## Rate Limiting\n\nAll responses include rate limit headers:\n\n| Header | Description |\n|---|---|\n| `X-RateLimit-Limit` | Maximum requests allowed in the current window (1 minute) |\n| `X-RateLimit-Remaining` | Requests remaining in the current window |\n| `X-RateLimit-Reset` | Seconds until the window resets |\n| `Retry-After` | Seconds to wait before retrying (429 responses only) |\n\nRate limits vary by role: agents get 500 req/min, admin keys (and their org agents) get 1,000 req/min. Defaults are tunable via `RATE_LIMIT_AGENT` / `RATE_LIMIT_ADMIN` env vars. Rate limiting is keyed by API key when authenticated, falling back to IP address.\n\n## Request Correlation (`X-Request-ID`)\n\nClients may send an `X-Request-ID` header (max 128 characters, alphanumeric plus hyphens) on any request for end-to-end correlation. The server echoes the same value back on the response. If the header is not provided, the server generates a UUID automatically. This header is present on **all** responses.\n\n## Standard Response Headers\n\nEvery authenticated response includes the following headers (see `standardResponseHeaders` in the SDK/schema definitions):\n\n| Header | Description |\n|---|---|\n| `X-Request-ID` | Request correlation ID — echoed from request or server-generated UUID |\n| `X-RateLimit-Limit` | Maximum requests allowed per window |\n| `X-RateLimit-Remaining` | Remaining requests in current window |\n| `X-RateLimit-Reset` | Seconds until rate limit window resets |\n\n## Idempotency\n\nSupported on POST endpoints that accept the `Idempotency-Key` header (max 256 characters). When present, the server returns the cached response for duplicate keys within a 24-hour window.",
    "version": "1.4.0",
    "contact": {
      "name": "AGLedger",
      "url": "https://agledger.ai"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key for admin, agent, or platform roles. Include as `Bearer <api-key>` in the Authorization header."
      },
      "platformAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Platform-role API key (`agl_plt_*`). Required for `/v1/admin/*` endpoints."
      },
      "adminOidcJwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "OIDC JWT issued by an IdP registered in `trusted_issuers` with `appliesTo: admin`. Customer's Okta/Azure AD/Auth0/Keycloak issues the JWT directly; AGLedger does NOT mint anything. Required claims: `iss` + `aud` matching the registered row, plus the IdP claim that the row's `claimMapping.role` points at (value must resolve to `platform`/`admin`/`org`). Validation runs every request (JWKS-cached). See GET /llms.txt → \"OIDC Workload Identity → Mode 1\"."
      },
      "agentEphemeralCert": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "AGLedger-issued ephemeral cert JWS (`POST /v1/auth/oidc/cert` mints it from an IdP JWT). Short-lived (cert TTL = min(now + maxCredentialTtlSeconds, jwt.exp); 10-min cap by default, 60s floor — sub-60s remaining JWT exp returns 422 instead of issuing a cert). Optional companion: X-Agent-Signature + X-Agent-Signature-Content-Hash for per-request co-signature. See GET /llms.txt → \"OIDC Workload Identity → Mode 2 — Agent ephemeral cert\"."
      },
      "federationPeerSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-AGLedger-Signature",
        "description": "V1 per-request Ed25519 signature in the `X-AGLedger-*` header set (Peer-Hub-Id, Timestamp, Nonce, Signature). Signature covers the sign-input `agledger.federation.v1:METHOD:PATH:bodyHash:timestamp:nonce` and is verified against the peer Server's published signing key. No bearer tokens — every request stands on its own signature."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "URI reference identifying the problem type (RFC 9457)"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable summary of the problem type (RFC 9457)"
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code (RFC 9457)"
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence (RFC 9457)"
          },
          "instance": {
            "type": "string",
            "description": "URI reference identifying the specific occurrence (RFC 9457)"
          },
          "errors": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Structured validation errors (RFC 9457 extension, present on 400 responses)"
          },
          "retryable": {
            "type": "boolean",
            "description": "Whether the client should retry this request (true for 429, 5xx; false for 4xx)"
          },
          "error": {
            "type": "string",
            "description": "Machine-readable error code (e.g., NOT_FOUND, VALIDATION_ERROR, FORBIDDEN)"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description"
          },
          "requestId": {
            "type": "string",
            "description": "Unique request identifier for support correlation"
          },
          "details": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Validation error details (present on 400/422 responses)"
          },
          "suggestion": {
            "type": "string",
            "description": "Suggested correction when a field-name typo is detected (e.g., \"Body contains 'type' — did you mean 'type'?\")"
          },
          "recoveryHint": {
            "type": "string",
            "description": "Machine-readable recovery guidance pointing to relevant endpoints (e.g., schema lookup URL)"
          },
          "missingFeatures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "License features required but not available at the current tier"
          },
          "currentTier": {
            "type": "string",
            "description": "Current license tier (developer, org)"
          },
          "requiredTier": {
            "type": "string",
            "description": "Minimum tier required for the missing features"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Guided next actions for AI agents and integrations"
          },
          "missingScopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "API key scopes required but not present"
          },
          "hint": {
            "type": "string",
            "description": "Contextual hint for record/completion validation (e.g., schema lookup URL)"
          },
          "requiredFields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Required fields for the request body (present on 400 for record/completion creation)"
          },
          "optionalFields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional fields for the request body (present on 400 for record/completion creation)"
          },
          "examplePayload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Example request body for record/completion creation"
          },
          "schemaUrl": {
            "type": "string",
            "description": "URL to the type schema for field reference"
          },
          "recordType": {
            "type": "string",
            "description": "Record Type (formerly Contract Type) related to the validation error"
          },
          "currentState": {
            "type": "string",
            "description": "Current state of the resource"
          },
          "attemptedTransition": {
            "type": "string",
            "description": "Transition that was attempted"
          },
          "attemptedState": {
            "type": "string",
            "description": "State the caller asked the resource to move to (federation: POST /federation/v1/state-transitions terminal-conflict 422 carries this alongside `currentState`)."
          },
          "validTransitions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Valid transitions from the current state"
          },
          "attemptedAction": {
            "type": "string",
            "description": "The /transition action name that was submitted"
          },
          "allowedActions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Action names accepted by POST /v1/records/{id}/transition in the current state"
          },
          "refreshUrl": {
            "type": "string",
            "description": "Concrete GET URL the agent should re-fetch to read fresh nextActions/validTransitions/allowedActions (set on 422 INVALID_ACTION when the request path includes a record id)."
          },
          "allowedValues": {
            "type": "array",
            "items": {},
            "description": "Permitted values for the field that failed an enum constraint, or the registered list when the rejection is a \"no such X\" lookup (e.g., unknown type → registered types)."
          },
          "disputeCount": {
            "type": "integer",
            "description": "Number of disputes already filed against this record (open + terminal). Surfaced on 422 when the dispute cap is hit."
          },
          "maxDisputes": {
            "type": "integer",
            "description": "Maximum disputes allowed on this record (default 1). Surfaced alongside disputeCount when the cap is hit."
          },
          "openDisputeId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "ID of the currently-open dispute (EVIDENCE_WINDOW or TIER_2_REVIEW). Null when all prior disputes have terminalized. Surfaced on 422 when the dispute cap is hit so the agent can escalate the existing one rather than try to open another."
          },
          "currentStatus": {
            "type": "string",
            "description": "Display status of the record at the moment the request was refused. Surfaced on 422 when a dispute is attempted while verification is still in progress."
          },
          "disputeableWhen": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Display statuses from which POST /v1/records/{recordId}/dispute is accepted. Poll GET /v1/records/{recordId} until status is one of these, then retry."
          },
          "allowedActors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Role/actor labels permitted for this action in the current resource state. Surfaced on 403 cross-tier rejections (e.g., parent-principal trying to act on a sub-record it is not direct-principal of)."
          },
          "parentRecordId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the parent record that rejected the delegation attempt. Surfaced on 422 when the parent state cannot accept children."
          },
          "reason": {
            "type": "string",
            "description": "Machine-readable reason code. On 409 conflicts: STATUS_NOT_DISABLED, RECORDS_REFERENCE_TYPE, CONFLICTING_VERSION, RESERVED_PUBLISHER_LABEL, VAULT_SCAN_IN_FLIGHT. On 422 authority-guard refusals: the snake_case guard identifier (has_children_leaf_only, leaf_record, no_children, children_not_terminal, mode_not_auto, mode_not_principal, record_disputed). Branch on this rather than on the prose in `detail`."
          },
          "jobId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the background job this request is being refused in favour of. Poll GET /v1/admin/vault/scan/{jobId} for its state and result. Present on 409 VAULT_SCAN_IN_FLIGHT."
          },
          "publisher": {
            "type": "string",
            "description": "Publisher label on the conflicting schema row."
          },
          "version": {
            "type": "string",
            "description": "Manifest version string on the conflicting schema row."
          },
          "incomingDigest": {
            "type": "string",
            "description": "sha256:<hex> digest of the manifest the caller just submitted."
          },
          "existingDigest": {
            "type": "string",
            "description": "sha256:<hex> digest of the manifest already registered at this (publisher, type, version)."
          },
          "publishers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Candidate publisher labels on a 422 `/problems/ambiguous-publisher`. Emitted by /v1/schemas/{type} reads and writes (pin with `?publisher=`) and by record creation (pin with a `publisher` body field)."
          },
          "pinnedRecords": {
            "type": "integer",
            "description": "Records written against the exact registration this delete would remove."
          },
          "unattributableRecords": {
            "type": "integer",
            "description": "Records of this type carrying no registration pin, so they block a delete under any publisher label."
          },
          "peerDigest": {
            "type": "string",
            "description": "sha256:<hex> digest the federation peer claimed in `schemaRef.manifestDigest`."
          },
          "localDigest": {
            "type": "string",
            "description": "sha256:<hex> digest the receiver holds locally for the same (publisher, type, version, org) tuple."
          },
          "revisionCount": {
            "type": "integer",
            "description": "Number of revisions consumed at the moment OVERFLOW_REJECT fired."
          },
          "maxRevisions": {
            "type": "integer",
            "description": "Configured maxRevisions cap on the record."
          },
          "terminalReason": {
            "type": "string",
            "description": "Machine-readable label naming the system action that terminalized the record (e.g. OVERFLOW_REJECT, ARBITRATION_LOCK, TIME_OUT)."
          },
          "deadline": {
            "type": "string",
            "format": "date-time",
            "description": "The record deadline that had already passed when the request was refused (system TIME_OUT)."
          },
          "previousStatus": {
            "type": "string",
            "description": "Display status the record was at immediately before the terminal transition."
          },
          "constraintViolations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Constraint violations for the request"
          },
          "constraint": {
            "type": "string",
            "description": "Database constraint that was violated"
          },
          "validationErrors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Schema validation errors"
          },
          "migratedTo": {
            "type": "string",
            "description": "Suggested replacement path for a renamed endpoint. Present on 404 responses for routes retired in a migration (e.g. /v1/admin/enterprises → /v1/admin/orgs)."
          },
          "expected": {
            "type": "string",
            "description": "Expected JSON type or value, paired with `received` on validation errors."
          },
          "signInputTemplate": {
            "type": "string",
            "description": "Exact byte template the Ed25519 proof-of-possession signature must cover, with the domain prefix. Surfaced on the federation 401 for an invalid signature."
          },
          "docs": {
            "type": "string",
            "description": "Pointer to the discovery document section describing the failed scheme (e.g. \"/llms.txt (Federation Signing Scheme section)\"). Paired with signInputTemplate + hint on the federation 401."
          }
        },
        "additionalProperties": false
      },
      "RateLimitError": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "URI reference identifying the problem type (RFC 9457)"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable summary of the problem type (RFC 9457)"
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code (RFC 9457)"
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence (RFC 9457)"
          },
          "instance": {
            "type": "string",
            "description": "URI reference identifying the specific occurrence (RFC 9457)"
          },
          "errors": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Structured validation errors (RFC 9457 extension, present on 400 responses)"
          },
          "retryable": {
            "type": "boolean",
            "description": "Whether the client should retry this request (true for 429, 5xx; false for 4xx)"
          },
          "error": {
            "type": "string",
            "description": "Machine-readable error code (e.g., NOT_FOUND, VALIDATION_ERROR, FORBIDDEN)"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description"
          },
          "requestId": {
            "type": "string",
            "description": "Unique request identifier for support correlation"
          },
          "details": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Validation error details (present on 400/422 responses)"
          },
          "suggestion": {
            "type": "string",
            "description": "Suggested correction when a field-name typo is detected (e.g., \"Body contains 'type' — did you mean 'type'?\")"
          },
          "recoveryHint": {
            "type": "string",
            "description": "Machine-readable recovery guidance pointing to relevant endpoints (e.g., schema lookup URL)"
          },
          "missingFeatures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "License features required but not available at the current tier"
          },
          "currentTier": {
            "type": "string",
            "description": "Current license tier (developer, org)"
          },
          "requiredTier": {
            "type": "string",
            "description": "Minimum tier required for the missing features"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Guided next actions for AI agents and integrations"
          },
          "missingScopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "API key scopes required but not present"
          },
          "hint": {
            "type": "string",
            "description": "Contextual hint for record/completion validation (e.g., schema lookup URL)"
          },
          "requiredFields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Required fields for the request body (present on 400 for record/completion creation)"
          },
          "optionalFields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional fields for the request body (present on 400 for record/completion creation)"
          },
          "examplePayload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Example request body for record/completion creation"
          },
          "schemaUrl": {
            "type": "string",
            "description": "URL to the type schema for field reference"
          },
          "recordType": {
            "type": "string",
            "description": "Record Type (formerly Contract Type) related to the validation error"
          },
          "currentState": {
            "type": "string",
            "description": "Current state of the resource"
          },
          "attemptedTransition": {
            "type": "string",
            "description": "Transition that was attempted"
          },
          "attemptedState": {
            "type": "string",
            "description": "State the caller asked the resource to move to (federation: POST /federation/v1/state-transitions terminal-conflict 422 carries this alongside `currentState`)."
          },
          "validTransitions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Valid transitions from the current state"
          },
          "attemptedAction": {
            "type": "string",
            "description": "The /transition action name that was submitted"
          },
          "allowedActions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Action names accepted by POST /v1/records/{id}/transition in the current state"
          },
          "refreshUrl": {
            "type": "string",
            "description": "Concrete GET URL the agent should re-fetch to read fresh nextActions/validTransitions/allowedActions (set on 422 INVALID_ACTION when the request path includes a record id)."
          },
          "allowedValues": {
            "type": "array",
            "items": {},
            "description": "Permitted values for the field that failed an enum constraint, or the registered list when the rejection is a \"no such X\" lookup (e.g., unknown type → registered types)."
          },
          "disputeCount": {
            "type": "integer",
            "description": "Number of disputes already filed against this record (open + terminal). Surfaced on 422 when the dispute cap is hit."
          },
          "maxDisputes": {
            "type": "integer",
            "description": "Maximum disputes allowed on this record (default 1). Surfaced alongside disputeCount when the cap is hit."
          },
          "openDisputeId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "ID of the currently-open dispute (EVIDENCE_WINDOW or TIER_2_REVIEW). Null when all prior disputes have terminalized. Surfaced on 422 when the dispute cap is hit so the agent can escalate the existing one rather than try to open another."
          },
          "currentStatus": {
            "type": "string",
            "description": "Display status of the record at the moment the request was refused. Surfaced on 422 when a dispute is attempted while verification is still in progress."
          },
          "disputeableWhen": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Display statuses from which POST /v1/records/{recordId}/dispute is accepted. Poll GET /v1/records/{recordId} until status is one of these, then retry."
          },
          "allowedActors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Role/actor labels permitted for this action in the current resource state. Surfaced on 403 cross-tier rejections (e.g., parent-principal trying to act on a sub-record it is not direct-principal of)."
          },
          "parentRecordId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the parent record that rejected the delegation attempt. Surfaced on 422 when the parent state cannot accept children."
          },
          "reason": {
            "type": "string",
            "description": "Machine-readable reason code. On 409 conflicts: STATUS_NOT_DISABLED, RECORDS_REFERENCE_TYPE, CONFLICTING_VERSION, RESERVED_PUBLISHER_LABEL, VAULT_SCAN_IN_FLIGHT. On 422 authority-guard refusals: the snake_case guard identifier (has_children_leaf_only, leaf_record, no_children, children_not_terminal, mode_not_auto, mode_not_principal, record_disputed). Branch on this rather than on the prose in `detail`."
          },
          "jobId": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the background job this request is being refused in favour of. Poll GET /v1/admin/vault/scan/{jobId} for its state and result. Present on 409 VAULT_SCAN_IN_FLIGHT."
          },
          "publisher": {
            "type": "string",
            "description": "Publisher label on the conflicting schema row."
          },
          "version": {
            "type": "string",
            "description": "Manifest version string on the conflicting schema row."
          },
          "incomingDigest": {
            "type": "string",
            "description": "sha256:<hex> digest of the manifest the caller just submitted."
          },
          "existingDigest": {
            "type": "string",
            "description": "sha256:<hex> digest of the manifest already registered at this (publisher, type, version)."
          },
          "publishers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Candidate publisher labels on a 422 `/problems/ambiguous-publisher`. Emitted by /v1/schemas/{type} reads and writes (pin with `?publisher=`) and by record creation (pin with a `publisher` body field)."
          },
          "pinnedRecords": {
            "type": "integer",
            "description": "Records written against the exact registration this delete would remove."
          },
          "unattributableRecords": {
            "type": "integer",
            "description": "Records of this type carrying no registration pin, so they block a delete under any publisher label."
          },
          "peerDigest": {
            "type": "string",
            "description": "sha256:<hex> digest the federation peer claimed in `schemaRef.manifestDigest`."
          },
          "localDigest": {
            "type": "string",
            "description": "sha256:<hex> digest the receiver holds locally for the same (publisher, type, version, org) tuple."
          },
          "revisionCount": {
            "type": "integer",
            "description": "Number of revisions consumed at the moment OVERFLOW_REJECT fired."
          },
          "maxRevisions": {
            "type": "integer",
            "description": "Configured maxRevisions cap on the record."
          },
          "terminalReason": {
            "type": "string",
            "description": "Machine-readable label naming the system action that terminalized the record (e.g. OVERFLOW_REJECT, ARBITRATION_LOCK, TIME_OUT)."
          },
          "deadline": {
            "type": "string",
            "format": "date-time",
            "description": "The record deadline that had already passed when the request was refused (system TIME_OUT)."
          },
          "previousStatus": {
            "type": "string",
            "description": "Display status the record was at immediately before the terminal transition."
          },
          "constraintViolations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Constraint violations for the request"
          },
          "constraint": {
            "type": "string",
            "description": "Database constraint that was violated"
          },
          "validationErrors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Schema validation errors"
          },
          "migratedTo": {
            "type": "string",
            "description": "Suggested replacement path for a renamed endpoint. Present on 404 responses for routes retired in a migration (e.g. /v1/admin/enterprises → /v1/admin/orgs)."
          },
          "expected": {
            "type": "string",
            "description": "Expected JSON type or value, paired with `received` on validation errors."
          },
          "signInputTemplate": {
            "type": "string",
            "description": "Exact byte template the Ed25519 proof-of-possession signature must cover, with the domain prefix. Surfaced on the federation 401 for an invalid signature."
          },
          "docs": {
            "type": "string",
            "description": "Pointer to the discovery document section describing the failed scheme (e.g. \"/llms.txt (Federation Signing Scheme section)\"). Paired with signInputTemplate + hint on the federation 401."
          },
          "retryAfterSeconds": {
            "type": "integer",
            "description": "Seconds to wait before retrying this request. This is temporary — retry the same request after this delay."
          }
        },
        "additionalProperties": false
      },
      "NextStepAction": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "description": "What to do next"
          },
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST",
              "PUT",
              "PATCH",
              "DELETE"
            ],
            "description": "HTTP method"
          },
          "href": {
            "type": "string",
            "description": "Relative URL template (substitute {id} placeholders)"
          },
          "description": {
            "type": "string",
            "description": "Why this step matters"
          },
          "workflowStep": {
            "type": "integer",
            "minimum": 1,
            "description": "1-indexed position of this action in the end-to-end workflow. Only set on the primary forward action of a multi-step flow (not on sibling actions like cancel/view)."
          },
          "workflowTotal": {
            "type": "integer",
            "minimum": 1,
            "description": "Total number of user-visible steps to reach terminal state. Pairs with workflowStep."
          },
          "workflowLabel": {
            "type": "string",
            "description": "Human-readable progress label (e.g., \"Step 2 of 3: submit completion\"). Pairs with workflowStep + workflowTotal."
          },
          "afterThis": {
            "type": "string",
            "description": "What happens after this action completes. Helps agents plan ahead and avoid stopping at \"work done\" when more steps remain."
          }
        },
        "additionalProperties": false
      },
      "RecordRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "orgId": {
            "type": "string",
            "format": "uuid"
          },
          "performerAgentId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "Performer agent assigned to fulfill this record. Null when no performer is assigned (notarize-only flow or pre-proposal admin-created records)."
          },
          "principalAgentId": {
            "type": "string",
            "format": "uuid",
            "description": "Named accountable party. Always an agent."
          },
          "createdByKeyId": {
            "type": "string",
            "format": "uuid",
            "description": "API key that created this record. May be admin, agent, or platform — see audit_vault for the full chain of custody."
          },
          "selfPrincipal": {
            "type": "boolean",
            "description": "True when principalAgentId equals performerAgentId at creation — the same agent is both principal and performer. Auto-verdict is blocked in this case: the principal must explicitly render verdict."
          },
          "acceptanceStatus": {
            "type": [
              "null",
              "string"
            ],
            "description": "Proposal status: PROPOSED, ACCEPTED, REJECTED, COUNTER_PROPOSED, or BYPASSED. BYPASSED indicates an admin/platform key drove register/activate (or autoActivate) without performer acceptance — the named performer never opted in via /accept. The Signed Statement on that transition carries `acceptanceBypassed: true` + `bypassActorRole` + `bypassReason` for forensic detail."
          },
          "acceptanceRespondedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When the performer responded to the proposal"
          },
          "parentRecordId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "Parent record ID in a delegation chain"
          },
          "chainDepth": {
            "type": "integer",
            "description": "Depth in delegation chain (0 = top-level)"
          },
          "rootRecordId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "Root record in the delegation chain"
          },
          "childRecordIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "IDs of child records in the delegation chain (present on single-record fetch only)"
          },
          "latestCompletionId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "Most recent completion id for this record (present on single-record fetch only). Key a verdict to it via POST /v1/records/{id}/verdict without a separate GET /completions round-trip. Null until the first completion is submitted."
          },
          "hasChildren": {
            "type": "boolean",
            "description": "True iff this record has at least one delegated child. Maintained by the agledger_records_has_children trigger and reads as live truth (do NOT compute from `childRecordIds.length` — that field is only present on single-record fetches)."
          },
          "parentPrincipalOrgMatchesPerformer": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Delegation-shell indicator: true when parent record's principal org equals this child's performer org. NULL on root records and on children without an assigned performer. Informational signal — never blocks."
          },
          "commissionPct": {
            "type": [
              "null",
              "number"
            ],
            "description": "Commission percentage for delegation"
          },
          "commissionAmount": {
            "type": [
              "null",
              "number"
            ],
            "description": "Computed commission amount"
          },
          "operatingMode": {
            "type": "string",
            "enum": [
              "cleartext",
              "encrypted"
            ],
            "description": "Operating mode: cleartext (server-side gate evaluation) or encrypted (server cannot read payloads)"
          },
          "gateMode": {
            "type": "string",
            "enum": [
              "auto",
              "principal"
            ],
            "description": "Gate mode: auto (rules engine renders the verdict and auto-settles) or principal (engine runs an advisory pass when rules exist, then the principal renders accept/reject)"
          },
          "constraintInheritance": {
            "type": "string",
            "enum": [
              "none",
              "advisory",
              "enforced"
            ],
            "description": "Constraint inheritance mode for delegation chains: none (default, no inheritance), advisory (audit warning if child exceeds parent), enforced (block child creation if exceeds parent)"
          },
          "riskClassification": {
            "type": "string",
            "enum": [
              "unacceptable",
              "high",
              "limited",
              "minimal",
              "unclassified"
            ],
            "description": "EU AI Act risk classification"
          },
          "euAiActDomain": {
            "type": [
              "null",
              "string"
            ],
            "description": "EU AI Act high-risk domain (only when riskClassification=high)"
          },
          "humanOversight": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "description": "Human oversight designation per EU AI Act Art. 14"
          },
          "metadata": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "description": "Arbitrary key-value data for customer use (project refs, tags, integration context)"
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 100,
            "description": "Free-form taxonomy of what kind of artifact this Record represents — denormalized from the Type at create. Immutable. Customer-defined string (e.g. \"decision\", \"delivery-attempt\", \"telemetry-tick\"). No engine semantics."
          },
          "outcome": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "success",
              "failure",
              "denied",
              "partial",
              null
            ],
            "description": "Optional free-form outcome supplied at create. Stored on metadata.outcome and surfaced here regardless of Type. NOT the gate verdict — that is `verdict` (local gate) or `settlementSignal.outcome` (federation-received records)."
          },
          "correlationId": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional grouping ID supplied at create. Multiple Records sharing a correlationId can be queried with GET /v1/records/search?correlationId=…"
          },
          "requestedBy": {
            "type": [
              "null",
              "string"
            ],
            "description": "Free-form identifier of the human or upstream system that asked for the work (e.g. \"user:alice@example.com\", \"system:cron-2026-04-25\")."
          },
          "share": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "V1 sharing override. Echoes the value supplied at create — `true`/`false` is an explicit per-record decision; `null` means inherit from the contract type's `defaultShare` then the global `AGLEDGER_DEFAULT_SHARE` (default `true`). The effective value is computed at outbound time, not stored."
          },
          "imported": {
            "type": "boolean",
            "description": "True iff the record was inserted via POST /v1/admin/records/import (backfill from a legacy system). False for records created via the live API. Lets dashboards filter \"live activity\" vs \"archival data\" without walking the audit chain. The chain payload also carries this flag on the BACKFILL_IMPORT entry for cryptographic non-repudiation."
          },
          "source": {
            "type": [
              "null",
              "string"
            ],
            "description": "Free-form label provided at backfill time identifying the origin system (e.g. \"legacy-erp\", \"salesforce-export-2024\"). Null on live records. Same value also appears on the BACKFILL_IMPORT chain entry."
          },
          "federationStatus": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "pending",
              "delivered",
              "partial",
              "failed",
              "inbound",
              null
            ],
            "description": "Federation rollup for this record. Sender side: `pending` = enqueued but not yet delivered, `delivered` = every (peer, kind) row reached 2xx, `partial` = some delivered, some pending or failed, `failed` = every row terminally failed (DLQ). Receiver side: `inbound` = this Server RECEIVED the record's federation traffic from a peer — read `settlementSignal` (source `inbound`, `receivedFrom` names the peer) for the originator's verdict and reason; there is no sender-side delivery rollup to report. `null` when the record never federated (no active peers, share=false, or no rows yet). For per-peer breakdown see `sharedToPeers` and `settlementSignal.{deliveredToPeers,pendingToPeers,failedToPeers}`."
          },
          "sharedToPeers": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Distinct peer hub_ids the record was dispatched to. Empty when the record did not federate (share=false or no active peers)."
          },
          "coSignRequired": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "V1 Additive E — schema-level bilateral co-sign opt-in for this contract type, so an LLM agent can see the contract type's posture before any signal fires. **Populated on single-record fetch (GET /v1/records/{id}) only**; list/search/batch responses omit it (left `null`) — on those, read `coSignStatus` (which IS hydrated: `not_required` vs `pending`/`succeeded`/`failed` distinguishes co-sign types) or GET /v1/schemas/{type}. `null` for notarize-only types or when the schema is unresolved (federated record with unknown schemaRef)."
          },
          "coSignStatus": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "not_required",
              "pending",
              "succeeded",
              "failed",
              null
            ],
            "description": "Bilateral co-sign rollup. `not_required` for single-sig contracts; `pending` while a co-sign request is in flight; `succeeded` once a counter-signature was returned; `failed` on terminal co-sign failure (peer mismatch, exhausted retries — the parent signal row also goes to `failed`). `null` when no signal has fired yet."
          },
          "counterSignature": {
            "type": [
              "null",
              "string"
            ],
            "description": "Hex Ed25519 counter-signature attached to the most recent successful co-sign. Verifiable offline against the peer's published vault keys (`GET /.well-known/agledger-vault-keys.json` on the peer Server). Null when co-sign is not configured or has not yet succeeded."
          },
          "settlementSignal": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "recommendation",
              "outcome",
              "deliveredToPeers",
              "pendingToPeers",
              "failedToPeers",
              "idempotencyKey"
            ],
            "properties": {
              "recommendation": {
                "type": "string",
                "enum": [
                  "SETTLE",
                  "HOLD",
                  "RELEASE"
                ]
              },
              "outcome": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "accept",
                  "reject",
                  null
                ],
                "description": "Verdict the recommendation binds to — `accept` (recommendation typically SETTLE) or `reject` (HOLD). Mirrors the value engines and federation projections write to the wire; pre-diff this enum read [PASS, FAIL] which never matched the runtime values that ship today."
              },
              "reasonCode": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Machine-readable label naming the cause behind this signal so a payment platform can branch on `recommendation: HOLD` (gate failure vs timeout vs cancel vs dispute-overturn) AND on `recommendation: SETTLE` (auto-mode engine pass vs principal-mode human accept). Engine-emitted values (verdict path): `AUTO_SETTLE` / `AUTO_FAIL` (auto-mode), `AUTO_SETTLE_WITHIN_TOLERANCE` (auto-mode SETTLE where a numeric/datetime rule cleared only via its non-zero `tolerance` band, not the base criteria threshold — the band-widened clear is on-chain in `verdictChecks`; this label surfaces it in the terminal so an auditor/platform can tell it from a clean within-threshold settle), `PRINCIPAL_ACCEPT` / `PRINCIPAL_REJECT` (principal-mode), `DISPUTE_OVERTURNED` (RELEASE from a dispute overturn). Read-path local-synthesis additionally mirrors the record's `terminalReason` for system-driven terminals (`TIMED_OUT`, `REMEDIATED`, `CANCEL_PRE_WORK`, `CANCEL_IN_PROGRESS`, `OVERFLOW_REJECT`, `ARBITRATION_LOCK`) and adds `VERDICT_REJECTED` as a legacy catch-all for the recoverable-FAILED display state. Null when the cause isn't classifiable (e.g., bare REJECTED without a known prefix) or on projections predating the fix."
              },
              "failingRuleIds": {
                "type": [
                  "null",
                  "array"
                ],
                "items": {
                  "type": "string"
                },
                "description": "RuleIds that failed when the engine ran a gate evaluation that produced this signal. Populated only when rules ran AND at least one failed (HOLD recommendation, gated record). Null for non-rule failures (TIMED_OUT, cancel, dispute-overturn, AUTO_SETTLE) and on projections predating the fix. The structured per-rule check details (expected/actual/tolerance) stay on the record's `verdictChecks` field — this is just the discriminator for routing."
              },
              "reason": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Free-text human-readable hint. Mirrors `record.lastVerdictReason` (engine summary for auto-gate) or the principal's verdict notes (principal-mode). Optional supplement to `reasonCode` + `failingRuleIds`. Null on projections predating the fix."
              },
              "deliveredToPeers": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "pendingToPeers": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "failedToPeers": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "idempotencyKey": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "uuid"
              },
              "coSignStatus": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "not_required",
                  "pending",
                  "succeeded",
                  "failed",
                  null
                ],
                "description": "Bilateral co-sign rollup surfaced ON the signal a payment platform reads — not only at the record top level. `succeeded` (with `counterSignature` set) is the visible proof this SETTLE/HOLD was dual-signed by the receiving peer; `not_required` for single-sig contract types; `pending` while a co-sign request is in flight; `failed` on terminal co-sign failure. Null when no signal row carries co-sign metadata yet. Present only on `source: \"outbound\"` (the firing Server holds the counter-signature); `inbound`/`local` omit it."
              },
              "counterSignature": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Hex Ed25519 counter-signature from the most recent successful co-sign, attached to this Settlement Signal. Verifiable offline against the peer's published vault keys (`GET /.well-known/agledger-vault-keys.json` on the peer Server). Mirrors the record top-level `counterSignature` so a consumer reading `settlementSignal` sees the bilateral proof inline. Null when co-sign is not configured or has not yet succeeded; present only on `source: \"outbound\"`."
              },
              "validUntil": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "description": "Expiry of this Settlement Signal — a payment integration should reject a HOLD/RELEASE whose `validUntil` is in the past as stale. Present on both outbound and inbound; null on projections predating the fix."
              },
              "outcomeHash": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Hash binding this settle/hold decision to the underlying verdict outcome, for audit. The same value rides the `federation.settlement.signal` event and the bilateral co-sign wire. Null on projections predating the fix."
              },
              "source": {
                "type": "string",
                "enum": [
                  "outbound",
                  "inbound",
                  "local"
                ],
                "description": "`outbound` — this Server emitted the signal; per-peer arrays describe fanout (may be empty when the fanout has not yet been attempted). `inbound` — this Server received the signal from a federation peer (per-peer arrays are empty; see `receivedFrom`). `local` — verdict-derived synthesis when the federation projection has not (yet) landed: either the race window right after submitVerdict (publisher fires post-commit, GET lands before the projection INSERT) or a non-federated install (no peers configured). `local` carries empty pending/delivered/failed arrays and null idempotencyKey/validUntil/outcomeHash — consumers can wait + re-read for the federation projection to overtake it, or treat it as the final signal on standalone installs. Omitted on legacy outbound projections."
              },
              "receivedFrom": {
                "type": [
                  "null",
                  "object"
                ],
                "description": "Present only when `source: \"inbound\"` — names the originating peer.",
                "required": [
                  "peerHubId",
                  "receivedAt"
                ],
                "properties": {
                  "peerHubId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "receivedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "additionalProperties": false
              }
            },
            "description": "Most recent Settlement Signal on this record. `null` when no signal has fired. Two shapes share this field, discriminated by `source`: `outbound` (this Server emitted the signal) carries per-peer fanout arrays; `inbound` (this Server received the signal from a federation peer) carries `receivedFrom` and empty per-peer arrays. Customers at a receiver Server should look here — not `/v1/events` — to confirm a record was settled."
          },
          "type": {
            "type": "string"
          },
          "contractVersion": {
            "type": "string"
          },
          "publisher": {
            "type": [
              "null",
              "string"
            ],
            "description": "Publisher label of the registration this record binds to. Together with `type` and `contractVersion` it names exactly which schema the record was judged against, which `type` alone cannot when two publishers offer the same `record_type` in this org. Records created through this API carry it whether or not you pinned it on create, so a single-publisher org gets its one label (usually `local`) rather than null. Records backfilled through `POST /v1/admin/records/import` carry it too: the import validates each item against a registration in this org and pins the record to it, so an imported record names the schema it was judged against, and an ambiguous bare `type` is refused there with the same 422 as on create. `null` means the record has no such binding, which is the case for records the engine never validated against a local registration: federation-received records, where this Server did not run the gate and the originator did, against its own registration. Treat `null` as \"ask the originator\", not as \"the schema is missing locally\"."
          },
          "schemaUrl": {
            "type": [
              "null",
              "string"
            ],
            "description": "URL to the type schema for discovering expected criteria and evidence structure. Carries `?publisher=` whenever the publisher is known, so the link resolves even for a type two publishers offer (e.g. /v1/schemas/notarize-generic-v1?publisher=local). `null` on a federation-received record whose type this Server does not hold: the record was judged against the originator's registration, and no URL here would resolve to it. A link into this Server's own namespace would either 404 on a type that does exist elsewhere, or answer 200 with this Server's unrelated schema of the same name, so the field is null instead and the record's `nextSteps` carry the originating peer's manifest URL and the `/v1/schemas/import` call that mirrors it. Once mirrored (same publisher label, same manifest, therefore the same `manifestDigest`) this becomes a scoped URL that resolves."
          },
          "platform": {
            "type": "string"
          },
          "platformRef": {
            "type": [
              "null",
              "string"
            ]
          },
          "projectRef": {
            "type": [
              "null",
              "string"
            ],
            "description": "External project reference for grouping records"
          },
          "externalTaskId": {
            "type": [
              "null",
              "string"
            ],
            "description": "External task system ID for linking records to CI/CD pipelines, RPA tasks, or workflow engines"
          },
          "enforcementOverrides": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "description": "Per-record enforcement overrides (Phase 3). Can only relax org settings."
          },
          "dependsOn": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Informational dependency references to other record IDs (no activation gating)"
          },
          "status": {
            "type": "string",
            "enum": [
              "CREATED",
              "PROPOSED",
              "ACTIVE",
              "PROCESSING",
              "REVISION_REQUESTED",
              "DISPUTED",
              "FULFILLED",
              "FAILED",
              "REMEDIATED",
              "EXPIRED",
              "PENDING_ARBITRATION",
              "CANCELLED",
              "REJECTED",
              "RECORDED"
            ],
            "description": "Customer-facing display lifecycle state — 14 business-meaningful values that map from a wider set of internal state-machine states. The same display token can correspond to multiple internal states (e.g. CREATED covers internal DRAFT and REGISTERED; PROCESSING covers COMPLETION_ACCEPTED and PENDING_VERDICT; CANCELLED covers CANCELLED_PRE_WORK and CANCELLED_IN_PROGRESS; EXPIRED is the alias for internal TIMED_OUT). Match against THIS enum, not internal-state names. Display tokens: CREATED (not yet active), PROPOSED (agent proposal pending), ACTIVE (awaiting work — covers COMPLETION_INVALID retries), PROCESSING (completion/gate evaluation in progress), REVISION_REQUESTED, DISPUTED (tribunal review), FULFILLED, FAILED, REMEDIATED, EXPIRED (deadline missed — internal TIMED_OUT), PENDING_ARBITRATION (tribunal exhausted), CANCELLED, REJECTED, RECORDED (terminal: notarize-only Type — Records that did not declare a completion phase land here at create)."
          },
          "criteria": {
            "type": "object",
            "additionalProperties": true,
            "description": "Acceptance criteria matching the type JSON Schema"
          },
          "tolerance": {
            "type": "object",
            "additionalProperties": true,
            "description": "Per-record tolerance values. Most keys are gate-evaluation bands (e.g. quantity deviation %). graceSeconds is the exception: a deadline grace window (effective expiry = deadline + graceSeconds)."
          },
          "deadline": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "ISO 8601 deadline after which the record auto-expires"
          },
          "verdict": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "accept",
              "reject",
              null
            ],
            "description": "Phase 2 gate verdict (null until the gate evaluation completes). Check verdictChecks for per-rule details. Stays null on federation-received records (federationStatus `inbound`) — this Server never ran the gate; the originator's verdict surfaces on `settlementSignal.outcome` with `settlementSignal.reason`."
          },
          "verdictChecks": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "description": "Detailed per-rule gate-evaluation results with tolerance bands (e.g., quantity_match, price_ceiling). Each rule includes pass/fail, expected vs actual values, and tolerance info."
          },
          "lastTransitionReason": {
            "type": [
              "null",
              "string"
            ],
            "description": "Reason provided for the most recent state transition"
          },
          "terminalReason": {
            "type": [
              "null",
              "string"
            ],
            "description": "Machine-readable label naming the system action that terminalized this record (OVERFLOW_REJECT, TIMED_OUT, ARBITRATION_LOCK, AUTO_SETTLE, AUTO_SETTLE_WITHIN_TOLERANCE, PRINCIPAL_ACCEPT, CANCEL_PRE_WORK, CANCEL_IN_PROGRESS, REMEDIATED, RECORDED). A FULFILLED record gated in principal mode reads `PRINCIPAL_ACCEPT` (a human/principal rendered the verdict), distinct from auto-mode `AUTO_SETTLE` — so a reconciliation system can tell principal-approved from auto-approved terminals. An auto-mode FULFILLED whose gate cleared only because a non-zero `tolerance` band widened a numeric/datetime rule past the base criteria threshold reads `AUTO_SETTLE_WITHIN_TOLERANCE` instead of `AUTO_SETTLE`, so a tolerance-widened clear is distinguishable from a clean within-threshold one (the tolerance value itself is on-chain in `verdictChecks` / the audit export). Both reject-side terminals — auto-mode `AUTO_FAIL` and principal-mode `PRINCIPAL_REJECT` — land in VERDICT_REJECTED, a non-terminal/recoverable state (overturn → FULFILLED, remediate, revise, and dispute all remain open), so `terminalReason` is null there by design; read `settlementSignal.reasonCode` (`AUTO_FAIL` in auto mode, `PRINCIPAL_REJECT` in principal mode) for the reject cause. This is deliberately asymmetric with the accept side: a passing gate lands at the true terminal FULFILLED and carries its cause here, while a failing gate stays recoverable and carries its cause on the signal. Null when the record is non-terminal or when an unknown writer landed it in a terminal state. Mirrors the same value the 422 envelope on OVERFLOW_REJECT carries in `context.terminalReason`."
          },
          "lastTransitionBy": {
            "type": [
              "null",
              "string"
            ],
            "description": "Identifier of who triggered the most recent state transition"
          },
          "lastVerdictReason": {
            "type": [
              "null",
              "string"
            ],
            "description": "Reason from the most recent verdict or revision request. Unlike lastTransitionReason, this persists across subsequent state changes so performers can always see why their completion was rejected. Stays null on federation-received records (federationStatus `inbound`) — the originator's verdict reason surfaces on `settlementSignal.reason` / `settlementSignal.reasonCode`."
          },
          "lastVerdictAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When the most recent verdict or revision request was made. Stays null on federation-received records — see `settlementSignal.receivedFrom.receivedAt` for when the originator's signal arrived."
          },
          "submissionCount": {
            "type": "integer",
            "description": "Number of completions submitted (incremented on each accepted completion)"
          },
          "maxSubmissions": {
            "type": [
              "null",
              "integer"
            ],
            "description": "Maximum allowed completion submissions (null = unlimited)"
          },
          "revisionCount": {
            "type": "integer",
            "description": "Number of revisions consumed by RESUBMIT_COMPLETION calls. Capped by `maxRevisions`: when this equals it, the next resubmit terminates the record at REJECTED via OVERFLOW_REJECT. Read this before requesting another revision."
          },
          "maxRevisions": {
            "type": "integer",
            "description": "Maximum revisions allowed before OVERFLOW_REJECT (default 3). Compare with revisionCount to know remaining capacity."
          },
          "disputeCount": {
            "type": "integer",
            "description": "Number of disputes opened against this record. Capped by `maxDisputes`: when this equals it, no further DISPUTE actions are accepted. Default cap is 1 in v1."
          },
          "maxDisputes": {
            "type": "integer",
            "description": "Maximum disputes allowed (default 1). Compare with disputeCount to know whether opening another DISPUTE will be accepted."
          },
          "pastDeadline": {
            "type": "boolean",
            "description": "True iff a deadline is set AND has passed. When true, the engine's in-tx submit guard rejects any /completions call (terminalizes at TIMED_OUT). Read this before submitting — saves a round-trip on past-deadline records and lets the agent fall through to /cancel cleanly."
          },
          "awaitingActor": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "principal",
              "performer",
              "system",
              "arbitration",
              null
            ],
            "description": "Who the record is waiting on for forward progress. Disambiguates display `PROCESSING` (engine vs principal) and surfaces the wait state without forcing a `gate-status` round-trip + 403-probe. `principal` = awaiting a principal-side action: accept/reject verdict (PENDING_VERDICT / DISPUTED), or a pre-work move only the principal can make — display `CREATED` awaiting propose/activate, including the wait after a performer accepts. `performer` = assigned to a performer who hasn't acted yet (PROPOSED, ACTIVE-with-performer, REVISION_REQUESTED). `system` = engine mid-evaluation (COMPLETION_ACCEPTED — gate worker about to run). `arbitration` = tier-3 tribunal review (PENDING_ARBITRATION). `null` = no actor is blocking (terminal states; ACTIVE with no performer)."
          },
          "version": {
            "type": "integer",
            "description": "Optimistic concurrency version number"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "activatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "fulfilledAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "expiredAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When the expiry worker transitioned this record to EXPIRED. Null until the deadline passes and the sweep fires."
          },
          "disputeId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "ID of the most recent dispute against this record (open or resolved). Null if no dispute has ever been filed. Present only on single-record fetch (`GET /v1/records/{id}`); list endpoints omit it. Use `GET /v1/records/{id}/dispute` for the full dispute object + evidence history."
          },
          "disputeStatus": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "EVIDENCE_WINDOW",
              "TIER_2_REVIEW",
              "ESCALATED",
              "TIER_3_ARBITRATION",
              "RESOLVED",
              "WITHDRAWN",
              null
            ],
            "description": "Status of the most recent dispute. Null if no dispute exists. Now hydrated on list endpoints too (previously single-record-only — N+1 fetch from a compliance dashboard). Matches the externally-observable subset of dispute statuses (engine never commits transient `OPENED`/`TIER_1_REVIEW`)."
          },
          "hasDispute": {
            "type": "boolean",
            "description": "Derived from `disputeCount > 0` so dashboards can render a quick \"disputed yes/no\" badge without inspecting the count. Populated on both per-record and list responses."
          },
          "completionHint": {
            "type": [
              "null",
              "object"
            ],
            "properties": {
              "requiredFields": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Required field names for completion evidence submission"
              },
              "optionalFields": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Optional field names accepted by the completion schema (non-required properties)"
              },
              "schemaUrl": {
                "type": "string",
                "description": "URL to the full completion schema"
              }
            },
            "additionalProperties": false,
            "description": "Lightweight hint showing required and optional completion evidence fields. Use schemaUrl for the full JSON Schema with types and descriptions. Populated on create-record responses so the agent does not have to round-trip /v1/schemas/{type} before submitting a completion."
          },
          "nextActions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "register",
                "propose",
                "activate",
                "cancel"
              ]
            },
            "description": "Exact action names that `POST /v1/records/{id}/transition` accepts right now. Empty when no transition applies (e.g., terminal states or awaiting-completion states). Actions on other endpoints (submit completion, counter-propose, reject, request-revision, verdict) are surfaced via `nextSteps` with method+path."
          },
          "validTransitions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "CREATED",
                "PROPOSED",
                "ACTIVE",
                "PROCESSING",
                "REVISION_REQUESTED",
                "DISPUTED",
                "FULFILLED",
                "FAILED",
                "REMEDIATED",
                "EXPIRED",
                "PENDING_ARBITRATION",
                "CANCELLED",
                "REJECTED",
                "RECORDED"
              ]
            },
            "description": "Display states (matching the same enum as `status` above) the record can transition to next. These are CUSTOMER-FACING display tokens — internal state-machine names (DRAFT/REGISTERED/COMPLETION_ACCEPTED/PENDING_VERDICT/TIMED_OUT/etc.) are mapped to display tokens before emission. Match against this enum, not internal-state names. For action verbs accepted by `POST /v1/records/{id}/transition`, read `nextActions`; for full hyperlinks (including non-/transition endpoints like /completions, /dispute, /outcome), read `nextSteps`."
          },
          "advisoryWarnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rule": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "details": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "additionalProperties": false
            },
            "description": "Advisory enforcement warnings (only present when org advisory mode is enabled and a constraint was exceeded but allowed)"
          },
          "references": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            },
            "description": "External entity references attached to this record (present on single-record fetch only)"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NextStepAction"
            },
            "description": "Suggested next API calls based on current record state. Guides AI agents through the record lifecycle without requiring prior knowledge of the state machine."
          },
          "recordRead": {
            "type": "object",
            "properties": {
              "leafIndex": {
                "type": "integer",
                "minimum": 0,
                "description": "Per-org monotonic leaf index in the org_admin_reads chain."
              },
              "leafHash": {
                "type": "string",
                "minLength": 64,
                "maxLength": 64,
                "description": "Hex sha256 of the canonical chain entry — the leaf hash a Merkle inclusion proof verifies against the checkpoint root."
              },
              "signedCheckpointRef": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "uuid",
                "description": "Most recent signed checkpoint that includes this leaf, or null until the next 6h sweep covers it."
              }
            },
            "required": [
              "leafIndex",
              "leafHash",
              "signedCheckpointRef"
            ],
            "additionalProperties": false,
            "description": "SCITT-style inclusion-proof completion. Present only on org-admin cross-party reads — proves the read was logged."
          },
          "signedStatement": {
            "type": "object",
            "properties": {
              "chainPosition": {
                "type": "integer",
                "minimum": 1,
                "description": "Per-record monotonic chain position of the head Signed Statement (1-indexed)."
              },
              "leafHash": {
                "type": "string",
                "minLength": 64,
                "maxLength": 64,
                "description": "Hex sha256 over the canonical COSE_Sign1 envelope bytes."
              },
              "previousHash": {
                "type": [
                  "null",
                  "string"
                ],
                "minLength": 64,
                "maxLength": 64,
                "description": "leafHash of the prior entry (null only on chain_position=1)."
              },
              "signingKeyId": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "ID of the vault signing key — resolves to a public key at GET /v1/verification-keys."
              },
              "signedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "description": "Signed instant of the head Signed Statement — the CWT `iat` claim (second precision) sealed in the COSE_Sign1 protected header. THE authoritative timestamp for time-anchored contracts (wait windows, notice clocks); the record's `createdAt` is a millisecond-precision DB clock that only approximates it. Null if the envelope fails to decode."
              },
              "signedCheckpointRef": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "uuid",
                "description": "Most recent signed checkpoint covering this chain position, or null until the next 6h sweep."
              },
              "url": {
                "type": "string",
                "description": "Path to the canonical COSE_Sign1 envelope for this record's head Signed Statement (application/cose)."
              }
            },
            "required": [
              "chainPosition",
              "leafHash",
              "previousHash",
              "signingKeyId",
              "signedAt",
              "signedCheckpointRef",
              "url"
            ],
            "additionalProperties": false,
            "description": "Inline tamper-evident pointer to the head Signed Statement (COSE_Sign1) in this record's audit chain. Lets a notarize-only caller verify the record was chained without a follow-up call to /v1/records/{id}/audit-export. The `url` resolves to the canonical COSE_Sign1 envelope."
          },
          "integrity": {
            "type": "object",
            "properties": {
              "verified": {
                "type": "boolean",
                "description": "True iff (a) the record's full audit chain re-verifies — per-entry hash re-derive from the COSE_Sign1 envelope, hash linkage, signatures, checkpoint cross-check — AND (b) the record fields in THIS response match what the chain asserts (type, orgId, principalAgentId, parentRecordId, criteria). False means this response body may not match the signed evidence — treat GET /v1/records/{id}/audit-export as the authoritative source."
              },
              "integrityLevel": {
                "type": "string",
                "enum": [
                  "hash_chain_only",
                  "hash_chain_partial_signatures",
                  "hash_chain_and_signatures",
                  "invalid"
                ],
                "description": "Strength of the chain verification: whether every chain entry was independently signed, or only hash-linked."
              },
              "reason": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Failure class when verified=false. `record_projection_drift` = the record row served here diverges from the verified chain (out-of-band database edit of the records table — see driftFields). Chain-level classes: chain_broken_at, payload_drift, checkpoint_hash_mismatch, audit_vault_row_missing_for_checkpoint, oidc_actor_drift, cert_*, signature_invalid, signing_key_unknown, unsupported_algorithm. Null when verified."
              },
              "entries": {
                "type": "integer",
                "minimum": 0,
                "description": "Number of audit-chain entries verified."
              },
              "projectionChecked": {
                "type": "boolean",
                "description": "True when the row-vs-chain comparison ran. False for records whose chain has no creation assertion (imported/backfilled, federation-projected) — for those, only the chain itself was verified, not this response body against it."
              },
              "driftFields": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Record fields whose served value diverges from the chain-asserted value. Empty when clean. Non-empty is evidence of direct database modification of the records row."
              }
            },
            "required": [
              "verified",
              "integrityLevel",
              "reason",
              "entries",
              "projectionChecked",
              "driftFields"
            ],
            "additionalProperties": false,
            "description": "On-read chain verification result. Present only when requested via `?integrity=true` on GET /v1/records/{id} (full-chain cryptographic verify per call — expensive, so opt-in). The record fields in this response are a denormalized projection of the signed audit chain; the chain in audit_vault is the evidence. Absent ≠ verified."
          }
        },
        "additionalProperties": false
      },
      "Completion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "recordId": {
            "type": "string",
            "format": "uuid"
          },
          "agentId": {
            "type": "string",
            "format": "uuid"
          },
          "evidence": {
            "type": "object",
            "additionalProperties": true,
            "description": "Task attestation evidence payload"
          },
          "evidenceHash": {
            "type": "string",
            "description": "SHA-256 hash of the canonicalized evidence payload"
          },
          "structuralValidation": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "INVALID",
              "WARNING"
            ],
            "description": "Phase 1 structural validation result. ACCEPTED = evidence conforms to schema. WARNING = evidence has issues but accepted (advisory mode). INVALID = schema mismatch (rejected)."
          },
          "validationErrors": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "JSON Schema validation errors (present when structuralValidation is INVALID)"
          },
          "warnings": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "object",
              "properties": {
                "keyword": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "instancePath": {
                  "type": "string"
                },
                "params": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "additionalProperties": true
            },
            "description": "Schema validation warnings (present when structuralValidation is WARNING — advisory mode). These are the errors that would have caused rejection under enforced mode."
          },
          "idempotencyKey": {
            "type": [
              "null",
              "string"
            ],
            "description": "Client-provided idempotency key for deduplication"
          },
          "recordStatus": {
            "type": "string",
            "description": "Current record status after this completion was processed"
          },
          "verdict": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "PASS",
              "FAIL",
              null
            ],
            "description": "Phase 2 gate evaluation outcome when the gate ran inline (auto mode + non-encrypted). Null when the gate was skipped (encrypted records, principal-mode) or deferred to the worker. Lets the caller learn the verdict in one round-trip without a follow-up GET on the record."
          },
          "lastVerdictReason": {
            "type": [
              "null",
              "string"
            ],
            "description": "Human-readable verdict text — same string surfaced on GET /v1/records/{id}.lastVerdictReason. Populated whenever verdict is populated."
          },
          "settlementSignal": {
            "type": [
              "null",
              "object"
            ],
            "properties": {
              "recommendation": {
                "type": "string",
                "enum": [
                  "SETTLE",
                  "HOLD",
                  "RELEASE"
                ],
                "description": "The gate decision in GET /v1/records vocabulary: SETTLE (record settled FULFILLED), HOLD (held — e.g. failed a rule), RELEASE (dispute overturn)."
              },
              "outcome": {
                "type": "string",
                "enum": [
                  "accept",
                  "reject"
                ],
                "description": "Engine verdict that drove the recommendation."
              },
              "reasonCode": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "Discriminator code (same as the settlement webhook), e.g. AUTO_SETTLE — or AUTO_SETTLE_WITHIN_TOLERANCE when the gate cleared only via a non-zero tolerance band rather than the base criteria threshold."
              }
            },
            "additionalProperties": false,
            "description": "The auto-gate's settlement decision, surfaced inline so the caller learns settle-vs-hold-vs-reject at completion time without a follow-up GET. `structuralValidation:\"ACCEPTED\"` means only the body parsed — THIS field carries the gate's decision. Null when the gate did not render inline (encrypted records, principal-mode held at PENDING_VERDICT, or inline run skipped) — read `recordStatus` and GET /v1/records/{id} in that case."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NextStepAction"
            },
            "description": "Suggested next API calls after completion submission (e.g., check gate status)"
          }
        },
        "additionalProperties": false
      },
      "WebhookSubscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "HTTPS endpoint that receives webhook deliveries"
          },
          "eventTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Event type filter. `[\"*\"]` means all events are delivered (canonical wildcard sentinel — equivalent to omitting the field on create). Any other array restricts to the listed types only."
          },
          "recordTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Record-type filter for record-scoped events. `[\"*\"]` means all record types (wildcard sentinel). Any other array means record events are delivered ONLY for the listed types (fail-closed)."
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the subscription is active (auto-disabled on 410 response)"
          },
          "isPaused": {
            "type": "boolean",
            "description": "Whether deliveries are temporarily paused (subscription remains active)"
          },
          "format": {
            "type": "string",
            "enum": [
              "standard",
              "cloudevents"
            ],
            "description": "Payload format: standard (default) or CloudEvents 1.0 envelope"
          },
          "signingAlg": {
            "type": "string",
            "enum": [
              "hmac",
              "ed25519",
              "ecdsa-p256-sha256"
            ],
            "description": "Delivery signing scheme. `hmac` (shared secret, default), or an RFC 9421 registered name matching the active vault key's algorithm (`ed25519` by default; `ecdsa-p256-sha256` on a Server opted into ES256): RFC 9421 HTTP Message Signatures signed with the Server vault key, verifiable against /v1/verification-keys with no shared secret (non-repudiation)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "secret": {
            "type": "string",
            "description": "HMAC-SHA256 signing secret (returned ONCE on creation/rotation of an `hmac` subscription -- store it securely). Absent for asymmetric (`ed25519`/`ecdsa-p256-sha256`) subscriptions, which sign with the vault key."
          },
          "secretGraceActive": {
            "type": "boolean",
            "description": "True when a previous secret is still valid within the grace period after rotation"
          },
          "secretGraceExpiresAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When the rotation grace period expires (previous secret becomes invalid)"
          },
          "circuitState": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "half_open"
            ],
            "description": "Circuit breaker state: closed (healthy), open (failing, deliveries skipped), half_open (probing with one delivery)"
          },
          "consecutiveFailures": {
            "type": "integer",
            "description": "Number of consecutive delivery failures since last success"
          },
          "lastSuccessfulAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "Timestamp of last successful delivery"
          },
          "lastFailureAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "Timestamp of last failed delivery — pair with consecutiveFailures and circuitState for \"how long has this endpoint been down\" dashboards"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NextStepAction"
            },
            "description": "Suggested next API calls (present on creation and rotation responses)"
          }
        },
        "additionalProperties": false
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "description": "Event type that triggered this delivery"
          },
          "status": {
            "type": "string",
            "description": "Delivery status: PENDING, DELIVERED, FAILED, DEAD_LETTER"
          },
          "attemptNumber": {
            "type": "integer",
            "description": "Current retry attempt (1-based)"
          },
          "responseStatus": {
            "type": [
              "null",
              "integer"
            ],
            "description": "HTTP status code from the consumer"
          },
          "responseBody": {
            "type": [
              "null",
              "string"
            ],
            "description": "Response body from the consumer (truncated)"
          },
          "signature": {
            "type": [
              "null",
              "string"
            ],
            "description": "Signature sent with the delivery — the `X-AGLedger-Signature` header value for hmac subs, or the RFC 9421 `Signature` header value for ed25519 subs"
          },
          "requestBody": {
            "type": [
              "null",
              "string"
            ],
            "description": "Raw JSON body sent to the endpoint — the exact bytes covered by the signature (HMAC input for hmac, Content-Digest for ed25519)"
          },
          "nextRetryAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "Scheduled time for next retry attempt"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "deliveredAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "Timestamp when delivery was confirmed"
          }
        },
        "additionalProperties": false
      },
      "DisputeResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "recordId": {
            "type": "string",
            "format": "uuid"
          },
          "initiatedByRole": {
            "type": "string",
            "enum": [
              "principal",
              "performer",
              "org-admin",
              "platform"
            ],
            "description": "Structural role of the dispute initiator relative to the record. `principal` and `performer` are the two parties to the disputed record; `org-admin` is a org-admin key acting on either side; `platform` is reserved for cross-org intervention."
          },
          "initiatedById": {
            "type": "string",
            "format": "uuid",
            "description": "For agent keys (`principal`/`performer`), this is the agent UUID. For org-admin keys, this is the org UUID."
          },
          "grounds": {
            "type": "string",
            "description": "Dispute grounds category"
          },
          "context": {
            "type": [
              "null",
              "string"
            ],
            "description": "Free-text context explaining the dispute"
          },
          "status": {
            "type": "string",
            "enum": [
              "EVIDENCE_WINDOW",
              "TIER_2_REVIEW",
              "ESCALATED",
              "TIER_3_ARBITRATION",
              "RESOLVED",
              "WITHDRAWN"
            ],
            "description": "Dispute lifecycle state. Externally-observable values only — the engine writes transient `OPENED`/`TIER_1_REVIEW` inside the same transaction that opens the dispute and never commits a row at those states. Match against this enum."
          },
          "currentTier": {
            "type": "integer",
            "description": "Current dispute tier (1 = auto, 2 = manual review, 3 = binding arbitration)"
          },
          "outcome": {
            "type": [
              "null",
              "string"
            ],
            "description": "Resolution outcome: UPHELD, OVERTURNED, or SPLIT"
          },
          "resolutionRationale": {
            "type": [
              "null",
              "string"
            ],
            "description": "Explanation of the resolution decision"
          },
          "feeChargedTo": {
            "type": [
              "null",
              "string"
            ],
            "description": "Party charged the arbitration fee. **Engine does NOT compute fees** — AGLedger is the record-keeper, not the arbiter. Stays `null` until an external tribunal/admin process records the verdict. Tribunal integrations write this via the dispute repository on resolution."
          },
          "feeAmount": {
            "type": [
              "null",
              "string"
            ],
            "description": "Arbitration fee amount. **Engine does NOT compute fees** (record-keeper, not arbiter). Stays `null` until an external tribunal records the verdict."
          },
          "feeCurrency": {
            "type": [
              "null",
              "string"
            ],
            "description": "Currency of the arbitration fee (e.g., USD, EUR). Set by the external tribunal alongside `feeAmount`."
          },
          "evidenceWindowClosesAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "Deadline for evidence submission"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NextStepAction"
            },
            "description": "Suggested next API calls for the dispute workflow"
          }
        },
        "additionalProperties": false
      },
      "DisputeEvidence": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "disputeId": {
            "type": "string",
            "format": "uuid"
          },
          "submittedByRole": {
            "type": "string"
          },
          "submittedById": {
            "type": "string",
            "format": "uuid"
          },
          "evidenceType": {
            "type": "string",
            "description": "Type of evidence: screenshot, external_lookup, document, communication, or other"
          },
          "payload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Evidence data payload"
          },
          "payloadHash": {
            "type": "string",
            "description": "SHA-256 hash of the canonicalized evidence payload"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ReputationScore": {
        "type": "object",
        "properties": {
          "agentId": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "description": "Type this score applies to"
          },
          "reliabilityScore": {
            "type": [
              "null",
              "number"
            ],
            "description": "Task completion reliability (0-1)"
          },
          "accuracyScore": {
            "type": [
              "null",
              "number"
            ],
            "description": "Evidence accuracy vs record criteria, adjusted for overturned verdicts (0-1)"
          },
          "efficiencyScore": {
            "type": [
              "null",
              "number"
            ],
            "description": "Efficiency (0-1). v1 placeholder: currently mirrors accuracy until activation→completion timing is tracked."
          },
          "compositeScore": {
            "type": [
              "null",
              "number"
            ],
            "description": "Weighted composite of all dimensions (0-1)"
          },
          "confidenceLevel": {
            "type": [
              "null",
              "number"
            ],
            "description": "Statistical confidence (0-1); tightens as transaction volume grows"
          },
          "lifetimeRecords": {
            "type": "integer",
            "description": "Records ever assigned to this agent for this type (monotonic)"
          },
          "lifetimeVerdicts": {
            "type": "integer",
            "description": "Gate verdicts ever rendered for this agent+contract (monotonic)"
          },
          "lifetimeAccepted": {
            "type": "integer",
            "description": "Verdicts accepted, ever (monotonic — includes verdicts later overturned)"
          },
          "lifetimeCompletions": {
            "type": "integer",
            "description": "Completions ever accepted from this agent for this type (monotonic)"
          },
          "reversals": {
            "type": "integer",
            "description": "Count of dispute OVERTURNED outcomes; accuracy subtracts these from lifetimeAccepted"
          },
          "lastUpdatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "formulaVersion": {
            "type": "integer",
            "description": "Scoring formula version for reproducibility"
          }
        },
        "additionalProperties": false
      },
      "EntityReference": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "system": {
            "type": "string"
          },
          "refType": {
            "type": "string"
          },
          "refId": {
            "type": "string"
          },
          "displayName": {
            "type": [
              "null",
              "string"
            ]
          },
          "uri": {
            "type": [
              "null",
              "string"
            ]
          },
          "attributes": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    }
  },
  "paths": {
    "/metrics": {
      "get": {
        "operationId": "getMetrics",
        "summary": "Prometheus metrics",
        "tags": [
          "Observability"
        ],
        "description": "Returns Prometheus-format metrics. Authentication options: (a) METRICS_AUTH_TOKEN — bearer-token gate, no API-key auth required; (b) restrict at the network layer (private ingress, VPC, LB rule). Default is public (matches prior behavior). Production installs MUST enable one of these or expose /metrics on a worker-only port.",
        "security": [],
        "responses": {
          "200": {
            "description": "Prometheus metrics in text format.",
            "content": {
              "text/plain; version=0.0.4; charset=utf-8": {
                "schema": {
                  "description": "Prometheus metrics in text format.",
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Bearer token missing or invalid (only returned when METRICS_AUTH_TOKEN is set).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "description": "Bearer token missing or invalid (only returned when METRICS_AUTH_TOKEN is set).",
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "healthCheck",
        "summary": "Health check",
        "tags": [
          "Health"
        ],
        "description": "Returns service health status. No authentication or rate limiting. Use this endpoint for load balancer health checks and connectivity verification. Aliased at /healthz for Kubernetes-canonical clients.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Service is healthy.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "version": {
                      "type": "string",
                      "description": "AGLedger API version"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "healthCheckKubernetes",
        "summary": "Health check (Kubernetes-canonical alias for /health)",
        "tags": [
          "Health"
        ],
        "description": "Behaves identically to /health. Present for clients that follow the /healthz, /readyz, /livez convention.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Service is healthy.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "version": {
                      "type": "string",
                      "description": "AGLedger API version"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/health/ready": {
      "get": {
        "operationId": "readinessCheck",
        "summary": "Readiness check",
        "tags": [
          "Health"
        ],
        "description": "Verifies the service can serve requests by probing database connectivity. Returns 200 when ready, 503 when dependencies are unavailable. Use this for Kubernetes readiness probes and Docker Compose healthchecks. Use /health for liveness probes. Aliased at /readyz for Kubernetes-canonical clients.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is ready to accept traffic.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Service is ready to accept traffic.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready"
                      ]
                    },
                    "version": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Service is not ready.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "description": "Service is not ready.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "not_ready"
                      ]
                    },
                    "version": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "reason": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/readyz": {
      "get": {
        "operationId": "readinessCheckKubernetes",
        "summary": "Readiness check (Kubernetes-canonical alias for /health/ready)",
        "tags": [
          "Health"
        ],
        "description": "Behaves identically to /health/ready. Present for clients that follow the /healthz, /readyz, /livez convention.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is ready to accept traffic.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Service is ready to accept traffic.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready"
                      ]
                    },
                    "version": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Service is not ready.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "description": "Service is not ready.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "not_ready"
                      ]
                    },
                    "version": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "reason": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/livez": {
      "get": {
        "operationId": "livenessCheck",
        "summary": "Liveness check",
        "tags": [
          "Health"
        ],
        "description": "Trivial 200 response indicating the process is alive and serving HTTP. No database or dependency check. Use for Kubernetes liveness probes when you explicitly want to avoid cascading restarts on downstream outages.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service process is alive.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Service process is alive.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "alive"
                      ]
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/v1/conformance": {
      "get": {
        "operationId": "getConformance",
        "summary": "Server capability declaration",
        "tags": [
          "Discovery"
        ],
        "description": "Declares which capabilities this AGLedger instance has wired up. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Server capability declaration — which features are wired on this install.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Server capability declaration — which features are wired on this install.",
                  "type": "object",
                  "properties": {
                    "capabilities": {
                      "type": "object",
                      "properties": {
                        "recordLifecycle": {
                          "type": "boolean"
                        },
                        "twoPhaseGate": {
                          "type": "boolean"
                        },
                        "auditVault": {
                          "type": "boolean"
                        },
                        "hashChainIntegrity": {
                          "type": "boolean"
                        },
                        "ed25519Signatures": {
                          "type": "boolean"
                        },
                        "signingAlgorithms": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Signature algorithms this build can sign chain envelopes with. Ed25519 is the default; a non-default algorithm additionally requires the AGLEDGER_ALLOW_NON_DEFAULT_SIGNING_ALG opt-in at boot. Per-key algorithm resolution for verification lives at /v1/verification-keys."
                        },
                        "delegationChains": {
                          "type": "boolean"
                        },
                        "cascadingGate": {
                          "type": "boolean"
                        },
                        "disputeResolution": {
                          "type": "boolean"
                        },
                        "reputationScoring": {
                          "type": "boolean"
                        },
                        "webhookDelivery": {
                          "type": "boolean"
                        },
                        "a2aProtocol": {
                          "type": "boolean"
                        },
                        "encryptedMode": {
                          "type": "boolean"
                        },
                        "euAiActCompliance": {
                          "type": "boolean"
                        },
                        "scittRegistration": {
                          "type": "boolean",
                          "description": "POST /v1/scitt/entries — register a customer-signed COSE_Sign1 Signed Statement against the per-org SCITT log, returns a Receipt."
                        },
                        "signedStatementExport": {
                          "type": "boolean",
                          "description": "GET /v1/records/{id}/attestation — canonical COSE_Sign1 chain envelopes (application/cose-sequence). `?receipts=true` upgrades to a Transparent Statement sequence (Receipts attached at unprotected label 394)."
                        },
                        "sigstoreBundleExport": {
                          "type": "boolean",
                          "description": "GET /v1/records/{id}/attestation.bundle — structural sigstore-bundle v0.3 projection for Rekor / in-toto consumers. Structural-only; cryptographic verification is /attestation."
                        },
                        "coseMerkleReceipts": {
                          "type": "boolean",
                          "description": "SCITT Receipts (draft-ietf-cose-merkle-tree-proofs) — RFC 9162 inclusion proofs at unprotected label 396, available on /audit-export?receipts=true and /scitt/entries."
                        },
                        "oidcWorkloadIdentity": {
                          "type": "boolean",
                          "description": "Direct-JWT admin auth on /v1/admin/* and JWT-exchange agent auth via /v1/auth/oidc/cert routes are wired. Acceptance is data-driven by `trusted_issuers` rows — `true` here means the surface exists; query GET /v1/admin/trusted-issuers for actual issuer registrations."
                        },
                        "ephemeralCerts": {
                          "type": "boolean",
                          "description": "POST /v1/auth/oidc/cert route is wired — agents exchange an IdP JWT for a short-lived Ed25519-bound AGLedger cert. Cert TTL is min(now + maxCredentialTtlSeconds, jwt.exp); 10-min cap by default, 60s floor (sub-60s remaining returns 422). Acceptance requires a matching `trusted_issuers` row with `appliesTo: agent` or `any`."
                        },
                        "trustedIssuers": {
                          "type": "boolean",
                          "description": "GET/POST/PATCH/DELETE /v1/admin/trusted-issuers routes are wired — platform-key registration of OIDC IdP allow-list. Required precondition for `oidcWorkloadIdentity` / `ephemeralCerts` to actually accept JWTs."
                        },
                        "agentSignatureCoSign": {
                          "type": "boolean",
                          "description": "X-Agent-Signature + X-Agent-Signature-Content-Hash headers accepted on POST /v1/records, /v1/records/:id/transition, /v1/records/:id/completions. Cert-bound Ed25519 per-request co-signature carried into the COSE_Sign1 chain envelope as predicate.on_behalf_of.agent_signature. Honored only when the caller authenticated via an ephemeral cert."
                        }
                      },
                      "additionalProperties": false
                    },
                    "contractTypes": {
                      "type": "integer",
                      "description": "Number of registered types"
                    },
                    "schemasUrl": {
                      "type": "string",
                      "description": "URL to list all type schemas (criteria + evidence structure)"
                    },
                    "settlementSignals": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Supported settlement signal types"
                    },
                    "version": {
                      "type": "string",
                      "description": "AGLedger API version"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/lifecycle": {
      "get": {
        "operationId": "getLifecycle",
        "summary": "RecordRow and dispute state machines",
        "tags": [
          "Discovery"
        ],
        "description": "Returns the complete state machine for record and dispute lifecycles, including valid transitions from each state and common paths. Agents should call this once to understand the state machine. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "State machine definitions.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "State machine definitions.",
                  "type": "object",
                  "properties": {
                    "record": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "dispute": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "getPublicStatus",
        "summary": "Platform status",
        "tags": [
          "Status"
        ],
        "description": "Returns the current operational status of AGLedger platform components. No authentication required. Designed for status pages, dashboards, and monitoring.",
        "security": [],
        "responses": {
          "200": {
            "description": "Current platform status.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Current platform status.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "operational",
                        "degraded",
                        "outage"
                      ]
                    },
                    "components": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "operational",
                              "degraded",
                              "outage"
                            ]
                          },
                          "latencyMs": {
                            "type": "number",
                            "nullable": true
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "uptime": {
                      "type": "number"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "LLM agent discovery document",
        "tags": [
          "Discovery"
        ],
        "description": "Returns a Markdown document following the llms.txt standard (llmstxt.org) with instructions for AI agents consuming this API. Includes all active types (platform + org-scoped). The primary example is controlled by AGLEDGER_EXAMPLE_CONTRACT_TYPE.\n\n**Auth:** none (public endpoint)",
        "security": [],
        "responses": {
          "200": {
            "description": "Markdown document for LLM agent consumption.",
            "content": {
              "text/plain; charset=utf-8": {
                "schema": {
                  "type": "string",
                  "description": "Markdown document for LLM agent consumption."
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "summary": "LLM agent discovery document (full version with schema details)",
        "tags": [
          "Discovery"
        ],
        "description": "Returns an expanded Markdown document with full type details: record/completion schema fields, quickStart examples, and gate rules for every registered type. Larger than /llms.txt but gives agents everything they need in a single fetch.\n\n**Auth:** none (public endpoint)",
        "security": [],
        "responses": {
          "200": {
            "description": "Expanded Markdown document with schema details.",
            "content": {
              "text/plain; charset=utf-8": {
                "schema": {
                  "type": "string",
                  "description": "Expanded Markdown document with schema details."
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/discovery/reload": {
      "post": {
        "operationId": "adminReloadDiscovery",
        "summary": "Reload agent-discovery documents",
        "tags": [
          "Admin"
        ],
        "description": "Busts the in-memory caches for /llms.txt and /llms-full.txt. The next fetch regenerates from current DB state. Schema create/deprecate operations already invalidate these caches automatically via LISTEN/NOTIFY — this endpoint is the manual escape hatch for operators who want to force a refresh.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reloaded": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "reloaded"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/predicates": {
      "get": {
        "operationId": "listPredicates",
        "summary": "Index of AGLedger in-toto predicate schemas",
        "tags": [
          "Discovery"
        ],
        "description": "Returns one entry per AGLedger claim kind with the predicate type URI (used as `predicateType` in DSSE bundle exports) and the schema fetch URL on this deployment.\n\n**Auth:** none (public discovery endpoint).",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "kind",
                          "predicateType",
                          "schemaUrl"
                        ],
                        "additionalProperties": false,
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "record-state",
                              "settlement-signal",
                              "vault-checkpoint",
                              "org-read",
                              "counter-attestation",
                              "federation-projection",
                              "schema-event"
                            ]
                          },
                          "predicateType": {
                            "type": "string",
                            "format": "uri"
                          },
                          "schemaUrl": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/predicates/{kind}/v1": {
      "get": {
        "operationId": "getPredicateSchema",
        "summary": "JSON Schema for an AGLedger predicate kind",
        "tags": [
          "Discovery"
        ],
        "description": "Returns the canonical JSON Schema (draft-2019-09) for the in-toto Statement predicate body emitted under `predicateType=https://agledger.ai/predicates/{kind}/v1`. Generated from the engine's body schema — never hand-written.\n\n**Auth:** none (public discovery endpoint).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "in": "path",
            "name": "kind",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "JSON Schema document (draft-2019-09).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON Schema document (draft-2019-09)."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown predicate kind. See GET /predicates for the canonical list.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/security.txt": {
      "get": {
        "operationId": "getSecurityTxt",
        "summary": "Security contact information (RFC 9116)",
        "tags": [
          "Discovery"
        ],
        "description": "Returns a security.txt file per RFC 9116 with vulnerability reporting contact information, disclosure policy, and preferred language.\n\n**Auth:** none (public endpoint)",
        "security": [],
        "responses": {
          "200": {
            "description": "RFC 9116 security.txt document",
            "content": {
              "text/plain; charset=utf-8": {
                "schema": {
                  "type": "string",
                  "description": "RFC 9116 security.txt document"
                }
              }
            }
          }
        }
      }
    },
    "/v1/verification-keys": {
      "get": {
        "operationId": "listVerificationKeys",
        "summary": "List vault verification keys (public)",
        "tags": [
          "Discovery"
        ],
        "description": "Returns all current and historical public keys used to sign Signed Statements, plus the COSE_Sign1 envelope/algorithm parameters so external auditors can independently verify hash-chained, signed audit chains without admin access, source code access, or full audit exports.\n\n**Auth:** none (public endpoint). Public keys are, by definition, public.\n\n**Algorithm resolution:** each key carries its own `algorithm` and `coseAlgorithm`; verify every entry with the algorithm of the key its `signingKeyId` resolves to. The document-level `coseAlgorithm`/`signatureAlgorithm` describe the currently-active key only. Every key is Ed25519 unless the operator explicitly opted into a non-default algorithm.\n\n**Verification workflow:** For each Signed Statement, pull the `cose_sign1` byte string from `/v1/records/{id}/audit-export` (base64-encoded) or `/v1/records/{id}/attestation` (raw CBOR). Resolve the entry's `signingKeyId` to a public key from this response, then verify the COSE_Sign1 signature per RFC 9052 §4.4: reconstruct `Sig_structure = [\"Signature1\", protected_bstr, h'', payload_bstr]`, deterministically CBOR-encode it (RFC 8949 §4.2.1), and verify with the key's algorithm. **Stock-library path:** any RFC 9052 implementation works — `go-cose`, `coset` (Rust), or `pycose` (pass `allow_unknown_attributes=True` for the private label −65537). The `signatureInputTemplate` field below documents the byte-level signing input so no AGLedger package is required. `@agledger/verify` (npm) is a turnkey alternative that consumes the same dump format the stock libs read; each key's `minVerifierVersion` names the minimum version able to verify it.",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyId": {
                            "type": "string",
                            "description": "SHA-256 fingerprint (16 hex chars). Matches the RFC 9421 `keyid` on ed25519 webhook signatures and the COSE_Sign1 protected-header kid."
                          },
                          "algorithm": {
                            "type": "string",
                            "description": "Signature algorithm of THIS key (e.g. Ed25519). Authoritative per key: entries signed under a retired key verify with that key's algorithm, not the active one."
                          },
                          "coseAlgorithm": {
                            "type": "integer",
                            "description": "COSE alg label for THIS key (RFC 9053; -8 = EdDSA). Authoritative per key: a chain entry's protected-header alg must equal the value for the key its kid resolves to, and a mismatch is a tamper signal, not an upgrade hint. Single integer today; may be ABSENT when this build cannot resolve the row's algorithm, so consumers must tolerate absence."
                          },
                          "minVerifierVersion": {
                            "type": "string",
                            "description": "Minimum @agledger/verify version able to verify entries signed under this key. The algorithm support lives in that package's @agledger/verify-core dependency, so this floor is the @agledger/verify release that resolves a core carrying it under every install shape; an earlier version may happen to work depending on what its core resolves to."
                          },
                          "publicKey": {
                            "type": "string",
                            "description": "Base64-encoded SPKI DER public key"
                          },
                          "publicKeyRaw": {
                            "type": "string",
                            "description": "Base64 of the raw 32-byte Ed25519 public key, for raw-key verifiers (RFC 9421 / Standard-Webhooks-style). Present only on Ed25519 keys: a raw key carries no AlgorithmIdentifier, so other algorithms publish SPKI only."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "retired"
                            ]
                          },
                          "activatedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Instant this key became the active signing key (RFC 3339, millisecond precision). Lower bound of the key's temporal-validity window: an entry whose write time precedes it was not signed by this key."
                          },
                          "retiredAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Instant this key was retired (RFC 3339, millisecond precision), or null while it is still active. Upper bound of the temporal-validity window. Compare against the entry's write time at full precision: rotation happens at an instant, not at a day boundary, so a key legitimately signs entries on its retirement day."
                          }
                        },
                        "required": [
                          "keyId",
                          "algorithm",
                          "publicKey",
                          "status",
                          "activatedAt",
                          "retiredAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "envelope": {
                      "type": "string",
                      "enum": [
                        "COSE_Sign1"
                      ],
                      "description": "Canonical chain envelope shape — RFC 9052 §4.4 (CBOR tag 18)."
                    },
                    "payloadFormat": {
                      "type": "string",
                      "enum": [
                        "application/vnd.in-toto+cbor"
                      ],
                      "description": "Canonical COSE payload media type — in-toto v1 Statement in deterministic CBOR."
                    },
                    "canonicalization": {
                      "type": "string",
                      "enum": [
                        "RFC8949-CDE"
                      ],
                      "description": "Deterministic CBOR encoding rule (RFC 8949 §4.2.1 Core Deterministic Encoding)."
                    },
                    "coseAlgorithm": {
                      "type": [
                        "null",
                        "integer"
                      ],
                      "description": "COSE algorithm label (RFC 9053; -8 = EdDSA) of the currently-ACTIVE signing key only, or null when the active key cannot be resolved. Retained for existing consumers; never use it to verify an entry whose kid resolves to a different key. The per-key `coseAlgorithm` in `data` is authoritative."
                    },
                    "signatureAlgorithm": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Signature algorithm of the currently-ACTIVE signing key only, or null when the active key cannot be resolved. Retained for existing consumers; the per-key `algorithm` in `data` is authoritative."
                    },
                    "signatureInputTemplate": {
                      "type": "string",
                      "description": "Recipe for the byte-level Ed25519 signing input on every chain entry. COSE_Sign1 envelopes sign over the RFC 9052 §4.4 Sig_structure: `Sig_structure = [\"Signature1\", protected_bstr, h'', payload_bstr]`, deterministically CBOR-encoded per RFC 8949 §4.2.1. Pull `cose_sign1` from `/v1/records/{id}/audit-export` (base64) or `/v1/records/{id}/attestation` (raw CBOR), reconstruct the Sig_structure with empty external_aad, deterministically encode, then Ed25519 verify against the public key resolved by the entry's `signingKeyId`. No AGLedger package required."
                    }
                  },
                  "required": [
                    "data",
                    "envelope",
                    "payloadFormat",
                    "canonicalization",
                    "coseAlgorithm",
                    "signatureAlgorithm",
                    "signatureInputTemplate"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agledger-vault-keys.json": {
      "get": {
        "operationId": "getWellKnownVaultKeys",
        "summary": "List vault verification keys (public)",
        "tags": [
          "Discovery"
        ],
        "description": "Returns all current and historical public keys used to sign Signed Statements, plus the COSE_Sign1 envelope/algorithm parameters so external auditors can independently verify hash-chained, signed audit chains without admin access, source code access, or full audit exports.\n\n**Auth:** none (public endpoint). Public keys are, by definition, public.\n\n**Algorithm resolution:** each key carries its own `algorithm` and `coseAlgorithm`; verify every entry with the algorithm of the key its `signingKeyId` resolves to. The document-level `coseAlgorithm`/`signatureAlgorithm` describe the currently-active key only. Every key is Ed25519 unless the operator explicitly opted into a non-default algorithm.\n\n**Verification workflow:** For each Signed Statement, pull the `cose_sign1` byte string from `/v1/records/{id}/audit-export` (base64-encoded) or `/v1/records/{id}/attestation` (raw CBOR). Resolve the entry's `signingKeyId` to a public key from this response, then verify the COSE_Sign1 signature per RFC 9052 §4.4: reconstruct `Sig_structure = [\"Signature1\", protected_bstr, h'', payload_bstr]`, deterministically CBOR-encode it (RFC 8949 §4.2.1), and verify with the key's algorithm. **Stock-library path:** any RFC 9052 implementation works — `go-cose`, `coset` (Rust), or `pycose` (pass `allow_unknown_attributes=True` for the private label −65537). The `signatureInputTemplate` field below documents the byte-level signing input so no AGLedger package is required. `@agledger/verify` (npm) is a turnkey alternative that consumes the same dump format the stock libs read; each key's `minVerifierVersion` names the minimum version able to verify it.",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyId": {
                            "type": "string",
                            "description": "SHA-256 fingerprint (16 hex chars). Matches the RFC 9421 `keyid` on ed25519 webhook signatures and the COSE_Sign1 protected-header kid."
                          },
                          "algorithm": {
                            "type": "string",
                            "description": "Signature algorithm of THIS key (e.g. Ed25519). Authoritative per key: entries signed under a retired key verify with that key's algorithm, not the active one."
                          },
                          "coseAlgorithm": {
                            "type": "integer",
                            "description": "COSE alg label for THIS key (RFC 9053; -8 = EdDSA). Authoritative per key: a chain entry's protected-header alg must equal the value for the key its kid resolves to, and a mismatch is a tamper signal, not an upgrade hint. Single integer today; may be ABSENT when this build cannot resolve the row's algorithm, so consumers must tolerate absence."
                          },
                          "minVerifierVersion": {
                            "type": "string",
                            "description": "Minimum @agledger/verify version able to verify entries signed under this key. The algorithm support lives in that package's @agledger/verify-core dependency, so this floor is the @agledger/verify release that resolves a core carrying it under every install shape; an earlier version may happen to work depending on what its core resolves to."
                          },
                          "publicKey": {
                            "type": "string",
                            "description": "Base64-encoded SPKI DER public key"
                          },
                          "publicKeyRaw": {
                            "type": "string",
                            "description": "Base64 of the raw 32-byte Ed25519 public key, for raw-key verifiers (RFC 9421 / Standard-Webhooks-style). Present only on Ed25519 keys: a raw key carries no AlgorithmIdentifier, so other algorithms publish SPKI only."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "retired"
                            ]
                          },
                          "activatedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Instant this key became the active signing key (RFC 3339, millisecond precision). Lower bound of the key's temporal-validity window: an entry whose write time precedes it was not signed by this key."
                          },
                          "retiredAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Instant this key was retired (RFC 3339, millisecond precision), or null while it is still active. Upper bound of the temporal-validity window. Compare against the entry's write time at full precision: rotation happens at an instant, not at a day boundary, so a key legitimately signs entries on its retirement day."
                          }
                        },
                        "required": [
                          "keyId",
                          "algorithm",
                          "publicKey",
                          "status",
                          "activatedAt",
                          "retiredAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "envelope": {
                      "type": "string",
                      "enum": [
                        "COSE_Sign1"
                      ],
                      "description": "Canonical chain envelope shape — RFC 9052 §4.4 (CBOR tag 18)."
                    },
                    "payloadFormat": {
                      "type": "string",
                      "enum": [
                        "application/vnd.in-toto+cbor"
                      ],
                      "description": "Canonical COSE payload media type — in-toto v1 Statement in deterministic CBOR."
                    },
                    "canonicalization": {
                      "type": "string",
                      "enum": [
                        "RFC8949-CDE"
                      ],
                      "description": "Deterministic CBOR encoding rule (RFC 8949 §4.2.1 Core Deterministic Encoding)."
                    },
                    "coseAlgorithm": {
                      "type": [
                        "null",
                        "integer"
                      ],
                      "description": "COSE algorithm label (RFC 9053; -8 = EdDSA) of the currently-ACTIVE signing key only, or null when the active key cannot be resolved. Retained for existing consumers; never use it to verify an entry whose kid resolves to a different key. The per-key `coseAlgorithm` in `data` is authoritative."
                    },
                    "signatureAlgorithm": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Signature algorithm of the currently-ACTIVE signing key only, or null when the active key cannot be resolved. Retained for existing consumers; the per-key `algorithm` in `data` is authoritative."
                    },
                    "signatureInputTemplate": {
                      "type": "string",
                      "description": "Recipe for the byte-level Ed25519 signing input on every chain entry. COSE_Sign1 envelopes sign over the RFC 9052 §4.4 Sig_structure: `Sig_structure = [\"Signature1\", protected_bstr, h'', payload_bstr]`, deterministically CBOR-encoded per RFC 8949 §4.2.1. Pull `cose_sign1` from `/v1/records/{id}/audit-export` (base64) or `/v1/records/{id}/attestation` (raw CBOR), reconstruct the Sig_structure with empty external_aad, deterministically encode, then Ed25519 verify against the public key resolved by the entry's `signingKeyId`. No AGLedger package required."
                    }
                  },
                  "required": [
                    "data",
                    "envelope",
                    "payloadFormat",
                    "canonicalization",
                    "coseAlgorithm",
                    "signatureAlgorithm",
                    "signatureInputTemplate"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/scitt-configuration": {
      "get": {
        "operationId": "getScittConfiguration",
        "summary": "SCITT spec discovery document",
        "tags": [
          "SCITT",
          "Discovery"
        ],
        "description": "draft-ietf-scitt-scrapi §4 transparency configuration. Advertises the SCRAPI endpoints + key set this TS exposes plus the supported signing/registration algorithms. Unauthenticated so a SCITT-aware client can bootstrap without holding a key. Mirrors /llms.txt §SCRAPI for machine consumers.",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "registration_endpoint",
                    "resolution_endpoint",
                    "jwks_uri",
                    "supported_signature_algorithms",
                    "supported_registration_policies"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "description": "Issuer URL identifying this Transparency Service (matches AGLEDGER_EXTERNAL_URL)."
                    },
                    "registration_endpoint": {
                      "type": "string",
                      "description": "POST /v1/scitt/entries — register a Signed Statement; 201 + Receipt."
                    },
                    "resolution_endpoint": {
                      "type": "string",
                      "description": "GET /v1/scitt/entries/{entryId} — fetch a Transparent Statement with a freshly-issued Receipt."
                    },
                    "checkpoint_endpoint": {
                      "type": "string",
                      "description": "GET /v1/scitt/checkpoint — signed tree head (root + tree size + signature)."
                    },
                    "jwks_uri": {
                      "type": "string",
                      "description": "GET /.well-known/scitt-keys — TS verification keys as a CBOR COSE_KeySet."
                    },
                    "supported_signature_algorithms": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "COSE algorithm names this TS SIGNS WITH (Receipts, Transparent Statements, checkpoints). Registration is content-agnostic: POST /v1/scitt/entries does not verify Issuer signatures, so this list does not constrain what may be registered."
                    },
                    "supported_registration_policies": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Registration policy identifiers. `accept-all` means the TS does not gate registration by issuer or subject — any well-formed COSE_Sign1 is accepted."
                    },
                    "llms_txt": {
                      "type": "string",
                      "description": "Pointer to the human/LLM-readable discovery doc with worked examples."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/scitt-keys": {
      "get": {
        "operationId": "getScittKeySet",
        "summary": "TS verification keys as a CBOR COSE_KeySet",
        "tags": [
          "SCITT",
          "Discovery"
        ],
        "description": "SCRAPI-required keyset endpoint. Returns every known vault signing key as a CBOR COSE_KeySet (array of COSE_Key maps per RFC 9052 §7). Unauthenticated; the JSON equivalent at `/v1/verification-keys` carries the same keys for non-SCITT consumers.",
        "security": [],
        "responses": {
          "200": {
            "description": "COSE_KeySet bytes.",
            "content": {
              "application/cbor": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "COSE_KeySet bytes."
                }
              },
              "application/problem+json": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "COSE_KeySet bytes."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/cbor": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/scitt-keys/{kid}": {
      "get": {
        "operationId": "getScittKeyByKid",
        "summary": "Single TS verification key as CBOR COSE_Key",
        "tags": [
          "SCITT",
          "Discovery"
        ],
        "description": "Resolve one verification key by its hex `kid`. Returns a single CBOR COSE_Key map (NOT wrapped in an array). The schema `pattern` on `kid` rejects malformed values before the handler runs — non-hex inputs surface as Fastify validation errors (JSON), not CBOR problem details.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{16,}$",
              "maxLength": 128
            },
            "in": "path",
            "name": "kid",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "COSE_Key bytes.",
            "content": {
              "application/cbor": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "COSE_Key bytes."
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "COSE_Key bytes."
                }
              },
              "application/problem+json": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "COSE_Key bytes."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/cbor": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas": {
      "get": {
        "operationId": "listSchemas",
        "summary": "List available types",
        "tags": [
          "Schemas"
        ],
        "description": "Returns type summaries — one row per type, showing the latest version and lifecycle status so the catalog is usable without per-type round-trips. Default view is ACTIVE only; pass `?includeDisabled=true` to see DISABLED types as well. Use `?orgId=` (with auth) to include that org's custom types.\n\n**Auth:** none — this is part of the always-on Agent Discovery Surface (alongside `/llms.txt`, `/openapi.json`, `/.well-known/agent-card.json`, `/v1/verification-keys`, `/v1/scope-profiles`). An unauthenticated `GET /v1/schemas` returns `200 { total: 0, data: [], nextSteps: [register one] }` on a fresh install rather than `401`, on purpose: LLM agents discover this Server's capabilities before they hold any credentials, and a 401 here would force a credential-fetch loop before the discovery flow can complete. To enumerate org-custom types the caller still needs a key (`?orgId=`); `POST /v1/schemas` for registration always requires auth.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Include this org's custom types (requires auth)"
          },
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "includeDisabled",
            "required": false,
            "description": "Include DISABLED types in the response (default: ACTIVE only)."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Maximum number of results to return"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Number of results to skip"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "Type identifier (e.g., acme-po-v1)"
                          },
                          "version": {
                            "type": "integer",
                            "description": "Latest version number for this type"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "ACTIVE",
                              "DISABLED"
                            ],
                            "description": "Lifecycle status — DISABLED types reject new records"
                          },
                          "displayName": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Human-readable name"
                          },
                          "category": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Customer-defined taxonomy label (no engine semantics) — e.g. `decision`, `delivery-attempt`, `incident_report`. Lets a newcomer triage the catalog by domain."
                          },
                          "description": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Truncated preview of the per-type description (max ~280 chars + ellipsis). Full text is on `GET /v1/schemas/{type}`. Lets a newcomer judge fit without N round-trips."
                          },
                          "templateUrl": {
                            "type": "string",
                            "description": "URL to fetch a forkable template seeded from this type — the \"fork an existing type into your namespace\" verb. The returned template is freely editable (you can flip `additionalProperties:false` → `true` on the recordSchema if you need to extend with your own fields, edit the type name, swap displayName, etc.) and POST-able to `/v1/schemas` to register your own."
                          },
                          "publisher": {
                            "type": "string",
                            "description": "Publisher label that owns this row. the schema catalog — list returns one row per (publisher, type) so callers can disambiguate before issuing scoped reads."
                          },
                          "orgId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "Owning org id, or `null` for platform-bundled types. Present only on platform-key reads without `?orgId=` — surfaces the org axis a platform admin needs to see what is registered where. Omitted on org-scoped reads."
                          },
                          "defaultGateMode": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Lifecycle discriminator — `auto` or `principal` for a principal-/auto-gated type, `null` for notarize-only / no-default-gate. Mirrors `defaultGateMode` on `GET /v1/schemas/{type}` so a newcomer can tell a gated type from a notarize-only one from the list row alone, without a per-type GET."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "registerSchema",
        "summary": "Register a custom type",
        "tags": [
          "Schemas"
        ],
        "description": "Register a new type with custom record and completion JSON Schemas. Org auth creates org-scoped types; platform auth can register types in any org.\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "recordSchema"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "description": "Custom type name. Customers own their entire type namespace within their org — no prefixes are reserved."
                  },
                  "displayName": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 8000,
                    "description": "Plain-English description of what this Type records and why. Write it as you would describe it to a colleague (2-4 paragraphs is fine). Example: \"Logs every time our procurement bot accepts a vendor quote — captures the supplier, the line items, and the bot's confidence score for the audit trail.\""
                  },
                  "category": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Free-form taxonomy of what kind of artifact this Type produces — your label, your vocabulary. Examples customers have used: \"decision\", \"delivery-attempt\", \"telemetry-tick\", \"auth_attempt\", \"incident_report\". No engine semantics; it is exposed back on read and surfaced in /v1/schemas listings so agents can browse by domain."
                  },
                  "recordSchema": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "JSON Schema for record criteria"
                  },
                  "completionSchema": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Optional JSON Schema for completion evidence. Omit (or pass `{}`) when this Type does not have a completion phase — Records of such Types terminalize at `RECORDED` on create. Provide a structured schema to opt into the completion + verdict lifecycle."
                  },
                  "fieldMappings": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "ruleId": {
                          "type": "string",
                          "description": "Generic gate rule ID"
                        },
                        "criteriaPath": {
                          "type": "string",
                          "description": "Dot-notation path in criteria. Required when `valueType` is anything other than `expression`. For `valueType: 'expression'` the field is accepted but ignored — expression rules read from the `criteria.*` / `evidence.*` / `tolerance.*` bindings directly. Omit it on expression rules to avoid stale paths persisting on the rule row."
                        },
                        "evidencePath": {
                          "type": "string",
                          "description": "Dot-notation path in evidence. Required when `valueType` is anything other than `expression`. For `valueType: 'expression'` the field is accepted but ignored. Omit it on expression rules."
                        },
                        "toleranceField": {
                          "type": "string",
                          "description": "Tolerance band field name"
                        },
                        "maxTolerance": {
                          "type": "number",
                          "minimum": 0,
                          "description": "Cap on the per-record tolerance a caller may pass for this rule. `0` forbids any tolerance (the rule is an undodgeable threshold gate); a positive value pins the widest band a record may declare. Omitted = uncapped. The cap applies in whatever unit the tolerance key uses (percent for `*Pct`/`*_pct` keys, absolute otherwise). Enforced with 400 at every tolerance write (create, bulk, update)."
                        },
                        "valueType": {
                          "type": "string",
                          "enum": [
                            "number",
                            "denomination",
                            "string",
                            "boolean",
                            "datetime",
                            "expression"
                          ],
                          "description": "Value type for comparison logic. Use \"expression\" for safe expression-based rules."
                        },
                        "expression": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "Safe expression string (required when valueType is \"expression\"). **Must evaluate to a boolean** — true = check passes, false = check fails. A non-boolean result (number, string, etc) is rejected with \"Expression evaluated to <type>, expected boolean\"; wrap arithmetic in a comparison (e.g. `evidence.amount <= criteria.budget`, not `evidence.amount`). Top-level variable bindings are: `criteria.*`, `evidence.*`, `tolerance.*`, `metadata.*`, `record.*`, `parent.*` (the parent record's server-truth projection: signed `created_at`/`activated_at`/`fulfilled_at` timestamps + id/status/type; on a parent-less record any parent.* reference fails the check with a clear error, fail-closed, rather than trusting a supplied copy). NOT `completion.evidence.*` or `record.criteria.*` — these are the top-level scope objects, not nested. Helpers: abs, min, max, len, sum, contains, lower, daysBetween, coalesce. See GET /v1/schemas/meta-schema for the full binding spec + helper signatures."
                        }
                      },
                      "required": [
                        "ruleId",
                        "valueType"
                      ],
                      "additionalProperties": false,
                      "allOf": [
                        {
                          "if": {
                            "properties": {
                              "valueType": {
                                "enum": [
                                  "expression"
                                ]
                              }
                            },
                            "required": [
                              "valueType"
                            ]
                          },
                          "then": {
                            "required": [
                              "expression"
                            ]
                          },
                          "else": {
                            "required": [
                              "criteriaPath",
                              "evidencePath"
                            ]
                          }
                        }
                      ]
                    },
                    "maxItems": 20
                  },
                  "compatibilityMode": {
                    "type": "string",
                    "enum": [
                      "none",
                      "backward",
                      "forward",
                      "full"
                    ]
                  },
                  "defaultShare": {
                    "type": "boolean",
                    "description": "V1 sharing default for records of this contract type. Omit to inherit the global `AGLEDGER_DEFAULT_SHARE` (which itself defaults to `true`). Per-record `share` overrides this. Row-only metadata; NOT canonicalized into the manifest digest, so federation digest-echo treats `defaultShare`-divergent installs as identical schemas."
                  },
                  "defaultGateMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "principal"
                    ],
                    "description": "Default gate mode applied to records of this type when the create payload omits `gateMode`. Omit for the engine default (`auto` — rules engine renders the verdict and auto-settles). Set `principal` when this type's purpose is a principal-held verdict, so records created from the quickStart cannot silently auto-settle; the quickStart then surfaces `gateMode` explicitly too. An explicit per-record `gateMode` always wins. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "coSignRequired": {
                    "type": "boolean",
                    "description": "V1 Additive E — opt into bilateral co-signed Settlement Signals for records of this contract type. Omit/`false` for single-signature signals (V1-FRAME default — firing Server signs alone). `true` = before firing a terminal Settlement Signal, the firing Server first POSTs a co-sign request to the counterparty's `/federation/v1/co-sign-requests` and attaches the returned counter-signature to the signal as `counterSignature`. Use for high-value or regulated dual-control flows. Per-contract-type only (no per-record override). Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "flipRecordStatusOnDispute": {
                    "type": "boolean",
                    "description": "When `true` (default), opening a dispute against a record of this type flips `record.status` to DISPUTED while the dispute is in flight; the record returns to its pre-dispute status on resolve/withdraw via `dispute_pre_status`. When `false`, the record stays at its current status and the dispute is observable only via `disputeStatus`/`disputeId`/`disputeCount` on the record body (plus `?hasDispute=` / `?disputeStatus=` query filters on /v1/records). Set to `false` when \"FULFILLED at time T\" must remain a historical fact even during dispute (compliance/audit framing). Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "federateDisputes": {
                    "type": "boolean",
                    "description": "When `true` (default), disputes on federated records of this contract type propagate to peers: the originator's dispute lifecycle emits federation outbound jobs that update the peer's record body (`disputeStatus`/`hasDispute`/`disputeCount`/`grounds`/`context`) and write a receiver chain entry. When `false`, disputes stay local to the originator's chain; the peer's record body is unchanged until a RELEASE Settlement Signal fires on overturn. Default-on fits the intra-org federation case (the typical V1 deployment). Cross-org deployments wanting strict boundary flip to `false` per type. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "publisher": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$",
                    "description": "Optional publisher label. Omit (or pass `local`) for engine-authored schemas — that's the standalone-Server default. Pass a non-`local` label (e.g. `trust-circle-a`) to publish under a coordinated label that two federated Servers can agree on out-of-band, so cross-peer schemaRef matching resolves on both sides. The label is part of the manifest digest, so the same body published under two different labels produces two different rows."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Custom type registered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces. Customer-defined; no engine semantics."
                    },
                    "compatibilityMode": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label. \"local\" for engine-authored, anything else for imported."
                    },
                    "manifestDigest": {
                      "type": "string",
                      "description": "sha256:<hex> federation-comparable digest."
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ]
                    },
                    "federatable": {
                      "type": "boolean"
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) for records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-sig; `true` = firing Server requests a counter-signature before firing. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "Per-type opt-out for dispute propagation across federation. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable starter Record + completion bodies derived from the registered schemas. Returned inline on POST /v1/schemas so the caller does not need a follow-up GET."
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "The live gate rule wiring (syncRuleIds, asyncRuleIds, fieldMappings) echoed on write so the caller can confirm what the engine will evaluate without a follow-up GET. Same nested shape as GET /v1/schemas/{type}."
                    },
                    "warnings": {
                      "type": "array",
                      "description": "Keywords in the submitted schemas that this validator does not enforce, so they are ignored. Usually a misspelling (`maxLenght` for `maxLength`), which is worth acting on: the constraint the author intended is not applied and every value passes. Absent when there are none. Prefix a deliberate annotation with `x-` to keep it out of this list.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "Location of the keyword within the schema (empty string = root)."
                          },
                          "keyword": {
                            "type": "string",
                            "description": "The unrecognized keyword."
                          },
                          "message": {
                            "type": "string",
                            "description": "What was ignored, and the closest recognized keyword when one is near."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "description": "Custom type registered."
                }
              }
            }
          },
          "400": {
            "description": "Invalid schema or naming.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Name conflicts with an existing version for the same publisher/org.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/meta-schema": {
      "get": {
        "operationId": "getMetaSchema",
        "summary": "Get schema constraint specification",
        "tags": [
          "Schemas"
        ],
        "description": "Returns the full constraint specification for the AGLedger meta-schema validator. Use this to configure local IDE validation (e.g., VS Code JSON Schema settings), build custom linting, or power schema authoring tools.\n\n**Recommended OSS tools for local authoring:**\n- **VS Code**: Point `json.schemas` at the constraints from this endpoint\n- **json-editor** (github.com/json-editor/json-editor): Embeddable React schema editor\n- **Stoplight Studio** (free tier): Visual JSON Schema design (draft-07)\n\n**Auth:** none (public endpoint)",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "constraints": {
                      "type": "object",
                      "properties": {
                        "maxDepth": {
                          "type": "integer"
                        },
                        "maxNodes": {
                          "type": "integer"
                        },
                        "maxSizeBytes": {
                          "type": "integer"
                        },
                        "maxCombinerEntries": {
                          "type": "integer"
                        },
                        "rootTypeMustBe": {
                          "type": "string"
                        },
                        "rootMustHaveRequired": {
                          "type": "boolean"
                        },
                        "blockedKeywords": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "supportedApplicators": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "JSON Schema applicator keywords the validator walks and enforces in custom schemas — conditional (`if`/`then`/`else`), combiners (`allOf`/`anyOf`/`oneOf`, bounded by `maxCombinerEntries`), and `not`. See `examples.conditionalCompletion` for a worked if/then/else."
                        },
                        "noIdAllowed": {
                          "type": "boolean"
                        }
                      }
                    },
                    "allowedFormats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "allowedRefs": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "limits": {
                      "type": "object",
                      "properties": {
                        "contractTypeMaxLength": {
                          "type": "integer"
                        },
                        "maxFieldMappings": {
                          "type": "integer"
                        },
                        "ruleIdPattern": {
                          "type": "string"
                        },
                        "ruleIdMaxLength": {
                          "type": "integer"
                        },
                        "reservedPrefixes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "fieldMappingValueTypes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "fieldMappingValueTypeSpec": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "evidenceShape": {
                            "type": "string"
                          },
                          "comparator": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "evidenceShape",
                          "comparator"
                        ],
                        "additionalProperties": false
                      },
                      "description": "Per-valueType evidence shape + comparator semantics. Read this BEFORE designing fieldMappings — `denomination` requires `{amount, currency}`, `string` does strict equality (use `valueType: expression` with `contains`/`lower` for pattern match)."
                    },
                    "expressionHelpers": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "signature": {
                            "type": "string"
                          },
                          "semantics": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "signature",
                          "semantics"
                        ],
                        "additionalProperties": false
                      },
                      "description": "Helper functions callable inside an expression, keyed by name. `signature` is the call shape; `semantics` states the edge behavior (invalid-input result, rounding direction, coercion) to read BEFORE relying on a helper in a gate rule. Example: `daysBetween` counts whole elapsed 24h periods between UTC instants (floored, order-independent), NOT calendar days, and returns 0 on unparseable dates."
                    },
                    "expressionBindings": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Top-level variable bindings available inside an expression-type field mapping. Each key is the path root (write `<key>.<field>`); each value documents what that scope object contains."
                    },
                    "expressionMustReturnBoolean": {
                      "type": "boolean",
                      "description": "Hard contract: an expression MUST evaluate to true/false. Numeric or string results are rejected. Wrap arithmetic in a comparison."
                    },
                    "expressionLimits": {
                      "type": "object",
                      "properties": {
                        "maxLength": {
                          "type": "integer"
                        },
                        "maxAstNodes": {
                          "type": "integer"
                        },
                        "maxAstDepth": {
                          "type": "integer"
                        },
                        "maxOperations": {
                          "type": "integer"
                        },
                        "allowedContexts": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "builtinRuleIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "RESERVED — these `ruleId` strings are reserved by the engine for built-in semantic checks (e.g. `quantity_match`, `price_ceiling`). Do NOT use them as `ruleId` values in custom `fieldMappings` — registration will reject with 400. Pick a different identifier (kebab-case, your-domain prefix recommended)."
                    },
                    "verbVocabulary": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "additionalProperties": {
                          "type": "string"
                        }
                      },
                      "description": "Verb vocabulary keyed by valueType. A `ruleId` shaped as `<valueType>:<verb>` is a semantic claim — the prefix MUST equal the declared `valueType`, and the verb MUST appear in this table. Registry rejects unknown verbs at registration with the allowed list. Free-form ruleIds (no colon) fall through to each valueType's default verb in `verbVocabularyDefaults`."
                    },
                    "verbVocabularyDefaults": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Default verb per valueType when a fieldMapping uses a free-form `ruleId` (no `<valueType>:<verb>` prefix). e.g. `{ number: \"exact-match\", datetime: \"max-inclusive\", string: \"exact\", ... }`."
                    },
                    "sharedSchemas": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "examples": {
                      "type": "object",
                      "properties": {
                        "minimalRecord": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "minimalCompletion": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "conditionalCompletion": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Worked if/then/else example — conditional-required completion evidence (\"if determination=denied, require denialBasis\"). Fully enforced at Phase-1 structural validation; the same shape also works on a recordSchema."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/_blank": {
      "get": {
        "operationId": "getBlankTemplate",
        "summary": "Get a blank schema template",
        "tags": [
          "Schemas"
        ],
        "description": "Returns a minimal registration-ready skeleton with TODO placeholders. Default is **notarize-only** (`completionSchema: {}`, `fieldMappings: []`) — the 90% path. Pass `?withCompletion=true` for the judgment-mode skeleton (completion-bearing schema + a sample fieldMapping).\n\n**Auth:** none (public)",
        "parameters": [
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "withCompletion",
            "required": false,
            "description": "Return the judgment-mode skeleton (populated completionSchema + fieldMappings) instead of the notarize-only default."
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sourceType": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "template": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "displayName": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "recordSchema": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "completionSchema": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/template": {
      "get": {
        "operationId": "getSchemaTemplate",
        "summary": "Fork an existing type into your namespace",
        "tags": [
          "Schemas"
        ],
        "description": "Returns a registration-ready skeleton seeded from the specified type — the \"fork an existing type into your namespace\" verb. Preserves the source type's `recordSchema` / `completionSchema` / `fieldMappings` (the rule wiring stays verbatim — `<valueType>:<verb>` ruleIds are not renamed); rewrites `type` / `displayName` / `description` to TODO markers in the response.\n\n**The returned template is freely editable.** Rename `type` to land it in your namespace, flip `recordSchema.additionalProperties: false` → `true` (or edit `required[]` / `properties`) if you need to extend the source's structure with your own fields, swap `displayName`, then POST to `/v1/schemas`. Use this when a catalogue type is structurally close to your domain but its record fields don't match (e.g. a carrier-payout type whose `recordSchema` you want to adapt for invoice-approval).\n\n**Discoverable on every list row.** `GET /v1/schemas` surfaces `templateUrl` per row so an agent surveying the catalog finds the fork path without reading the OpenAPI.\n\n**Auth:** none (public)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sourceType": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "template": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "displayName": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "recordSchema": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "completionSchema": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/manifest": {
      "get": {
        "operationId": "getSchemaManifest",
        "summary": "Get the import-ready manifest for a type",
        "tags": [
          "Schemas"
        ],
        "description": "Returns the canonical manifest body for this Server's registration of `{type}`, shaped exactly as `POST /v1/schemas/import` accepts it. The bytes are JCS-canonicalized before hashing so the returned `manifestDigest` matches the digest a peer would compute on import. Use this to mirror a schema to a federated peer without out-of-band coordination beyond agreeing on a non-`local` publisher label.\n\n**Auth:** none (public endpoint, same posture as `GET /v1/schemas/{type}`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Disambiguate when multiple publishers offer the same type in this org."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "manifest",
                    "manifestDigest"
                  ],
                  "properties": {
                    "manifest": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The canonical manifest body. Send under `{ \"manifest\": <this> }` to `POST /v1/schemas/import` on a peer Server; the peer will compute the same digest."
                    },
                    "manifestDigest": {
                      "type": "string",
                      "description": "sha256:<hex> over the JCS-canonicalized manifest."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher; pass `?publisher=` to disambiguate.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}": {
      "get": {
        "operationId": "getSchema",
        "summary": "Get record and completion schemas for a type",
        "tags": [
          "Schemas"
        ],
        "description": "Returns the JSON Schema definitions for both record criteria and completion evidence for the specified type. Use `?orgId=` to resolve org-scoped custom types. Use `?format=template` to get a registration-ready skeleton.\n\n**Auth:** none (public endpoint)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "template"
              ]
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Set to \"template\" to get a registration-ready skeleton"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "RecordRow and completion JSON Schema definitions plus gate rules for the type. Use the quickStart field for copy-pasteable example payloads.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer",
                      "description": "Schema revision number"
                    },
                    "latestVersion": {
                      "type": "integer",
                      "description": "Latest active revision number"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces (e.g. \"decision\", \"delivery-attempt\"). Customer-defined; no engine semantics."
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label that owns this row. \"local\" for engine-authored; anything else for file-imported schemas."
                    },
                    "manifestDigest": {
                      "type": "string",
                      "description": "sha256:<hex> of the JCS-canonicalized manifest. Federation peers compare schemas by this value."
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ],
                      "description": "How this row was authored. Federation digest-echo treats both identically."
                    },
                    "federatable": {
                      "type": "boolean",
                      "description": "Whether this engine exposes the schema to federated peer hubs. Row-only metadata; not in the canonical manifest."
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for records of this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`; `true`/`false` is an explicit per-type decision. Per-record `share` overrides this. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) applied to records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). An explicit per-record `gateMode` always wins. Types whose purpose is the principal-held verdict set `principal` here so the copy-paste path cannot silently auto-settle. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-signature (firing Server only, V1-FRAME default). `true` = before firing, the firing Server requests a counter-signature from the counterparty's `/federation/v1/co-sign-requests` and attaches it to the Settlement Signal as `counterSignature`. Per-contract-type only (no per-record override). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "When `true` (default), opening a dispute against a record of this type flips `record.status` to DISPUTED while the dispute is in flight (restored to pre-status on resolve/withdraw). When `false`, the record stays at its current status (most often FULFILLED/REMEDIATED/FAILED) and the dispute is observable only via `disputeStatus`/`disputeId`/`disputeCount` on the record body plus `?hasDispute=` and `?disputeStatus=` query filters. Compliance-minded customers (where FULFILLED at time T must remain a historical fact) set this `false` per type. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "When `true` (default), disputes on federated records of this contract type propagate to peers: the originator's dispute lifecycle (open/resolve/withdraw + tier transitions) emits federation outbound jobs that update the peer's record body (`disputeStatus`, `hasDispute`, `disputeCount`, `grounds`, `context`) and write a receiver chain entry. When `false`, disputes stay local to the originator's chain — the peer's record body is unchanged until a RELEASE Settlement Signal fires on overturn. Default-on fits the intra-org federation case (the typical V1 deployment) where counterparty reconciliation benefits from full dispute visibility. Cross-org deployments wanting strict boundary flip to `false` per type. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ACTIVE",
                        "DISABLED"
                      ],
                      "description": "Lifecycle status: ACTIVE or DISABLED"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable example payloads for this type. null when neither schema is registered (rare; a type without either schema cannot be used)."
                    },
                    "recordSchema": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "JSON Schema for record criteria"
                    },
                    "completionSchema": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "JSON Schema for completion evidence"
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "Gate rules configuration for the type."
                    }
                  },
                  "description": "RecordRow and completion JSON Schema definitions plus gate rules for the type. Use the quickStart field for copy-pasteable example payloads."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteContractType",
        "summary": "Permanently delete a type",
        "tags": [
          "Schemas"
        ],
        "description": "Physically removes a type and all its versions from the registry, scoped to the publisher the call resolves to. Two preconditions, both must pass:\n\n1. All versions under that publisher must be DISABLED (409 `STATUS_NOT_DISABLED` otherwise)\n2. No record still depends on the rows being removed (409 `RECORDS_REFERENCE_TYPE` otherwise). A record pins the exact registration it was written against, so this counts the records bound to THIS publisher's rows, not every record sharing the type name. Records carrying no pin (written before every create path recorded one, or received as federated projections) cannot be attributed to any publisher and so block a delete under every label. The 409 body splits the two counts as `pinnedRecords` and `unattributableRecords`.\n\nDelete is for a registration nothing was ever written against. The way to retire one that has records is `PATCH /v1/schemas/{type}/disable`, which stops new records binding to it and leaves the existing ones able to resolve the schema their criteria and evidence were validated against.\n\n**Auth:** admin (own schemas), platform (any schema).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope (platform only)"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label this delete targeted, always the one the call resolved to. Rows under any OTHER publisher of the same type are untouched and still in the catalog: this field, not the absence of the type, is what says which registration went away."
                    },
                    "versionsDeleted": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Type not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Precondition failed. Response includes a machine-readable `reason`: `STATUS_NOT_DISABLED` or `RECORDS_REFERENCE_TYPE`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The type exists under more than one publisher in this org, so the target is ambiguous. The body lists the candidates in `publishers`; re-issue with ?publisher=<label>.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/rules": {
      "get": {
        "operationId": "getRules",
        "summary": "Get gate rules config for a type",
        "tags": [
          "Schemas"
        ],
        "description": "Returns the gate rules configuration for the specified type.\n\nRules are per-registration, so on a type offered by more than one publisher this behaves like every other scoped schema surface: pin `?publisher=`, or take a 422 naming the candidates. The response echoes the `publisher` it resolved to.\n\n**Auth:** none — public discovery surface; org-scoped types require auth (`?orgId=`)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "template"
              ]
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Set to \"template\" to get a registration-ready skeleton"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Gate rules configuration for the type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "syncRuleIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                    },
                    "asyncRuleIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                    },
                    "fieldMappings": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ruleId": {
                            "type": "string"
                          },
                          "criteriaPath": {
                            "type": "string"
                          },
                          "evidencePath": {
                            "type": "string"
                          },
                          "toleranceField": {
                            "type": "string"
                          },
                          "maxTolerance": {
                            "type": "number"
                          },
                          "valueType": {
                            "type": "string"
                          },
                          "expression": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false
                      },
                      "description": "Custom field mappings for gate rules"
                    },
                    "commissionSourceField": {
                      "type": "string",
                      "description": "Dot-notation path to the commission base value field in criteria"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label of the registration these rules came from. Echoes the resolved value, so it is populated whether or not the request pinned `?publisher=`."
                    }
                  },
                  "description": "Gate rules configuration for the type."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher, or a `?publisher=` label no registration of this type carries.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/validate": {
      "post": {
        "operationId": "validateCompletion",
        "summary": "Dry-run completion evidence validation",
        "tags": [
          "Schemas"
        ],
        "description": "Validates completion evidence against the type completion schema without creating a completion.\n\n**Auth:** none — public discovery surface; org-scoped types require auth (`?orgId=`)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "evidence"
                ],
                "properties": {
                  "evidence": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Evidence payload to validate against the completion schema"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "template"
              ]
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Set to \"template\" to get a registration-ready skeleton"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Validation result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean",
                      "description": "Whether the evidence conforms to the completion schema"
                    },
                    "errors": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyword": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "instancePath": {
                            "type": "string"
                          },
                          "schemaPath": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "description": "Validation errors (null when valid is true)"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "description": "Validation result."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/preview": {
      "post": {
        "operationId": "previewSchema",
        "summary": "Preview schema registration (dry run)",
        "tags": [
          "Schemas"
        ],
        "description": "Full dry-run of the registration flow without persisting. Returns structured validation results including compiled schema info or detailed errors. Use this to iterate on schemas before registering.\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "recordSchema"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "description": "Custom type name. Customers own their entire type namespace within their org — no prefixes are reserved."
                  },
                  "displayName": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 8000,
                    "description": "Plain-English description of what this Type records and why. Write it as you would describe it to a colleague (2-4 paragraphs is fine). Example: \"Logs every time our procurement bot accepts a vendor quote — captures the supplier, the line items, and the bot's confidence score for the audit trail.\""
                  },
                  "category": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Free-form taxonomy of what kind of artifact this Type produces — your label, your vocabulary. Examples customers have used: \"decision\", \"delivery-attempt\", \"telemetry-tick\", \"auth_attempt\", \"incident_report\". No engine semantics; it is exposed back on read and surfaced in /v1/schemas listings so agents can browse by domain."
                  },
                  "recordSchema": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "JSON Schema for record criteria"
                  },
                  "completionSchema": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Optional JSON Schema for completion evidence. Omit (or pass `{}`) when this Type does not have a completion phase — Records of such Types terminalize at `RECORDED` on create. Provide a structured schema to opt into the completion + verdict lifecycle."
                  },
                  "fieldMappings": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "ruleId": {
                          "type": "string",
                          "description": "Generic gate rule ID"
                        },
                        "criteriaPath": {
                          "type": "string",
                          "description": "Dot-notation path in criteria. Required when `valueType` is anything other than `expression`. For `valueType: 'expression'` the field is accepted but ignored — expression rules read from the `criteria.*` / `evidence.*` / `tolerance.*` bindings directly. Omit it on expression rules to avoid stale paths persisting on the rule row."
                        },
                        "evidencePath": {
                          "type": "string",
                          "description": "Dot-notation path in evidence. Required when `valueType` is anything other than `expression`. For `valueType: 'expression'` the field is accepted but ignored. Omit it on expression rules."
                        },
                        "toleranceField": {
                          "type": "string",
                          "description": "Tolerance band field name"
                        },
                        "maxTolerance": {
                          "type": "number",
                          "minimum": 0,
                          "description": "Cap on the per-record tolerance a caller may pass for this rule. `0` forbids any tolerance (the rule is an undodgeable threshold gate); a positive value pins the widest band a record may declare. Omitted = uncapped. The cap applies in whatever unit the tolerance key uses (percent for `*Pct`/`*_pct` keys, absolute otherwise). Enforced with 400 at every tolerance write (create, bulk, update)."
                        },
                        "valueType": {
                          "type": "string",
                          "enum": [
                            "number",
                            "denomination",
                            "string",
                            "boolean",
                            "datetime",
                            "expression"
                          ],
                          "description": "Value type for comparison logic. Use \"expression\" for safe expression-based rules."
                        },
                        "expression": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "Safe expression string (required when valueType is \"expression\"). **Must evaluate to a boolean** — true = check passes, false = check fails. A non-boolean result (number, string, etc) is rejected with \"Expression evaluated to <type>, expected boolean\"; wrap arithmetic in a comparison (e.g. `evidence.amount <= criteria.budget`, not `evidence.amount`). Top-level variable bindings are: `criteria.*`, `evidence.*`, `tolerance.*`, `metadata.*`, `record.*`, `parent.*` (the parent record's server-truth projection: signed `created_at`/`activated_at`/`fulfilled_at` timestamps + id/status/type; on a parent-less record any parent.* reference fails the check with a clear error, fail-closed, rather than trusting a supplied copy). NOT `completion.evidence.*` or `record.criteria.*` — these are the top-level scope objects, not nested. Helpers: abs, min, max, len, sum, contains, lower, daysBetween, coalesce. See GET /v1/schemas/meta-schema for the full binding spec + helper signatures."
                        }
                      },
                      "required": [
                        "ruleId",
                        "valueType"
                      ],
                      "additionalProperties": false,
                      "allOf": [
                        {
                          "if": {
                            "properties": {
                              "valueType": {
                                "enum": [
                                  "expression"
                                ]
                              }
                            },
                            "required": [
                              "valueType"
                            ]
                          },
                          "then": {
                            "required": [
                              "expression"
                            ]
                          },
                          "else": {
                            "required": [
                              "criteriaPath",
                              "evidencePath"
                            ]
                          }
                        }
                      ]
                    },
                    "maxItems": 20
                  },
                  "compatibilityMode": {
                    "type": "string",
                    "enum": [
                      "none",
                      "backward",
                      "forward",
                      "full"
                    ]
                  },
                  "defaultShare": {
                    "type": "boolean",
                    "description": "V1 sharing default for records of this contract type. Omit to inherit the global `AGLEDGER_DEFAULT_SHARE` (which itself defaults to `true`). Per-record `share` overrides this. Row-only metadata; NOT canonicalized into the manifest digest, so federation digest-echo treats `defaultShare`-divergent installs as identical schemas."
                  },
                  "defaultGateMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "principal"
                    ],
                    "description": "Default gate mode applied to records of this type when the create payload omits `gateMode`. Omit for the engine default (`auto` — rules engine renders the verdict and auto-settles). Set `principal` when this type's purpose is a principal-held verdict, so records created from the quickStart cannot silently auto-settle; the quickStart then surfaces `gateMode` explicitly too. An explicit per-record `gateMode` always wins. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "coSignRequired": {
                    "type": "boolean",
                    "description": "V1 Additive E — opt into bilateral co-signed Settlement Signals for records of this contract type. Omit/`false` for single-signature signals (V1-FRAME default — firing Server signs alone). `true` = before firing a terminal Settlement Signal, the firing Server first POSTs a co-sign request to the counterparty's `/federation/v1/co-sign-requests` and attaches the returned counter-signature to the signal as `counterSignature`. Use for high-value or regulated dual-control flows. Per-contract-type only (no per-record override). Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "flipRecordStatusOnDispute": {
                    "type": "boolean",
                    "description": "When `true` (default), opening a dispute against a record of this type flips `record.status` to DISPUTED while the dispute is in flight; the record returns to its pre-dispute status on resolve/withdraw via `dispute_pre_status`. When `false`, the record stays at its current status and the dispute is observable only via `disputeStatus`/`disputeId`/`disputeCount` on the record body (plus `?hasDispute=` / `?disputeStatus=` query filters on /v1/records). Set to `false` when \"FULFILLED at time T\" must remain a historical fact even during dispute (compliance/audit framing). Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "federateDisputes": {
                    "type": "boolean",
                    "description": "When `true` (default), disputes on federated records of this contract type propagate to peers: the originator's dispute lifecycle emits federation outbound jobs that update the peer's record body (`disputeStatus`/`hasDispute`/`disputeCount`/`grounds`/`context`) and write a receiver chain entry. When `false`, disputes stay local to the originator's chain; the peer's record body is unchanged until a RELEASE Settlement Signal fires on overturn. Default-on fits the intra-org federation case (the typical V1 deployment). Cross-org deployments wanting strict boundary flip to `false` per type. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "publisher": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$",
                    "description": "Optional publisher label. Omit (or pass `local`) for engine-authored schemas — that's the standalone-Server default. Pass a non-`local` label (e.g. `trust-circle-a`) to publish under a coordinated label that two federated Servers can agree on out-of-band, so cross-peer schemaRef matching resolves on both sides. The label is part of the manifest digest, so the same body published under two different labels produces two different rows."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "description": "Error category: META_SCHEMA, AJV_COMPILE, NAMING, FIELD_MAPPING, COMPATIBILITY"
                          },
                          "message": {
                            "type": "string"
                          },
                          "path": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "description": "Keywords in the submitted schemas that this validator does not enforce, so they are ignored. Usually a misspelling (`maxLenght` for `maxLength`), which is worth acting on: the constraint the author intended is not applied and every value passes. Absent when there are none. Prefix a deliberate annotation with `x-` to keep it out of this list.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "Location of the keyword within the schema (empty string = root)."
                          },
                          "keyword": {
                            "type": "string",
                            "description": "The unrecognized keyword."
                          },
                          "message": {
                            "type": "string",
                            "description": "What was ignored, and the closest recognized keyword when one is near."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "compiled": {
                      "type": "object",
                      "properties": {
                        "recordProperties": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "recordRequired": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "completionProperties": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "completionRequired": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "ruleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "fieldMappingCount": {
                          "type": "integer"
                        },
                        "compatibilityCheck": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "properties": {
                            "record": {
                              "type": "object",
                              "properties": {
                                "compatible": {
                                  "type": "boolean"
                                },
                                "changes": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "path": {
                                        "type": "string"
                                      },
                                      "type": {
                                        "type": "string"
                                      },
                                      "breaking": {
                                        "type": "boolean"
                                      },
                                      "detail": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "completion": {
                              "type": "object",
                              "properties": {
                                "compatible": {
                                  "type": "boolean"
                                },
                                "changes": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "path": {
                                        "type": "string"
                                      },
                                      "type": {
                                        "type": "string"
                                      },
                                      "breaking": {
                                        "type": "boolean"
                                      },
                                      "detail": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "estimatedVersion": {
                          "type": "integer"
                        }
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/import": {
      "post": {
        "operationId": "importSchema",
        "summary": "Import a schema manifest",
        "tags": [
          "Schemas"
        ],
        "description": "Register a schema authored by a third party from a manifest file. The manifest is JCS-canonicalized and SHA-256 hashed; the digest persists on `schema_subjects.manifest_digest` so federation peers can verify schema equality by digest, not name.\n\n**Idempotent on full-tuple match** (publisher, type, version, org, digest) — returns 200 with the existing row. **409 conflicting-version** when the same publisher/type/version exists with different bytes. Same digest under a different identity tuple in the same org is allowed (relabeling).\n\n**Auth:** schema-admin scope (`schemas:admin`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "manifest"
                ],
                "properties": {
                  "manifest": {
                    "type": "object",
                    "required": [
                      "manifestVersion",
                      "publisher",
                      "type",
                      "version",
                      "recordSchema"
                    ],
                    "properties": {
                      "manifestVersion": {
                        "type": "string",
                        "pattern": "^\\d+\\.\\d+$",
                        "description": "Envelope version (currently \"1.0\")."
                      },
                      "publisher": {
                        "type": "string",
                        "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$",
                        "description": "Publisher coordination label (1–64 lowercase alphanumerics + hyphens). \"local\" and `local-*` / `*-local` are reserved."
                      },
                      "type": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100,
                        "description": "Type identifier."
                      },
                      "version": {
                        "type": "string",
                        "description": "SemVer-ish version string. The major component is stored on schema_subjects.version."
                      },
                      "publishedAt": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "displayName": {
                        "type": "string",
                        "maxLength": 100
                      },
                      "description": {
                        "type": "string",
                        "maxLength": 8000
                      },
                      "category": {
                        "type": "string",
                        "maxLength": 100
                      },
                      "compatibility": {
                        "type": "string",
                        "enum": [
                          "none",
                          "backward",
                          "forward",
                          "full"
                        ]
                      },
                      "deprecation": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "properties": {
                          "since": {
                            "type": "string"
                          },
                          "replacedBy": {
                            "type": "string"
                          }
                        }
                      },
                      "previousVersion": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Advisory documentation only. The engine MUST NEVER read this field."
                      },
                      "recordSchema": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "completionSchema": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "fieldMappings": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      },
                      "tolerances": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    },
                    "additionalProperties": false
                  },
                  "orgId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Override target org (platform keys only)."
                  },
                  "federatable": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether this engine exposes the schema to federated peer hubs. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "defaultShare": {
                    "type": "boolean",
                    "description": "V1 sharing default for records of this imported contract type. Omit to inherit the global `AGLEDGER_DEFAULT_SHARE`. Per-record `share` overrides this. Row-only metadata; NOT canonicalized into the manifest digest."
                  },
                  "defaultGateMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "principal"
                    ],
                    "description": "Default gate mode for records of the imported contract type when the create payload omits `gateMode`. Same posture as `defaultShare` (row-only, not in the manifest digest). Omit for the engine default (`auto`)."
                  },
                  "coSignRequired": {
                    "type": "boolean",
                    "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in for the imported contract type. Same posture as `defaultShare` (row-only, not in the manifest digest). Omit for single-signature signals."
                  },
                  "flipRecordStatusOnDispute": {
                    "type": "boolean",
                    "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. Row-only metadata, NOT in the canonical manifest body."
                  },
                  "federateDisputes": {
                    "type": "boolean",
                    "description": "Per-type opt-out for dispute propagation across federation. Default true. Row-only metadata, NOT in the canonical manifest body."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Idempotent — manifest already registered with identical bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces. Customer-defined; no engine semantics."
                    },
                    "compatibilityMode": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label. \"local\" for engine-authored, anything else for imported."
                    },
                    "manifestDigest": {
                      "type": "string"
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ]
                    },
                    "federatable": {
                      "type": "boolean"
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) for records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-sig; `true` = firing Server requests a counter-signature before firing. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "Per-type opt-out for dispute propagation across federation. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable starter Record + completion bodies derived from the registered schemas. Returned inline on POST /v1/schemas so the caller does not need a follow-up GET."
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "The live gate rule wiring (syncRuleIds, asyncRuleIds, fieldMappings) echoed on write so the caller can confirm what the engine will evaluate without a follow-up GET. Same nested shape as GET /v1/schemas/{type}."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "description": "Idempotent — manifest already registered with identical bytes."
                }
              }
            }
          },
          "201": {
            "description": "Manifest registered for the first time at this (publisher, type, version, org).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces. Customer-defined; no engine semantics."
                    },
                    "compatibilityMode": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label. \"local\" for engine-authored, anything else for imported."
                    },
                    "manifestDigest": {
                      "type": "string"
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ]
                    },
                    "federatable": {
                      "type": "boolean"
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) for records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-sig; `true` = firing Server requests a counter-signature before firing. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "Per-type opt-out for dispute propagation across federation. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable starter Record + completion bodies derived from the registered schemas. Returned inline on POST /v1/schemas so the caller does not need a follow-up GET."
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "The live gate rule wiring (syncRuleIds, asyncRuleIds, fieldMappings) echoed on write so the caller can confirm what the engine will evaluate without a follow-up GET. Same nested shape as GET /v1/schemas/{type}."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "description": "Manifest registered for the first time at this (publisher, type, version, org)."
                }
              }
            }
          },
          "400": {
            "description": "Invalid manifest.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflicting version — same tuple, different digest. Body carries both digests + recoveryHint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Manifest validation failed or publisher label is reserved.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/diff": {
      "get": {
        "operationId": "diffSchemaVersions",
        "summary": "Diff two schema versions",
        "tags": [
          "Schemas"
        ],
        "description": "Returns a structured diff between two schema versions, including breaking change analysis.\n\n**Auth:** none — public discovery surface; org-scoped types require auth (`?orgId=`)",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "in": "query",
            "name": "from",
            "required": true,
            "description": "Source version number"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "in": "query",
            "name": "to",
            "required": true,
            "description": "Target version number"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "from": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "status": {
                          "type": "string"
                        }
                      }
                    },
                    "to": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "status": {
                          "type": "string"
                        }
                      }
                    },
                    "record": {
                      "type": "object",
                      "properties": {
                        "changes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "breaking": {
                                "type": "boolean"
                              },
                              "detail": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "completion": {
                      "type": "object",
                      "properties": {
                        "changes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "breaking": {
                                "type": "boolean"
                              },
                              "detail": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "overallCompatibility": {
                      "type": "object",
                      "properties": {
                        "backward": {
                          "type": "boolean"
                        },
                        "forward": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "One of the requested versions does not exist. Response carries a recoveryHint listing available active versions.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "One of the requested versions exists but is DISABLED. Re-enable the type or pick an active version.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher (`/problems/ambiguous-publisher`, body carries `publishers`): more than one publisher offers this type in the org. Add `?publisher=` so both sides of the diff come from the same registration.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/export": {
      "post": {
        "operationId": "exportSchema",
        "summary": "Export a type for environment promotion",
        "tags": [
          "Schemas"
        ],
        "description": "Exports a complete schema package including all versions and shared schemas. Use with `POST /v1/schemas/import` to promote schemas between environments.\n\nScoped to one publisher, because `/import` consumes one manifest under one label: pin `?publisher=` when more than one offers the type, or take a 422 naming the candidates. The artifact echoes the `publisher` it was taken from.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "versions",
            "required": false,
            "description": "Comma-separated version numbers (default: all)"
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label to export. Required when more than one publisher offers this type; the 422 names the candidates."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exportVersion": {
                      "type": "integer"
                    },
                    "exportedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "type": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label of the registration this artifact was exported from."
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "compatibilityMode": {
                      "type": "string"
                    },
                    "versions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "version": {
                            "type": "integer"
                          },
                          "status": {
                            "type": "string"
                          },
                          "recordSchema": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "completionSchema": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "rulesConfig": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "sharedSchemas": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Type not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher, or a `?publisher=` label no registration of this type carries.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/versions": {
      "get": {
        "operationId": "getSchemaVersions",
        "summary": "Get version history for a type",
        "tags": [
          "Schemas"
        ],
        "description": "Returns all schema revisions for a type.\n\n**Auth:** none (public endpoint)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Filter to one publisher's registrations. Optional, and unlike the scoped reads this endpoint never returns 422 when omitted: it is where you enumerate the candidates, and every row carries its own `publisher`. A label no publisher offers is a 422 naming the ones that exist, rather than an empty list that reads as \"this type has no versions\"."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "version": {
                            "type": "integer"
                          },
                          "orgId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "displayName": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "description": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "category": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "maxLength": 100,
                            "description": "Free-form taxonomy of what kind of artifact this Type produces. Customer-defined; no engine semantics."
                          },
                          "compatibilityMode": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "publisher": {
                            "type": "string",
                            "description": "Publisher label. \"local\" for engine-authored, anything else for imported."
                          },
                          "manifestDigest": {
                            "type": "string",
                            "description": "sha256:<hex> federation-comparable digest."
                          },
                          "trustClass": {
                            "type": "string",
                            "enum": [
                              "local",
                              "imported"
                            ]
                          },
                          "federatable": {
                            "type": "boolean"
                          },
                          "defaultShare": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "description": "V1 sharing default for this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`. Row-only metadata, NOT in the canonical manifest body."
                          },
                          "defaultGateMode": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Default gate mode (`auto` or `principal`) for records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). Row-only metadata, NOT in the canonical manifest body."
                          },
                          "coSignRequired": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-sig; `true` = firing Server requests a counter-signature before firing. Row-only metadata, NOT in the canonical manifest body."
                          },
                          "flipRecordStatusOnDispute": {
                            "type": "boolean",
                            "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. See the full doc on this field in the `getSchemaResponse`."
                          },
                          "federateDisputes": {
                            "type": "boolean",
                            "description": "Per-type opt-out for dispute propagation across federation. Default true. See the full doc on this field in the `getSchemaResponse`."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "quickStart": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "properties": {
                              "criteria": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                              },
                              "evidence": {
                                "type": [
                                  "null",
                                  "object"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                              },
                              "tolerance": {
                                "type": [
                                  "null",
                                  "object"
                                ],
                                "additionalProperties": {
                                  "type": "number"
                                },
                                "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                              },
                              "gateMode": {
                                "type": "string",
                                "enum": [
                                  "auto",
                                  "principal"
                                ],
                                "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                              }
                            },
                            "description": "Copy-pasteable starter Record + completion bodies derived from the registered schemas. Returned inline on POST /v1/schemas so the caller does not need a follow-up GET."
                          },
                          "rulesConfig": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string"
                              },
                              "syncRuleIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                              },
                              "asyncRuleIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                              },
                              "fieldMappings": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "ruleId": {
                                      "type": "string"
                                    },
                                    "criteriaPath": {
                                      "type": "string"
                                    },
                                    "evidencePath": {
                                      "type": "string"
                                    },
                                    "toleranceField": {
                                      "type": "string"
                                    },
                                    "maxTolerance": {
                                      "type": "number"
                                    },
                                    "valueType": {
                                      "type": "string"
                                    },
                                    "expression": {
                                      "type": "string"
                                    }
                                  },
                                  "additionalProperties": false
                                },
                                "description": "Custom field mappings for gate rules"
                              },
                              "commissionSourceField": {
                                "type": "string",
                                "description": "Dot-notation path to the commission base value field in criteria"
                              }
                            },
                            "description": "The live gate rule wiring (syncRuleIds, asyncRuleIds, fieldMappings) echoed on write so the caller can confirm what the engine will evaluate without a follow-up GET. Same nested shape as GET /v1/schemas/{type}."
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "`?publisher=` names a label no publisher offers for this type (`/problems/ambiguous-publisher`, body carries `publishers`). The type itself exists; only the filter is wrong.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/versions/{version}": {
      "get": {
        "operationId": "getSchemaVersion",
        "summary": "Get a specific schema revision",
        "tags": [
          "Schemas"
        ],
        "description": "Returns a specific schema revision with full schema content.\n\n**Auth:** none (public endpoint)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "in": "path",
            "name": "version",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "RecordRow and completion JSON Schema definitions plus gate rules for the type. Use the quickStart field for copy-pasteable example payloads.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer",
                      "description": "Schema revision number"
                    },
                    "latestVersion": {
                      "type": "integer",
                      "description": "Latest active revision number"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces (e.g. \"decision\", \"delivery-attempt\"). Customer-defined; no engine semantics."
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label that owns this row. \"local\" for engine-authored; anything else for file-imported schemas."
                    },
                    "manifestDigest": {
                      "type": "string",
                      "description": "sha256:<hex> of the JCS-canonicalized manifest. Federation peers compare schemas by this value."
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ],
                      "description": "How this row was authored. Federation digest-echo treats both identically."
                    },
                    "federatable": {
                      "type": "boolean",
                      "description": "Whether this engine exposes the schema to federated peer hubs. Row-only metadata; not in the canonical manifest."
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for records of this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`; `true`/`false` is an explicit per-type decision. Per-record `share` overrides this. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) applied to records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). An explicit per-record `gateMode` always wins. Types whose purpose is the principal-held verdict set `principal` here so the copy-paste path cannot silently auto-settle. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-signature (firing Server only, V1-FRAME default). `true` = before firing, the firing Server requests a counter-signature from the counterparty's `/federation/v1/co-sign-requests` and attaches it to the Settlement Signal as `counterSignature`. Per-contract-type only (no per-record override). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "When `true` (default), opening a dispute against a record of this type flips `record.status` to DISPUTED while the dispute is in flight (restored to pre-status on resolve/withdraw). When `false`, the record stays at its current status (most often FULFILLED/REMEDIATED/FAILED) and the dispute is observable only via `disputeStatus`/`disputeId`/`disputeCount` on the record body plus `?hasDispute=` and `?disputeStatus=` query filters. Compliance-minded customers (where FULFILLED at time T must remain a historical fact) set this `false` per type. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "When `true` (default), disputes on federated records of this contract type propagate to peers: the originator's dispute lifecycle (open/resolve/withdraw + tier transitions) emits federation outbound jobs that update the peer's record body (`disputeStatus`, `hasDispute`, `disputeCount`, `grounds`, `context`) and write a receiver chain entry. When `false`, disputes stay local to the originator's chain — the peer's record body is unchanged until a RELEASE Settlement Signal fires on overturn. Default-on fits the intra-org federation case (the typical V1 deployment) where counterparty reconciliation benefits from full dispute visibility. Cross-org deployments wanting strict boundary flip to `false` per type. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ACTIVE",
                        "DISABLED"
                      ],
                      "description": "Lifecycle status: ACTIVE or DISABLED"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable example payloads for this type. null when neither schema is registered (rare; a type without either schema cannot be used)."
                    },
                    "recordSchema": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "JSON Schema for record criteria"
                    },
                    "completionSchema": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "JSON Schema for completion evidence"
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "Gate rules configuration for the type."
                    }
                  },
                  "description": "RecordRow and completion JSON Schema definitions plus gate rules for the type. Use the quickStart field for copy-pasteable example payloads."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Version not found. Response carries a recoveryHint listing available active versions (or a did-you-mean for the type when the type itself does not exist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Requested version exists but is DISABLED. Re-enable the type or pick an active version.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher (`/problems/ambiguous-publisher`, body carries `publishers`): more than one publisher offers this type in the org. Add `?publisher=` to pick one, the same as the bare `/v1/schemas/{type}` read.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchSchemaVersion",
        "summary": "Update schema version compatibility mode",
        "tags": [
          "Schemas"
        ],
        "description": "Change the compatibility mode for a specific schema version.\n\nLifecycle state (ACTIVE/DISABLED) is managed at the contract-type level via `PATCH /v1/schemas/{type}/disable` and `/enable`, not per version.\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "minProperties": 1,
                "properties": {
                  "compatibilityMode": {
                    "type": "string",
                    "enum": [
                      "none",
                      "backward",
                      "forward",
                      "full"
                    ]
                  }
                },
                "required": [
                  "compatibilityMode"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope for custom types"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "in": "path",
            "name": "version",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "category": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "maxLength": 100,
                      "description": "Free-form taxonomy of what kind of artifact this Type produces. Customer-defined; no engine semantics."
                    },
                    "compatibilityMode": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label. \"local\" for engine-authored, anything else for imported."
                    },
                    "manifestDigest": {
                      "type": "string",
                      "description": "sha256:<hex> federation-comparable digest."
                    },
                    "trustClass": {
                      "type": "string",
                      "enum": [
                        "local",
                        "imported"
                      ]
                    },
                    "federatable": {
                      "type": "boolean"
                    },
                    "defaultShare": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 sharing default for this contract type. `null` = inherit the global `AGLEDGER_DEFAULT_SHARE`. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "defaultGateMode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Default gate mode (`auto` or `principal`) for records of this type when the create payload omits `gateMode`. `null` = engine default (`auto`). Row-only metadata, NOT in the canonical manifest body."
                    },
                    "coSignRequired": {
                      "type": [
                        "null",
                        "boolean"
                      ],
                      "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. `null`/`false` = signals fire single-sig; `true` = firing Server requests a counter-signature before firing. Row-only metadata, NOT in the canonical manifest body."
                    },
                    "flipRecordStatusOnDispute": {
                      "type": "boolean",
                      "description": "Per-type opt-in for whether opening a dispute flips `record.status` to DISPUTED in flight. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "federateDisputes": {
                      "type": "boolean",
                      "description": "Per-type opt-out for dispute propagation across federation. Default true. See the full doc on this field in the `getSchemaResponse`."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "quickStart": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Minimal valid criteria example — copy and modify. Synthesized from the record schema (prefers the JSON Schema standard `examples` keyword; falls back to required fields with type-driven placeholders)."
                        },
                        "evidence": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": true,
                          "description": "Minimal valid completion evidence example — copy and modify. Null on notarize-only Types (no completion phase, no /completions call to make)."
                        },
                        "tolerance": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Copy-pasteable tolerance example — one entry per registered fieldMapping. The key is the fieldMapping`s `toleranceField` (when declared) or its `ruleId` (the natural fallback both engine and validator accept). Keys ending in `Pct`/`_pct` apply as percentage tolerance (example value 5 = ±5%); other keys apply as absolute tolerance. Null when the type has no fieldMappings registered."
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ],
                          "description": "Present only when the type declares a `defaultGateMode` — include it in the POST /v1/records payload (the engine also applies it when you omit `gateMode`, so the copy-paste path is safe either way). Absent = engine default `auto` (rules engine renders the verdict and auto-settles at completion time; no principal verdict window)."
                        }
                      },
                      "description": "Copy-pasteable starter Record + completion bodies derived from the registered schemas. Returned inline on POST /v1/schemas so the caller does not need a follow-up GET."
                    },
                    "rulesConfig": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string"
                        },
                        "syncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied synchronously during Phase 1 structural validation"
                        },
                        "asyncRuleIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Rule IDs applied asynchronously during Phase 2 gate evaluation"
                        },
                        "fieldMappings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ruleId": {
                                "type": "string"
                              },
                              "criteriaPath": {
                                "type": "string"
                              },
                              "evidencePath": {
                                "type": "string"
                              },
                              "toleranceField": {
                                "type": "string"
                              },
                              "maxTolerance": {
                                "type": "number"
                              },
                              "valueType": {
                                "type": "string"
                              },
                              "expression": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Custom field mappings for gate rules"
                        },
                        "commissionSourceField": {
                          "type": "string",
                          "description": "Dot-notation path to the commission base value field in criteria"
                        }
                      },
                      "description": "The live gate rule wiring (syncRuleIds, asyncRuleIds, fieldMappings) echoed on write so the caller can confirm what the engine will evaluate without a follow-up GET. Same nested shape as GET /v1/schemas/{type}."
                    },
                    "warnings": {
                      "type": "array",
                      "description": "Keywords in the submitted schemas that this validator does not enforce, so they are ignored. Usually a misspelling (`maxLenght` for `maxLength`), which is worth acting on: the constraint the author intended is not applied and every value passes. Absent when there are none. Prefix a deliberate annotation with `x-` to keep it out of this list.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "Location of the keyword within the schema (empty string = root)."
                          },
                          "keyword": {
                            "type": "string",
                            "description": "The unrecognized keyword."
                          },
                          "message": {
                            "type": "string",
                            "description": "What was ignored, and the closest recognized keyword when one is near."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Version not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Ambiguous publisher (`/problems/ambiguous-publisher`, body carries `publishers`): more than one publisher offers this type in the org. Add `?publisher=` so the change lands on the registration you meant.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/check-compatibility": {
      "post": {
        "operationId": "checkSchemaCompatibility",
        "summary": "Check schema compatibility",
        "tags": [
          "Schemas"
        ],
        "description": "Dry-run compatibility check against the latest version.\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordSchema",
                  "completionSchema"
                ],
                "properties": {
                  "recordSchema": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "completionSchema": {
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "record": {
                      "type": "object",
                      "properties": {
                        "compatible": {
                          "type": "boolean"
                        },
                        "changes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "breaking": {
                                "type": "boolean"
                              },
                              "detail": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "completion": {
                      "type": "object",
                      "properties": {
                        "compatible": {
                          "type": "boolean"
                        },
                        "changes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "breaking": {
                                "type": "boolean"
                              },
                              "detail": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/disable": {
      "patch": {
        "operationId": "disableContractType",
        "summary": "Disable a type",
        "tags": [
          "Schemas"
        ],
        "description": "Flips all ACTIVE versions of a type to DISABLED. Disabled types are hidden from discovery (`/v1/schemas`, `/llms.txt`) and cannot be used to create new records, but existing records remain valid. Reversible via `PATCH /v1/schemas/{type}/enable`.\n\n**Auth:** admin (own schemas), platform (any schema).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope (platform only)"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label this disable targeted, always the one the call resolved to. `local` for a type registered here rather than imported; never null, so read it rather than testing for absence to decide whether scoping applied."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "DISABLED"
                      ],
                      "description": "Post-state of the type after this call. Always DISABLED on a 200."
                    },
                    "versionsDisabled": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Type not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Type exists but has no ACTIVE versions to disable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schemas/{type}/enable": {
      "patch": {
        "operationId": "enableContractType",
        "summary": "Enable a disabled type",
        "tags": [
          "Schemas"
        ],
        "description": "Flips all DISABLED versions of a type back to ACTIVE, restoring discovery visibility and new-record eligibility.\n\n**Auth:** admin (own schemas), platform (any schema).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Org scope (platform only)"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$"
            },
            "in": "query",
            "name": "publisher",
            "required": false,
            "description": "Publisher label scope. When omitted and >1 publisher offers this type in the org, the response is 422 with the candidate list."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "path",
            "name": "type",
            "required": true,
            "description": "Type identifier (e.g., notarize-generic-v1)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label this enable targeted, always the one the call resolved to. `local` for a type registered here rather than imported; never null, so read it rather than testing for absence to decide whether scoping applied."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ACTIVE"
                      ],
                      "description": "Post-state of the type after this call. Always ACTIVE on a 200."
                    },
                    "versionsEnabled": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Type not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Type exists but has no DISABLED versions to enable.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/schemas/cache/flush": {
      "post": {
        "operationId": "flushSchemaCache",
        "summary": "Flush schema cache",
        "tags": [
          "Admin"
        ],
        "description": "Emergency cache invalidation for schema registry.\n\n**Auth:** platform only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "flushed": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent-card.json": {
      "get": {
        "operationId": "getAgentCard",
        "summary": "A2A Agent Card",
        "tags": [
          "A2A Protocol"
        ],
        "description": "Returns the A2A Agent Card describing the AGLedger capabilities, skills (types), and authentication requirements. This is the standard A2A discovery endpoint.\n\n**Auth:** None (public)",
        "security": [],
        "responses": {
          "200": {
            "description": "A2A Agent Card.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "A2A Agent Card.",
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/a2a": {
      "post": {
        "operationId": "a2aJsonRpc",
        "summary": "A2A JSON-RPC endpoint",
        "tags": [
          "A2A Protocol"
        ],
        "description": "A2A JSON-RPC 2.0 endpoint. Supports canonical (PascalCase), dotted-prefix, and legacy method names.\n\n**Protocol version:** this endpoint speaks both A2A 0.3 and A2A 1.0, selected by the `A2A-Version` request header. Omit the header (or send `0.3`) for the v0.3 dialect: lowercase task states (`completed`), `user`/`agent` message roles, and the `kind` discriminator. Send `A2A-Version: 1.0` for the v1.0 dialect: proto enum names (`TASK_STATE_COMPLETED`, `ROLE_USER`) and no `kind` field. Under v1.0 the `SendMessage` result is the `SendMessageResponse` payload oneof, so the Task arrives as `result.task` rather than as `result` itself; every other method returns its payload directly in both dialects (`GetTask` and `CancelTask` a bare Task, `ListTasks` a `ListTasksResponse`). Identifiers, method names, params, and `agledger:*` metadata are identical in both. The response echoes the dialect served in `A2A-Version` and sets `Vary: A2A-Version`. An unsupported version is rejected rather than silently downgraded.\n\n**Methods (canonical):**\n- `SendMessage` (aliases: `a2a.SendMessage`, `message/send`) — Dispatch one of the actions below\n- `GetTask` (aliases: `a2a.GetTask`, `tasks/get`) — Retrieve task by ID\n- `CancelTask` (aliases: `a2a.CancelTask`, `tasks/cancel`) — Cancel a task\n- `ListTasks` (alias: `a2a.ListTasks`) — List tasks with auth-scoped filtering\n\n**Supported `SendMessage` actions.** The action name goes in the required `action` field of `params`:\n- `create_record` — Create a new record. Params: { type, criteria, contractVersion?, publisher?, platform?, deadline?, agentId?, performerAgentId?, autoActivate?, operatingMode?, tolerance? }. Requires scope `records:write`.\n- `submit_completion` — Submit completion evidence (performer agent). Params: { recordId, evidence, idempotencyKey? }. Requires scope `completions:write`.\n- `get_status` — Get record status with completions as artifacts. Params: { recordId }. Requires scope `records:read`.\n- `transition` — Transition record state (register, activate, cancel). Params: { recordId, transition, reason? }. Requires scope `records:write`.\n- `accept_proposal` — Performer accepts a PROPOSED record. Params: { recordId }. Requires scope `records:write`.\n- `reject_proposal` — Performer rejects a PROPOSED record. Params: { recordId, reason? }. Requires scope `records:write`.\n- `submit_verdict` — Principal submits an accept/reject verdict on a completion. Params: { recordId, completionId, verdict: \"accept\" | \"reject\", reason? }. Requires scope `records:write`.\n- `open_dispute` — Open a dispute against a record. Params: { recordId, grounds, context? }. `grounds` MUST be one of `equivalent_item`, `fraudulent_completion`, `record_ambiguity`, `pricing_dispute`, `quality_issue`, `verdict_disagreement`, `other` (mirrors REST enum). Requires scope `disputes:read`.\n\n**`ListTasks` params:** `status` (an A2A TaskState, in either dialect spelling: `TASK_STATE_WORKING` or `working`; `state` is accepted as an alias), `contextId`, `pageSize` (max 100), `pageToken`, `historyLength`, `includeArtifacts` (default false), `statusTimestampAfter` (ISO 8601), and `filter` (an AIP-160 subset over `status.state` / `createTime` / `updateTime`). An unrecognized task state or timestamp is rejected with `-32602` and a `recoveryHint` rather than silently matching nothing. To list every task, omit `status` or send the unset enum (`TASK_STATE_UNSPECIFIED`, or the `UNRECOGNIZED` literal a proto client emits for an absent enum); neither is treated as a filter. `historyLength` and `includeArtifacts` are independent: history is returned only when `historyLength` is given (most recent N, `0` for none), and artifacts only when `includeArtifacts` is true.\n\n**`GetTask` params:** `name` (`tasks/<uuid>`, the v1.0 canonical resource name), or `id` / `taskId`. `historyLength` caps the returned history at the most recent N messages; `0` returns none and omitting it returns the full history.\n\n**Per-method scope enforcement:** the `/a2a` route declares no `requiredScopes` (each method needs different scopes); per-action + per-method `assertScopes()` runs inside the handler. Missing-scope errors carry `missingScopes` in the JSON-RPC error envelope.\n\n**Errors:** `error.data` is an array of `@type`-tagged detail objects, per the A2A v1.0 JSON-RPC binding. AGLedger emits a `google.rpc.ErrorInfo` carrying `reason`, `domain`, and a string-valued `metadata` map with the agent-UX hooks (`detail`, `recoveryHint`, `currentState`, `allowedActions`, `refreshUrl`, and any error-specific context). An unsupported `A2A-Version` returns `-32009` (`VERSION_NOT_SUPPORTED`).\n\n**Auth:** Bearer token (admin, agent, or platform)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "jsonrpc",
                      "method"
                    ],
                    "properties": {
                      "jsonrpc": {
                        "type": "string",
                        "enum": [
                          "2.0"
                        ]
                      },
                      "method": {
                        "type": "string",
                        "minLength": 1
                      },
                      "params": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "id": {
                        "type": [
                          "string",
                          "integer"
                        ]
                      }
                    },
                    "additionalProperties": false
                  },
                  {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "required": [
                        "jsonrpc",
                        "method"
                      ],
                      "properties": {
                        "jsonrpc": {
                          "type": "string",
                          "enum": [
                            "2.0"
                          ]
                        },
                        "method": {
                          "type": "string",
                          "minLength": 1
                        },
                        "params": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "id": {
                          "type": [
                            "string",
                            "integer"
                          ]
                        }
                      },
                      "additionalProperties": false
                    }
                  }
                ]
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON-RPC 2.0 response (single object, or array for batch requests per JSON-RPC 2.0 §6).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "JSON-RPC 2.0 response (single object, or array for batch requests per JSON-RPC 2.0 §6).",
                  "oneOf": [
                    {
                      "type": "object",
                      "additionalProperties": true
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  ]
                }
              }
            }
          },
          "204": {
            "description": "Notification (no `id` field on the request) — JSON-RPC 2.0 §4.1 mandates no response body."
          },
          "400": {
            "description": "JSON-RPC parse / validation error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON-RPC parse / validation error."
                }
              }
            }
          },
          "401": {
            "description": "JSON-RPC error envelope for missing/invalid auth.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON-RPC error envelope for missing/invalid auth."
                }
              }
            }
          },
          "403": {
            "description": "JSON-RPC error envelope for forbidden actions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON-RPC error envelope for forbidden actions."
                }
              }
            }
          },
          "429": {
            "description": "JSON-RPC error envelope for rate-limited calls.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON-RPC error envelope for rate-limited calls."
                }
              }
            }
          },
          "500": {
            "description": "JSON-RPC error envelope for internal errors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "JSON-RPC error envelope for internal errors."
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/state-transitions": {
      "post": {
        "operationId": "federationStateTransition",
        "summary": "Submit a cross-Server state transition",
        "tags": [
          "Federation"
        ],
        "description": "Server-to-Server: a peer Server submits a signed record state transition. The receiver verifies the per-request Ed25519 header signature against the peer's published key and returns a signed ack.\n\n**Sign-input format (Ed25519 over UTF-8 bytes):**\n```\nagledger.federation.v1:POST:/federation/v1/state-transitions:<bodyHash>:<timestamp>:<nonce>\n```\n\nWhere `<bodyHash>` is the SHA-256 hex of RFC 8785 (JCS) canonical JSON of the full request body. `<timestamp>` and `<nonce>` ride in the `X-AGLedger-Timestamp` and `X-AGLedger-Nonce` headers — they participate in the sign-input but are NOT body fields. The `agledger.federation.v1:` prefix is mandatory. Full worked example in Node.js and Python: GET `/llms.txt` (Federation Signing Scheme section).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordId",
                  "state",
                  "type",
                  "idempotencyKey"
                ],
                "additionalProperties": false,
                "properties": {
                  "recordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "state": {
                    "type": "string",
                    "enum": [
                      "DRAFT",
                      "PROPOSED",
                      "REGISTERED",
                      "ACTIVE",
                      "COMPLETION_INVALID",
                      "COMPLETION_ACCEPTED",
                      "PENDING_VERDICT",
                      "REVISION_REQUESTED",
                      "FULFILLED",
                      "REMEDIATED",
                      "VERDICT_REJECTED",
                      "DISPUTED",
                      "TIMED_OUT",
                      "PENDING_ARBITRATION",
                      "CANCELLED_PRE_WORK",
                      "CANCELLED_IN_PROGRESS",
                      "REJECTED",
                      "RECORDED"
                    ],
                    "description": "Server-side RecordStatus value (the engine's canonical lifecycle state). Bilateral inbound treats the value as authoritative for what the firing Server asserts; the receiver verifies the signature and projects to its local record (no Hub-side projection — V1 has no Hub)."
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "schemaRef": {
                    "type": "object",
                    "required": [
                      "publisher",
                      "type",
                      "version",
                      "manifestDigest"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "publisher": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                      },
                      "type": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "version": {
                        "type": "string",
                        "pattern": "^[0-9]+(\\.[0-9]+)*$",
                        "maxLength": 20
                      },
                      "manifestDigest": {
                        "type": "string",
                        "pattern": "^sha256:[0-9a-f]{64}$",
                        "description": "sha256:<hex> digest of the canonical manifest bytes."
                      }
                    },
                    "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                  },
                  "principalAgentId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
                    "description": "V1 Additive B: principal agent UUID on the firing Server. Optional for forward-compat with peers that have not upgraded — when both principalAgentId and performerAgentId are absent, the receiver acks the message but does not project to its local records table (counter: agledger_federation_inbound_projection_skipped_total)."
                  },
                  "performerAgentId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
                    "description": "V1 Additive B: performer agent UUID on the firing Server. Same forward-compat ramp as principalAgentId."
                  },
                  "coSignRequired": {
                    "type": "boolean",
                    "description": "Schema-level `coSignRequired` flag echoed on the wire so receivers that have not imported the matching schema can still distinguish \"single-sig type\" from \"bilateral type whose schema is unresolved here.\" Receivers stash it on the projected record so `GET /v1/records/{id}.coSignRequired` reflects the firing Server's truth for federated rows even when the local schema lookup returns null."
                  },
                  "correlationId": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "Customer-supplied work-session group id, echoed across federation when share:true. Receivers project onto records.correlation_id and become queryable via GET /v1/records/search?correlationId=…"
                  },
                  "projectRef": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External project reference (e.g. \"PO-2026-04421\"), echoed across federation when share:true."
                  },
                  "externalTaskId": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External task system id (e.g. CI pipeline run, RPA task id), echoed across federation when share:true."
                  },
                  "platformRef": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External reference id on the payment platform (e.g. a charge/payout id), echoed across federation when share:true alongside the other correlation identifiers. Receivers project onto records.platform_ref so Settlement Signals can be mapped to the payment system without a callback to the originator."
                  },
                  "operatingMode": {
                    "type": "string",
                    "enum": [
                      "cleartext",
                      "encrypted"
                    ],
                    "description": "Origin-side operatingMode echo so the peer body reports the right mode. Without this, encrypted records mis-project as `cleartext` on the peer and dashboards branch wrong (try to render criteria, queue server-side gate evaluation, etc.). Receivers project onto records.operating_mode."
                  },
                  "riskClassification": {
                    "type": "string",
                    "enum": [
                      "unacceptable",
                      "high",
                      "limited",
                      "minimal",
                      "unclassified"
                    ],
                    "description": "EU AI Act risk classification echoed across federation when share:true. Receivers project onto records.risk_classification so the regulator export reflects the inbound record's true risk class."
                  },
                  "euAiActDomain": {
                    "type": "string",
                    "enum": [
                      "biometrics",
                      "critical_infrastructure",
                      "education",
                      "employment",
                      "essential_services",
                      "law_enforcement",
                      "migration",
                      "justice"
                    ],
                    "description": "EU AI Act Annex-III domain echoed across federation when share:true (only set on high-risk records). Receivers project onto records.eu_ai_act_domain."
                  },
                  "parentRecordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
                    "description": "Parent record id on the firing Server. The peer projects it so GET /v1/records/{id} on the receiver carries the delegation parent."
                  },
                  "rootRecordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
                    "description": "Root record id of the delegation tree on the firing Server."
                  },
                  "chainDepth": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Delegation depth (0 = root). Omitted for non-delegated records; receivers preserve a prior non-zero depth if a later sync omits it."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ack",
                    "state",
                    "serverTimestamp",
                    "serverSignature",
                    "applied"
                  ],
                  "properties": {
                    "ack": {
                      "type": "boolean"
                    },
                    "state": {
                      "type": "string",
                      "description": "The state echoed back from the request. Whether the receiver actually projected this state to its local record is on `applied`, not on `ack`."
                    },
                    "serverTimestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "serverSignature": {
                      "type": "string",
                      "description": "Ed25519 signature over `ack:<recordId>:<state>:<serverTimestamp>` with the receiving Server's signing key."
                    },
                    "applied": {
                      "type": "boolean",
                      "description": "True when the receiver projected the transition to its local records table. False when the message was acked but skipped (peer not bound to an org, wire body missing principal/performer agent IDs, or local row already at this exact state). Senders MUST gate downstream effects on this, not on `ack`. Terminal-state conflicts (incoming transition arriving after the local row reached a terminal state) DO NOT return here — those throw 422 with `currentState` + `attemptedState`."
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "peer_unbound",
                        "missing_agent_ids",
                        "same_state"
                      ],
                      "description": "Machine-readable skip code present when `applied: false`. `peer_unbound` — peer Server has no bound_org_id (handshake pre-dates V1 Additive B; operator must revoke + re-handshake). `missing_agent_ids` — wire body did not include principalAgentId / performerAgentId (peer pre-Additive-B). `same_state` — local row was already at this exact state; benign no-op."
                    },
                    "schemaRef": {
                      "type": "object",
                      "required": [
                        "publisher",
                        "type",
                        "version",
                        "manifestDigest"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "publisher": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "version": {
                          "type": "string",
                          "pattern": "^[0-9]+(\\.[0-9]+)*$",
                          "maxLength": 20
                        },
                        "manifestDigest": {
                          "type": "string",
                          "pattern": "^sha256:[0-9a-f]{64}$",
                          "description": "sha256:<hex> digest of the canonical manifest bytes."
                        }
                      },
                      "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable -- the request is well-formed but a domain precondition fails (expired window, state mismatch, unverifiable signature). detail names the offending precondition and recoveryHint says what to try next. The retryable flag is authoritative: false means re-sending the same request cannot succeed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/signals": {
      "post": {
        "operationId": "federationSettlementSignal",
        "summary": "Relay a settlement signal",
        "tags": [
          "Federation"
        ],
        "description": "Server-to-Server: relay a SETTLE/HOLD/RELEASE Settlement Signal from a peer Server to the receiver. The receiver verifies the per-request Ed25519 header signature and returns a signed ack.\n\n**Sign-input format (Ed25519 over UTF-8 bytes):**\n```\nagledger.federation.v1:POST:/federation/v1/signals:<bodyHash>:<timestamp>:<nonce>\n```\n\nWhere `<bodyHash>` is the SHA-256 hex of RFC 8785 (JCS) canonical JSON of the full request body. `<timestamp>` and `<nonce>` ride in the `X-AGLedger-Timestamp` and `X-AGLedger-Nonce` headers — they participate in the sign-input but are NOT body fields. The `agledger.federation.v1:` prefix is mandatory. Full worked example in Node.js and Python: GET `/llms.txt` (Federation Signing Scheme section).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordId",
                  "recommendation",
                  "outcomeHash",
                  "validUntil",
                  "idempotencyKey"
                ],
                "additionalProperties": false,
                "properties": {
                  "recordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "recommendation": {
                    "type": "string",
                    "enum": [
                      "SETTLE",
                      "HOLD",
                      "RELEASE"
                    ]
                  },
                  "outcome": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "accept",
                      "reject",
                      null
                    ]
                  },
                  "outcomeHash": {
                    "type": "string",
                    "minLength": 64,
                    "maxLength": 64
                  },
                  "validUntil": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
                    "description": "Client-side idempotency key (UUID). The receiver caches the signed ack response under this key for 24h; a retry with the same key returns the cached ack without re-projecting."
                  },
                  "reasonCode": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Machine-readable cause for the signal (`AUTO_SETTLE` / `AUTO_SETTLE_WITHIN_TOLERANCE` / `AUTO_FAIL` / `PRINCIPAL_ACCEPT` / `PRINCIPAL_REJECT` / `DISPUTE_OVERTURNED` / `TIMED_OUT` / `REMEDIATED` / `CANCEL_PRE_WORK` / `CANCEL_IN_PROGRESS` / `OVERFLOW_REJECT` / `ARBITRATION_LOCK`). `AUTO_SETTLE_WITHIN_TOLERANCE` marks an auto-settle that cleared only via a non-zero tolerance band. Null on older peer Servers that predate the field."
                  },
                  "failingRuleIds": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string"
                    },
                    "description": "RuleIds that failed when a gate evaluation produced this HOLD. Null for non-rule terminals or older peers."
                  },
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Free-text hint (engine summary or principal verdict notes). Null on older peers."
                  },
                  "counterSignature": {
                    "type": "string",
                    "minLength": 1,
                    "description": "V1 Additive E — bilateral co-sign attachment. Hex Ed25519 signature returned by the counterparty Server's POST /federation/v1/co-sign-requests over the canonical co-sign payload. Optional; present only when the firing contract type opted into co-sign (`coSignRequired=true`). When present, downstream payment systems can verify both the firing Server's signature on the signal and the counterparty's counter-signature on the co-sign payload, giving stronger non-repudiation than the single-sig default."
                  },
                  "schemaRef": {
                    "type": "object",
                    "required": [
                      "publisher",
                      "type",
                      "version",
                      "manifestDigest"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "publisher": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                      },
                      "type": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "version": {
                        "type": "string",
                        "pattern": "^[0-9]+(\\.[0-9]+)*$",
                        "maxLength": 20
                      },
                      "manifestDigest": {
                        "type": "string",
                        "pattern": "^sha256:[0-9a-f]{64}$",
                        "description": "sha256:<hex> digest of the canonical manifest bytes."
                      }
                    },
                    "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "relayed",
                    "serverSignature",
                    "serverTimestamp",
                    "applied"
                  ],
                  "properties": {
                    "relayed": {
                      "type": "boolean"
                    },
                    "serverSignature": {
                      "type": "string",
                      "description": "Ed25519 signature over `signal:<recordId>:<recommendation>:<serverTimestamp>` with the receiving Server's signing key."
                    },
                    "serverTimestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "applied": {
                      "type": "boolean",
                      "description": "True when the receiver projected the signal onto its local row's metadata. False when acked but skipped (peer not bound to an org). Note: the `signal_before_state` skip throws 404 (paired state-transition still in flight); callers never see `applied: false` together with that skip on a 200 response."
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "peer_unbound"
                      ],
                      "description": "Machine-readable skip code present when `applied: false`."
                    },
                    "schemaRef": {
                      "type": "object",
                      "required": [
                        "publisher",
                        "type",
                        "version",
                        "manifestDigest"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "publisher": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "version": {
                          "type": "string",
                          "pattern": "^[0-9]+(\\.[0-9]+)*$",
                          "maxLength": 20
                        },
                        "manifestDigest": {
                          "type": "string",
                          "pattern": "^sha256:[0-9a-f]{64}$",
                          "description": "sha256:<hex> digest of the canonical manifest bytes."
                        }
                      },
                      "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable -- the request is well-formed but a domain precondition fails (expired window, state mismatch, unverifiable signature). detail names the offending precondition and recoveryHint says what to try next. The retryable flag is authoritative: false means re-sending the same request cannot succeed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/disputes": {
      "post": {
        "operationId": "federationDisputeProtocol",
        "summary": "Project a dispute lifecycle event from a peer",
        "tags": [
          "Federation"
        ],
        "description": "Server-to-Server: relay a dispute lifecycle event (opened / resolved / withdrawn) from the originator to a peer that holds a federated projection of the record. The receiver updates its local record body (`disputeStatus`, `hasDispute`, `disputeCount`, `grounds`) and appends a FEDERATION_STATE_SYNC chain entry with `kind: 'dispute'`. Gated on the per-contract `federateDisputes` toggle (default true); the originator suppresses the POST when the firing contract type opted out. Wire body carries structural fields only (no evidence — that stays on the originator and is reachable via GET /v1/records/{id}/dispute/evidence). Idempotent on (idempotencyKey, peer_hub_id) like state-transition and signal.\n\n**Sign-input format (Ed25519 over UTF-8 bytes):**\n```\nagledger.federation.v1:POST:/federation/v1/disputes:<bodyHash>:<timestamp>:<nonce>\n```\n\nWhere `<bodyHash>` is the SHA-256 hex of RFC 8785 (JCS) canonical JSON of the full request body. `<timestamp>` and `<nonce>` ride in the `X-AGLedger-Timestamp` and `X-AGLedger-Nonce` headers — they participate in the sign-input but are NOT body fields. The `agledger.federation.v1:` prefix is mandatory. Full worked example in Node.js and Python: GET `/llms.txt` (Federation Signing Scheme section).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordId",
                  "action",
                  "disputeId",
                  "disputeStatus",
                  "idempotencyKey"
                ],
                "additionalProperties": false,
                "properties": {
                  "recordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "opened",
                      "resolved",
                      "withdrawn",
                      "escalated"
                    ]
                  },
                  "disputeId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "disputeStatus": {
                    "type": "string",
                    "description": "Post-action dispute status (e.g. `EVIDENCE_WINDOW` on opened, `RESOLVED` on resolved, `WITHDRAWN` on withdrawn)."
                  },
                  "tier": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3
                  },
                  "grounds": {
                    "type": "string",
                    "enum": [
                      "equivalent_item",
                      "fraudulent_completion",
                      "record_ambiguity",
                      "pricing_dispute",
                      "quality_issue",
                      "verdict_disagreement",
                      "other"
                    ]
                  },
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "OVERTURNED",
                      "UPHELD",
                      "SPLIT"
                    ]
                  },
                  "initiatedByRole": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "schemaRef": {
                    "type": "object",
                    "required": [
                      "publisher",
                      "type",
                      "version",
                      "manifestDigest"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "publisher": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                      },
                      "type": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "version": {
                        "type": "string",
                        "pattern": "^[0-9]+(\\.[0-9]+)*$",
                        "maxLength": 20
                      },
                      "manifestDigest": {
                        "type": "string",
                        "pattern": "^sha256:[0-9a-f]{64}$",
                        "description": "sha256:<hex> digest of the canonical manifest bytes."
                      }
                    },
                    "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ack",
                    "serverSignature",
                    "serverTimestamp",
                    "applied"
                  ],
                  "properties": {
                    "ack": {
                      "type": "boolean"
                    },
                    "serverSignature": {
                      "type": "string",
                      "description": "Ed25519 signature over `dispute:<recordId>:<action>:<serverTimestamp>` with the receiving Server's signing key."
                    },
                    "serverTimestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "applied": {
                      "type": "boolean",
                      "description": "True when the receiver projected the dispute event to its local records table. False when acked but skipped (peer not bound to an org, no local row for this recordId). Senders gate dispute-lifecycle audit (\"did the peer record the dispute?\") on this rather than the bare `ack`."
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "peer_unbound",
                        "signal_before_state"
                      ],
                      "description": "Machine-readable skip code present when `applied: false`. `signal_before_state` here means \"dispute arrived before any state-transition\" — the peer has no local row to project the dispute onto."
                    },
                    "schemaRef": {
                      "type": "object",
                      "required": [
                        "publisher",
                        "type",
                        "version",
                        "manifestDigest"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "publisher": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "version": {
                          "type": "string",
                          "pattern": "^[0-9]+(\\.[0-9]+)*$",
                          "maxLength": 20
                        },
                        "manifestDigest": {
                          "type": "string",
                          "pattern": "^sha256:[0-9a-f]{64}$",
                          "description": "sha256:<hex> digest of the canonical manifest bytes."
                        }
                      },
                      "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/co-sign-requests": {
      "post": {
        "operationId": "federationCoSignRequest",
        "summary": "Counter-sign a peer's Settlement Signal payload",
        "tags": [
          "Federation"
        ],
        "description": "V1 Additive E — bilateral co-signed Settlement Signal opt-in. The firing Server POSTs this request before issuing a terminal Settlement Signal when the contract type has `coSignRequired=true`. The receiver verifies the peer signature, looks up its local record, confirms the asserted terminal state matches and the local contract type also has `coSignRequired=true`, and returns an Ed25519 counter-signature over the canonical co-sign payload. The firing Server then attaches that counter-signature to the outbound Settlement Signal as `counterSignature`. Failure modes: 404 (record unknown), 422 (state mismatch / co-sign not configured / outcomeHash divergence). Single-sig signals do NOT call this endpoint.\n\n**Sign-input format (Ed25519 over UTF-8 bytes):**\n```\nagledger.federation.v1:POST:/federation/v1/co-sign-requests:<bodyHash>:<timestamp>:<nonce>\n```\n\nWhere `<bodyHash>` is the SHA-256 hex of RFC 8785 (JCS) canonical JSON of the full request body. `<timestamp>` and `<nonce>` ride in the `X-AGLedger-Timestamp` and `X-AGLedger-Nonce` headers — they participate in the sign-input but are NOT body fields. The `agledger.federation.v1:` prefix is mandatory. Full worked example in Node.js and Python: GET `/llms.txt` (Federation Signing Scheme section).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordId",
                  "recommendation",
                  "outcomeHash",
                  "state",
                  "performerHubId",
                  "validUntil",
                  "idempotencyKey"
                ],
                "additionalProperties": false,
                "properties": {
                  "recordId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "recommendation": {
                    "type": "string",
                    "enum": [
                      "SETTLE",
                      "HOLD",
                      "RELEASE"
                    ]
                  },
                  "outcome": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "accept",
                      "reject",
                      null
                    ]
                  },
                  "outcomeHash": {
                    "type": "string",
                    "minLength": 64,
                    "maxLength": 64
                  },
                  "state": {
                    "type": "string",
                    "description": "The asserted terminal RecordStatus on the firing Server. The receiver verifies its local record sits at this state."
                  },
                  "performerHubId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "validUntil": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "schemaRef": {
                    "type": "object",
                    "required": [
                      "publisher",
                      "type",
                      "version",
                      "manifestDigest"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "publisher": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "Publisher label (`local` for engine-authored, free-form coordination label otherwise)."
                      },
                      "type": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "version": {
                        "type": "string",
                        "pattern": "^[0-9]+(\\.[0-9]+)*$",
                        "maxLength": 20
                      },
                      "manifestDigest": {
                        "type": "string",
                        "pattern": "^sha256:[0-9a-f]{64}$",
                        "description": "sha256:<hex> digest of the canonical manifest bytes."
                      }
                    },
                    "description": "Locally-held manifest identity for the type carried in this federation message. Receiver-side verification: org-scoped (publisher, type, version) lookup; on match admit; on digest mismatch 422 `/problems/schema-digest-mismatch` with both digests; on not-found existing unknown-type path. Optional today (WARN+counter when absent); a future release may require it on specific routes."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "coSigned",
                    "counterSignature",
                    "serverTimestamp"
                  ],
                  "properties": {
                    "coSigned": {
                      "type": "boolean"
                    },
                    "counterSignature": {
                      "type": "string",
                      "description": "Hex Ed25519 signature over the canonical co-sign payload (recordId, recommendation, outcomeHash, state, performerHubId, validUntil)."
                    },
                    "serverTimestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable -- the request is well-formed but a domain precondition fails (expired window, state mismatch, unverifiable signature). detail names the offending precondition and recoveryHint says what to try next. The retryable flag is authoritative: false means re-sending the same request cannot succeed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/reputation/contribute": {
      "post": {
        "operationId": "contributeReputation",
        "summary": "Submit a reputation contribution for an agent",
        "tags": [
          "Federation"
        ],
        "description": "A peer Server submits aggregate record statistics for an agent over an ISO week period. Anti-Sybil: the contributing peer must have been registered for at least 30 days by default — fresh peers are rejected with 403 + recoveryHint listing how many days remain until the window unlocks. Dev/test environments can override the floor via `AGLEDGER_REPUTATION_PEER_AGE_MIN_MS` (milliseconds; set to 0 to disable the gate). Peer reputation reads are not gated and are available immediately via GET /federation/v1/agents/{agentId}/reputation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "agentId",
                  "type",
                  "period",
                  "totalRecords",
                  "totalVerified",
                  "totalPassed"
                ],
                "additionalProperties": false,
                "properties": {
                  "agentId": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "period": {
                    "type": "string",
                    "pattern": "^[0-9]{4}-W[0-9]{2}$",
                    "description": "ISO week, e.g. 2026-W14"
                  },
                  "totalRecords": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "totalVerified": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "totalPassed": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "signature": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "contributed"
                  ],
                  "properties": {
                    "contributed": {
                      "type": "boolean"
                    },
                    "duplicate": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/agents/{agentId}/reputation": {
      "get": {
        "operationId": "getAgentReputation",
        "summary": "Query reputation scores for an agent",
        "tags": [
          "Federation"
        ],
        "description": "Returns composite reputation scores for an agent across types. Optionally filter by a specific type.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "in": "query",
            "name": "type",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agentId",
                    "scores"
                  ],
                  "properties": {
                    "agentId": {
                      "type": "string"
                    },
                    "scores": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "type",
                          "reliability",
                          "accuracy",
                          "efficiency",
                          "compositeScore",
                          "confidence",
                          "sampleSize"
                        ],
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "reliability": {
                            "type": "number"
                          },
                          "accuracy": {
                            "type": "number"
                          },
                          "efficiency": {
                            "type": "number"
                          },
                          "compositeScore": {
                            "type": "number"
                          },
                          "confidence": {
                            "type": "number"
                          },
                          "sampleSize": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/peer": {
      "post": {
        "operationId": "peerHandshake",
        "summary": "Initiate a Server-to-Server peering handshake",
        "tags": [
          "Federation Peering"
        ],
        "description": "Register a bilateral peering relationship between two Servers. The initiating Server provides its hub_id, signing key, encryption key, a peering token, and an initial agent directory snapshot.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "peerHubId",
                  "peerUrl",
                  "signingPublicKey",
                  "encryptionPublicKey",
                  "peeringToken",
                  "boundOrgId",
                  "agentDirectory"
                ],
                "additionalProperties": false,
                "properties": {
                  "peerHubId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Initiating peer Server hub_id (UUID v7) — must match the X-AGLedger-Peer-Hub-Id header on subsequent signed messages from this peer."
                  },
                  "peerUrl": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "Base URL for outbound delivery to the initiating peer (e.g. https://server-b.example.com). The receiving Server stores this and uses it as the URL base for cross-peer state-transition / signal POSTs. Rejected: a non-http(s) scheme, a raw backslash, embedded control characters (tab/newline), an empty authority such as `https:///peer`, and embedded credentials, because URL parsers silently reinterpret those into a different host than the one written. Private and internal targets are refused at connect time by the SSRF resolver, with SSRF_ALLOW_CIDRS as the escape hatch."
                  },
                  "signingPublicKey": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Initiating Server's Ed25519 signing public key, SPKI-DER, base64-encoded (`createPublicKey(privateKey).export({format:\"der\", type:\"spki\"}).toString(\"base64\")`). The receiver verifies subsequent federation messages from this peer against this key. GET /federation/v1/admin/instance returns it on the initiating Server in the same wire format.",
                    "example": "MCowBQYDK2VwAyEA/QqBnpbWVUe6mqyiq8WAWJg9OmKAvNNUx0V8j+u2nUw="
                  },
                  "encryptionPublicKey": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Initiating Server's federation encryption public key (X25519, a separate keypair from the Ed25519 signing key), SPKI-DER, base64-encoded. Exchanged during the handshake for the encrypted-payload channel; V1 does not yet encrypt federation payloads with it. GET /federation/v1/admin/instance returns it on the initiating Server.",
                    "example": "MCowBQYDK2VuAyEAPaCCndcCaAE7eNP+Wc/LqRUm4uQ3xQfIsB8mzv2zgW4="
                  },
                  "peeringToken": {
                    "type": "string",
                    "minLength": 16,
                    "maxLength": 256,
                    "description": "Single-use bootstrap secret minted by the RECEIVING Server's operator at POST /federation/v1/admin/peering-tokens (platform scope) and shared out-of-band with the initiating Server's operator. The token is the cross-org auth credential for this handshake — the receiving Server's platform Bearer is NOT required. Token is SHA-256 hashed at mint, validated + consumed in the same tx as the peer insert, and expires 7 days after mint."
                  },
                  "boundOrgId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "V1 Additive B: local orgId that owns inbound projections from this peer. When the firing Server posts state-transitions and signals, the receiver projects them into rows in this org. Must reference an existing row in the local orgs table — unknown id returns 422 with a hint pointing at the operator's org list."
                  },
                  "agentDirectory": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "agentId",
                        "contractTypes"
                      ],
                      "properties": {
                        "agentId": {
                          "type": "string",
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "contractTypes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "minItems": 1
                        },
                        "displayName": {
                          "type": "string",
                          "maxLength": 255
                        }
                      }
                    },
                    "maxItems": 1000
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "peered",
                    "peerId",
                    "serverSigningPublicKey",
                    "serverEncryptionPublicKey"
                  ],
                  "properties": {
                    "peered": {
                      "type": "boolean"
                    },
                    "peerId": {
                      "type": "string"
                    },
                    "serverSigningPublicKey": {
                      "type": "string"
                    },
                    "serverEncryptionPublicKey": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable — the peering token is unknown, already consumed, or expired, or boundOrgId references no local org. Mint a fresh token via POST /federation/v1/admin/peering-tokens (platform scope) and confirm boundOrgId against the operator's org list.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/peer/agent-sync": {
      "post": {
        "operationId": "receivePeerAgentDirectorySync",
        "summary": "Receive an agent directory update from a peer Server",
        "tags": [
          "Federation Peering"
        ],
        "description": "A peer Server pushes a full or incremental agent directory update. Remote agents are upserted and the directory hash is updated.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "peerHubId",
                  "agents",
                  "directoryHash"
                ],
                "additionalProperties": false,
                "properties": {
                  "peerHubId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "agents": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "agentId",
                        "contractTypes"
                      ],
                      "properties": {
                        "agentId": {
                          "type": "string",
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "contractTypes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "minItems": 1
                        },
                        "displayName": {
                          "type": "string",
                          "maxLength": 255
                        }
                      }
                    },
                    "maxItems": 5000
                  },
                  "directoryHash": {
                    "type": "string",
                    "minLength": 64,
                    "maxLength": 64
                  },
                  "since": {
                    "type": "string",
                    "format": "date-time",
                    "description": "If present, this is an incremental sync since this timestamp"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "federationPeerSignature": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "synced",
                    "agentsUpserted"
                  ],
                  "properties": {
                    "synced": {
                      "type": "boolean"
                    },
                    "agentsUpserted": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/instance": {
      "get": {
        "operationId": "getFederationInstance",
        "summary": "Get this Server's federation INSTANCE_ID and public keys",
        "tags": [
          "Federation Admin"
        ],
        "description": "Returns the value used as `peer_hub_id` when this Server initiates peering or signs outbound messages. When initiating a bilateral handshake against a peer, the body's `peerHubId` MUST equal this value — the peer's auth middleware looks up federation_peers by the X-AGLedger-Peer-Hub-Id header, which the outbound worker fills with INSTANCE_ID. A handshake with any other id commits successfully but every subsequent signed message 401s with \"Unknown peer hub\". Returns `instanceId: null` and `configured: false` unless this Server has all three of the things a handshake needs: a hub-id that is a UUID, a signing key and an encryption key. A hub-id that is set but not a UUID reads as null here, because `peerHubId` is declared `format: uuid` on the handshake and a non-UUID is not an identity a peer can store. `nextSteps` names every missing piece and the variable to set. Also returns the published handshake-time public keys (SPKI-DER, base64-encoded). The remote peer verifies subsequent signed messages from this Server against `signingPublicKey` (Ed25519); `encryptionPublicKey` is a separate X25519 keypair reserved for the encrypted-payload channel.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "instanceId",
                    "configured",
                    "nextSteps"
                  ],
                  "properties": {
                    "instanceId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "AGLEDGER_INSTANCE_ID, or AGLEDGER_ORGANIZATION_ID as fallback. Null when neither is set to a UUID. Safe to paste verbatim as a peer's `peerHubId`: when it is non-null it has already passed the same format check the handshake applies."
                    },
                    "configured": {
                      "type": "boolean",
                      "description": "True only when this Server can complete a handshake: a UUID hub-id plus both federation keys. Not a report that some value is set."
                    },
                    "signingPublicKey": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "SPKI-DER public half of AGLEDGER_FEDERATION_SIGNING_KEY, base64-encoded. Hand to peer operators out-of-band — peers paste this as `signingPublicKey` on their POST /federation/v1/peer handshake body. Null when AGLEDGER_FEDERATION_SIGNING_KEY is not configured."
                    },
                    "encryptionPublicKey": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "SPKI-DER public half of AGLEDGER_FEDERATION_ENCRYPTION_KEY (an X25519 keypair, separate from the Ed25519 signing key), base64-encoded. V1 exchanges it during the handshake but does not yet encrypt federation payloads with it. Null when AGLEDGER_FEDERATION_ENCRYPTION_KEY is not configured."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/peers": {
      "get": {
        "operationId": "listPeerServers",
        "summary": "List peered Servers",
        "tags": [
          "Federation Admin"
        ],
        "description": "List all bilateral Server peering relationships with status, sync health, and agent directory hash.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "suspended",
                "revoked"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "peerId",
                          "peerHubId",
                          "peerUrl",
                          "status",
                          "createdAt"
                        ],
                        "properties": {
                          "peerId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "peerHubId": {
                            "type": "string"
                          },
                          "peerUrl": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "suspended",
                              "revoked"
                            ]
                          },
                          "agentDirectoryHash": {
                            "type": "string",
                            "nullable": true
                          },
                          "lastSyncAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "tokenExpiresAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/peers/{hubId}/revoke": {
      "post": {
        "operationId": "revokePeerServer",
        "summary": "Revoke a peered Server",
        "tags": [
          "Federation Admin"
        ],
        "description": "Revoke a bilateral peering relationship. All remote agents from this peer are deleted. Body is optional — pass `{ \"reason\": \"...\" }` for an audit-chain note, or POST with no body to revoke without a reason.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "in": "path",
            "name": "hubId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "revoked"
                  ],
                  "properties": {
                    "revoked": {
                      "type": "boolean"
                    },
                    "remoteAgentsDeleted": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict -- the request collides with the current state of the resource (e.g. a duplicate, or an action not valid in the current lifecycle state). See currentState/allowedActions or detail for the conflicting condition.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/peers/{hubId}": {
      "delete": {
        "operationId": "deleteRevokedPeerServer",
        "summary": "Hard-delete a tombstoned (revoked) peer Server",
        "tags": [
          "Federation Admin"
        ],
        "description": "Permanently removes a peer row that has already been revoked. Allows the same peer hub_id to be re-registered from scratch via POST /federation/v1/peer with a fresh peering token. Refuses to delete active or suspended peers — those must be revoked first via POST /federation/v1/admin/peers/{hubId}/revoke. The remote-agents directory is already deleted at revoke time, so this call only removes the federation_peers row itself.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "in": "path",
            "name": "hubId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted",
                    "peerHubId",
                    "nextSteps"
                  ],
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "peerHubId": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict -- the request collides with the current state of the resource (e.g. a duplicate, or an action not valid in the current lifecycle state). See currentState/allowedActions or detail for the conflicting condition.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getPeerDetail",
        "summary": "Get a single peer Server detail",
        "tags": [
          "Federation Admin"
        ],
        "description": "Get detailed information about a specific peered Server by its hub_id.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "in": "path",
            "name": "hubId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Peer Server detail.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "peerId",
                    "peerHubId",
                    "peerUrl",
                    "status",
                    "createdAt"
                  ],
                  "properties": {
                    "peerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "peerHubId": {
                      "type": "string"
                    },
                    "peerUrl": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "suspended",
                        "revoked"
                      ]
                    },
                    "agentDirectoryHash": {
                      "type": "string",
                      "nullable": true
                    },
                    "lastSyncAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "tokenExpiresAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "description": "Peer Server detail."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/peering-tokens": {
      "post": {
        "operationId": "generatePeeringToken",
        "summary": "Generate a peering token for Server-to-Server handshake",
        "tags": [
          "Federation Admin"
        ],
        "description": "Generate a random peering token for out-of-band sharing with a peer Server. The admin shares this token with the peer Server operator, who uses it in the peering handshake.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Optional label identifying the intended peer"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "peeringToken",
                    "createdAt",
                    "expiresAt"
                  ],
                  "properties": {
                    "peeringToken": {
                      "type": "string",
                      "description": "Raw peering token — share out-of-band with the peer Server operator. Single-use: the first successful handshake against this Server consumes the token; any replay or unknown token returns 401."
                    },
                    "label": {
                      "type": "string",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Default 7 days from mint. After this point the handshake rejects the token even if unused."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/peers/{hubId}/resync": {
      "post": {
        "operationId": "resyncPeer",
        "summary": "Reset local sync state for a peer Server",
        "tags": [
          "Federation Admin"
        ],
        "description": "Clears `last_sync_at` and `agent_directory_hash` for the named peer so the next inbound `/peer/agent-sync` push from the peer is treated as a full sync. **This does NOT pull the peer's directory** — V1 federation has no pull protocol; agent-sync is push-only from each Server. To force a refresh of agent metadata that has changed since the original handshake, ask the peer's operator to re-call `POST /federation/v1/peer` against this Server with the updated `agentDirectory` payload, or wait for their next outbound message (which carries the directory hash and triggers a re-push if it has drifted).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "in": "path",
            "name": "hubId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "localSyncStateReset"
                  ],
                  "properties": {
                    "localSyncStateReset": {
                      "type": "boolean",
                      "description": "True when the peer was found and its `last_sync_at` / `agent_directory_hash` were cleared."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/dlq": {
      "get": {
        "operationId": "listFederationDlq",
        "summary": "List federation outbound DLQ entries",
        "tags": [
          "Federation Admin"
        ],
        "description": "Returns federation-outbound jobs that exhausted pg-boss retry budget and landed in the DLQ. Use this to triage stuck deliveries before calling `POST /federation/v1/admin/dlq/recover`. Each row carries the full job payload (kind, peerHubId, recordId, body) so an operator can see which records, peers, and message kinds are stuck. Paginated — pass `cursor` or `offset` to page past `limit`.",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "total",
                    "nextCursor",
                    "hasMore"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "data",
                          "createdOn",
                          "kind",
                          "peerHubId",
                          "recordId"
                        ],
                        "additionalProperties": false,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "pg-boss job id (DLQ row)."
                          },
                          "data": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Original outbound job body (kind=state-transition|signal, peerHubId, recordId, body)."
                          },
                          "createdOn": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "kind": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "state-transition | signal"
                          },
                          "peerHubId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "recordId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/federation/v1/admin/dlq/recover": {
      "post": {
        "operationId": "recoverFederationDlq",
        "summary": "Re-enqueue stuck federation outbound DLQ jobs",
        "tags": [
          "Federation Admin"
        ],
        "description": "V1 federated-gates operator surface — manually replay stuck federation outbound jobs after fixing the peer-side configuration (e.g. registering the matching contract type with `coSignRequired:true`, rotating signing keys, restoring peer URL). Re-enqueues to `federation-outbound` and removes the DLQ row on success; jobs that fail again will land back in the DLQ with their fresh failure context. A periodic background sweep handles eligible jobs every 10 minutes — this endpoint is the manual override that doesn't wait for the next sweep tick.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "default": 100,
                    "description": "Cap on the number of DLQ jobs to inspect this call. Re-run if `inspected === limit` to drain in batches."
                  },
                  "dryRun": {
                    "type": "boolean",
                    "default": false,
                    "description": "When true, returns the count of jobs that would be replayed without touching the queue."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recovered",
                    "inspected",
                    "dryRun"
                  ],
                  "properties": {
                    "recovered": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Jobs successfully re-enqueued and removed from DLQ."
                    },
                    "inspected": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Jobs examined this call (capped by `limit`)."
                    },
                    "dryRun": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records": {
      "post": {
        "operationId": "createRecord",
        "summary": "Create a new record in CREATED status",
        "tags": [
          "Records"
        ],
        "description": "Creates a record in CREATED status. The record must be activated (transition to ACTIVE) before completions can be submitted against it. Every record has a named agent principal. Agent callers default the principal to themselves; admin and platform callers must name a principal — explicitly via `principalAgentId`, or implicitly by setting `performerAgentId` (the named performer becomes the principal, a self-commitment). Every record starts in CREATED. When `performerAgentId` differs from `principalAgentId`, the principal opens the proposal handshake via POST /v1/records/{id}/transition with `{ \"action\": \"propose\" }`; the performer then accepts (POST /accept), counter-proposes (POST /counter-propose), or rejects (POST /reject) before the principal activates. When the principal equals the performer, the record is self-principal (selfPrincipal=true on the response) and auto-verdict is blocked. The criteria object must conform to the JSON Schema for the specified type (use GET /schemas/:type to inspect). Supports idempotency via the `Idempotency-Key` header.\n\n**Auth:** admin, agent, platform — must hold scope `records:write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "criteria"
                ],
                "properties": {
                  "orgId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Org that owns this record. Defaulted from auth for admin and agent callers; required for platform callers."
                  },
                  "principalAgentId": {
                    "type": "string",
                    "format": "uuid",
                    "minLength": 36,
                    "maxLength": 36,
                    "description": "Named accountable party (agent). Defaults to the calling agent for agent callers; for admin/platform callers, defaults to `performerAgentId` if set (self-commitment via the named performer). A record naming a principal must be created by that principal's own key or an org-admin key — an agent key naming a different agent here is rejected with 403."
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "description": "Type identifier (e.g., notarize-generic-v1). Use GET /v1/schemas to list available types."
                  },
                  "contractVersion": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10,
                    "description": "Schema version for the type. Defaults to the latest active version."
                  },
                  "publisher": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Publisher label pinning WHICH registration of `type` this record binds to. Only needed when two publishers offer the same `record_type` in this org (e.g. an imported peer manifest alongside a local registration) — that case returns 422 `/problems/ambiguous-publisher` with the candidate list rather than picking one. GET /v1/schemas carries `publisher` on every row."
                  },
                  "platform": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "description": "Payment platform label (e.g., stripe-acp, google-ap2). Defaults to \"generic\"."
                  },
                  "platformRef": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External reference ID on the payment platform"
                  },
                  "projectRef": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External project reference for grouping related records"
                  },
                  "externalTaskId": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "External task system ID (e.g., CI pipeline run, RPA task ID, workflow step)"
                  },
                  "criteria": {
                    "type": "object",
                    "maxProperties": 100,
                    "description": "Acceptance criteria per the type schema"
                  },
                  "tolerance": {
                    "type": "object",
                    "properties": {
                      "quantityPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMargin": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMarginPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "graceSeconds": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "Deadline grace window, in seconds. NOT a gate-evaluation band: it extends the record's effective expiry to `deadline + graceSeconds`, so a completion submitted late but within the window is accepted instead of timing out. Only meaningful on a record that carries a `deadline`; the same effective deadline governs both the in-transaction submit check and the background expiry sweep."
                      },
                      "budgetMargin": {
                        "type": "number",
                        "minimum": 0
                      }
                    },
                    "additionalProperties": {
                      "type": "number",
                      "minimum": 0
                    },
                    "description": "Per-record tolerance values. Most keys are gate-evaluation bands (e.g. quantityPct for quantity deviation). One key is not a band: graceSeconds is a deadline grace window (effective expiry = deadline + graceSeconds)."
                  },
                  "deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO 8601 deadline; record auto-expires after this time"
                  },
                  "performerAgentId": {
                    "type": "string",
                    "format": "uuid",
                    "minLength": 36,
                    "maxLength": 36,
                    "description": "Agent assigned to fulfill this record (optional at creation). When set and distinct from `principalAgentId`, opens the proposal handshake on activate."
                  },
                  "parentRecordId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Parent record ID for building delegation chains"
                  },
                  "commissionPct": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Commission percentage for the performer (0-100)"
                  },
                  "operatingMode": {
                    "type": "string",
                    "enum": [
                      "cleartext",
                      "encrypted"
                    ],
                    "default": "cleartext",
                    "description": "Operating mode. `cleartext`: server reads both criteria and evidence and runs full Phase-1 + Phase-2 gate evaluation. `encrypted`: completion **evidence** is server-opaque (must be the AES-256-GCM envelope; server never decrypts), so the verdict is principal-led via POST /v1/records/{id}/verdict. **Encryption scope is evidence-only — criteria remains server-readable** for tolerance evaluation, rule matching, and audit-export legibility. If you need criteria privacy too, commit to it off-record and store only a hash inside criteria. Encrypted mode requires gateMode principal; auto is rejected at creation."
                  },
                  "gateMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "principal"
                    ],
                    "description": "Gate mode: auto (rules engine renders the verdict and auto-settles) or principal (engine runs an advisory pass when rules exist, then the principal submits accept/reject via POST /v1/records/{id}/verdict). Omit to inherit the contract type's `defaultGateMode` (see GET /v1/schemas/{type}); when the type declares none, the engine default is `auto`."
                  },
                  "riskClassification": {
                    "type": "string",
                    "enum": [
                      "unacceptable",
                      "high",
                      "limited",
                      "minimal",
                      "unclassified"
                    ],
                    "default": "unclassified",
                    "description": "EU AI Act risk classification"
                  },
                  "euAiActDomain": {
                    "type": "string",
                    "enum": [
                      "biometrics",
                      "critical_infrastructure",
                      "education",
                      "employment",
                      "essential_services",
                      "law_enforcement",
                      "migration",
                      "justice"
                    ],
                    "description": "EU AI Act high-risk domain (only when riskClassification=high)"
                  },
                  "humanOversight": {
                    "type": "object",
                    "description": "Human oversight designation per EU AI Act Art. 14. Required: overseerName, overseerRole, authorityScope, designatedAt (date-time). Optional: overseerContact. No additional properties.",
                    "properties": {
                      "overseerName": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerRole": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerContact": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "authorityScope": {
                        "type": "string",
                        "maxLength": 2000
                      },
                      "designatedAt": {
                        "type": "string",
                        "format": "date-time"
                      }
                    },
                    "required": [
                      "overseerName",
                      "overseerRole",
                      "authorityScope",
                      "designatedAt"
                    ],
                    "additionalProperties": false
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "maxProperties": 50,
                    "description": "Arbitrary key-value data for customer use (max 10KB)"
                  },
                  "maxSubmissions": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "Maximum number of completion submissions allowed (default: unlimited). When reached, no further revisions can be requested."
                  },
                  "constraintInheritance": {
                    "type": "string",
                    "enum": [
                      "none",
                      "advisory",
                      "enforced"
                    ],
                    "default": "none",
                    "description": "Constraint inheritance mode for delegation chains. none: no inheritance (default). advisory: allow but audit when child exceeds parent bounds. enforced: block child creation if exceeds parent."
                  },
                  "enforcementOverrides": {
                    "type": "object",
                    "properties": {
                      "toleranceEnforcement": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ]
                      },
                      "deadlineEnforcement": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ]
                      },
                      "schemaValidation": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ]
                      },
                      "maxSubmissionsMode": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ]
                      },
                      "expressionRuleMode": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ]
                      }
                    },
                    "additionalProperties": false,
                    "description": "Per-record enforcement overrides. Can only relax org settings (not tighten). Requires org allowRecordOverrides=true."
                  },
                  "dependsOn": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 20,
                    "description": "Informational dependency references to other record IDs (no activation gating)"
                  },
                  "autoActivate": {
                    "type": "boolean",
                    "default": false,
                    "description": "When true, the record is created and immediately activated (CREATED → ACTIVE) in a single request. The audit trail records all internal transitions. Default: false."
                  },
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "success",
                      "failure",
                      "denied",
                      "partial"
                    ],
                    "description": "Optional free-form outcome label. Stored on metadata.outcome. No engine semantics; surfaced back on read regardless of Type."
                  },
                  "correlationId": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "Optional grouping ID. Multiple Records sharing a correlationId can be queried with GET /v1/records/search?correlationId=…"
                  },
                  "requestedBy": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Free-form identifier of the human or upstream system that asked for the work (e.g. \"user:alice@example.com\", \"system:cron-2026-04-25\")."
                  },
                  "share": {
                    "type": "boolean",
                    "description": "V1 sharing override. When the counterparty is on a federated peer Server, `true` ships a signed copy of terminal-state transitions and Settlement Signals to the peer; `false` keeps the record private to this Server. Omit to inherit the contract type's `defaultShare`, then the global `AGLEDGER_DEFAULT_SHARE` (default `true`). The chain itself is local either way; this flag only controls cross-Server transport."
                  },
                  "references": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "system",
                        "refType",
                        "refId"
                      ],
                      "properties": {
                        "system": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "External system identifier (lowercase, alphanumeric + dots/hyphens/underscores)"
                        },
                        "refType": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "Reference type within the system (e.g., sales-order, ticket, service-principal)"
                        },
                        "refId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500,
                          "description": "External identifier within the system"
                        },
                        "displayName": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "Human-readable label (snapshot at attachment time, not refreshed)"
                        },
                        "uri": {
                          "type": "string",
                          "maxLength": 2048,
                          "pattern": "^https?://",
                          "description": "URL back to the source system (https only)"
                        },
                        "attributes": {
                          "type": "object",
                          "maxProperties": 10,
                          "additionalProperties": {
                            "type": [
                              "string",
                              "number",
                              "boolean",
                              "null"
                            ]
                          },
                          "description": "Flat key-value metadata (max 10 keys, max 4KB total)"
                        }
                      },
                      "additionalProperties": false
                    },
                    "maxItems": 25,
                    "description": "External entity references to attach at creation (append-only, max 25 per record)"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "type": "test-generic-v1",
                "contractVersion": "1",
                "platform": "stripe-acp",
                "platformRef": "pi_3abc123",
                "criteria": {
                  "item_description": "Organic whole milk, 1 gallon",
                  "quantity": {
                    "target": 500,
                    "tolerance_pct": 5
                  },
                  "price_ceiling": {
                    "amount": 2250,
                    "currency": "USD"
                  },
                  "supplier_requirements": {
                    "min_rating": 85
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Record created in CREATED status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body, unknown type, or criteria do not match the type schema. When schema validation fails, use examplePayload as a starting point, or inspect requiredFields/optionalFields for valid field names.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "The type that was validated against (e.g., notarize-generic-v1)"
                    },
                    "title": {
                      "type": "string",
                      "description": "Short human-readable summary of the problem type (RFC 9457)"
                    },
                    "status": {
                      "type": "integer",
                      "description": "HTTP status code (RFC 9457)"
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation specific to this occurrence (RFC 9457)"
                    },
                    "instance": {
                      "type": "string",
                      "description": "URI reference identifying the specific occurrence (RFC 9457)"
                    },
                    "errors": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Structured validation errors (RFC 9457 extension, present on 400 responses)"
                    },
                    "retryable": {
                      "type": "boolean",
                      "description": "Whether the client should retry this request (true for 429, 5xx; false for 4xx)"
                    },
                    "error": {
                      "type": "string",
                      "description": "Machine-readable error code (e.g., NOT_FOUND, VALIDATION_ERROR, FORBIDDEN)"
                    },
                    "message": {
                      "type": "string",
                      "description": "Human-readable error description"
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Unique request identifier for support correlation"
                    },
                    "details": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Validation error details (present on 400/422 responses)"
                    },
                    "suggestion": {
                      "type": "string",
                      "description": "Suggested correction when a field-name typo is detected (e.g., \"Body contains 'type' — did you mean 'type'?\")"
                    },
                    "recoveryHint": {
                      "type": "string",
                      "description": "Machine-readable recovery guidance pointing to relevant endpoints (e.g., schema lookup URL)"
                    },
                    "missingFeatures": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "License features required but not available at the current tier"
                    },
                    "currentTier": {
                      "type": "string",
                      "description": "Current license tier (developer, org)"
                    },
                    "requiredTier": {
                      "type": "string",
                      "description": "Minimum tier required for the missing features"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Guided next actions for AI agents and integrations"
                    },
                    "missingScopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "API key scopes required but not present"
                    },
                    "hint": {
                      "type": "string",
                      "description": "Agent-friendly guidance pointing to the schema endpoint for this type"
                    },
                    "requiredFields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Required field names for the criteria object per the type schema"
                    },
                    "optionalFields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Optional field names for the criteria object per the type schema"
                    },
                    "examplePayload": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "A minimal valid request body that an agent can copy and modify. Contains example criteria for the type."
                    },
                    "schemaUrl": {
                      "type": "string",
                      "description": "URL to the type schema (e.g., /v1/schemas/notarize-generic-v1). Call this endpoint to discover required criteria fields."
                    },
                    "recordType": {
                      "type": "string",
                      "description": "Record Type (formerly Contract Type) related to the validation error"
                    },
                    "currentState": {
                      "type": "string",
                      "description": "Current state of the resource"
                    },
                    "attemptedTransition": {
                      "type": "string",
                      "description": "Transition that was attempted"
                    },
                    "attemptedState": {
                      "type": "string",
                      "description": "State the caller asked the resource to move to (federation: POST /federation/v1/state-transitions terminal-conflict 422 carries this alongside `currentState`)."
                    },
                    "validTransitions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Valid transitions from the current state"
                    },
                    "attemptedAction": {
                      "type": "string",
                      "description": "The /transition action name that was submitted"
                    },
                    "allowedActions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Action names accepted by POST /v1/records/{id}/transition in the current state"
                    },
                    "refreshUrl": {
                      "type": "string",
                      "description": "Concrete GET URL the agent should re-fetch to read fresh nextActions/validTransitions/allowedActions (set on 422 INVALID_ACTION when the request path includes a record id)."
                    },
                    "allowedValues": {
                      "type": "array",
                      "items": {},
                      "description": "Permitted values for the field that failed an enum constraint, or the registered list when the rejection is a \"no such X\" lookup (e.g., unknown type → registered types)."
                    },
                    "disputeCount": {
                      "type": "integer",
                      "description": "Number of disputes already filed against this record (open + terminal). Surfaced on 422 when the dispute cap is hit."
                    },
                    "maxDisputes": {
                      "type": "integer",
                      "description": "Maximum disputes allowed on this record (default 1). Surfaced alongside disputeCount when the cap is hit."
                    },
                    "openDisputeId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "ID of the currently-open dispute (EVIDENCE_WINDOW or TIER_2_REVIEW). Null when all prior disputes have terminalized. Surfaced on 422 when the dispute cap is hit so the agent can escalate the existing one rather than try to open another."
                    },
                    "currentStatus": {
                      "type": "string",
                      "description": "Display status of the record at the moment the request was refused. Surfaced on 422 when a dispute is attempted while verification is still in progress."
                    },
                    "disputeableWhen": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Display statuses from which POST /v1/records/{recordId}/dispute is accepted. Poll GET /v1/records/{recordId} until status is one of these, then retry."
                    },
                    "allowedActors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Role/actor labels permitted for this action in the current resource state. Surfaced on 403 cross-tier rejections (e.g., parent-principal trying to act on a sub-record it is not direct-principal of)."
                    },
                    "parentRecordId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID of the parent record that rejected the delegation attempt. Surfaced on 422 when the parent state cannot accept children."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Machine-readable reason code. On 409 conflicts: STATUS_NOT_DISABLED, RECORDS_REFERENCE_TYPE, CONFLICTING_VERSION, RESERVED_PUBLISHER_LABEL, VAULT_SCAN_IN_FLIGHT. On 422 authority-guard refusals: the snake_case guard identifier (has_children_leaf_only, leaf_record, no_children, children_not_terminal, mode_not_auto, mode_not_principal, record_disputed). Branch on this rather than on the prose in `detail`."
                    },
                    "jobId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID of the background job this request is being refused in favour of. Poll GET /v1/admin/vault/scan/{jobId} for its state and result. Present on 409 VAULT_SCAN_IN_FLIGHT."
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label on the conflicting schema row."
                    },
                    "version": {
                      "type": "string",
                      "description": "Manifest version string on the conflicting schema row."
                    },
                    "incomingDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest of the manifest the caller just submitted."
                    },
                    "existingDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest of the manifest already registered at this (publisher, type, version)."
                    },
                    "publishers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Candidate publisher labels on a 422 `/problems/ambiguous-publisher`. Emitted by /v1/schemas/{type} reads and writes (pin with `?publisher=`) and by record creation (pin with a `publisher` body field)."
                    },
                    "pinnedRecords": {
                      "type": "integer",
                      "description": "Records written against the exact registration this delete would remove."
                    },
                    "unattributableRecords": {
                      "type": "integer",
                      "description": "Records of this type carrying no registration pin, so they block a delete under any publisher label."
                    },
                    "peerDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest the federation peer claimed in `schemaRef.manifestDigest`."
                    },
                    "localDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest the receiver holds locally for the same (publisher, type, version, org) tuple."
                    },
                    "revisionCount": {
                      "type": "integer",
                      "description": "Number of revisions consumed at the moment OVERFLOW_REJECT fired."
                    },
                    "maxRevisions": {
                      "type": "integer",
                      "description": "Configured maxRevisions cap on the record."
                    },
                    "terminalReason": {
                      "type": "string",
                      "description": "Machine-readable label naming the system action that terminalized the record (e.g. OVERFLOW_REJECT, ARBITRATION_LOCK, TIME_OUT)."
                    },
                    "deadline": {
                      "type": "string",
                      "format": "date-time",
                      "description": "The record deadline that had already passed when the request was refused (system TIME_OUT)."
                    },
                    "previousStatus": {
                      "type": "string",
                      "description": "Display status the record was at immediately before the terminal transition."
                    },
                    "constraintViolations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Constraint violations for the request"
                    },
                    "constraint": {
                      "type": "string",
                      "description": "Database constraint that was violated"
                    },
                    "validationErrors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyword": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "instancePath": {
                            "type": "string"
                          },
                          "params": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": true
                      },
                      "description": "Per-field JSON Schema validation errors (present when criteria do not match the type schema)"
                    },
                    "migratedTo": {
                      "type": "string",
                      "description": "Suggested replacement path for a renamed endpoint. Present on 404 responses for routes retired in a migration (e.g. /v1/admin/enterprises → /v1/admin/orgs)."
                    },
                    "expected": {
                      "type": "string",
                      "description": "Expected JSON type or value, paired with `received` on validation errors."
                    },
                    "signInputTemplate": {
                      "type": "string",
                      "description": "Exact byte template the Ed25519 proof-of-possession signature must cover, with the domain prefix. Surfaced on the federation 401 for an invalid signature."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Pointer to the discovery document section describing the failed scheme (e.g. \"/llms.txt (Federation Signing Scheme section)\"). Paired with signInputTemplate + hint on the federation 401."
                    }
                  },
                  "additionalProperties": false,
                  "description": "Invalid request body, unknown type, or criteria do not match the type schema. When schema validation fails, use examplePayload as a starting point, or inspect requiredFields/optionalFields for valid field names."
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The body is well-formed but a precondition fails. Five causes, and the fix differs: `parentRecordId` names a record whose state cannot accept children (body carries `parentRecordId`); the delegation chain is at its depth limit; the `type` is registered but DISABLED (enable it, or pick another); `performerAgentId` already appears in the parent chain (circular delegation, so name a different agent); or `type` is offered by more than one publisher in this org, so it is ambiguous (`/problems/ambiguous-publisher`, body carries `publishers` — re-send with a `publisher` field). Read detail + recoveryHint before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listRecords",
        "summary": "List records for an org",
        "tags": [
          "Records"
        ],
        "description": "Returns a simple paginated list of records for the given org. Admin keys can only list records in their org. For advanced filtering, use GET /records/search.\n\n**Agent-key auto-scoping:** when called with an agent API key, the response is automatically narrowed to records where the calling agent is either the performer OR the principal — no `performerAgentId=` needed (and supplying it for a different agent has no effect on the filter, the auto-scope wins). Use `?role=performer` or `?role=principal` to narrow further to one side. The auto-scope is the resilient self-discovery path for the enterprise-driven pattern where an orchestrator hands work to a performer via webhook — a performer can recover its queue without remembering record IDs.\n\n**Recovery:** `?actionable=true` is the canonical \"what awaits my action\" query — one call, no status enumeration. See the parameter description.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "CREATED",
                "PROPOSED",
                "ACTIVE",
                "PROCESSING",
                "REVISION_REQUESTED",
                "DISPUTED",
                "FULFILLED",
                "FAILED",
                "REMEDIATED",
                "EXPIRED",
                "PENDING_ARBITRATION",
                "CANCELLED",
                "REJECTED",
                "RECORDED"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by record status"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Filter by type (e.g. notarize-generic-v1)"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "performerAgentId",
            "required": false,
            "description": "Filter by assigned performer agent"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "performer",
                "principal"
              ]
            },
            "in": "query",
            "name": "role",
            "required": false,
            "description": "Narrow agent-key auto-scoping to one role. `performer` → only records where the calling agent is the performer; `principal` → only records where the calling agent is the principal; omitted → both (default). Agent-key only — admin/platform keys get 400 with a hint to use `?performerAgentId=<uuid>` instead."
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "actionable",
            "required": false,
            "description": "The one-call recovery query — \"what is awaiting MY action right now?\". When true, returns only records whose `awaitingActor` matches YOUR structural side on that record: records where you are the named performer and the record awaits the performer (open proposals, ACTIVE work, revision/fix requests), plus records where you are the principal and the record awaits the principal (activation after acceptance, counter-proposals to answer, pending verdicts, disputes). This replaces enumerating per-status queries during recovery — a record in ANY status that needs your action is in this list; an empty list means nothing awaits you. Combine with `?role=` to restrict to one side. Agent-key only — admin/platform keys get 400."
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "from",
            "required": false,
            "description": "Filter records created on or after this timestamp (ISO 8601)"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "to",
            "required": false,
            "description": "Filter records created on or before this timestamp (ISO 8601)"
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "hasDispute",
            "required": false,
            "description": "When set, restrict to records that have (true) or have not (false) had any dispute filed against them."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "EVIDENCE_WINDOW",
                "TIER_2_REVIEW",
                "ESCALATED",
                "TIER_3_ARBITRATION",
                "RESOLVED",
                "WITHDRAWN"
              ]
            },
            "in": "query",
            "name": "disputeStatus",
            "required": false,
            "description": "Restrict to records whose latest dispute is in this status. Orthogonal to top-level `status`. See GET /records/search for full docs."
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "imported",
            "required": false,
            "description": "Restrict to backfill-imported records (true) or live records (false). Backed by the partial index `idx_records_imported_true`."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "source",
            "required": false,
            "description": "Restrict to records imported from a specific source label (e.g. `legacy-erp`). Implies `imported=true` server-side."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Wrapped array of records.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Wrapped array of records.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Platform keys must name the target org: add `?orgId=<uuid>`. The response `recoveryHint` names the listing that supplies it.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/summary": {
      "get": {
        "operationId": "recordsSummaryRetired",
        "summary": "Retired — use /v1/records/search",
        "tags": [
          "Records"
        ],
        "description": "Retired in v0.20. Returns 410 Gone with an upgrade hint to GET /v1/records/search.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "410": {
            "description": "Endpoint retired.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}": {
      "get": {
        "operationId": "getRecord",
        "summary": "Get record by ID",
        "tags": [
          "Records"
        ],
        "description": "Retrieves a single record by its UUID. Admin keys can only view records in their org; agents can only view records where they are the assigned agent.\n\n**Integrity:** the record fields returned here are a denormalized projection; the signed audit chain (GET /v1/records/{id}/audit-export) is the authoritative evidence. Pass `?integrity=true` to re-verify the full chain on this read and get an `integrity` block on the response — use it before treating a read as evidence (GRC review, settlement decision, dashboard of record). It is a full cryptographic re-verify per call, so keep it off high-frequency polling.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "integrity",
            "required": false,
            "description": "Re-verify the record's full audit chain (hashes, signatures, checkpoint cross-check) and attach an `integrity` block to the response. Detects out-of-band database tampering of the denormalized record row. Expensive (per-entry crypto) — use for evidence-grade reads, not polling."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Record details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateRecord",
        "summary": "Update record fields (CREATED only)",
        "tags": [
          "Records"
        ],
        "description": "Updates criteria, tolerance, or deadline on a record. Only records in CREATED status can be updated. At least one field must be provided. The record owner is verified before update.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "criteria": {
                    "type": "object",
                    "maxProperties": 100,
                    "description": "Updated acceptance criteria"
                  },
                  "tolerance": {
                    "type": "object",
                    "properties": {
                      "quantityPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMargin": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMarginPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "graceSeconds": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "Deadline grace window, in seconds. NOT a gate-evaluation band: it extends the record's effective expiry to `deadline + graceSeconds`, so a completion submitted late but within the window is accepted instead of timing out. Only meaningful on a record that carries a `deadline`; the same effective deadline governs both the in-transaction submit check and the background expiry sweep."
                      },
                      "budgetMargin": {
                        "type": "number",
                        "minimum": 0
                      }
                    },
                    "additionalProperties": {
                      "type": "number",
                      "minimum": 0
                    },
                    "description": "Updated tolerance values. Most keys are gate-evaluation bands; graceSeconds is a deadline grace window (effective expiry = deadline + graceSeconds)."
                  },
                  "deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Updated deadline"
                  },
                  "riskClassification": {
                    "type": "string",
                    "enum": [
                      "unacceptable",
                      "high",
                      "limited",
                      "minimal",
                      "unclassified"
                    ],
                    "description": "EU AI Act risk classification"
                  },
                  "euAiActDomain": {
                    "type": "string",
                    "enum": [
                      "biometrics",
                      "critical_infrastructure",
                      "education",
                      "employment",
                      "essential_services",
                      "law_enforcement",
                      "migration",
                      "justice"
                    ],
                    "description": "EU AI Act high-risk domain (only when riskClassification=high)"
                  },
                  "humanOversight": {
                    "type": "object",
                    "description": "Human oversight designation per EU AI Act Art. 14. Required: overseerName, overseerRole, authorityScope, designatedAt (date-time). Optional: overseerContact. No additional properties.",
                    "properties": {
                      "overseerName": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerRole": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerContact": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "authorityScope": {
                        "type": "string",
                        "maxLength": 2000
                      },
                      "designatedAt": {
                        "type": "string",
                        "format": "date-time"
                      }
                    },
                    "required": [
                      "overseerName",
                      "overseerRole",
                      "authorityScope",
                      "designatedAt"
                    ],
                    "additionalProperties": false
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "maxProperties": 50,
                    "description": "Arbitrary key-value data for customer use (max 10KB)"
                  }
                },
                "additionalProperties": false,
                "minProperties": 1
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Record updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Invalid update payload.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The record is past the editable point: PATCH applies only before a record is registered or proposed, after which criteria and tolerance are on the signed chain. Display status reads CREATED on both sides of that line, so check `allowedActions` (an editable record still lists `register` / `propose`), and read recoveryHint for the lifecycle endpoints (/propose, /counter-propose, /revision) that apply instead of PATCH.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/search": {
      "get": {
        "operationId": "searchRecords",
        "summary": "Search records with filters and pagination",
        "tags": [
          "Records"
        ],
        "description": "Enhanced record listing with filtering by status, type, agent, and date range. Returns paginated results with total count. Admin keys can only search records in their org.\n\n**Pagination:** Prefer cursor-based pagination via the `nextCursor` field in the response envelope — it is O(1) per page regardless of dataset size. Offset-based pagination is still supported but is **deprecated**: it scales linearly with offset depth (PG scans and discards offset rows before returning the page). Clients using `offset` will receive `Deprecation: true` and `Warning: 299` response headers. When both `cursor` and `offset` are supplied, `cursor` takes precedence.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "CREATED",
                "PROPOSED",
                "ACTIVE",
                "PROCESSING",
                "REVISION_REQUESTED",
                "DISPUTED",
                "FULFILLED",
                "FAILED",
                "REMEDIATED",
                "EXPIRED",
                "PENDING_ARBITRATION",
                "CANCELLED",
                "REJECTED",
                "RECORDED"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by record status"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "in": "query",
            "name": "category",
            "required": false,
            "description": "Filter by category — the free-form taxonomy denormalized from the Type at create."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "in": "query",
            "name": "correlationId",
            "required": false,
            "description": "Filter Records sharing the same correlationId (work-session group)."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Filter by type (e.g., notarize-generic-v1)"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "performerAgentId",
            "required": false,
            "description": "Filter by assigned performer agent"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "performer",
                "principal"
              ]
            },
            "in": "query",
            "name": "role",
            "required": false,
            "description": "Narrow agent-key auto-scoping to one role (same semantics as GET /v1/records — agent-key only)."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "projectRef",
            "required": false,
            "description": "Filter by project reference"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "externalTaskId",
            "required": false,
            "description": "Filter by external task ID"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "parentRecordId",
            "required": false,
            "description": "Filter by parent record (delegation chain)"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "from",
            "required": false,
            "description": "Start of date range (inclusive)"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "to",
            "required": false,
            "description": "End of date range (inclusive)"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "updatedAfter",
            "required": false,
            "description": "Filter by updated_at >= this value"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "updatedBefore",
            "required": false,
            "description": "Filter by updated_at <= this value"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "auto",
                "principal"
              ]
            },
            "in": "query",
            "name": "gateMode",
            "required": false,
            "description": "Filter by gate mode"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "cleartext",
                "encrypted"
              ]
            },
            "in": "query",
            "name": "operatingMode",
            "required": false,
            "description": "Filter by operating mode"
          },
          {
            "schema": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              },
              "maxProperties": 5
            },
            "in": "query",
            "name": "metadata",
            "required": false,
            "description": "Filter by metadata key-value pairs using bracket notation: metadata[key]=value"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "in": "query",
            "name": "ref.system",
            "required": false,
            "description": "Filter records by reference system"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "in": "query",
            "name": "ref.type",
            "required": false,
            "description": "Filter records by reference type"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 500
            },
            "in": "query",
            "name": "ref.id",
            "required": false,
            "description": "Filter records by reference ID"
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "hasDispute",
            "required": false,
            "description": "When set, restrict to records that have (true) or have not (false) had any dispute filed against them. Reads the trigger-maintained dispute_count column — cheap."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "EVIDENCE_WINDOW",
                "TIER_2_REVIEW",
                "ESCALATED",
                "TIER_3_ARBITRATION",
                "RESOLVED",
                "WITHDRAWN"
              ]
            },
            "in": "query",
            "name": "disputeStatus",
            "required": false,
            "description": "Restrict to records whose latest dispute is in this status (EVIDENCE_WINDOW, TIER_2_REVIEW, ESCALATED, TIER_3_ARBITRATION, RESOLVED, WITHDRAWN). Joins to disputes table — use ?hasDispute=true for cheap boolean discovery. Orthogonal to top-level `status` (which is the record status). On types with `flipRecordStatusOnDispute: true` (default), in-flight disputes also flip `status` to DISPUTED so `?status=DISPUTED` works too. On types with the flag false, `?status=` stays at FULFILLED/etc. and only this filter surfaces the dispute."
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "imported",
            "required": false,
            "description": "Restrict to backfill-imported records (true) or live records (false). Backed by the partial index `idx_records_imported_true` so this filter stays cheap on orgs with millions of historical rows."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "source",
            "required": false,
            "description": "Restrict to records imported from a specific source label (e.g. `legacy-erp`, `sap-export-2024`). Implies imported=true server-side."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "updatedAt"
              ],
              "default": "createdAt"
            },
            "in": "query",
            "name": "sort",
            "required": false,
            "description": "Sort field"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "in": "query",
            "name": "order",
            "required": false,
            "description": "Sort order"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated record results with total count.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Paginated record results with total count.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Platform keys must name the target org: add `?orgId=<uuid>`. The response `recoveryHint` names the listing that supplies it.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/batch": {
      "post": {
        "operationId": "batchGetRecords",
        "summary": "Get multiple records by ID",
        "tags": [
          "Records"
        ],
        "description": "Returns up to 100 records by their IDs in a single request. Results are returned in request order. IDs the caller submitted that did not match a visible record are echoed back in `notFound[]` so callers can tell partial failures from total ones.\n\n**Auth:** admin, agent, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "Record IDs to fetch (max 100)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Records in request order (missing/inaccessible IDs reported in `notFound[]`).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Records in request order (missing/inaccessible IDs reported in `notFound[]`).",
                  "type": "object",
                  "required": [
                    "data",
                    "notFound",
                    "nextSteps"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "notFound": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "description": "IDs the caller submitted that returned no record — either the id does not exist or the caller cannot see it. The two cases are not distinguished (no information leak about cross-org existence)."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/transition": {
      "post": {
        "operationId": "transitionRecord",
        "summary": "Transition record state",
        "tags": [
          "Records"
        ],
        "description": "Advances the record through its lifecycle state machine. Valid actions:\n\n- **register**: lock criteria in preparation for activation. Applies while the record is freshly created and still editable; display status stays `CREATED` across the lock step (internally DRAFT → REGISTERED).\n- **propose**: open the proposal handshake to a distinct performer. Requires `performerAgentId` to be set on the record; display status transitions from `CREATED` to `PROPOSED`. The performer then accepts (POST /accept), rejects (POST /reject), or counter-proposes (POST /counter-propose) before the principal activates.\n- **activate**: open the record for completion submission. Display status transitions from `CREATED` to `ACTIVE`.\n- **cancel**: terminate the record. Allowed from most non-terminal states; display status becomes `CANCELLED`.\n\n**Do not pick an action from this list.** Which actions apply depends on the record's current internal state (display `CREATED` covers both DRAFT and REGISTERED, which accept different actions). Read `nextActions` on the record response to get the exact action names valid right now. Fulfillment is automatic after the gate accepts a completion — there is no manual `settle` action. Remediation is issued via the verdict endpoints, not `/transition`. Submitting an action that doesn't apply returns 422 `INVALID_ACTION` with `currentState`, `allowedActions`, `recoveryHint`, and `refreshUrl`. Invalid state transitions also return 422. Supports idempotency via the `Idempotency-Key` header. Rate limited to 20 requests per minute.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "register",
                      "propose",
                      "activate",
                      "cancel"
                    ],
                    "description": "State transition action to perform. Use `nextActions` on the record response to see which apply right now."
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Optional reason for this transition (recorded in audit vault)"
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "example1": {
                  "value": {
                    "action": "register"
                  }
                },
                "example2": {
                  "value": {
                    "action": "propose"
                  }
                },
                "example3": {
                  "value": {
                    "action": "activate"
                  }
                },
                "example4": {
                  "value": {
                    "action": "cancel",
                    "reason": "Budget reallocated to higher-priority task"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable: the record's current state does not allow the requested action (INVALID_ACTION) or the resulting transition is invalid (INVALID_TRANSITION).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/bulk": {
      "post": {
        "operationId": "bulkCreateRecords",
        "summary": "Create multiple records in a single request",
        "tags": [
          "Records"
        ],
        "description": "Creates up to 100 records in a single request. Each record is created independently using database savepoints, so individual failures do not abort the entire batch. Returns HTTP 207 Multi-Status with per-item results.\n\nHigh-volume notarize ingest (telemetry, ML inference logs, conversational turns) should set per-item `idempotencyKey` so a retried batch returns the original `id` + `signedStatement` instead of duplicating the chain. The HTTP `Idempotency-Key` header dedups the whole batch; per-item key dedups one row.\n\n**Auth:** admin, agent, platform. Admin keys can only bulk-create for their own orgId.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "records"
                ],
                "properties": {
                  "records": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "criteria"
                      ],
                      "properties": {
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 50
                        },
                        "contractVersion": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 10
                        },
                        "publisher": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Publisher label pinning which registration of `type` this item binds to. Required only when two publishers offer the same `record_type` in this org; otherwise that item fails with 422 `/problems/ambiguous-publisher`."
                        },
                        "platform": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 50
                        },
                        "platformRef": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "projectRef": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "externalTaskId": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "criteria": {
                          "type": "object",
                          "maxProperties": 100
                        },
                        "tolerance": {
                          "type": "object",
                          "properties": {
                            "quantityPct": {
                              "type": "number",
                              "minimum": 0
                            },
                            "priceMargin": {
                              "type": "number",
                              "minimum": 0
                            },
                            "priceMarginPct": {
                              "type": "number",
                              "minimum": 0
                            },
                            "graceSeconds": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "Deadline grace window, in seconds. NOT a gate-evaluation band: it extends the record's effective expiry to `deadline + graceSeconds`, so a completion submitted late but within the window is accepted instead of timing out. Only meaningful on a record that carries a `deadline`; the same effective deadline governs both the in-transaction submit check and the background expiry sweep."
                            },
                            "budgetMargin": {
                              "type": "number",
                              "minimum": 0
                            }
                          },
                          "additionalProperties": {
                            "type": "number",
                            "minimum": 0
                          }
                        },
                        "deadline": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "operatingMode": {
                          "type": "string",
                          "enum": [
                            "cleartext",
                            "encrypted"
                          ],
                          "default": "cleartext"
                        },
                        "gateMode": {
                          "type": "string",
                          "enum": [
                            "auto",
                            "principal"
                          ]
                        },
                        "riskClassification": {
                          "type": "string",
                          "enum": [
                            "unacceptable",
                            "high",
                            "limited",
                            "minimal",
                            "unclassified"
                          ],
                          "default": "unclassified"
                        },
                        "euAiActDomain": {
                          "type": "string",
                          "enum": [
                            "biometrics",
                            "critical_infrastructure",
                            "education",
                            "employment",
                            "essential_services",
                            "law_enforcement",
                            "migration",
                            "justice"
                          ]
                        },
                        "humanOversight": {
                          "type": "object",
                          "description": "Human oversight designation per EU AI Act Art. 14. Required: overseerName, overseerRole, authorityScope, designatedAt (date-time). Optional: overseerContact. No additional properties.",
                          "properties": {
                            "overseerName": {
                              "type": "string",
                              "maxLength": 500
                            },
                            "overseerRole": {
                              "type": "string",
                              "maxLength": 500
                            },
                            "overseerContact": {
                              "type": "string",
                              "maxLength": 500
                            },
                            "authorityScope": {
                              "type": "string",
                              "maxLength": 2000
                            },
                            "designatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          },
                          "required": [
                            "overseerName",
                            "overseerRole",
                            "authorityScope",
                            "designatedAt"
                          ],
                          "additionalProperties": false
                        },
                        "metadata": {
                          "type": "object",
                          "additionalProperties": true,
                          "maxProperties": 50
                        },
                        "idempotencyKey": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256,
                          "description": "Per-record idempotency key (caller-supplied). Replay-safe for high-volume notarize ingest: a second batch sending the same key returns the original record's id + signedStatement instead of creating a duplicate. Scoped to (callerOwnerId, key); 7-day TTL. The HTTP `Idempotency-Key` header dedups the whole batch; this field dedups one item."
                        },
                        "autoActivate": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the record is created and immediately activated (CREATED → ACTIVE) in a single request. Mirrors POST /v1/records — bulk pipelines reusing a singleton body get the same activation behavior."
                        },
                        "parentRecordId": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Make this record a child of an existing parent (delegation). Same semantics as the singleton create."
                        },
                        "performerAgentId": {
                          "type": "string",
                          "format": "uuid",
                          "minLength": 36,
                          "maxLength": 36,
                          "description": "Named performer agent for proposal flows. Mirrors POST /v1/records."
                        },
                        "principalAgentId": {
                          "type": "string",
                          "format": "uuid",
                          "minLength": 36,
                          "maxLength": 36,
                          "description": "Principal agent (admin keys must set this; agent keys default to themselves). Mirrors POST /v1/records."
                        },
                        "share": {
                          "type": "boolean",
                          "description": "V1 sharing override; mirrors POST /v1/records. Omit to inherit per-contract `defaultShare` then the global `AGLEDGER_DEFAULT_SHARE`."
                        },
                        "commissionPct": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Commission percentage for the performer (0-100). Mirrors POST /v1/records."
                        },
                        "maxSubmissions": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 100,
                          "description": "Maximum number of completion submissions allowed (default: unlimited). When reached, no further revisions can be requested. Mirrors POST /v1/records."
                        },
                        "constraintInheritance": {
                          "type": "string",
                          "enum": [
                            "none",
                            "advisory",
                            "enforced"
                          ],
                          "default": "none",
                          "description": "Constraint inheritance mode for delegation chains. none: no inheritance (default). advisory: allow but audit when child exceeds parent bounds. enforced: block child creation if exceeds parent. Mirrors POST /v1/records."
                        },
                        "enforcementOverrides": {
                          "type": "object",
                          "properties": {
                            "toleranceEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ]
                            },
                            "deadlineEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ]
                            },
                            "schemaValidation": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ]
                            },
                            "maxSubmissionsMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ]
                            },
                            "expressionRuleMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ]
                            }
                          },
                          "additionalProperties": false,
                          "description": "Per-record enforcement overrides. Can only relax org settings (not tighten). Requires org allowRecordOverrides=true. Mirrors POST /v1/records."
                        },
                        "dependsOn": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "maxItems": 20,
                          "description": "Informational dependency references to other record IDs (no activation gating). Mirrors POST /v1/records."
                        },
                        "outcome": {
                          "type": "string",
                          "enum": [
                            "success",
                            "failure",
                            "denied",
                            "partial"
                          ],
                          "description": "Optional free-form outcome label. Stored on metadata.outcome. No engine semantics; surfaced back on read regardless of Type. Mirrors POST /v1/records."
                        },
                        "correlationId": {
                          "type": "string",
                          "maxLength": 128,
                          "description": "Optional grouping ID. Multiple Records sharing a correlationId can be queried with GET /v1/records/search?correlationId=…. Mirrors POST /v1/records."
                        },
                        "requestedBy": {
                          "type": "string",
                          "maxLength": 256,
                          "description": "Free-form identifier of the human or upstream system that asked for the work. Mirrors POST /v1/records."
                        },
                        "references": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "system",
                              "refType",
                              "refId"
                            ],
                            "properties": {
                              "system": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100,
                                "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                                "description": "External system identifier (lowercase, alphanumeric + dots/hyphens/underscores)"
                              },
                              "refType": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100,
                                "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                                "description": "Reference type within the system (e.g., sales-order, ticket, service-principal)"
                              },
                              "refId": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 500,
                                "description": "External identifier within the system"
                              },
                              "displayName": {
                                "type": "string",
                                "maxLength": 500,
                                "description": "Human-readable label (snapshot at attachment time, not refreshed)"
                              },
                              "uri": {
                                "type": "string",
                                "maxLength": 2048,
                                "pattern": "^https?://",
                                "description": "URL back to the source system (https only)"
                              },
                              "attributes": {
                                "type": "object",
                                "maxProperties": 10,
                                "additionalProperties": {
                                  "type": [
                                    "string",
                                    "number",
                                    "boolean",
                                    "null"
                                  ]
                                },
                                "description": "Flat key-value metadata (max 10 keys, max 4KB total)"
                              }
                            },
                            "additionalProperties": false
                          },
                          "maxItems": 25,
                          "description": "External entity references to attach at creation (append-only, max 25 per record). Mirrors POST /v1/records."
                        }
                      },
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "Array of record objects to create (max 100)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "207": {
            "description": "Multi-status response with per-item results and summary counts.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Multi-status response with per-item results and summary counts.",
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "description": "Zero-based index in the input array"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "created",
                              "replayed",
                              "error"
                            ],
                            "description": "`created` = new record. `replayed` = idempotencyKey matched a prior submission; data is the ORIGINAL record (no new chain entry). `error` = per-item validation failure (caller fault — fix the input and resubmit only this item)."
                          },
                          "data": {
                            "$ref": "#/components/schemas/RecordRow"
                          },
                          "error": {
                            "type": "string",
                            "description": "Error message if creation failed"
                          },
                          "errorCode": {
                            "type": "string",
                            "description": "Machine-readable error class for `status: error` items. Always a validation-class error (the bulk call would have returned 5xx if an infra-class error occurred). Examples: `ValidationError`, `NotFoundError`, `ConflictError`, `InvalidTransitionError`, `SchemaValidationError`, `InvalidActionError`, `UnprocessableStateError`."
                          },
                          "problemType": {
                            "type": "string",
                            "description": "RFC 9457 problem URI when the failure carries a narrower one than its class, e.g. `/problems/ambiguous-publisher`. Branch on this rather than on `error` prose."
                          },
                          "context": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Structured extras from the failure. For `/problems/ambiguous-publisher` this carries `publishers` (the candidate labels) and `recordType`, matching the singleton error body."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "succeeded": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        },
                        "replayed": {
                          "type": "integer",
                          "description": "Count of items returned as `replayed` (also included in `succeeded`)."
                        }
                      },
                      "additionalProperties": false
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/cancel": {
      "post": {
        "operationId": "cancelRecord",
        "summary": "Cancel a record",
        "tags": [
          "Records"
        ],
        "description": "Convenience endpoint that transitions a record to CANCELLED status. Can be called on records in CREATED or ACTIVE status. An optional reason can be provided. Supports idempotency via the `Idempotency-Key` header. Rate limited to 20 requests per minute.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Optional cancellation reason for audit trail"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after cancellation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "RecordRow cannot be cancelled from its current state.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/chain": {
      "get": {
        "operationId": "getRecordChain",
        "summary": "Get full delegation chain",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "Returns all records in a delegation chain, ordered by depth. Access: org owner of root, any agent in chain, or platform.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 1000
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Max records to return. Default 1000. When the chain exceeds the limit, `hasMore: true` signals truncation; reduce filter scope or use `GET /v1/records/search?parentRecordId=` for cursor pagination."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/sub-records": {
      "get": {
        "operationId": "getSubRecords",
        "summary": "Get direct sub-records",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "Returns the immediate child records of a given record in a delegation chain.\n\n**Auth:** admin, agent, platform (must have access to the parent record)",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 1000
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Max records to return. Default 1000. When the chain exceeds the limit, `hasMore: true` signals truncation; reduce filter scope or use `GET /v1/records/search?parentRecordId=` for cursor pagination."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/revision": {
      "post": {
        "operationId": "requestRevision",
        "summary": "Request revision after principal rejection",
        "tags": [
          "Records"
        ],
        "description": "Transitions a record from FAILED to REVISION_REQUESTED, allowing the performer to submit a new completion. Only the principal (org owner or delegating agent) can request revision. Enforces max_submissions cap — if the cap is reached, revision is blocked.\n\n**Auth:** admin, agent, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Reason for requesting revision (recorded in audit trail). `message` and `notes` are accepted aliases for this rationale field."
                  },
                  "message": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `reason`."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `reason`."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow transitioned to REVISION_REQUESTED — OR, when the revision budget is already spent (revisionCount has reached maxRevisions), terminalized to REJECTED via OVERFLOW_REJECT. Branch on the returned `status`/`terminalReason` rather than assuming REVISION_REQUESTED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Record is not in FAILED state, or the submission cap (`maxSubmissions`) is already reached. The detail names the current state.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Record is already terminal, so no action can move it. currentState + allowedActions (empty) say so; re-fetch via refreshUrl rather than resending.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/counter-propose": {
      "post": {
        "operationId": "counterProposeRecord",
        "summary": "Counter-propose a record",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "The proposed performer agent counter-proposes modified terms for a record. Updates the record terms and sets acceptanceStatus to COUNTER_PROPOSED. Include at least one modified field: counterCriteria, counterTolerance, counterDeadline, or counterCommissionPct. The principal agent must then accept the counter via POST /records/:id/accept-counter.\n\n**Auth:** agent only (must be the proposed performer)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "counterCriteria": {
                    "type": "object",
                    "maxProperties": 100,
                    "description": "Modified criteria"
                  },
                  "counterTolerance": {
                    "type": "object",
                    "properties": {
                      "quantityPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMargin": {
                        "type": "number",
                        "minimum": 0
                      },
                      "priceMarginPct": {
                        "type": "number",
                        "minimum": 0
                      },
                      "graceSeconds": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "Deadline grace window, in seconds. NOT a gate-evaluation band: it extends the record's effective expiry to `deadline + graceSeconds`, so a completion submitted late but within the window is accepted instead of timing out. Only meaningful on a record that carries a `deadline`; the same effective deadline governs both the in-transaction submit check and the background expiry sweep."
                      },
                      "budgetMargin": {
                        "type": "number",
                        "minimum": 0
                      }
                    },
                    "additionalProperties": {
                      "type": "number",
                      "minimum": 0
                    },
                    "description": "Modified tolerance"
                  },
                  "counterDeadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Modified deadline"
                  },
                  "counterCommissionPct": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Modified commission"
                  },
                  "message": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Message explaining the counter-proposal. `reason` and `notes` are accepted aliases for this rationale field."
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "counterCriteria": {
                  "price_ceiling": {
                    "amount": 600,
                    "currency": "USD"
                  }
                },
                "message": "Need higher budget"
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after counter-proposal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Malformed body (e.g. no modified fields supplied).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Acceptance state does not admit a counter-proposal. currentState + recoveryHint name the status and who has to act next; re-read the record rather than resending.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/accept": {
      "post": {
        "operationId": "acceptRecord",
        "summary": "Accept a record proposal",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "The proposed performer agent accepts a record. Transitions the record to CREATED with ACCEPTED status.\n\n**Auth:** agent only (must be the proposed performer)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Optional message explaining the acceptance. `reason` and `notes` are accepted aliases for this rationale field."
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after acceptance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request body, or a path parameter that is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Acceptance state is not PROPOSED, so there is nothing to accept. currentState + recoveryHint name the status and the endpoint that applies instead.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/reject": {
      "post": {
        "operationId": "rejectRecord",
        "summary": "Reject a record proposal",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "The proposed performer agent rejects a record. Transitions the record to REJECTED (terminal).\n\n**Auth:** agent only (must be the proposed performer)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Optional message explaining the rejection. `reason` and `notes` are accepted aliases — the same rationale field is named `message` here, `reason` on /revision, and `notes` on /verdict; all four handshake endpoints accept any of the three so switching endpoints never costs a 400."
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Alias of `message`."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after rejection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request body, or a path parameter that is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Acceptance state is not PROPOSED, so there is nothing to reject. currentState + recoveryHint name the status and the endpoint that applies instead.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/accept-counter": {
      "post": {
        "operationId": "acceptCounterProposal",
        "summary": "Accept a counter-proposal",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "The principal agent accepts a counter-proposal from the performer. Transitions the record to CREATED with ACCEPTED status.\n\n**Auth:** agent only (must be the principal agent)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "RecordRow after accepting counter-proposal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordRow"
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Acceptance status is not COUNTER_PROPOSED, so there is no counter-proposal to accept. detail names the acceptance status the record is actually at; currentState + allowedActions cover the record itself. Re-fetch GET /v1/records/{id} and read `acceptanceStatus` to see whose turn it is.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/agent/proposals": {
      "get": {
        "operationId": "listAgentProposals",
        "summary": "List proposals awaiting agent response",
        "tags": [
          "Agent-to-Agent"
        ],
        "description": "Returns records proposed to the authenticated agent that are awaiting acceptance.\n\n**Auth:** agent only",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Wrapped array of proposed records.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Wrapped array of proposed records.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecordRow"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/me/verdict-statistics": {
      "get": {
        "operationId": "getOwnVerdictStatistics",
        "summary": "Get own verdict-distribution counters",
        "tags": [
          "Records"
        ],
        "description": "Returns engine-emitted verdict counters where the calling agent is either principal or performer. Per (principal, performer) pair: verdict_accept_count, verdict_reject_count, cancel_after_completion_count. The principal cannot suppress these — they record the realized verdict distribution between two agents. Phase 1b ships own-stats only (no peer-comparison bucketed distribution; that is Phase 2).\n\n**Note:** Records that did not declare a completion phase terminalize at `RECORDED` and never reach a FULFILLED/VERDICT_REJECTED verdict — they are invisible to verdict-statistics by design.\n\n**Auth:** agent only — admin/platform get 403 with a hint.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Own verdict-distribution counters, decomposed by the caller's structural role on each pair.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Own verdict-distribution counters, decomposed by the caller's structural role on each pair.",
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "The calling agent (auth.ownerId)."
                    },
                    "asPrincipal": {
                      "type": "object",
                      "description": "Counters for pairs where the calling agent acted as principal. Each row keyed by performer.",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "performerAgentId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "verdictAcceptCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of transitions into FULFILLED (accept verdict) for this counterparty pair."
                              },
                              "verdictRejectCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of transitions into VERDICT_REJECTED for this counterparty pair."
                              },
                              "cancelAfterCompletionCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of CANCELLED_IN_PROGRESS terminations after at least one completion was submitted."
                              },
                              "firstEventAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When the first counted event occurred for this pair."
                              },
                              "lastEventAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When the most recent counted event occurred for this pair."
                              }
                            },
                            "required": [
                              "performerAgentId",
                              "verdictAcceptCount",
                              "verdictRejectCount",
                              "cancelAfterCompletionCount",
                              "firstEventAt",
                              "lastEventAt"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "total": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "data",
                        "total"
                      ],
                      "additionalProperties": false
                    },
                    "asPerformer": {
                      "type": "object",
                      "description": "Counters for pairs where the calling agent acted as performer. Each row keyed by principal.",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "principalAgentId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "verdictAcceptCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of transitions into FULFILLED (accept verdict) for this counterparty pair."
                              },
                              "verdictRejectCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of transitions into VERDICT_REJECTED for this counterparty pair."
                              },
                              "cancelAfterCompletionCount": {
                                "type": "integer",
                                "minimum": 0,
                                "description": "Count of CANCELLED_IN_PROGRESS terminations after at least one completion was submitted."
                              },
                              "firstEventAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When the first counted event occurred for this pair."
                              },
                              "lastEventAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When the most recent counted event occurred for this pair."
                              }
                            },
                            "required": [
                              "principalAgentId",
                              "verdictAcceptCount",
                              "verdictRejectCount",
                              "cancelAfterCompletionCount",
                              "firstEventAt",
                              "lastEventAt"
                            ],
                            "additionalProperties": false
                          }
                        },
                        "total": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "data",
                        "total"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "agentId",
                    "asPrincipal",
                    "asPerformer"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/completions": {
      "post": {
        "operationId": "submitCompletion",
        "summary": "Submit task attestation evidence",
        "tags": [
          "Completions"
        ],
        "description": "Submits completion evidence against an active record. Phase 1 structural validation (JSON Schema conformance) runs synchronously. If the evidence does not conform to the type completion schema, the request is rejected with HTTP 400 including `validationErrors` (per-field details) and `schemaUrl` (link to the expected schema). The record stays in its current state — no completion is recorded and no state transition occurs.\n\nIf Phase 1 passes (HTTP 201), Phase 2 gate evaluation (field-by-field checks with tolerance bands) is triggered asynchronously via pg-boss; results are delivered via webhook.\n\nUse `GET /v1/schemas/{type}` to discover the expected evidence structure before submitting.\n\nThe record must be in ACTIVE or REVISION_REQUESTED status. The requester must have access to the parent record. Duplicate submissions with the same idempotencyKey return the original completion (HTTP 200 instead of 201).\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "evidence"
                ],
                "properties": {
                  "evidence": {
                    "type": "object",
                    "maxProperties": 100,
                    "description": "Evidence payload matching the type completion schema"
                  },
                  "evidenceHash": {
                    "type": "string",
                    "minLength": 64,
                    "maxLength": 64,
                    "pattern": "^[a-f0-9]{64}$",
                    "description": "Client-provided SHA-256 hash (required for encrypted mode; server cannot compute it)"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Client-side idempotency key for deduplication"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "evidence": {
                  "item_description": "Organic whole milk, 1 gallon",
                  "quantity": 495,
                  "unit_price": {
                    "amount": 4.29,
                    "currency": "USD"
                  },
                  "total_cost": {
                    "amount": 2123.55,
                    "currency": "USD"
                  },
                  "supplier": {
                    "id": "SUP-001",
                    "name": "Pacific Dairy Co.",
                    "rating": 92
                  },
                  "confirmation_ref": "ORD-2026-03-001"
                },
                "idempotencyKey": "completion-2026-03-001"
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Idempotent return — a completion with this idempotencyKey already exists for this record. Body is byte-identical to the original 201 response (with current recordStatus reflecting any state advance since creation).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Completion"
                }
              }
            }
          },
          "201": {
            "description": "Completion created. Phase 2 gate evaluation triggered asynchronously (or runs inline in auto mode + non-encrypted; verdict and lastVerdictReason populated when it does).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Completion"
                }
              }
            }
          },
          "400": {
            "description": "Completion evidence does not conform to the type schema. Inspect validationErrors for details and schemaUrl for the expected structure. The record remains in its current state — fix the evidence and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "URI reference identifying the problem type (RFC 9457)"
                    },
                    "title": {
                      "type": "string",
                      "description": "Short human-readable summary of the problem type (RFC 9457)"
                    },
                    "status": {
                      "type": "integer",
                      "description": "HTTP status code (RFC 9457)"
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation specific to this occurrence (RFC 9457)"
                    },
                    "instance": {
                      "type": "string",
                      "description": "URI reference identifying the specific occurrence (RFC 9457)"
                    },
                    "errors": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Structured validation errors (RFC 9457 extension, present on 400 responses)"
                    },
                    "retryable": {
                      "type": "boolean",
                      "description": "Whether the client should retry this request (true for 429, 5xx; false for 4xx)"
                    },
                    "error": {
                      "type": "string",
                      "description": "Machine-readable error code (e.g., NOT_FOUND, VALIDATION_ERROR, FORBIDDEN)"
                    },
                    "message": {
                      "type": "string",
                      "description": "Human-readable error description"
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Unique request identifier for support correlation"
                    },
                    "details": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Validation error details (present on 400/422 responses)"
                    },
                    "suggestion": {
                      "type": "string",
                      "description": "Suggested correction when a field-name typo is detected (e.g., \"Body contains 'type' — did you mean 'type'?\")"
                    },
                    "recoveryHint": {
                      "type": "string",
                      "description": "Machine-readable recovery guidance pointing to relevant endpoints (e.g., schema lookup URL)"
                    },
                    "missingFeatures": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "License features required but not available at the current tier"
                    },
                    "currentTier": {
                      "type": "string",
                      "description": "Current license tier (developer, org)"
                    },
                    "requiredTier": {
                      "type": "string",
                      "description": "Minimum tier required for the missing features"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Guided next actions for AI agents and integrations"
                    },
                    "missingScopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "API key scopes required but not present"
                    },
                    "hint": {
                      "type": "string",
                      "description": "Contextual hint for record/completion validation (e.g., schema lookup URL)"
                    },
                    "requiredFields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Required fields for the request body (present on 400 for record/completion creation)"
                    },
                    "optionalFields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Optional fields for the request body (present on 400 for record/completion creation)"
                    },
                    "examplePayload": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Example request body for record/completion creation"
                    },
                    "schemaUrl": {
                      "type": "string",
                      "description": "URL to the type schema for the expected evidence structure (e.g., /v1/schemas/principal-gate-generic-v1)"
                    },
                    "recordType": {
                      "type": "string",
                      "description": "Record Type (formerly Contract Type) related to the validation error"
                    },
                    "currentState": {
                      "type": "string",
                      "description": "Current state of the resource"
                    },
                    "attemptedTransition": {
                      "type": "string",
                      "description": "Transition that was attempted"
                    },
                    "attemptedState": {
                      "type": "string",
                      "description": "State the caller asked the resource to move to (federation: POST /federation/v1/state-transitions terminal-conflict 422 carries this alongside `currentState`)."
                    },
                    "validTransitions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Valid transitions from the current state"
                    },
                    "attemptedAction": {
                      "type": "string",
                      "description": "The /transition action name that was submitted"
                    },
                    "allowedActions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Action names accepted by POST /v1/records/{id}/transition in the current state"
                    },
                    "refreshUrl": {
                      "type": "string",
                      "description": "Concrete GET URL the agent should re-fetch to read fresh nextActions/validTransitions/allowedActions (set on 422 INVALID_ACTION when the request path includes a record id)."
                    },
                    "allowedValues": {
                      "type": "array",
                      "items": {},
                      "description": "Permitted values for the field that failed an enum constraint, or the registered list when the rejection is a \"no such X\" lookup (e.g., unknown type → registered types)."
                    },
                    "disputeCount": {
                      "type": "integer",
                      "description": "Number of disputes already filed against this record (open + terminal). Surfaced on 422 when the dispute cap is hit."
                    },
                    "maxDisputes": {
                      "type": "integer",
                      "description": "Maximum disputes allowed on this record (default 1). Surfaced alongside disputeCount when the cap is hit."
                    },
                    "openDisputeId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "ID of the currently-open dispute (EVIDENCE_WINDOW or TIER_2_REVIEW). Null when all prior disputes have terminalized. Surfaced on 422 when the dispute cap is hit so the agent can escalate the existing one rather than try to open another."
                    },
                    "currentStatus": {
                      "type": "string",
                      "description": "Display status of the record at the moment the request was refused. Surfaced on 422 when a dispute is attempted while verification is still in progress."
                    },
                    "disputeableWhen": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Display statuses from which POST /v1/records/{recordId}/dispute is accepted. Poll GET /v1/records/{recordId} until status is one of these, then retry."
                    },
                    "allowedActors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Role/actor labels permitted for this action in the current resource state. Surfaced on 403 cross-tier rejections (e.g., parent-principal trying to act on a sub-record it is not direct-principal of)."
                    },
                    "parentRecordId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID of the parent record that rejected the delegation attempt. Surfaced on 422 when the parent state cannot accept children."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Machine-readable reason code. On 409 conflicts: STATUS_NOT_DISABLED, RECORDS_REFERENCE_TYPE, CONFLICTING_VERSION, RESERVED_PUBLISHER_LABEL, VAULT_SCAN_IN_FLIGHT. On 422 authority-guard refusals: the snake_case guard identifier (has_children_leaf_only, leaf_record, no_children, children_not_terminal, mode_not_auto, mode_not_principal, record_disputed). Branch on this rather than on the prose in `detail`."
                    },
                    "jobId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID of the background job this request is being refused in favour of. Poll GET /v1/admin/vault/scan/{jobId} for its state and result. Present on 409 VAULT_SCAN_IN_FLIGHT."
                    },
                    "publisher": {
                      "type": "string",
                      "description": "Publisher label on the conflicting schema row."
                    },
                    "version": {
                      "type": "string",
                      "description": "Manifest version string on the conflicting schema row."
                    },
                    "incomingDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest of the manifest the caller just submitted."
                    },
                    "existingDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest of the manifest already registered at this (publisher, type, version)."
                    },
                    "publishers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Candidate publisher labels on a 422 `/problems/ambiguous-publisher`. Emitted by /v1/schemas/{type} reads and writes (pin with `?publisher=`) and by record creation (pin with a `publisher` body field)."
                    },
                    "pinnedRecords": {
                      "type": "integer",
                      "description": "Records written against the exact registration this delete would remove."
                    },
                    "unattributableRecords": {
                      "type": "integer",
                      "description": "Records of this type carrying no registration pin, so they block a delete under any publisher label."
                    },
                    "peerDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest the federation peer claimed in `schemaRef.manifestDigest`."
                    },
                    "localDigest": {
                      "type": "string",
                      "description": "sha256:<hex> digest the receiver holds locally for the same (publisher, type, version, org) tuple."
                    },
                    "revisionCount": {
                      "type": "integer",
                      "description": "Number of revisions consumed at the moment OVERFLOW_REJECT fired."
                    },
                    "maxRevisions": {
                      "type": "integer",
                      "description": "Configured maxRevisions cap on the record."
                    },
                    "terminalReason": {
                      "type": "string",
                      "description": "Machine-readable label naming the system action that terminalized the record (e.g. OVERFLOW_REJECT, ARBITRATION_LOCK, TIME_OUT)."
                    },
                    "deadline": {
                      "type": "string",
                      "format": "date-time",
                      "description": "The record deadline that had already passed when the request was refused (system TIME_OUT)."
                    },
                    "previousStatus": {
                      "type": "string",
                      "description": "Display status the record was at immediately before the terminal transition."
                    },
                    "constraintViolations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Constraint violations for the request"
                    },
                    "constraint": {
                      "type": "string",
                      "description": "Database constraint that was violated"
                    },
                    "validationErrors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyword": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "instancePath": {
                            "type": "string"
                          },
                          "params": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": true
                      },
                      "description": "JSON Schema validation errors from completion evidence validation"
                    },
                    "migratedTo": {
                      "type": "string",
                      "description": "Suggested replacement path for a renamed endpoint. Present on 404 responses for routes retired in a migration (e.g. /v1/admin/enterprises → /v1/admin/orgs)."
                    },
                    "expected": {
                      "type": "string",
                      "description": "Expected JSON type or value, paired with `received` on validation errors."
                    },
                    "signInputTemplate": {
                      "type": "string",
                      "description": "Exact byte template the Ed25519 proof-of-possession signature must cover, with the domain prefix. Surfaced on the federation 401 for an invalid signature."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Pointer to the discovery document section describing the failed scheme (e.g. \"/llms.txt (Federation Signing Scheme section)\"). Paired with signInputTemplate + hint on the federation 401."
                    }
                  },
                  "additionalProperties": false,
                  "description": "Completion evidence does not conform to the type schema. Inspect validationErrors for details and schemaUrl for the expected structure. The record remains in its current state — fix the evidence and retry."
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The record cannot take a completion in its current state: not ACTIVE, past its deadline (the record terminalizes to EXPIRED and the body carries `deadline` + `terminalReason: TIME_OUT`), the revision budget is spent (`revisionCount`/`maxRevisions`, terminalReason OVERFLOW_REJECT), or it has children and terminalizes by cascade rollup rather than a direct completion. detail names which; `refreshUrl` points at the record to re-read.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listCompletions",
        "summary": "List completions for a record",
        "tags": [
          "Completions"
        ],
        "description": "Returns a paginated list of all completions submitted against the specified record. The requester must have access to the parent record.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ACCEPTED",
                "INVALID",
                "WARNING"
              ]
            },
            "in": "query",
            "name": "structuralValidation",
            "required": false,
            "description": "Filter by Phase 1 structural validation result"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated completions for the record.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Paginated completions for the record.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Completion"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/completions/{completionId}": {
      "get": {
        "operationId": "getCompletion",
        "summary": "Get completion by ID",
        "tags": [
          "Completions"
        ],
        "description": "Retrieves a single completion by ID. The requester must have access to the parent record.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "completionId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Completion details with validation results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Completion"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "RecordRow or completion not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "operationId": "createWebhook",
        "summary": "Register a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "description": "Registers a new webhook subscription. The signing secret is generated server-side and returned once in the response -- store it securely for signature verification. The URL is validated against SSRF (blocks RFC 1918, link-local, loopback, and AWS metadata service IPs). Supports idempotency via the `Idempotency-Key` header.\n\n**Recommended events** (cover the full record lifecycle):\n`record.created` — a record now exists (status reflects final state after auto-activate),\n`record.completion_submitted` — an agent submitted a completion,\n`record.gate_complete` — gate evaluation finished,\n`record.gate_held` — principal-mode record held at PROCESSING awaiting the principal verdict; payload carries the `completionId` to verdict against plus the engine/rollup advisory result,\n`record.fulfilled` — the accept verdict (terminal),\n`record.failed` — the **reject** verdict / settlement HOLD. NOT terminal: the record sits at the recoverable FAILED (VERDICT_REJECTED) hub and may still go on to `record.revision_requested` → resubmit → `record.fulfilled`, or be remediated/disputed/overturned. So `record.failed` fires once per reject, including mid-rework — a failure-meter that counts it as a terminal failure double-counts every revision cycle. Branch on the payload's `outcome`/`recommendation` and pair it with `record.revision_requested` + `record.fulfilled` rather than treating the event name as a final count.\n`record.expired` / `record.cancelled` — terminal states.\n\nAlso available: `record.proposed`, `record.proposal_accepted`, `record.proposal_counter_proposed`, `record.proposal_rejected`, `record.delegated`, `record.revision_requested`, `signal.emitted` (exactly-once original-emit), `signal.received` (federation-derived signal — sender per-peer fan-out + receiver inbound), `dispute.opened`, `dispute.resolved`, `dispute.withdrawn`, `dispute.escalated`, `federation.record.state_changed`, `federation.settlement.signal`, `federation.dispute` (receiver-side — fires when the originator opens/resolves/withdraws a dispute on a record this Server counter-acknowledged; payload carries `action`, `disputeStatus`, `grounds`/`outcome`/`tier`), `record.federation_activated`/`_fulfilled`/`_remediated`/`_recorded`/`_cancelled`/`_expired`/`_proposal_rejected` (federation-projected lifecycle events; payload shape distinct from local `record.<state>`), `record.reference_added`, `agent.reference_added`, `record.ai_impact_assessment_filed`, `record.compliance_attestation_filed` (EU AI Act filings notarized against a record).\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "eventTypes"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "HTTPS endpoint URL to receive webhook deliveries. Accepts the same strings as the `GET /v1/webhooks?url=` provisioning filter, so a subscription created here is always findable by its exact URL. Rejected: a raw backslash, embedded control characters (tab/newline), and an empty authority such as `https:///hook`, because URL parsers silently reinterpret those into a different host than the one written. Percent-encode them instead."
                  },
                  "eventTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "record.created",
                        "record.recorded",
                        "record.registered",
                        "record.activated",
                        "record.completion_submitted",
                        "record.completion_invalid",
                        "record.gate_complete",
                        "record.gate_held",
                        "record.fulfilled",
                        "record.failed",
                        "record.expired",
                        "record.cancelled",
                        "record.proposed",
                        "record.proposal_accepted",
                        "record.proposal_counter_proposed",
                        "record.proposal_rejected",
                        "record.delegated",
                        "record.revision_requested",
                        "cascading.gate.complete",
                        "record.ai_impact_assessment_filed",
                        "record.compliance_attestation_filed",
                        "signal.emitted",
                        "signal.received",
                        "dispute.opened",
                        "dispute.resolved",
                        "dispute.withdrawn",
                        "dispute.escalated",
                        "federation.record.state_changed",
                        "federation.settlement.signal",
                        "federation.dispute",
                        "record.federation_activated",
                        "record.federation_fulfilled",
                        "record.federation_failed",
                        "record.federation_remediated",
                        "record.federation_recorded",
                        "record.federation_cancelled",
                        "record.federation_expired",
                        "record.federation_proposal_rejected",
                        "record.reference_added",
                        "agent.reference_added",
                        "*"
                      ],
                      "maxLength": 100
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "Event types to subscribe to. Use ['*'] to subscribe to all events. Valid types (40): record.created, record.recorded, record.registered, record.activated, record.completion_submitted, record.completion_invalid, record.gate_complete, record.gate_held, record.fulfilled, record.failed, record.expired, record.cancelled, record.proposed, record.proposal_accepted, record.proposal_counter_proposed, record.proposal_rejected, record.delegated, record.revision_requested, cascading.gate.complete, record.ai_impact_assessment_filed, record.compliance_attestation_filed, signal.emitted, signal.received, dispute.opened, dispute.resolved, dispute.withdrawn, dispute.escalated, federation.record.state_changed, federation.settlement.signal, federation.dispute, record.federation_activated, record.federation_fulfilled, record.federation_failed, record.federation_remediated, record.federation_recorded, record.federation_cancelled, record.federation_expired, record.federation_proposal_rejected, record.reference_added, agent.reference_added. This enum is exactly the set of events a subscription can fire on. The /v1/events `eventType` query enum is a deliberate superset — types queryable there but not subscribable here (`record.released`, `record.settled` (deprecated alias of `record.fulfilled`), `dispute.evidence_window_closed`) are persisted-event/replay surface only: settlement outcomes reach webhooks via `signal.emitted`/`signal.received`, not per-variant types."
                  },
                  "recordTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "Record types this subscription receives record-scoped events for. Omit (or ['*']) for all record types. A typed subscription NEVER receives a record event whose type it does not list (fail-closed), so confidentiality-segregated routing (e.g. a regulator channel for SAR types that the customer channel must not see) is enforced server-side. Owner fan-out events with no record in play (key lifecycle) are unaffected. Entries are not checked against the schema registry — a subscription may pre-date its type."
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "cloudevents"
                    ],
                    "default": "standard",
                    "description": "Payload format: standard (default) or cloudevents (CloudEvents 1.0 envelope with application/cloudevents+json content type)"
                  },
                  "signingAlg": {
                    "type": "string",
                    "enum": [
                      "hmac",
                      "ed25519",
                      "ecdsa-p256-sha256"
                    ],
                    "description": "Delivery signing scheme. Omit for the default: `hmac` (shared secret), except a subscription that explicitly lists a settlement event (`signal.emitted`/`signal.received`/`federation.settlement.signal`) defaults to the active vault key's RFC 9421 name when the Server has a signing key. An asymmetric name (`ed25519`, or `ecdsa-p256-sha256` on a Server opted into ES256; RFC 9421, signed with the vault key, verifiable against /v1/verification-keys, no shared secret) requires VAULT_SIGNING_KEY and must match the active key's algorithm; otherwise 422."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "example1": {
                  "value": {
                    "url": "https://api.example.com/webhooks/agledger",
                    "eventTypes": [
                      "record.created",
                      "record.completion_submitted",
                      "record.gate_complete",
                      "record.fulfilled",
                      "record.failed",
                      "record.expired",
                      "record.cancelled"
                    ]
                  }
                },
                "example2": {
                  "value": {
                    "url": "https://api.example.com/webhooks/signals",
                    "eventTypes": [
                      "signal.emitted",
                      "record.fulfilled",
                      "record.failed"
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Webhook created. The `secret` field is only returned on creation -- store it securely for HMAC signature verification.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL (e.g., SSRF blocked) or invalid event types.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "A non-hmac `signingAlg` was requested but this Server cannot sign with it: either VAULT_SIGNING_KEY is unset, or the active vault key signs a different algorithm. recoveryHint names the algorithm to use.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listWebhooks",
        "summary": "List webhook subscriptions",
        "tags": [
          "Webhooks"
        ],
        "description": "Returns webhook subscriptions for the authenticated owner. The secret field is NOT included in list responses.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response). Overrides offset when provided."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset for offset-based pagination. Ignored when cursor is provided."
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            },
            "in": "query",
            "name": "url",
            "required": false,
            "description": "Filter by exact webhook URL (for provisioning lookups). Byte-for-byte match against the stored value, so pass back the same string that was used at create."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookSubscription"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}": {
      "get": {
        "operationId": "getWebhook",
        "summary": "Get a webhook subscription by ID",
        "tags": [
          "Webhooks"
        ],
        "description": "Returns a single webhook subscription. The secret field is NOT included.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook subscription.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Deactivate a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "description": "Soft-deletes (deactivates) a webhook subscription. The webhook will no longer receive deliveries. Only the owner of the webhook can deactivate it.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "204": {
            "description": "Webhook deactivated successfully."
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook",
        "summary": "Update webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "description": "Update the URL and/or event type filters for an existing webhook subscription without regenerating the signing secret. Only the subscription owner can update.\n\n**Auth:** admin, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "New HTTPS endpoint URL. Same validation as POST /v1/webhooks and the `?url=` lookup filter."
                  },
                  "eventTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "record.created",
                        "record.recorded",
                        "record.registered",
                        "record.activated",
                        "record.completion_submitted",
                        "record.completion_invalid",
                        "record.gate_complete",
                        "record.gate_held",
                        "record.fulfilled",
                        "record.failed",
                        "record.expired",
                        "record.cancelled",
                        "record.proposed",
                        "record.proposal_accepted",
                        "record.proposal_counter_proposed",
                        "record.proposal_rejected",
                        "record.delegated",
                        "record.revision_requested",
                        "cascading.gate.complete",
                        "record.ai_impact_assessment_filed",
                        "record.compliance_attestation_filed",
                        "signal.emitted",
                        "signal.received",
                        "dispute.opened",
                        "dispute.resolved",
                        "dispute.withdrawn",
                        "dispute.escalated",
                        "federation.record.state_changed",
                        "federation.settlement.signal",
                        "federation.dispute",
                        "record.federation_activated",
                        "record.federation_fulfilled",
                        "record.federation_failed",
                        "record.federation_remediated",
                        "record.federation_recorded",
                        "record.federation_cancelled",
                        "record.federation_expired",
                        "record.federation_proposal_rejected",
                        "record.reference_added",
                        "agent.reference_added",
                        "*"
                      ],
                      "maxLength": 100
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "New event type filter. Same valid set as POST /v1/webhooks; use ['*'] for all."
                  },
                  "recordTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "New record-type filter. Use ['*'] to clear (receive all record types). Same fail-closed semantics as POST /v1/webhooks."
                  },
                  "isPaused": {
                    "type": "boolean",
                    "description": "Pause (true) or resume (false) webhook deliveries"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or event types.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403; concurrent modification returns 409.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Webhook was modified or deleted by a concurrent request; refresh and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Webhook is inactive; an inactive subscription cannot be updated.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/rotate": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "summary": "Rotate webhook signing secret",
        "tags": [
          "Webhooks"
        ],
        "description": "Generates a new HMAC-SHA256 signing secret for the webhook subscription. The new secret is returned once in the response -- store it securely. The old secret is immediately invalidated. Only the webhook owner can rotate.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated. The `secret` field contains the new signing secret -- store it securely.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403; concurrent modification returns 409.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Webhook was modified or deleted by a concurrent request; refresh and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Webhook is inactive, or the subscription signs asymmetrically (RFC 9421) and has no shared secret to rotate. Asymmetric subscriptions rotate via POST /v1/admin/vault/signing-keys/rotate instead.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/ping": {
      "post": {
        "operationId": "pingWebhook",
        "summary": "Send a test ping to a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Sends a signed test payload (`webhook.test` event) to the webhook URL and returns the response. Use this to verify your endpoint is reachable and correctly verifying signatures. Only the webhook owner can send pings.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Ping result with HTTP status code, response body (truncated to 1024 chars), and round-trip duration.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Ping result with HTTP status code, response body (truncated to 1024 chars), and round-trip duration.",
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer",
                      "description": "HTTP status code from the webhook endpoint (0 if connection failed)"
                    },
                    "body": {
                      "type": "string",
                      "description": "Response body from the endpoint (truncated to 1024 characters)"
                    },
                    "durationMs": {
                      "type": "integer",
                      "description": "Round-trip duration in milliseconds"
                    },
                    "success": {
                      "type": "boolean",
                      "description": "Whether the ping received a 2xx response"
                    },
                    "deliveryId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Unique delivery ID for this ping"
                    },
                    "httpStatus": {
                      "type": "integer",
                      "description": "Alias for statusCode — HTTP status code from the webhook endpoint"
                    },
                    "latencyMs": {
                      "type": "integer",
                      "description": "Alias for durationMs — round-trip duration in milliseconds"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID, or the subscription is paused / its circuit breaker is open (both refuse a test delivery with 400, unlike the DLQ retry routes which return 422 for a paused subscription).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The subscription cannot be signed: an asymmetric subscription on a Server with no VAULT_SIGNING_KEY, or an hmac subscription with no stored secret. recoveryHint names the fix.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/deliveries": {
      "get": {
        "operationId": "listDeliveries",
        "summary": "List webhook delivery log",
        "tags": [
          "Webhooks"
        ],
        "description": "Returns the delivery log for a specific webhook subscription, ordered by creation time descending. Use this to debug delivery failures and monitor retry status. Only the webhook owner can view deliveries.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response). Overrides offset when provided."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset for offset-based pagination. Ignored when cursor is provided."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "DELIVERED",
                "FAILED",
                "DEAD_LETTER"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by delivery status"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/dlq": {
      "get": {
        "operationId": "listWebhookDlq",
        "summary": "List dead-lettered events for a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Returns failed webhook deliveries that exhausted all retries. Only the subscription owner can view DLQ entries.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor from previous nextCursor (overrides offset)"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "subscriptionId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "eventId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "description": "Event type"
                          },
                          "recordId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "Correlation key for the affected record (null for federation peer events)."
                          },
                          "data": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Event-specific data"
                          },
                          "errorMessage": {
                            "type": "string"
                          },
                          "attempts": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/dlq/{dlqId}/retry": {
      "post": {
        "operationId": "retryWebhookDlq",
        "summary": "Retry a specific dead-lettered event",
        "tags": [
          "Webhooks"
        ],
        "description": "Removes the entry from the DLQ and re-enqueues it for delivery. Only the subscription owner can retry.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "dlqId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook or DLQ entry not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The subscription is paused; resume it (POST /v1/webhooks/{webhookId}/resume) before retrying dead-lettered events.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/dlq/retry-all": {
      "post": {
        "operationId": "retryAllWebhookDlq",
        "summary": "Retry all dead-lettered events for a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Removes all DLQ entries for this subscription and re-enqueues them (max 100 per call).\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "retried": {
                      "type": "integer",
                      "description": "Number of entries successfully re-enqueued"
                    },
                    "failed": {
                      "type": "integer",
                      "description": "Number of entries that failed to re-enqueue"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The subscription is paused; resume it (POST /v1/webhooks/{webhookId}/resume) before retrying dead-lettered events.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/pause": {
      "post": {
        "operationId": "pauseWebhook",
        "summary": "Pause webhook deliveries",
        "tags": [
          "Webhooks"
        ],
        "description": "Temporarily suspends delivery for this subscription. The subscription remains active and events arriving during the pause window are dropped (not queued). Resume to restart delivery.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook paused.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403; concurrent modification returns 409.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Webhook was modified or deleted by a concurrent request; refresh and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Webhook is inactive; an inactive subscription cannot be paused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{webhookId}/resume": {
      "post": {
        "operationId": "resumeWebhook",
        "summary": "Resume webhook deliveries",
        "tags": [
          "Webhooks"
        ],
        "description": "Resumes delivery for a paused subscription.\n\n**Auth:** admin, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook resumed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found. Cross-org access returns 403; concurrent modification returns 409.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Webhook was modified or deleted by a concurrent request; refresh and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Webhook is inactive; an inactive subscription cannot be resumed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "listEvents",
        "summary": "List events for reconciliation",
        "tags": [
          "Events"
        ],
        "description": "Reconciliation endpoint for consumers to catch events that may have been missed by webhooks. Requires a `since` timestamp to bound the query. Admin keys see events for records in their org; agent keys see events for records where they are principal or performer. Supports filtering by record ID and event type. Supports cursor-based pagination.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "since",
            "required": true,
            "description": "Return events created after this timestamp (required)"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "recordId",
            "required": false,
            "description": "Filter events for a specific record"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "agent.reference_added",
                "cascading.gate.complete",
                "dispute.escalated",
                "dispute.evidence_window_closed",
                "dispute.opened",
                "dispute.resolved",
                "dispute.withdrawn",
                "federation.dispute",
                "federation.record.state_changed",
                "federation.settlement.signal",
                "record.activated",
                "record.ai_impact_assessment_filed",
                "record.cancelled",
                "record.completion_invalid",
                "record.completion_submitted",
                "record.compliance_attestation_filed",
                "record.created",
                "record.delegated",
                "record.expired",
                "record.failed",
                "record.federation_activated",
                "record.federation_cancelled",
                "record.federation_expired",
                "record.federation_failed",
                "record.federation_fulfilled",
                "record.federation_proposal_rejected",
                "record.federation_recorded",
                "record.federation_remediated",
                "record.fulfilled",
                "record.gate_complete",
                "record.gate_held",
                "record.proposal_accepted",
                "record.proposal_counter_proposed",
                "record.proposal_rejected",
                "record.proposed",
                "record.recorded",
                "record.reference_added",
                "record.registered",
                "record.released",
                "record.revision_requested",
                "record.settled",
                "signal.emitted",
                "signal.received"
              ]
            },
            "in": "query",
            "name": "eventType",
            "required": false,
            "description": "Filter by event type. Closed enum — typos and renamed types 400 with `allowedValues` rather than silently returning empty pages."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "asc"
            },
            "in": "query",
            "name": "order",
            "required": false,
            "description": "Sort order by created_at (default: asc)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated events matching the filter criteria.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Paginated events matching the filter criteria.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "description": "Event type (e.g., record.created, gate.complete, dispute.resolved)"
                          },
                          "recordId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "agentId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "data": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Event-specific data"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/dispute": {
      "post": {
        "operationId": "initiateDispute",
        "summary": "Initiate a dispute with auto Tier 1 re-adjudication",
        "tags": [
          "Disputes"
        ],
        "description": "Initiates a dispute against a record. Tier 1 automatic re-adjudication runs immediately with expanded tolerance bands. If Tier 1 resolves the dispute, the response includes the auto-resolution result. If unresolved, the dispute remains OPEN for evidence submission and can be escalated to Tier 2 (manual review) and Tier 3 (binding arbitration). Emits `dispute.initiated` event.\n\nSupports idempotency via the `Idempotency-Key` header. Rate limited to 10 requests per minute.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "grounds"
                ],
                "properties": {
                  "grounds": {
                    "type": "string",
                    "enum": [
                      "equivalent_item",
                      "fraudulent_completion",
                      "record_ambiguity",
                      "pricing_dispute",
                      "quality_issue",
                      "verdict_disagreement",
                      "other"
                    ],
                    "description": "Category of dispute grounds"
                  },
                  "context": {
                    "type": "string",
                    "maxLength": 2000,
                    "minLength": 1,
                    "description": "Free-text explanation of the dispute"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "grounds": "pricing_dispute",
                "context": "The total price of $2,350 exceeds the record ceiling of $2,250 by 4.4%, outside the 3% tolerance band."
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Dispute created. If Tier 1 auto-resolved, `tier1Result.autoResolved` is true.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Dispute created. If Tier 1 auto-resolved, `tier1Result.autoResolved` is true.",
                  "type": "object",
                  "properties": {
                    "dispute": {
                      "$ref": "#/components/schemas/DisputeResponse"
                    },
                    "tier1Result": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "properties": {
                        "autoResolved": {
                          "type": "boolean",
                          "description": "Whether Tier 1 automatic re-adjudication resolved the dispute"
                        },
                        "outcome": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Auto-resolution outcome if resolved"
                        },
                        "reason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            null,
                            "outside_expanded_band",
                            "no_completion_to_readjudicate",
                            "type_not_resolved",
                            "principal_mode_no_readjudication",
                            "type_has_no_rules"
                          ],
                          "description": "Populated when autoResolved=false. Tells you why Tier 1 did not overturn the verdict — `outside_expanded_band` means re-adjudication ran with 1.5× tolerance and still failed, `principal_mode_no_readjudication` means the verdict was a human judgment call (rules cannot re-grade it), `type_has_no_rules` / `type_not_resolved` mean the Type does not have gate rules registered (notarize-only or DISABLED)."
                        }
                      },
                      "additionalProperties": false
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "This record already has an in-flight dispute. Escalate that one (POST /v1/records/{recordId}/dispute/escalate) or wait for it to resolve; a second concurrent dispute is not accepted.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The record cannot be disputed right now: verification is still in progress (body carries `currentStatus` + `disputeableWhen` -- poll GET /v1/records/{recordId} until status is one of those), or the dispute cap is spent with every prior dispute already terminal (`disputeCount`/`maxDisputes`, `openDisputeId: null`), which makes the verdict final. An in-flight dispute returns 409, not this.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getDispute",
        "summary": "Get dispute status and evidence history",
        "tags": [
          "Disputes"
        ],
        "description": "Retrieves the current dispute for a record, including all submitted evidence. The requester must have access to the parent record.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dispute details with full evidence history.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Dispute details with full evidence history.",
                  "type": "object",
                  "properties": {
                    "dispute": {
                      "$ref": "#/components/schemas/DisputeResponse"
                    },
                    "evidence": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DisputeEvidence"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "RecordRow or dispute not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/dispute/evidence": {
      "post": {
        "operationId": "submitDisputeEvidence",
        "summary": "Submit evidence during dispute window",
        "tags": [
          "Disputes"
        ],
        "description": "Submits evidence for an active dispute. Evidence can only be submitted while the evidence window is open (check `evidenceWindowClosesAt` on the dispute). Both parties (org and agent) can submit evidence. Supports idempotency via the `Idempotency-Key` header. Rate limited to 10 requests per minute.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "evidenceType",
                  "payload"
                ],
                "properties": {
                  "evidenceType": {
                    "type": "string",
                    "enum": [
                      "screenshot",
                      "external_lookup",
                      "document",
                      "communication",
                      "other"
                    ],
                    "description": "Category of evidence being submitted"
                  },
                  "payload": {
                    "type": "object",
                    "maxProperties": 100,
                    "description": "Evidence data payload"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "evidenceType": "document",
                "payload": {
                  "type": "invoice",
                  "url": "https://storage.example.com/invoices/INV-2026-001.pdf",
                  "description": "Original supplier invoice showing unit price of $4.29"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Evidence submitted and recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Evidence submitted and recorded.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "disputeId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "submittedByRole": {
                      "type": "string"
                    },
                    "submittedById": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "evidenceType": {
                      "type": "string",
                      "description": "Type of evidence: screenshot, external_lookup, document, communication, or other"
                    },
                    "payload": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Evidence data payload"
                    },
                    "payloadHash": {
                      "type": "string",
                      "description": "SHA-256 hash of the canonicalized evidence payload"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid evidence type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "RecordRow or dispute not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The evidence window has closed, or the dispute is no longer in a state that accepts evidence. `refreshUrl` points at GET /v1/records/{recordId}/dispute; read its `status` and `evidenceWindowClosesAt` before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/disputes": {
      "get": {
        "operationId": "listDisputes",
        "summary": "List disputes across the org (compliance browse)",
        "tags": [
          "Disputes"
        ],
        "description": "Org-wide dispute listing for compliance and triage workflows. Returns disputes across all records in the caller's org, filterable by `status` and/or `recordId`. Per-record dispute access stays available via `GET /v1/records/{id}/dispute`. For audit-grade reads (RECORD_READ chain entries), use the per-record `/audit-export` instead.\n\n**Auth:** org-admin only. Agent keys see disputes via per-record reads (records they're party to).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "EVIDENCE_WINDOW",
                "TIER_2_REVIEW",
                "ESCALATED",
                "TIER_3_ARBITRATION",
                "RESOLVED",
                "WITHDRAWN"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by dispute status. Unknown values return 400 — use one of the listed enum values. Only externally-observable statuses are listed; transient `OPENED`/`TIER_1_REVIEW` are never committed to the visible state."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "recordId",
            "required": false,
            "description": "Filter to a single record's dispute history."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Required for **platform** keys to scope the listing to one org. **org-admin** keys must omit this — admin keys can only list their own org."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Backwards-compat. Prefer `cursor` from a prior `nextCursor` for forward pagination."
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Opaque pagination cursor from a prior response's `nextCursor`. Round-trip verbatim — do not parse."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "initiatedByRole": {
                            "type": "string",
                            "enum": [
                              "principal",
                              "performer",
                              "org-admin",
                              "platform"
                            ],
                            "description": "Structural role of the dispute initiator relative to the record. `principal` and `performer` are the two parties to the disputed record; `org-admin` is a org-admin key acting on either side; `platform` is reserved for cross-org intervention."
                          },
                          "initiatedById": {
                            "type": "string",
                            "format": "uuid",
                            "description": "For agent keys (`principal`/`performer`), this is the agent UUID. For org-admin keys, this is the org UUID."
                          },
                          "grounds": {
                            "type": "string",
                            "description": "Dispute grounds category"
                          },
                          "context": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Free-text context explaining the dispute"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "EVIDENCE_WINDOW",
                              "TIER_2_REVIEW",
                              "ESCALATED",
                              "TIER_3_ARBITRATION",
                              "RESOLVED",
                              "WITHDRAWN"
                            ],
                            "description": "Dispute lifecycle state. Externally-observable values only — the engine writes transient `OPENED`/`TIER_1_REVIEW` inside the same transaction that opens the dispute and never commits a row at those states. Match against this enum."
                          },
                          "currentTier": {
                            "type": "integer",
                            "description": "Current dispute tier (1 = auto, 2 = manual review, 3 = binding arbitration)"
                          },
                          "outcome": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Resolution outcome: UPHELD, OVERTURNED, or SPLIT"
                          },
                          "resolutionRationale": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Explanation of the resolution decision"
                          },
                          "feeChargedTo": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Party charged the arbitration fee. **Engine does NOT compute fees** — AGLedger is the record-keeper, not the arbiter. Stays `null` until an external tribunal/admin process records the verdict. Tribunal integrations write this via the dispute repository on resolution."
                          },
                          "feeAmount": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Arbitration fee amount. **Engine does NOT compute fees** (record-keeper, not arbiter). Stays `null` until an external tribunal records the verdict."
                          },
                          "feeCurrency": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Currency of the arbitration fee (e.g., USD, EUR). Set by the external tribunal alongside `feeAmount`."
                          },
                          "evidenceWindowClosesAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "Deadline for evidence submission"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "resolvedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "nextSteps": {
                            "type": "array",
                            "items": {
                              "$ref": "#/components/schemas/NextStepAction"
                            },
                            "description": "Suggested next API calls for the dispute workflow"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/dispute/escalate": {
      "post": {
        "operationId": "escalateDispute",
        "summary": "Escalate dispute to next tier",
        "tags": [
          "Disputes"
        ],
        "description": "Escalates the dispute to the next resolution tier:\n\n- **Tier 1 -> Tier 2** (TIER_2_REVIEW): manual human review\n- **Tier 2 -> Tier 3** (TIER_3_ARBITRATION): binding arbitration with a flat fee\n\nTier 3 is the final tier and cannot be escalated further. Supports idempotency via the `Idempotency-Key` header. Rate limited to 10 requests per minute.\n\n**Auth:** admin, agent, platform (must have access to the record)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dispute after escalation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DisputeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Path parameter is not a UUID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "RecordRow or dispute not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The dispute is already at its maximum tier, or is not in an escalatable state. currentState + recoveryHint name the tier it is at and what remains available.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/dispute/withdraw": {
      "post": {
        "operationId": "withdrawDispute",
        "summary": "Withdraw an open dispute",
        "tags": [
          "Disputes"
        ],
        "description": "Withdraws a dispute the caller (or a org-admin) opened. Allowed while the dispute is in EVIDENCE_WINDOW or TIER_2_REVIEW — once the dispute reaches ESCALATED / TIER_3_ARBITRATION the tribunal owns it and only RESOLVE applies. (The state machine also permits withdrawal from OPENED / TIER_1_REVIEW, but those are transient in-transaction states the engine never commits to externally.) The dispute row transitions to WITHDRAWN with `outcome: null` (withdrawal is not a verdict). If the parent record is currently DISPUTED, it is restored to its pre-dispute status (mirrors RESOLVE_DISPUTE for pre-FULFILLED disputes). Emits `dispute.withdrawn` and appends a DISPUTE_STATE_CHANGE Signed Statement.\n\n**Auth:** the original dispute initiator (any agent or admin party who opened the dispute) OR a org-admin key. Other parties to the record are denied with 422.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Optional free-text reason recorded on the dispute and in the Signed Statement."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dispute after withdrawal (status=WITHDRAWN, outcome=null).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DisputeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record or dispute not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Caller is not the dispute initiator (and not a org-admin), or dispute is already in a terminal/tribunal-owned state.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{agentId}/reputation": {
      "get": {
        "operationId": "getAgentReputation",
        "summary": "Get composite reputation scores for all types",
        "tags": [
          "Reputation"
        ],
        "description": "Returns reputation scores for the specified agent across all types they have participated in. Each entry includes reliability, accuracy, and efficiency dimensions plus a confidence level that increases with transaction volume.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Reputation scores, one per type.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Reputation scores, one per type.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReputationScore"
                      },
                      "description": "Array of reputation scores, one per type."
                    },
                    "total": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{agentId}/reputation/{type}": {
      "get": {
        "operationId": "getAgentReputationByType",
        "summary": "Get reputation score for a specific type",
        "tags": [
          "Reputation"
        ],
        "description": "Returns the reputation score for the specified agent and type combination. Scores are auto-recalculated when gate.complete and dispute.resolved events occur.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "in": "path",
            "name": "type",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Reputation score for the agent and type, with recent history.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Reputation score for the agent and type, with recent history.",
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string",
                      "description": "Type this score applies to"
                    },
                    "reliabilityScore": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "description": "Task completion reliability (0-1)"
                    },
                    "accuracyScore": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "description": "Evidence accuracy vs record criteria, adjusted for overturned verdicts (0-1)"
                    },
                    "efficiencyScore": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "description": "Efficiency (0-1). v1 placeholder: currently mirrors accuracy until activation→completion timing is tracked."
                    },
                    "compositeScore": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "description": "Weighted composite of all dimensions (0-1)"
                    },
                    "confidenceLevel": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "description": "Statistical confidence (0-1); tightens as transaction volume grows"
                    },
                    "lifetimeRecords": {
                      "type": "integer",
                      "description": "Records ever assigned to this agent for this type (monotonic)"
                    },
                    "lifetimeVerdicts": {
                      "type": "integer",
                      "description": "Gate verdicts ever rendered for this agent+contract (monotonic)"
                    },
                    "lifetimeAccepted": {
                      "type": "integer",
                      "description": "Verdicts accepted, ever (monotonic — includes verdicts later overturned)"
                    },
                    "lifetimeCompletions": {
                      "type": "integer",
                      "description": "Completions ever accepted from this agent for this type (monotonic)"
                    },
                    "reversals": {
                      "type": "integer",
                      "description": "Count of dispute OVERTURNED outcomes; accuracy subtracts these from lifetimeAccepted"
                    },
                    "lastUpdatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "formulaVersion": {
                      "type": "integer",
                      "description": "Scoring formula version for reproducibility"
                    },
                    "recentHistory": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "description": "RecordRow status at time of record"
                          },
                          "outcome": {
                            "type": "string",
                            "description": "Gate verdict (accept, reject, PENDING)"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "completedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      },
                      "description": "Recent record history entries with gate verdicts (up to 10)"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Agent or type not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{agentId}/history": {
      "get": {
        "operationId": "getAgentHistory",
        "summary": "Get agent transaction history",
        "tags": [
          "Reputation"
        ],
        "description": "Returns the paginated transaction history for the specified agent. Agents can only view their own history; org and platform users can view any agent.\n\n**Auth:** admin, agent (own history only), platform",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Filter by type (e.g., notarize-generic-v1)"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "accept",
                "reject"
              ]
            },
            "in": "query",
            "name": "outcome",
            "required": false,
            "description": "Filter by gate verdict"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "from",
            "required": false,
            "description": "Filter records created on or after this date"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "to",
            "required": false,
            "description": "Filter records created on or before this date"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated transaction history for the agent.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Paginated transaction history for the agent.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "description": "RecordRow status at time of record"
                          },
                          "outcome": {
                            "type": "string",
                            "description": "Gate verdict (accept, reject, PENDING)"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "completedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of history entries"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{agentId}/capabilities": {
      "get": {
        "operationId": "getAgentCapabilities",
        "summary": "Get agent accepted types",
        "tags": [
          "Capabilities"
        ],
        "description": "Returns the types this agent has declared it accepts, enriched with reputation data for each type.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Agent capabilities with reputation enrichment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "declaredAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reputation": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "properties": {
                              "compositeScore": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "confidenceLevel": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "lifetimeRecords": {
                                "type": "integer"
                              },
                              "lifetimeAccepted": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    }
                  },
                  "additionalProperties": false,
                  "description": "Agent capabilities with reputation enrichment."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "setAgentCapabilities",
        "summary": "Set agent accepted types",
        "tags": [
          "Capabilities"
        ],
        "description": "Replace the full set of types this agent accepts. Empty array clears all declarations (agent accepts all types).\n\n**Auth:** agent (self only)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contractTypes"
                ],
                "properties": {
                  "contractTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 50
                    },
                    "maxItems": 100,
                    "description": "Types the agent accepts. Empty array clears all declarations."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Updated agent capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "declaredAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reputation": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "properties": {
                              "compositeScore": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "confidenceLevel": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "lifetimeRecords": {
                                "type": "integer"
                              },
                              "lifetimeAccepted": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false,
                  "description": "Updated agent capabilities."
                }
              }
            }
          },
          "400": {
            "description": "Invalid type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/verdict": {
      "post": {
        "operationId": "submitVerdict",
        "summary": "Submit the principal verdict on a completion",
        "tags": [
          "Gate"
        ],
        "description": "The principal (org owner, principal agent, or platform) submits an accept/reject verdict on a completion. Valid in `principal` gate mode while the record is awaiting the verdict — either at PROCESSING (no engine ran) or after the engine recorded an advisory pass (rules-bearing schema).\n\n`accept` settles the record to FULFILLED; `reject` lands it at FAILED.\n\nRecords a verdict result with `reporterType: \"principal\"` and emits gate.complete and settlement.signal events. Cascading rollup fires if the record is a sub-record.\n\n**Auth:** admin (must own record), agent (must be principal), platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "completionId",
                  "verdict"
                ],
                "properties": {
                  "completionId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Completion the verdict applies to"
                  },
                  "verdict": {
                    "type": "string",
                    "enum": [
                      "accept",
                      "reject"
                    ],
                    "description": "The principal verdict — accept settles to FULFILLED, reject to FAILED"
                  },
                  "checks": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Optional per-field check results (principal-defined)"
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 4000,
                    "description": "Optional free-text notes explaining the principal's verdict (recorded in audit trail)"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 4000,
                    "description": "Reason for the verdict (alias for notes — either field is accepted, notes takes precedence)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Verdict recorded. Record transitioned to FULFILLED (accept) or FAILED (reject).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Verdict recorded. Record transitioned to FULFILLED (accept) or FAILED (reject).",
                  "type": "object",
                  "properties": {
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "completionId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "accept",
                        "reject"
                      ]
                    },
                    "recommendation": {
                      "type": "string",
                      "enum": [
                        "SETTLE",
                        "HOLD",
                        "RELEASE"
                      ]
                    },
                    "reporterType": {
                      "type": "string",
                      "enum": [
                        "principal"
                      ]
                    },
                    "reportedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "recordStatus": {
                      "type": "string",
                      "description": "Record status after the verdict settled — FULFILLED (accept) or FAILED (reject). No re-fetch needed to learn the outcome."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Malformed request body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record or completion not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Either the record cannot take a verdict (outside COMPLETION_ACCEPTED/PENDING_VERDICT, gateMode `auto` so the engine renders it, or an open dispute), or the `completionId` is wrong: it belongs to a different record, or it has been superseded since you read it (the performer pushed refreshed evidence). The superseded case is the one to watch on a record that IS awaiting a verdict. recoveryHint names the fix; for the completion cases, re-fetch the record and use `latestCompletionId`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/evaluate": {
      "post": {
        "operationId": "evaluateGate",
        "summary": "Trigger an on-demand gate evaluation for a record",
        "tags": [
          "Gate"
        ],
        "description": "Runs the rules engine on one or more completions and returns the current gate results (for the specified completions, or all completions if none specified). In `principal` mode this produces an advisory result the principal can review before submitting their verdict; in `auto` mode the engine verdict is already final.\n\n**Auth:** admin, agent, platform",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "completionIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 50
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Gate evaluation result.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Gate evaluation result.",
                  "type": "object",
                  "properties": {
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "completions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "completionId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "phase1Result": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "additionalProperties": true
                          },
                          "phase2Result": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "overallStatus": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/gate-status": {
      "get": {
        "operationId": "getGateStatus",
        "summary": "Get gate status for a record",
        "tags": [
          "Gate"
        ],
        "description": "Returns Phase 1 (structural) and Phase 2 (gate evaluation) phase statuses, plus the rendered verdict and settlement recommendation when one exists. **For a polling consumer deciding settle-vs-hold on a non-disputed local record, key on `verdict` + `recommendation` (the business outcome) — NOT on `phase1Status` / `phase2Status`** (those are pass/fail per evaluation phase and can read `passed` on the structural side while the principal has rejected). `verdict` mirrors `records.{id}.verdict`; `recommendation` is `SETTLE` when accept, `HOLD` when reject, null while still awaiting a decision.\n\n**DISPUTED / federated caveat (mirrors `records.settlementSignal` suppression):** when the record is currently DISPUTED, or is a federation projection of a peer-rendered record, both `verdict` and `recommendation` are returned as `null` on this surface — the authoritative signal for those rows is `GET /v1/records/{id}` `settlementSignal` (which carries the dispute-overturn `RELEASE` and the peer-projected outcome). Polling consumers that may encounter dispute overturns MUST read the record body's `settlementSignal.recommendation` rather than this surface, or they will re-SETTLE a record whose payment has already been RELEASEd.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Gate status.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Gate status.",
                  "type": "object",
                  "properties": {
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "phase1Status": {
                      "type": "string",
                      "description": "Structural validation phase. `pending` | `passed` | `failed`. Pass/fail of the completion shape against the type's `completionSchema`; agents driving settle/hold should key on `verdict` instead."
                    },
                    "phase2Status": {
                      "type": "string",
                      "description": "Semantic (rules-engine) evaluation phase. `pending` | `in_progress` | `passed` | `failed`. **Caveat:** in `principal` gate mode, `phase2Status` reflects whichever verdict_results row is most recent (engine advisory or principal-rendered); `verdict` is the unambiguous accept/reject. Agents driving settle/hold should key on `verdict` + `recommendation`."
                    },
                    "lastEvaluatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "pendingRules": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "verdict": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "accept",
                        "reject",
                        null
                      ],
                      "description": "The rendered verdict (`accept` / `reject`) or null while still pending. Mirrors `records.{id}.verdict`. Final and signed-chain-stable once non-null."
                    },
                    "recommendation": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "SETTLE",
                        "HOLD",
                        null
                      ],
                      "description": "Settlement recommendation derived from the rendered verdict — `SETTLE` on accept, `HOLD` on reject, null while pending OR when the record is DISPUTED / federated (read `records.{id}.settlementSignal.recommendation` instead — that surface carries the dispute-overturn `RELEASE` and the peer-projected outcome)."
                    },
                    "gateMode": {
                      "type": "string",
                      "enum": [
                        "auto",
                        "principal"
                      ],
                      "description": "Gate mode for this record. `auto` = engine-rendered; `principal` = principal-rendered (engine may still run an advisory pass). Disambiguates `phase2Status` interpretation."
                    },
                    "reporterType": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "system",
                        "principal",
                        "accessor",
                        null
                      ],
                      "description": "Who wrote the latest verdict_results row. `system` = engine advisory (or auto-mode final); `principal` = principal-rendered; null while no verdict_results row exists yet."
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/compliance-records": {
      "post": {
        "operationId": "createComplianceRecord",
        "summary": "Create a compliance attestation record",
        "tags": [
          "Compliance"
        ],
        "description": "Records a deployer compliance attestation against a record. Required by EU AI Act for high-risk AI systems. Four record types are supported:\n\n- **workplace_notification**: Workers council / employee notification (Art. 26(7))\n- **affected_persons**: Affected persons notification (Art. 26(11))\n- **input_data_quality**: Input data quality review (Art. 26(4))\n- **fundamental_rights_impact_assessment**: Fundamental rights impact assessment (Art. 27)\n\nEach type requires specific attestation fields. Records are append-only and immutable.\n\n**Auth:** admin, platform (agents blocked — deployer obligation)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordType",
                  "attestation",
                  "attestedBy"
                ],
                "properties": {
                  "recordType": {
                    "type": "string",
                    "enum": [
                      "workplace_notification",
                      "affected_persons",
                      "input_data_quality",
                      "fundamental_rights_impact_assessment"
                    ],
                    "description": "Type of compliance attestation"
                  },
                  "attestation": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Attestation evidence (free-form JSONB, but required sub-fields are enforced at runtime per recordType — a missing field returns 400 naming it). Required fields by recordType:\n- **workplace_notification**: notification_date, notification_method, workers_informed\n- **affected_persons**: categories, notification_method, notification_date\n- **input_data_quality**: data_reviewed, review_date, data_sources\n- **fundamental_rights_impact_assessment**: risk_level, annex_iii_category, affected_groups, rights_assessed, mitigation_measures, residual_risk, assessment_date"
                  },
                  "attestedBy": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name or identifier of the person attesting"
                  },
                  "attestedAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "When the attestation was made (defaults to now)"
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "example1": {
                  "value": {
                    "recordType": "workplace_notification",
                    "attestation": {
                      "notification_date": "2026-03-01",
                      "notification_method": "email",
                      "workers_informed": "Engineering department (45 employees)"
                    },
                    "attestedBy": "Jane Smith, HR Director"
                  }
                },
                "example2": {
                  "value": {
                    "recordType": "affected_persons",
                    "attestation": {
                      "categories": [
                        "job applicants",
                        "current employees"
                      ],
                      "notification_method": "public notice",
                      "notification_date": "2026-03-01"
                    },
                    "attestedBy": "Legal Compliance Team"
                  }
                },
                "example3": {
                  "value": {
                    "recordType": "input_data_quality",
                    "attestation": {
                      "data_reviewed": true,
                      "review_date": "2026-02-28",
                      "data_sources": [
                        "internal HR database",
                        "skills assessment platform"
                      ]
                    },
                    "attestedBy": "Data Quality Officer"
                  }
                },
                "example4": {
                  "value": {
                    "recordType": "fundamental_rights_impact_assessment",
                    "attestation": {
                      "risk_level": "high",
                      "annex_iii_category": "employment",
                      "affected_groups": [
                        "job applicants",
                        "current employees"
                      ],
                      "rights_assessed": [
                        "non-discrimination",
                        "data protection"
                      ],
                      "mitigation_measures": [
                        "human review of all rejections",
                        "quarterly bias audit"
                      ],
                      "residual_risk": "low",
                      "assessment_date": "2026-02-25"
                    },
                    "attestedBy": "Fundamental Rights Officer"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Compliance record created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordType": {
                      "type": "string",
                      "enum": [
                        "workplace_notification",
                        "affected_persons",
                        "input_data_quality",
                        "fundamental_rights_impact_assessment"
                      ]
                    },
                    "attestation": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "attestedBy": {
                      "type": "string"
                    },
                    "attestedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false,
                  "description": "Compliance record created."
                }
              }
            }
          },
          "400": {
            "description": "Missing required attestation fields or invalid record type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listComplianceRecords",
        "summary": "List compliance records for a record",
        "tags": [
          "Compliance"
        ],
        "description": "Returns all compliance attestation records for the given record, ordered by creation date (newest first).\n\n**Auth:** admin, platform, or an agent that is principal or performer on the record. Requires scope `compliance:read`.",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "recordType": {
                            "type": "string",
                            "enum": [
                              "workplace_notification",
                              "affected_persons",
                              "input_data_quality",
                              "fundamental_rights_impact_assessment"
                            ]
                          },
                          "attestation": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "attestedBy": {
                            "type": "string"
                          },
                          "attestedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/compliance-records/{complianceRecordId}": {
      "get": {
        "operationId": "getComplianceRecord",
        "summary": "Get a compliance record by ID",
        "tags": [
          "Compliance"
        ],
        "description": "Retrieves a single compliance attestation record.\n\n**Auth:** admin, platform, or an agent that is principal or performer on the record. Requires scope `compliance:read`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "complianceRecordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Compliance record details.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordType": {
                      "type": "string",
                      "enum": [
                        "workplace_notification",
                        "affected_persons",
                        "input_data_quality",
                        "fundamental_rights_impact_assessment"
                      ]
                    },
                    "attestation": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "attestedBy": {
                      "type": "string"
                    },
                    "attestedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    }
                  },
                  "additionalProperties": false,
                  "description": "Compliance record details."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Compliance record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/audit-export": {
      "get": {
        "operationId": "getAuditExport",
        "summary": "Export audit trail for a record",
        "tags": [
          "Compliance"
        ],
        "description": "Generates a structured audit export for compliance record-keeping. Each entry carries a canonical COSE_Sign1 (RFC 9052, SCITT-aligned) envelope over an in-toto v1 Statement payload. The chain links via sha256 of each entry's envelope bytes; when VAULT_SIGNING_KEY is configured, the envelope signature is verifiable offline with the included public key — drive any RFC 9052 library (`go-cose`, `coset`, `pycose`) against the `signatureInputTemplate` on `/v1/verification-keys`. (`@agledger/verify` is on npm at v1.0.1 as a turnkey alternative.)\n\nSupports three output formats: JSON (default), CSV, and NDJSON.\n\n**Evidence:** pass `?evidence=true` to inline the completion evidence bodies at each COMPLETION_SUBMITTED entry — the export then carries what was declared, offline-verifiable by re-binding each body to the signed `payload.evidenceHash` (SHA-256 over RFC 8785 JCS canonical JSON; recipe in `verificationGuide.evidenceBinding`).\n\n**Auth:** admin, platform, or an agent that is principal or performer on the record (self-attestation). Requires scope `compliance:read`. Org-wide audit export is via `GET /v1/audit-vault/export` and remains admin-only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv",
                "ndjson",
                "cose"
              ],
              "default": "json"
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Export format: json (structured), csv (tabular), ndjson (one JSON object per line), cose (COSE_Sign1 sequence, RFC 9052 — served as application/cose-sequence)"
          },
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "receipts",
            "required": false,
            "description": "When `true`, each entry includes a base64-encoded SCITT Receipt at `integrity.receipt`. The Receipt is a COSE_Sign1 (draft-ietf-cose-merkle-tree-proofs) carrying the per-record Merkle root in its payload + an RFC 9162 inclusion proof at unprotected label 396. Opt-in to avoid bandwidth on consumers that only want the chain. Issued only when the engine has a `VAULT_SIGNING_KEY`; quietly absent in unsigned mode."
          },
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "evidence",
            "required": false,
            "description": "When `true`, each COMPLETION_SUBMITTED entry inlines the completion evidence body at its top-level `evidence` field, so the export carries WHAT was declared — not just its hash — with zero follow-up calls. The body is an UNSIGNED projection: the chain binds it via `payload.evidenceHash` (SHA-256 over RFC 8785 JCS canonical JSON — see `verificationGuide.evidenceBinding` for the offline re-binding recipe). Encrypted-mode bodies are the stored ciphertext envelope. JSON and NDJSON formats only."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Audit export (JSON format shown; CSV and NDJSON return raw text).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Audit export (JSON format shown; CSV and NDJSON return raw text).",
                  "type": "object",
                  "properties": {
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "chainIntegrity": {
                      "type": "boolean"
                    },
                    "chainIntegrityReason": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        null,
                        "chain_broken_at",
                        "audit_vault_row_missing_for_checkpoint",
                        "checkpoint_hash_mismatch",
                        "payload_drift",
                        "oidc_actor_drift",
                        "cert_actor_drift",
                        "cert_expired",
                        "cert_missing",
                        "agent_signature_invalid",
                        "signature_invalid",
                        "signing_key_unknown",
                        "unsupported_algorithm",
                        "signing_key_drift"
                      ],
                      "description": "Mirror of `exportMetadata.chainIntegrityReason`. Null when chainIntegrity is true."
                    },
                    "chainIntegrityDetail": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "description": "When chainIntegrity is false, localizes the break so a forensic auditor does not have to scan entries[] by hand. Null on a clean chain.",
                      "properties": {
                        "brokenAtPosition": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "minimum": 1
                        },
                        "brokenAtEntryId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        },
                        "expectedPreviousHash": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "actualPreviousHash": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "expectedPayloadHash": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "actualPayloadHash": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "failure": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            null,
                            "previous_hash_mismatch",
                            "payload_hash_mismatch",
                            "checkpoint_anchor_mismatch",
                            "audit_vault_truncated",
                            "payload_drift",
                            "oidc_actor_drift",
                            "cert_actor_drift",
                            "cert_expired",
                            "cert_missing",
                            "agent_signature_invalid",
                            "signature_invalid",
                            "signing_key_unknown",
                            "unsupported_algorithm",
                            "signing_key_drift"
                          ]
                        }
                      },
                      "required": [
                        "brokenAtPosition",
                        "brokenAtEntryId",
                        "expectedPreviousHash",
                        "actualPreviousHash",
                        "expectedPayloadHash",
                        "actualPayloadHash",
                        "failure"
                      ],
                      "additionalProperties": false
                    },
                    "signingPublicKey": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Mirror of `exportMetadata.signingPublicKey`."
                    },
                    "signingPublicKeys": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Mirror of `exportMetadata.signingPublicKeys` (keyId → base64 public key)."
                    },
                    "signatureCoverage": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "signed": {
                          "type": "integer",
                          "description": "Number of entries written by an engine with VAULT_SIGNING_KEY (signing_key_id IS NOT NULL)."
                        },
                        "unsigned": {
                          "type": "integer",
                          "description": "Number of entries with signing_key_id IS NULL (engine booted without VAULT_SIGNING_KEY at write time)."
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "signed",
                        "unsigned",
                        "total"
                      ]
                    },
                    "integrityLevel": {
                      "type": "string",
                      "enum": [
                        "hash_chain_only",
                        "hash_chain_partial_signatures",
                        "hash_chain_and_signatures",
                        "invalid"
                      ],
                      "description": "Discriminator on top of chainIntegrity. `hash_chain_only` = SHA-256 chain links verified, ZERO entries signed (no Ed25519 verification possible). `hash_chain_partial_signatures` = chain valid + a non-zero subset of entries signed (mixed-key rotation OR engine-booted-without-key on some writes). `hash_chain_and_signatures` = chain valid AND every entry signed. `invalid` = chainIntegrity is false. Auditors should NOT conclude \"Ed25519-verified\" from chainIntegrity:true alone — read this field."
                    },
                    "exportFormatVersion": {
                      "type": "string",
                      "description": "`2.0` since the COSE_Sign1 cutover. Major bump: per-entry signature/signatureAlg/hashAlg/canonical_payload fields dropped; each entry now carries a base64-encoded `coseSign1` envelope (RFC 9052) over an in-toto v1 Statement payload. Consumers MUST switch parsing on this field."
                    },
                    "canonicalization": {
                      "type": "string",
                      "description": "Canonicalization scheme. `RFC8949-CDE` since 2.0 — the COSE_Sign1 payload is deterministic CBOR (RFC 8949 §4.2.1 Core Deterministic Encoding) of an in-toto v1 Statement."
                    },
                    "verificationGuide": {
                      "type": "object",
                      "description": "Offline verification cookbook embedded in every export so an auditor reading the JSON top-down learns the procedure without scanning per-entry descriptions. The OOB-vs-embedded-key distinction is called out explicitly. Static text; same on every export from this install (the only variation is the externalUrl base in the OOB-keys hint).",
                      "properties": {
                        "summary": {
                          "type": "string"
                        },
                        "steps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "unsignedFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Per-entry top-level fields that are display projections resolved at export time and are NOT signature-covered (actorDisplayName, actorOwnerType, humanReadableLabel). Editing any of these in an exported file does NOT break offline verification — a verifier still reports PASS. Attribution is the signed `actorId`/`actorOwnerId` UUIDs; treat these as human-readable decoration only."
                        },
                        "evidenceBinding": {
                          "type": "string",
                          "description": "How completion evidence binds to the chain — `payload.evidenceHash` is SHA-256 over the RFC 8785 (JCS) canonicalization of the evidence JSON, distinct from the chain envelope's RFC8949-CDE CBOR canonicalization. Includes the offline re-binding recipe and the `?evidence=true` inlining option."
                        },
                        "embeddedKeysHint": {
                          "type": "string"
                        },
                        "oobKeysHint": {
                          "type": "string"
                        },
                        "offlineVerifier": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "summary",
                        "steps",
                        "unsignedFields",
                        "evidenceBinding",
                        "embeddedKeysHint",
                        "oobKeysHint",
                        "offlineVerifier"
                      ],
                      "additionalProperties": false
                    },
                    "exportMetadata": {
                      "type": "object",
                      "properties": {
                        "recordId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "orgId": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "type": {
                          "type": "string"
                        },
                        "operatingMode": {
                          "type": "string",
                          "enum": [
                            "cleartext",
                            "encrypted"
                          ]
                        },
                        "exportDate": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "totalEntries": {
                          "type": "integer"
                        },
                        "expectedEntries": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "description": "Latest signed checkpoint position for this record, or null if no checkpoint has been written yet. When non-null, totalEntries should equal expectedEntries; otherwise the chain has been truncated or pruned out-of-band. null is EXPECTED on a fresh install or for records newer than the last checkpoint sweep (VAULT_ANCHOR_INTERVAL_MINUTES, default every 6 hours) — skip the truncation cross-check until the first checkpoint lands; it is not a defect."
                        },
                        "chainIntegrity": {
                          "type": "boolean"
                        },
                        "chainIntegrityReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            null,
                            "chain_broken_at",
                            "audit_vault_row_missing_for_checkpoint",
                            "checkpoint_hash_mismatch",
                            "payload_drift",
                            "oidc_actor_drift",
                            "cert_actor_drift",
                            "cert_expired",
                            "cert_missing",
                            "agent_signature_invalid",
                            "signature_invalid",
                            "signing_key_unknown",
                            "unsupported_algorithm",
                            "signing_key_drift"
                          ],
                          "description": "Null when chainIntegrity is true. Otherwise: chain_broken_at = hash/link mismatch inside the chain; audit_vault_row_missing_for_checkpoint = chain shorter than the latest checkpoint anchor (likely TRUNCATE/DELETE); checkpoint_hash_mismatch = the entry at the anchored position does not match the signed checkpoint hash; payload_drift = visible `payload` jsonb diverges from the predicate signed in cose_sign1 (privileged-DBA-bypass tamper of the denormalized view); oidc_actor_drift = row actor_oidc_iss/sub columns diverge from the signed metadata.on_behalf_of.oidc claim (column-only tamper of OIDC actor attribution); cert_actor_drift = row actor_cert_id diverges from the signed predicate.on_behalf_of.cert.id (cert binding tamper); cert_expired = chain entry cwt.iat falls outside the cert's [issued_at, expires_at] window; cert_missing = predicate.on_behalf_of.cert.id references a cert row that no longer exists; agent_signature_invalid = predicate.on_behalf_of.agent_signature does not verify against the cert's bound public key; signing_key_drift = a populated signing_key_id column names a different key than the signature-covered kid in the entry's protected header (denormalized column rewritten); signature_invalid = an entry's COSE_Sign1 signature does not verify against its resolved signing key (envelope bytes rewritten; fail-closed); signing_key_unknown = an entry names a signing_key_id the key registry cannot resolve, so its signature is unverifiable (fail-closed); unsupported_algorithm = the entry's registered signing key names a signature algorithm this build cannot compute, so its signature is unverifiable (fail-closed; remedy is upgrading the Server, not tamper forensics)."
                        },
                        "chainIntegrityDetail": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "description": "When chainIntegrity is false, localizes the break (position, entry id, expected-vs-actual hashes, failure sub-classification). Null on a clean chain.",
                          "properties": {
                            "brokenAtPosition": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 1
                            },
                            "brokenAtEntryId": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "uuid"
                            },
                            "expectedPreviousHash": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "actualPreviousHash": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "expectedPayloadHash": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "actualPayloadHash": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "failure": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                null,
                                "previous_hash_mismatch",
                                "payload_hash_mismatch",
                                "checkpoint_anchor_mismatch",
                                "audit_vault_truncated",
                                "payload_drift",
                                "oidc_actor_drift",
                                "cert_actor_drift",
                                "cert_expired",
                                "cert_missing",
                                "agent_signature_invalid",
                                "signature_invalid",
                                "signing_key_unknown",
                                "unsupported_algorithm",
                                "signing_key_drift"
                              ]
                            }
                          },
                          "required": [
                            "brokenAtPosition",
                            "brokenAtEntryId",
                            "expectedPreviousHash",
                            "actualPreviousHash",
                            "expectedPayloadHash",
                            "actualPayloadHash",
                            "failure"
                          ],
                          "additionalProperties": false
                        },
                        "signatureCoverage": {
                          "type": "object",
                          "additionalProperties": false,
                          "properties": {
                            "signed": {
                              "type": "integer"
                            },
                            "unsigned": {
                              "type": "integer"
                            },
                            "total": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "signed",
                            "unsigned",
                            "total"
                          ]
                        },
                        "integrityLevel": {
                          "type": "string",
                          "enum": [
                            "hash_chain_only",
                            "hash_chain_partial_signatures",
                            "hash_chain_and_signatures",
                            "invalid"
                          ]
                        },
                        "exportFormatVersion": {
                          "type": "string"
                        },
                        "canonicalization": {
                          "type": "string"
                        },
                        "signingPublicKey": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "signingPublicKeys": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "All known signing public keys (keyId → base64 public key)"
                        },
                        "signingKeyWindows": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "activatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "retiredAt": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "format": "date-time"
                              }
                            }
                          },
                          "description": "keyId → signing-key temporal-validity window {activatedAt, retiredAt}. Input for an offline verifier's key_temporal check (an entry written outside its signing key's active window). Additive since v0.26."
                        }
                      },
                      "additionalProperties": false
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "chainPosition": {
                            "type": "integer",
                            "description": "Per-record monotonic chain position (1-indexed). Canonical name across /audit-export and /audit-vault/export."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Per-entry recordId, equal to the parent export's recordId. Surfaced at the entry level so consumers filtering/correlating across a flat NDJSON stream do not have to parse `payload` for it."
                          },
                          "actorId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "API-key id of the credential that performed this state-change. Mirrors the row's `actor_key_id` column (also inlined inside `payload._actor.keyId`)."
                          },
                          "actorRole": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "admin",
                              "agent",
                              "platform",
                              null
                            ],
                            "description": "Role of the credential that performed this state-change. Mirrors the row's `actor_role` column."
                          },
                          "actorOwnerId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Owner id of the API key — org id when actorRole=admin, agent id when actorRole=agent, platform sentinel when actorRole=platform. Pair with `actorDisplayName` for the human-readable label and `actorOwnerType` for the owner table."
                          },
                          "actorDisplayName": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Human-readable label for the actor owner (agent display_name, org name, or static \"Platform\"). Display PROJECTION — NOT signature-covered. Auditors verifying the chain still pull `integrity.coseSign1` and re-validate offline; this field exists to make the report readable, not authoritative. NULL when the owner row was deleted (rare)."
                          },
                          "actorOwnerType": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "agent",
                              "org",
                              "platform",
                              null
                            ],
                            "description": "Owner table discriminator. Pairs with `actorOwnerId` so an auditor can find the source row."
                          },
                          "actorOidcIss": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "OIDC issuer URI when the request authenticated via an admin OIDC bearer. NULL on API-key paths. Paired with `actorOidcSub`. The same identity is signature-covered inside `predicate.on_behalf_of.oidc` on the COSE_Sign1 envelope."
                          },
                          "actorOidcSub": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "OIDC subject (stable user id at the IdP), paired with `actorOidcIss`."
                          },
                          "actorOidcSynthesized": {
                            "type": "boolean",
                            "description": "TRUE iff the engine synthesized actor_oidc_iss/sub (admin OIDC / WIF path) rather than them riding in a delegated on_behalf_of claim. Input for an offline verifier's OIDC-actor cross-check (verify-core `oidcActor.synthesized`); without it that check is skipped_no_input."
                          },
                          "entryType": {
                            "type": "string"
                          },
                          "humanReadableLabel": {
                            "type": "string",
                            "description": "Auditor-readable label for `entryType` (e.g. RECORD_STATE_CHANGE → \"Record state transitioned\", OUTCOME_REPORTED → \"Principal rendered verdict\"). Static vocabulary, fixed per release. Display PROJECTION — NOT signature-covered. The canonical machine-readable name stays in `entryType`. Replaces the previously-shipped `description` field which mirrored `entryType` verbatim (placeholder; dropped pre-launch)."
                          },
                          "payload": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Denormalized predicate view (jsonb), Server-rebuilt at read time to strip on_behalf_of/traceparent and re-project from the signed envelope. Privileged-DBA tamper of the underlying jsonb column is detected via `chainIntegrityReason: payload_drift` (verifyChain rebuilds the predicate from this jsonb and deep-equals against the signed predicate in cose_sign1; any divergence flips chainIntegrity to false and per-entry `integrity.valid` to false at the drifted position). For independent cryptographic verification, use `integrity.coseSign1` — `payload` is the convenience view."
                          },
                          "evidence": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Completion evidence body, present only when `?evidence=true` AND this is a COMPLETION_SUBMITTED entry. UNSIGNED projection — the chain binds it by hash only: recompute SHA-256 over the RFC 8785 (JCS) canonicalization of this object and compare against `payload.evidenceHash` (recipe in `verificationGuide.evidenceBinding`). Encrypted-mode records inline the stored ciphertext envelope; their `evidenceHash` is client-supplied over the cleartext."
                          },
                          "integrity": {
                            "type": "object",
                            "properties": {
                              "payloadHash": {
                                "type": "string",
                                "description": "sha256 of the canonical COSE_Sign1 envelope bytes."
                              },
                              "previousHash": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "coseSign1": {
                                "type": "string",
                                "description": "Base64-encoded canonical COSE_Sign1 (RFC 9052) envelope over an in-toto v1 Statement payload. Verify with any RFC 9052 library (`go-cose`, `coset`, `pycose`) against the publicKey at the matching `signingKeyId` — the `signatureInputTemplate` field on `/v1/verification-keys` documents the byte-level signing input. (`@agledger/verify` is on npm at v1.0.1 as a turnkey alternative.)"
                              },
                              "signingKeyId": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "valid": {
                                "type": "boolean"
                              },
                              "receipt": {
                                "type": "string",
                                "description": "Base64-encoded SCITT Receipt (COSE_Sign1 per draft-ietf-cose-merkle-tree-proofs-18) for this leaf. Present only when `?receipts=true` AND the engine has a `VAULT_SIGNING_KEY`. Payload = per-record Merkle root the TS signed at issuance time; unprotected label 396 (VDP) carries the RFC 9162 §2.1.3 inclusion proof `[tree_size, leaf_index, [audit_path...]]` at key `-1`."
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "recordId",
                    "chainIntegrity",
                    "chainIntegrityReason",
                    "signatureCoverage",
                    "integrityLevel",
                    "exportFormatVersion",
                    "canonicalization",
                    "verificationGuide",
                    "exportMetadata",
                    "entries"
                  ],
                  "additionalProperties": false
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string",
                  "description": "Returned when `?format` selects text/csv."
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "Returned when `?format` selects application/x-ndjson."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/attestation": {
      "get": {
        "operationId": "getRecordAttestation",
        "summary": "Get canonical chain envelopes for a record (COSE_Sign1)",
        "tags": [
          "Compliance"
        ],
        "description": "Returns the canonical chain envelopes for a record's audit trail as a stream of tagged COSE_Sign1 messages (RFC 9052 §4.4, CBOR tag 18). Each envelope wraps an in-toto v1 Statement payload and carries the engine's Ed25519 signature. The chain is the product — this endpoint is the byte-level truth.\n\n**Content-Type:** `application/cose-sequence`. Consumers parse tagged COSE_Sign1 messages sequentially (each begins with `0xd2 0x84 …`).\n\n**Receipts:** pass `?receipts=true` to upgrade each Signed Statement to a Transparent Statement — the per-record Merkle Receipt is attached at unprotected label 394 (SCITT-arch §3.2). Each Receipt is a COSE_Sign1 (draft-ietf-cose-merkle-tree-proofs) carrying the per-record Merkle root in its payload + an RFC 9162 inclusion proof at unprotected label 396. Quietly omitted when the engine has no `VAULT_SIGNING_KEY`.\n\n**Verification:** any RFC 9052 library (`go-cose`, `coset`, `pycose` with `allow_unknown_attributes=True`) reads the same bytes — `signatureInputTemplate` on `/v1/verification-keys` documents the byte-level signing input so no AGLedger package is required. (`@agledger/verify` is published on npm at v1.0.1 as a turnkey alternative.)\n\n**Auth:** admin, platform, or an agent that is principal or performer on the record (self-attestation). Requires scope `audit:read`.",
        "parameters": [
          {
            "schema": {
              "type": "boolean",
              "default": false
            },
            "in": "query",
            "name": "receipts",
            "required": false,
            "description": "When `true`, each envelope in the response is a Transparent Statement (Signed Statement + per-record SCITT Receipt attached at unprotected label 394). When `false` or omitted, the response is a cose-sequence of bare Signed Statements."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Stream of tagged COSE_Sign1 envelopes (binary).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Stream of tagged COSE_Sign1 envelopes (binary).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/attestation.bundle": {
      "get": {
        "operationId": "getRecordAttestationBundle",
        "summary": "Get sigstore-bundle v0.3 for a record's head chain entry",
        "tags": [
          "Compliance"
        ],
        "description": "Returns a sigstore-bundle v0.3 envelope (`application/vnd.dev.sigstore.bundle.v0.3+json`) for the record's most recent chain entry. Response body IS the bundle JSON — no `{data: [...]}` wrapper.\n\nFor ingest into in-toto consumers / sigstore-policy-controller / SIEM. Customers wanting every chain entry pull `/attestation` (cose-sequence) or `/audit-export`.\n\n**Verifying with cosign 3.x.** AGLedger is a private-Sigstore deployment — BYO Ed25519 key, no Fulcio cert, no public Rekor. cosign's default policy requires a tlog entry; pass `--private-infrastructure` (the cosign-blessed flag for this case, NOT named \"insecure\") to skip tlog verification. The blob argument is the record-id as a UTF-8 string — cosign hashes it and matches against the in-toto Statement subject. Canonical invocation: `cosign verify-blob-attestation --bundle bundle.json --key vault.pem --type \"https://agledger.ai/predicates/record-state/v1\" --private-infrastructure <(printf '%s' \"$RECORD_ID\")`.\n\n**Cryptographic verification of the chain itself:** NOT against this bundle. The inner DSSE Ed25519 signature is byte-incompatible with the canonical COSE_Sign1 Sig_structure — they are two independent signatures over two independent pre-images. The bundle covers the in-toto Statement payload only; chain linkage lives on `/attestation` (COSE_Sign1). Auditors verify the chain via `@agledger/verify` against `/attestation`.\n\n**Unsigned mode:** 404 when the engine has no `VAULT_SIGNING_KEY` (no signing identity to issue a fresh bundle).\n\n**Auth:** same as `/attestation` — admin, platform, or party-on-record. Scope `audit:read`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "sigstore-bundle v0.3 envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "sigstore-bundle v0.3 envelope."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found, or engine has no signing key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit-vault/export": {
      "get": {
        "operationId": "bulkAuditVaultExport",
        "summary": "Bulk export Signed Statements",
        "tags": [
          "Compliance"
        ],
        "description": "Paginated export of Signed Statements across records with chain verification metadata. Supports filtering by date range, record ID, and agent ID. Includes chain-of-custody metadata (first/last chain positions and hash chain validity). Supports JSON (default) and NDJSON output formats.\n\n**Auth:** admin, platform (agents blocked — deployer obligation)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "from",
            "required": false,
            "description": "Include entries created at or after this timestamp"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "to",
            "required": false,
            "description": "Include entries created before this timestamp"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "recordId",
            "required": false,
            "description": "Filter by record ID"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "agentId",
            "required": false,
            "description": "Filter by agent ID (matches records where performer_agent_id = this value)"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "ndjson"
              ],
              "default": "json"
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Output format"
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response)"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Max entries per page"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "entryType": {
                            "type": "string"
                          },
                          "humanReadableLabel": {
                            "type": "string",
                            "description": "Auditor-readable label for `entryType` (static vocabulary, fixed per release). Display PROJECTION — NOT signature-covered."
                          },
                          "payload": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Denormalized predicate view (jsonb), Server-rebuilt at read time to strip on_behalf_of/traceparent and re-project from the signed envelope. Privileged-DBA tamper of the underlying jsonb column is detected via the per-record /audit-export endpoint's `chainIntegrityReason: payload_drift` (verifyChain rebuilds the predicate from this jsonb and deep-equals against the signed predicate in cose_sign1). For independent cryptographic verification, use `coseSign1` — `payload` is the convenience view."
                          },
                          "payloadHash": {
                            "type": "string",
                            "description": "sha256 of the canonical COSE_Sign1 envelope bytes."
                          },
                          "previousHash": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "chainPosition": {
                            "type": "integer"
                          },
                          "coseSign1": {
                            "type": "string",
                            "description": "Base64-encoded canonical COSE_Sign1 (RFC 9052) envelope."
                          },
                          "signingKeyId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "actorId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "API-key id of the credential that performed this state-change. Mirrors the row's `actor_key_id` column (also inlined inside `payload._actor.keyId`). Matches the per-record /audit-export shape."
                          },
                          "actorRole": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "admin",
                              "agent",
                              "platform",
                              null
                            ],
                            "description": "Role of the credential that performed this state-change. Mirrors the row's `actor_role` column. Matches the per-record /audit-export shape."
                          },
                          "actorOwnerId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Owner id of the API key — org id when actorRole=admin, agent id when actorRole=agent, platform sentinel when actorRole=platform."
                          },
                          "actorDisplayName": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Human-readable label for the actor owner (agent display_name, org name, or static \"Platform\"). Display PROJECTION — NOT signature-covered. NULL when the owner row was deleted."
                          },
                          "actorOwnerType": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "agent",
                              "org",
                              "platform",
                              null
                            ],
                            "description": "Owner table discriminator. Pairs with actorOwnerId so an auditor can find the source row."
                          },
                          "actorOidcIss": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "OIDC issuer URI when the request authenticated via an admin OIDC bearer. NULL on API-key paths. Paired with `actorOidcSub`. The same identity is signature-covered inside `predicate.on_behalf_of.oidc` on the COSE_Sign1 envelope."
                          },
                          "actorOidcSub": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "OIDC subject (stable user id at the IdP), paired with `actorOidcIss`."
                          },
                          "actorOidcSynthesized": {
                            "type": "boolean",
                            "description": "TRUE iff the engine synthesized actor_oidc_iss/sub (admin OIDC / WIF path) rather than them riding in a delegated on_behalf_of claim. Input for an offline verifier's OIDC-actor cross-check (verify-core `oidcActor.synthesized`); parity with the per-record export."
                          },
                          "coseSign1Decoded": {
                            "type": "boolean",
                            "description": "TRUE iff the engine successfully decoded `coseSign1` and projected `payload.on_behalf_of` / `payload.traceparent` from the signed predicate. FALSE means the envelope failed to decode and the projection silently no-op'd — same integrity signal as `chainIntegrity` on the per-record export."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "exportMetadata": {
                      "type": "object",
                      "description": "Export-level metadata. Mirrors the per-record /audit-export shape so bulk consumers can verify signatures without a second call to /v1/verification-keys.",
                      "properties": {
                        "exportFormatVersion": {
                          "type": "string",
                          "description": "`2.0` since the COSE_Sign1 cutover."
                        },
                        "canonicalization": {
                          "type": "string",
                          "description": "Canonicalization scheme. `RFC8949-CDE` since 2.0 (deterministic CBOR per RFC 8949 §4.2.1)."
                        },
                        "signingPublicKey": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Currently active signing public key (base64)."
                        },
                        "signingPublicKeys": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "All known signing keys (keyId → base64 public key) for verifying historical entries."
                        },
                        "signingKeyWindows": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "activatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "retiredAt": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "format": "date-time"
                              }
                            }
                          },
                          "description": "keyId → signing-key temporal-validity window {activatedAt, retiredAt}. Input for an offline verifier's key_temporal check. Additive since v0.26."
                        }
                      },
                      "additionalProperties": false
                    },
                    "chainMetadata": {
                      "type": "object",
                      "properties": {
                        "firstPosition": {
                          "type": [
                            "null",
                            "integer"
                          ]
                        },
                        "lastPosition": {
                          "type": [
                            "null",
                            "integer"
                          ]
                        },
                        "hashChainValid": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    },
                    "verificationGuide": {
                      "type": "object",
                      "description": "Top-level offline-verification cookbook. Same shape and content as the per-record endpoint — bulk consumers reading the JSON top-down learn the procedure without scanning per-entry descriptions.",
                      "properties": {
                        "summary": {
                          "type": "string"
                        },
                        "steps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "unsignedFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Per-entry top-level fields that are display projections resolved at export time and are NOT signature-covered (actorDisplayName, actorOwnerType, humanReadableLabel). Editing any of these in an exported file does NOT break offline verification — a verifier still reports PASS. Attribution is the signed `actorId`/`actorOwnerId` UUIDs; treat these as human-readable decoration only."
                        },
                        "evidenceBinding": {
                          "type": "string",
                          "description": "How completion evidence binds to the chain — `payload.evidenceHash` is SHA-256 over the RFC 8785 (JCS) canonicalization of the evidence JSON, distinct from the chain envelope's RFC8949-CDE CBOR canonicalization. Includes the offline re-binding recipe; evidence inlining (`?evidence=true`) is on the per-record /audit-export endpoint."
                        },
                        "embeddedKeysHint": {
                          "type": "string"
                        },
                        "oobKeysHint": {
                          "type": "string"
                        },
                        "offlineVerifier": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "summary",
                        "steps",
                        "unsignedFields",
                        "evidenceBinding",
                        "embeddedKeysHint",
                        "oobKeysHint",
                        "offlineVerifier"
                      ],
                      "additionalProperties": false
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "bulkExport": {
                      "type": "object",
                      "description": "Bulk RECORD_READ manifest completion — one manifest row + N per-record RECORD_READ entries tagged with exportBatchId. Customer queries `org_admin_reads WHERE export_batch_id = $1` to recover the per-record reads beside the manifest.",
                      "properties": {
                        "exportBatchId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "manifestId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "recordCount": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "queryHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64,
                          "description": "sha256 of canonical(filter) — proves two manifests came from the same query without revealing extra fields."
                        }
                      },
                      "required": [
                        "exportBatchId",
                        "manifestId",
                        "recordCount",
                        "queryHash"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "Returned when `?format` selects application/x-ndjson."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit-vault/checkpoints": {
      "get": {
        "operationId": "listVaultCheckpoints",
        "summary": "List vault checkpoints for offline integrity verification",
        "tags": [
          "Compliance"
        ],
        "description": "Returns vault_checkpoints rows — the per-record 6h signed Merkle anchors that survive audit_vault TRUNCATE/DELETE. Pair with /v1/records/{id}/audit-export to cross-check the live chain against the checkpoint anchor; if they diverge, the live chain has been tampered with out-of-band. See `chainIntegrityReason: \"audit_vault_row_missing_for_checkpoint\"` and `\"checkpoint_hash_mismatch\"` on /audit-export for the engine's own cross-check.\n\nCheckpoints are written by a scheduled sweep, so an empty `data` array on a young install is normal rather than a gap: read the `checkpointing` sidecar for the cadence, the next scheduled run, and when the last checkpoint was written.\n\nThree chains are checkpointed, discriminated by the `chain` field: per-record, per-org schema-registration, and platform-ops. Only `chain: \"record\"` carries a real record id (see `recordId`). An org-scoped key sees its own record and schema checkpoints; the platform-ops chain is platform-scope.\n\n**Auth:** admin (org-admin) or platform. Scope `compliance:read`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "recordId",
            "required": false,
            "description": "Filter to a single record."
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response)."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "in": "query",
            "name": "limit",
            "required": false
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of vault checkpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Paginated list of vault checkpoints.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "The uuid this checkpoint is keyed to. **Read `chain` before treating it as a record id.** Only `chain: \"record\"` rows point at a real record; for `\"schema\"` and `\"admin\"` this is a derived key that resolves to no record (GET /v1/records/{id} returns 404 by design). The schema key is recomputable offline from the org id alone: `sha256(\"agledger:schema-chain-checkpoint:v1|\" + orgId)`, first 16 bytes, then byte 6 masked to UUID version 8 (`b6 & 0x0f | 0x80`) and byte 8 to the RFC 4122 variant (`b8 & 0x3f | 0x80`). The admin key is the fixed platform sentinel `00000000-0000-0000-0000-000000000000`. The key is committed inside the signed COSE_Sign1 payload (`subject[0].digest.sha256` over the uuid bytes, and `cwt.sub`), so it is part of what the signature covers."
                          },
                          "chain": {
                            "type": "string",
                            "enum": [
                              "record",
                              "schema",
                              "admin"
                            ],
                            "description": "Which chain this checkpoint anchors. `record` = the per-record chain, keyed by a real record id. `schema` = an org's schema-registration chain (record-less; `record_id IS NULL` on the covered audit_vault rows). `admin` = the platform-ops chain (ADMIN_KEY_CREATED, ACCOUNT_DEACTIVATED, and similar). All three are the same signed-checkpoint construction over a different chain."
                          },
                          "chainPosition": {
                            "type": "integer"
                          },
                          "payloadHash": {
                            "type": "string",
                            "minLength": 64,
                            "maxLength": 64,
                            "description": "sha256 of cose_sign1 envelope bytes."
                          },
                          "coseSign1": {
                            "type": "string",
                            "description": "Base64-encoded canonical COSE_Sign1 envelope (RFC 9052 §4.4, tag 18) carrying a `vault-checkpoint` claim."
                          },
                          "signingKeyId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "recordId",
                          "chainPosition",
                          "payloadHash",
                          "coseSign1",
                          "createdAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    },
                    "checkpointing": {
                      "type": "object",
                      "description": "When the checkpoint sweep runs, and when it last did. Checkpoints are written on a schedule, not per record, so a fresh install legitimately returns an empty `data` array until the first sweep fires (up to VAULT_ANCHOR_INTERVAL_MINUTES after boot, 6h by default) no matter how many records it holds. A vault scan reports `healthy: true` throughout that window, so read this block before concluding that checkpoints are missing.",
                      "properties": {
                        "cron": {
                          "type": "string",
                          "description": "Cron expression the sweep runs on, in UTC."
                        },
                        "intervalMinutes": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "description": "Cadence in minutes, derived from `cron` (VAULT_ANCHOR_INTERVAL_MINUTES). Null when the schedule is not a fixed interval."
                        },
                        "nextRunAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "Next scheduled sweep. Null when the schedule names no reachable next run, or when it is registered in a non-UTC timezone."
                        },
                        "lastCheckpointAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "Write time of the most recent checkpoint visible to this caller, under the same scope as `data`. Null means none has been written yet for that scope."
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "worker",
                            "config"
                          ],
                          "description": "`worker` = read from the schedule the worker registered, which is authoritative. `config` = the worker schedule was unreadable and this is the API process's own configuration, which can differ if the two processes carry different environments."
                        },
                        "anchoringEnabled": {
                          "type": "boolean",
                          "description": "Whether checkpoints are also anchored off-box (VAULT_ANCHOR_ENABLED). False means the signed checkpoints live only in the database they attest to."
                        }
                      },
                      "required": [
                        "cron",
                        "intervalMinutes",
                        "nextRunAt",
                        "lastCheckpointAt",
                        "source",
                        "anchoringEnabled"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/compliance/export": {
      "post": {
        "operationId": "createComplianceExport",
        "summary": "Initiate a compliance data export",
        "tags": [
          "Compliance"
        ],
        "description": "Creates an **org-wide** compliance export (every record in the org, across all agents). The export is built synchronously: the response carries `status: ready` and a live `downloadUrl`. **Row cap: 10000 records, newest first.** When the filters match more, the response sets `truncated: true` with the full match count in `totalRecords`; split the range with `filters.from`/`filters.to` and export window by window to cover it all. This is a compliance-officer operation — scope `compliance:write`, **admin/platform only; agents are blocked** (an agent key is scoped to its own records and must not pull the whole org's trail).\n\n**Producing your own evidence (the agent self-path):** an agent does NOT need this endpoint to make an offline-verifiable packet for records it is principal/performer on. Use the per-record `GET /v1/records/{id}/audit-export` (scope `compliance:read`, included in `agent-full`) — add `?embed=signed-statements` for a self-contained COSE_Sign1 pack. `audit-export` is self-attestation; `compliance/export` is the privileged org-wide bulk path. (A self-scoped, claim-level multi-record export for agents is not offered today — assemble per-record packets, or have a compliance-scoped key run the org export filtered by `filters.ref`.)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "format"
                ],
                "properties": {
                  "format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "json",
                      "html"
                    ],
                    "description": "Export format. `csv` and `json` are SIEM-ingest shapes. `html` renders an inspector-ready report (plain-English narrative, per-record table, per-record /attestation URLs, cryptographic-evidence footer) sized for EU AI Act Article 12 inspector audits."
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "orgId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "from": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "to": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "contractTypes": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 20
                      },
                      "ref": {
                        "type": "object",
                        "properties": {
                          "system": {
                            "type": "string",
                            "maxLength": 100,
                            "description": "Reference system, e.g. claims, jira, sap."
                          },
                          "refType": {
                            "type": "string",
                            "maxLength": 100,
                            "description": "Reference type within the system, e.g. claim, ticket."
                          },
                          "refId": {
                            "type": "string",
                            "maxLength": 500,
                            "description": "External identifier, e.g. the claim number."
                          }
                        },
                        "additionalProperties": false,
                        "minProperties": 1,
                        "description": "Scope the export to the records tagged with this entity reference. At least one of system/refType/refId; partial refs match on the supplied sub-fields only."
                      },
                      "recordIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "maxItems": 1000,
                        "description": "Explicit record-id allowlist — the escape hatch when the claim was not ref-tagged. Org scope still applies."
                      },
                      "rootRecordId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Scope to a single delegation tree (the root and all descendants). Misses records in sibling trees joined only by shared reference — prefer `ref` for a full cross-actor claim pack."
                      }
                    },
                    "additionalProperties": false
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 64,
                    "description": "Optional column selection. When omitted, the export carries the default rich row (id, type, status, principalAgentId, performerAgentId, gateMode, verdict, riskClassification, euAiActDomain, assessmentRiskLevel, assessmentDomain, assessmentOverseerName, complianceAttestationCount, complianceAttestationTypes, correlationId, externalTaskId, requestedBy, category, revisionCount, maxRevisions, disputeCount, maxDisputes, imported, source, lastTransitionReason, createdAt, activatedAt, fulfilledAt, expiredAt). The `assessment*` columns come from the record's EU AI Act Article-9 impact assessment (null when none filed) and are DISTINCT from the create-time riskClassification/euAiActDomain — declared vs formally-assessed, now on the same risk/domain taxonomy. The `complianceAttestation*` columns summarize the record's Article-26/27/49 deployer attestations (POST /records/{id}/compliance-records): `complianceAttestationCount` (integer) and `complianceAttestationTypes` (distinct record_types filed, e.g. workplace_notification, fundamental_rights_impact_assessment). Opt-in extras: `criteria` (JSONB), `tolerance` (JSONB), `assessmentHumanOversight` (JSONB, Article 14), `assessmentTestingResults` (JSONB, Article 15), `complianceAttestations` (JSONB array — full attestation evidence [{recordType, attestedBy, attestedAt, attestation}, …]), `chainIntegrity` (expensive — per-row verifyChain against audit_vault; reserve for regulator packets)."
                  },
                  "embed": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "signed-statements"
                      ]
                    },
                    "maxItems": 4,
                    "description": "Inline cryptographic evidence into the packet so a regulator/court verifies it offline without trusting this server. `signed-statements` embeds each record's full COSE_Sign1 chain (base64) on a per-row `signedStatements` array, and the JSON/HTML download attaches a `verification` block (signing public keys, key temporal windows, and the offline-verification cookbook). Re-derive sha256 over each `coseSign1` to confirm `payloadHash`, then verify the Ed25519 signature against `verification.signingPublicKeys` — or run `@agledger/verify`. Not supported for format=csv (a record has many statements). Scope to one claim first (filters.ref/recordIds/rootRecordId); embed is capped at 1000 records."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Export initiated.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Export initiated.",
                  "type": "object",
                  "properties": {
                    "exportId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "ready"
                      ]
                    },
                    "downloadUrl": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "recordCount": {
                      "type": "integer",
                      "description": "Rows in the export. Capped at 10000 (newest first); compare with `truncated`/`totalRecords`."
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "True when the filters matched more than the 10000-row export cap. The export holds the newest 10000 rows; window with `filters.from`/`filters.to` to fetch the rest."
                    },
                    "totalRecords": {
                      "type": "integer",
                      "description": "Total rows the filters matched, before the cap. Equals `recordCount` unless `truncated`."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/compliance/export/{exportId}": {
      "get": {
        "operationId": "getComplianceExport",
        "summary": "Get compliance export status",
        "tags": [
          "Compliance"
        ],
        "description": "Check the status of a compliance export job and retrieve download URL when ready.\n\n**Auth:** admin, platform (agents blocked)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "exportId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Export status.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Export status.",
                  "type": "object",
                  "properties": {
                    "exportId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "ready",
                        "failed"
                      ]
                    },
                    "downloadUrl": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "recordCount": {
                      "type": "integer",
                      "description": "Rows in the export. Capped at 10000 (newest first); compare with `truncated`/`totalRecords`."
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "True when the filters matched more than the 10000-row export cap, so this export holds only the newest 10000 rows. Re-read from the stored export, not recomputed, so it is the same answer the create response gave. Exports created before this field existed report `false`."
                    },
                    "totalRecords": {
                      "type": "integer",
                      "description": "Total rows the filters matched at creation time, before the cap. Equals `recordCount` unless `truncated`."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Export not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/compliance/export/{exportId}/download": {
      "get": {
        "operationId": "downloadComplianceExport",
        "summary": "Download compliance export data",
        "tags": [
          "Compliance"
        ],
        "description": "Returns the actual export data in the format specified at creation time (JSON or CSV). Export data expires 24 hours after creation.\n\n**Auth:** admin, platform (agents blocked)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "exportId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Export data (JSON object or CSV text depending on format).",
            "headers": {
              "X-AGLedger-Export-Record-Count": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rows in this artifact."
              },
              "X-AGLedger-Export-Total-Records": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rows the filters matched at creation time, before the 10000-row cap. Absent on exports created before the cap was persisted (unknown, not \"not truncated\")."
              },
              "X-AGLedger-Export-Truncated": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                },
                "description": "Whether this artifact is the newest 10000 rows of a larger match set. Absent means unknown."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Export data (JSON object or CSV text depending on format).",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "recordCount": {
                      "type": "integer",
                      "description": "Rows in this artifact. Capped at 10000 (newest first); compare with `truncated`/`totalRecords`."
                    },
                    "format": {
                      "type": "string",
                      "enum": [
                        "csv",
                        "json",
                        "html"
                      ]
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "True when the export is the newest 10000 rows of a larger match set. Also on the `X-AGLedger-Export-Truncated` response header for every format (the only place a CSV download can carry it), and stated in the HTML packet header and scope narrative."
                    },
                    "totalRecords": {
                      "type": "integer",
                      "description": "Total rows the filters matched at creation time, before the cap. Equals `recordCount` unless `truncated`. Header twin: `X-AGLedger-Export-Total-Records`."
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true,
                      "nullable": true
                    }
                  },
                  "additionalProperties": false
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string",
                  "description": "Returned when `?format` selects text/csv."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Export not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{recordId}/ai-impact-assessment": {
      "post": {
        "operationId": "createAiImpactAssessment",
        "summary": "Create AI impact assessment for a record",
        "tags": [
          "Compliance"
        ],
        "description": "Records an EU AI Act Article 9 impact assessment against a record. One assessment per record.\n\n**Auth:** admin, platform (agents blocked)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "riskLevel",
                  "domain"
                ],
                "properties": {
                  "riskLevel": {
                    "type": "string",
                    "enum": [
                      "unacceptable",
                      "high",
                      "limited",
                      "minimal"
                    ]
                  },
                  "domain": {
                    "type": "string",
                    "enum": [
                      "biometrics",
                      "critical_infrastructure",
                      "education",
                      "employment",
                      "essential_services",
                      "law_enforcement",
                      "migration",
                      "justice"
                    ]
                  },
                  "humanOversight": {
                    "type": "object",
                    "description": "Human oversight designation per EU AI Act Art. 14. Required: overseerName, overseerRole, authorityScope, designatedAt (date-time). Optional: overseerContact. No additional properties.",
                    "properties": {
                      "overseerName": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerRole": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "overseerContact": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "authorityScope": {
                        "type": "string",
                        "maxLength": 2000
                      },
                      "designatedAt": {
                        "type": "string",
                        "format": "date-time"
                      }
                    },
                    "required": [
                      "overseerName",
                      "overseerRole",
                      "authorityScope",
                      "designatedAt"
                    ],
                    "additionalProperties": false
                  },
                  "testingResults": {
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Assessment created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "riskLevel": {
                      "type": "string",
                      "enum": [
                        "unacceptable",
                        "high",
                        "limited",
                        "minimal"
                      ]
                    },
                    "domain": {
                      "type": "string",
                      "enum": [
                        "biometrics",
                        "critical_infrastructure",
                        "education",
                        "employment",
                        "essential_services",
                        "law_enforcement",
                        "migration",
                        "justice"
                      ]
                    },
                    "overseerName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "humanOversight": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "additionalProperties": true
                    },
                    "testingResults": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "additionalProperties": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false,
                  "description": "Assessment created."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Assessment already exists for this record.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getAiImpactAssessment",
        "summary": "Get AI impact assessment for a record",
        "tags": [
          "Compliance"
        ],
        "description": "Retrieves the EU AI Act impact assessment for a record.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Assessment details.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "recordId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "riskLevel": {
                      "type": "string",
                      "enum": [
                        "unacceptable",
                        "high",
                        "limited",
                        "minimal"
                      ]
                    },
                    "domain": {
                      "type": "string",
                      "enum": [
                        "biometrics",
                        "critical_infrastructure",
                        "education",
                        "employment",
                        "essential_services",
                        "law_enforcement",
                        "migration",
                        "justice"
                      ]
                    },
                    "overseerName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "humanOversight": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "additionalProperties": true
                    },
                    "testingResults": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "additionalProperties": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    }
                  },
                  "additionalProperties": false,
                  "description": "Assessment details."
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Assessment not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit/org-reads/checkpoints": {
      "get": {
        "operationId": "listOrgAdminReadsCheckpoints",
        "summary": "List org_admin_reads checkpoints",
        "tags": [
          "Audit"
        ],
        "description": "Returns the calling org's org_admin_reads checkpoints (Trillian STH shape), newest first. Each row is the signed Merkle root over leaves [0..tree_size-1] at sweep time. Witness cosignature columns are null until an external auditor cosigns via POST …/checkpoints/:id/cosign. Paginated — pass `cursor` or `offset` to page past `limit`.\n\n**Auth:** admin or agent (audit:read).",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "treeSize": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "rootHash": {
                            "type": "string",
                            "minLength": 64,
                            "maxLength": 64
                          },
                          "checkpointAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "logId": {
                            "type": "string"
                          },
                          "coseSign1Base64": {
                            "type": "string",
                            "description": "Base64 of the canonical COSE_Sign1 (RFC 9052) envelope over the STH. Decode to extract the Ed25519 signature + signed payload."
                          },
                          "signingKeyId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "witnessSignature": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "witnessKeyId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "witnessCosignedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "orgId",
                          "treeSize",
                          "rootHash",
                          "checkpointAt",
                          "logId",
                          "coseSign1Base64",
                          "signingKeyId",
                          "witnessSignature",
                          "witnessKeyId",
                          "witnessCosignedAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "data",
                    "total",
                    "nextCursor",
                    "hasMore"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit/org-reads/checkpoints/{id}": {
      "get": {
        "operationId": "getOrgAdminReadsCheckpoint",
        "summary": "Get a org_admin_reads checkpoint",
        "tags": [
          "Audit"
        ],
        "description": "Returns one signed checkpoint envelope by id.\n\n**Auth:** admin or agent (audit:read).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "treeSize": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "rootHash": {
                      "type": "string",
                      "minLength": 64,
                      "maxLength": 64
                    },
                    "checkpointAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "logId": {
                      "type": "string"
                    },
                    "coseSign1Base64": {
                      "type": "string",
                      "description": "Base64 of the canonical COSE_Sign1 (RFC 9052) envelope over the STH. Decode to extract the Ed25519 signature + signed payload."
                    },
                    "signingKeyId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessSignature": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessKeyId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessCosignedAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "orgId",
                    "treeSize",
                    "rootHash",
                    "checkpointAt",
                    "logId",
                    "coseSign1Base64",
                    "signingKeyId",
                    "witnessSignature",
                    "witnessKeyId",
                    "witnessCosignedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Checkpoint not found in caller's org.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit/org-reads/checkpoints/{id}/cosign": {
      "post": {
        "operationId": "cosignOrgAdminReadsCheckpoint",
        "summary": "Apply witness cosignature to a org_admin_reads checkpoint",
        "tags": [
          "Audit"
        ],
        "description": "Customer's external auditor cosigns the checkpoint envelope with their own key. A compromised engine cannot fork the log undetected — the witness key would have to cosign both forks. witnessSignature and witnessKeyId are stored verbatim; the engine does NOT verify the witness signature (the customer's audit process does that). Each checkpoint may be cosigned at most once.\n\n**Auth:** admin (org-admin) only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "witnessKeyId",
                  "witnessSignature"
                ],
                "properties": {
                  "witnessKeyId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Identifier for the witness key (verifier-supplied; e.g. fingerprint or DID)."
                  },
                  "witnessSignature": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "Witness signature over the checkpoint's STH bytes. Format/algorithm is the customer's choice; the cap accommodates post-quantum signatures (base64 ML-DSA-87 is ~6.2k chars)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "treeSize": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "rootHash": {
                      "type": "string",
                      "minLength": 64,
                      "maxLength": 64
                    },
                    "checkpointAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "logId": {
                      "type": "string"
                    },
                    "coseSign1Base64": {
                      "type": "string",
                      "description": "Base64 of the canonical COSE_Sign1 (RFC 9052) envelope over the STH. Decode to extract the Ed25519 signature + signed payload."
                    },
                    "signingKeyId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessSignature": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessKeyId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "witnessCosignedAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "id",
                    "orgId",
                    "treeSize",
                    "rootHash",
                    "checkpointAt",
                    "logId",
                    "coseSign1Base64",
                    "signingKeyId",
                    "witnessSignature",
                    "witnessKeyId",
                    "witnessCosignedAt",
                    "nextSteps"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Checkpoint not found in caller's org, or already cosigned.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Checkpoint is already cosigned (per-checkpoint witness signature is single-use).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit/org-reads/checkpoints/{id}/proof": {
      "get": {
        "operationId": "getOrgAdminReadsInclusionProof",
        "summary": "Get Merkle inclusion proof for a leaf at a checkpoint",
        "tags": [
          "Audit"
        ],
        "description": "Returns the inclusion path that proves leaf at index `leaf` is included in the checkpoint's root hash. Verifier walks: sha256(left || right) up the path, comparing to the checkpoint's rootHash.\n\n**Auth:** admin or agent (audit:read).",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "in": "query",
            "name": "leaf",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "leafIndex": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "leafHash": {
                      "type": "string",
                      "minLength": 64,
                      "maxLength": 64
                    },
                    "treeSize": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "rootHash": {
                      "type": "string",
                      "minLength": 64,
                      "maxLength": 64
                    },
                    "path": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 64,
                        "maxLength": 64
                      }
                    }
                  },
                  "required": [
                    "leafIndex",
                    "leafHash",
                    "treeSize",
                    "rootHash",
                    "path"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Checkpoint not found, or leaf index out of range for this checkpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/graph": {
      "get": {
        "operationId": "getRecordGraph",
        "summary": "Get delegation chain graph for a record",
        "tags": [
          "Records"
        ],
        "description": "Returns the delegation chain as nodes and edges for visualization. Walks parent_record_id chain upward and finds all sub-records recursively. Also includes informational depends_on edges.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Graph representation of the delegation chain.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Graph representation of the delegation chain.",
                  "type": "object",
                  "properties": {
                    "nodes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "label": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "performerAgentId": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "chainDepth": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "edges": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "source": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "target": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "delegation",
                              "dependency"
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Get authenticated user profile",
        "tags": [
          "Auth"
        ],
        "description": "Returns the profile of the currently authenticated key. Admin keys include org name from the orgs table. Agent keys include display name and org from the agents table. Platform keys return null for profile fields.\n\nFor OIDC ephemeral-cert (Mode 2) sessions, `authType` is `ephemeral_cert` and `cert` + `oidc` carry the bound credential identity (the resolved agent is `ownerId` + `name`, same as a long-lived agent key).\n\n**Auth:** admin, agent, platform",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Authenticated user profile.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Authenticated user profile.",
                  "type": "object",
                  "properties": {
                    "apiKeyId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "admin",
                        "agent",
                        "platform"
                      ]
                    },
                    "ownerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "ownerType": {
                      "type": "string"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "Org for admin+agent keys; null for platform"
                    },
                    "scopes": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      },
                      "description": "Key scopes. null = full access for role."
                    },
                    "expiresAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    },
                    "allowedIps": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      }
                    },
                    "name": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "createdAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    },
                    "authType": {
                      "type": "string",
                      "enum": [
                        "api_key",
                        "ephemeral_cert",
                        "oidc"
                      ],
                      "description": "Credential class for this session. `ephemeral_cert` = OIDC-bound short-lived signing cert (Mode 2); `oidc` = direct OIDC bearer (admin Mode 1); `api_key` = long-lived `agl_` key."
                    },
                    "cert": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "description": "Present (non-null) only for `ephemeral_cert` sessions — the bound short-lived signing cert.",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "thumbprint": {
                          "type": "string"
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false,
                      "nullable": true
                    },
                    "oidc": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "description": "Present (non-null) for OIDC-bound sessions — the upstream IdP identity that minted the credential.",
                      "properties": {
                        "iss": {
                          "type": "string"
                        },
                        "sub": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": false,
                      "nullable": true
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/keys/rotate": {
      "post": {
        "operationId": "rotateApiKey",
        "summary": "Rotate API key",
        "tags": [
          "Auth"
        ],
        "description": "Issues a new API key and retires the current one. The new key is returned once — store it securely.\n\nBy default the old key is deactivated IMMEDIATELY (it 401s on the next request) — correct for rotating a compromised key. For zero-downtime hygiene rotation across a fleet, pass `gracePeriodSeconds` to keep the old key valid for a bounded overlap window (the response `previousKeyDeactivatesAt` is when it stops working); deploy the new key everywhere, then let the old one lapse. Alternatively, mint a second key via POST /v1/admin/api-keys and revoke the old one once traffic has moved (the multi-active-keys model).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "gracePeriodSeconds": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Optional overlap window (seconds) the OLD key stays valid after rotation, for zero-downtime fleet rollover. 0 / omitted = immediate cutover. Capped by AUTH_KEY_ROTATION_MAX_GRACE_SECONDS (default 604800 = 7 days)."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "New API key (shown once). The previous key is deactivated immediately, or at previousKeyDeactivatesAt if a grace window was requested.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "New API key (shown once). The previous key is deactivated immediately, or at previousKeyDeactivatesAt if a grace window was requested.",
                  "type": "object",
                  "properties": {
                    "apiKey": {
                      "type": "string",
                      "description": "New API key (plaintext, shown once). Use as Bearer token."
                    },
                    "role": {
                      "type": "string"
                    },
                    "previousKeyDeactivated": {
                      "type": "boolean",
                      "description": "true when the old key was deactivated immediately (no grace window)."
                    },
                    "previousKeyDeactivatesAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time",
                      "description": "When the old key stops working, if a grace window was requested; null on immediate cutover."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/oidc/cert": {
      "post": {
        "operationId": "issueEphemeralCert",
        "summary": "Exchange an OIDC JWT for a short-lived AGLedger cert",
        "tags": [
          "Auth"
        ],
        "description": "Validates the JWT against `trusted_issuers` (applies_to in agent, any), verifies the Ed25519 proof-of-possession over the JWT subject, and issues a cert binding the submitted public key to the OIDC identity for up to 10 minutes (or the issuer's max_credential_ttl_seconds, whichever is shorter). The returned certJws is itself a JWT signed by the active vault key — present it as `Authorization: Bearer <certJws>` on subsequent agent-surface requests.\n\n**No prior AGLedger credential required.** The OIDC JWT IS the authentication — this is the workload-identity-federation on-ramp.\n\n**Auth:** none (the JWT is the auth).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "oidcToken",
                  "publicKeyJwk",
                  "proofOfPossession"
                ],
                "additionalProperties": false,
                "properties": {
                  "oidcToken": {
                    "type": "string",
                    "minLength": 16,
                    "maxLength": 16384,
                    "description": "OIDC JWT (compact JWS) from a trusted issuer with applies_to in (agent, any)."
                  },
                  "publicKeyJwk": {
                    "type": "object",
                    "required": [
                      "kty",
                      "crv",
                      "x"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "kty": {
                        "type": "string",
                        "enum": [
                          "OKP"
                        ]
                      },
                      "crv": {
                        "type": "string",
                        "enum": [
                          "Ed25519"
                        ]
                      },
                      "x": {
                        "type": "string",
                        "minLength": 40,
                        "maxLength": 50,
                        "pattern": "^[A-Za-z0-9_-]{40,50}$"
                      },
                      "use": {
                        "type": "string",
                        "enum": [
                          "sig"
                        ]
                      },
                      "key_ops": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "sign",
                            "verify"
                          ]
                        },
                        "maxItems": 4
                      },
                      "alg": {
                        "type": "string",
                        "enum": [
                          "EdDSA"
                        ]
                      },
                      "kid": {
                        "type": "string",
                        "maxLength": 256
                      }
                    }
                  },
                  "proofOfPossession": {
                    "type": "string",
                    "minLength": 88,
                    "maxLength": 88,
                    "pattern": "^[A-Za-z0-9+/]{86}==$",
                    "description": "Ed25519 signature over UTF-8 bytes of `agledger.oidc.cert.v1\\n${jwt.sub}`, encoded with STANDARD base64 (`+/` alphabet, mandatory `==` padding — NOT base64url). 88 chars total. JS: `Buffer.from(sig).toString('base64')`. Python: `base64.b64encode(sig).decode()`. Proves possession of the private key paired with publicKeyJwk."
                  },
                  "agentId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional agent binding. Must belong to the same org as the trusted_issuers row. Falls back to claim_mapping[agent_id] when omitted."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "cert",
                    "certJws",
                    "nextSteps"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "cert": {
                      "type": "object",
                      "required": [
                        "id",
                        "trustedIssuerId",
                        "orgId",
                        "agentId",
                        "oidcIss",
                        "oidcSub",
                        "publicKeyThumbprint",
                        "scopes",
                        "issuedAt",
                        "expiresAt",
                        "signingKeyId",
                        "revokedAt"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "trustedIssuerId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "orgId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        },
                        "agentId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        },
                        "oidcIss": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 512
                        },
                        "oidcSub": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256
                        },
                        "publicKeyThumbprint": {
                          "type": "string",
                          "pattern": "^sha256:[0-9a-f]{64}$"
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "issuedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "signingKeyId": {
                          "type": "string"
                        },
                        "revokedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        }
                      }
                    },
                    "certJws": {
                      "type": "string",
                      "description": "Compact JWS (signed JWT under the active vault key's algorithm, EdDSA by default; kid=vault_signing_keys.key_id). Present as Authorization: Bearer <certJws> on subsequent agent-surface requests. Return-once; not retrievable via GET."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body validation failed (malformed JWK, wrong PoP length, invalid agent UUID).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "OIDC token did not validate against any agent-purpose trusted_issuers row, or the PoP signature does not verify.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "agentId does not resolve to an existing agent.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "OIDC token jti has already been exchanged for a cert from this issuer (replay).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "`OIDC_TOKEN_NEAR_EXPIRY` — the JWT's exp leaves <60s of cert lifetime after the trusted_issuers / DB CHECK clamp. Refresh the upstream IdP JWT and retry.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/ephemeral-certs/{id}/revoke": {
      "post": {
        "operationId": "adminRevokeEphemeralCert",
        "summary": "Revoke a single ephemeral cert",
        "tags": [
          "Admin"
        ],
        "description": "Revokes one ephemeral cert by id so it stops authenticating within the cert-auth cache TTL (~60s). Idempotent — re-revoking an already-revoked cert returns its current view with no new chain entry. 404 if no cert has this id.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "trustedIssuerId",
                    "oidcIss",
                    "oidcSub",
                    "publicKeyThumbprint",
                    "scopes",
                    "issuedAt",
                    "expiresAt",
                    "signingKeyId",
                    "revokedAt",
                    "nextSteps"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "trustedIssuerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true
                    },
                    "agentId": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true
                    },
                    "oidcIss": {
                      "type": "string"
                    },
                    "oidcSub": {
                      "type": "string"
                    },
                    "publicKeyThumbprint": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "issuedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "signingKeyId": {
                      "type": "string"
                    },
                    "revokedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No ephemeral cert with this id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/records/{id}/references": {
      "post": {
        "operationId": "addRecordReferences",
        "summary": "Append references to a record",
        "tags": [
          "References"
        ],
        "description": "Attach external entity references to a record. Append-only — references cannot be modified or deleted. Duplicates (same system + refType + refId) are silently ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "references"
                ],
                "properties": {
                  "references": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "system",
                        "refType",
                        "refId"
                      ],
                      "properties": {
                        "system": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "External system identifier (lowercase, alphanumeric + dots/hyphens/underscores)"
                        },
                        "refType": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "Reference type within the system (e.g., sales-order, ticket, service-principal)"
                        },
                        "refId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500,
                          "description": "External identifier within the system"
                        },
                        "displayName": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "Human-readable label (snapshot at attachment time, not refreshed)"
                        },
                        "uri": {
                          "type": "string",
                          "maxLength": 2048,
                          "pattern": "^https?://",
                          "description": "URL back to the source system (https only)"
                        },
                        "attributes": {
                          "type": "object",
                          "maxProperties": 10,
                          "additionalProperties": {
                            "type": [
                              "string",
                              "number",
                              "boolean",
                              "null"
                            ]
                          },
                          "description": "Flat key-value metadata (max 10 keys, max 4KB total)"
                        }
                      },
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 25,
                    "description": "References to attach (max 25 total per record)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "References added.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "References added.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getRecordReferences",
        "summary": "List references for a record",
        "tags": [
          "References"
        ],
        "description": "Returns all external entity references attached to a record. References are append-only and cannot be modified or deleted.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{id}/references": {
      "post": {
        "operationId": "addAgentReferences",
        "summary": "Append references to an agent",
        "tags": [
          "References"
        ],
        "description": "Attach external identity references to an agent. Append-only. Duplicates silently ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "references"
                ],
                "properties": {
                  "references": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "system",
                        "refType",
                        "refId"
                      ],
                      "properties": {
                        "system": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "External system identifier (lowercase, alphanumeric + dots/hyphens/underscores)"
                        },
                        "refType": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100,
                          "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
                          "description": "Reference type within the system (e.g., sales-order, ticket, service-principal)"
                        },
                        "refId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500,
                          "description": "External identifier within the system"
                        },
                        "displayName": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "Human-readable label (snapshot at attachment time, not refreshed)"
                        },
                        "uri": {
                          "type": "string",
                          "maxLength": 2048,
                          "pattern": "^https?://",
                          "description": "URL back to the source system (https only)"
                        },
                        "attributes": {
                          "type": "object",
                          "maxProperties": 10,
                          "additionalProperties": {
                            "type": [
                              "string",
                              "number",
                              "boolean",
                              "null"
                            ]
                          },
                          "description": "Flat key-value metadata (max 10 keys, max 4KB total)"
                        }
                      },
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "References to attach (max 10 total per agent)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "References added.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "References added.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getAgentReferences",
        "summary": "List references for an agent",
        "tags": [
          "References"
        ],
        "description": "Returns all external identity references attached to an agent. References are append-only and cannot be modified or deleted.\n\n**Auth:** admin, agent, platform",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/references": {
      "get": {
        "operationId": "lookupReferences",
        "summary": "Reverse lookup — find entities by external reference",
        "tags": [
          "References"
        ],
        "description": "Find all records and agents that reference a given external entity. Returns both record and agent references. Paginated — default 50/page, max 100.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$"
            },
            "in": "query",
            "name": "system",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$"
            },
            "in": "query",
            "name": "refType",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500
            },
            "in": "query",
            "name": "refId",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "entityType": {
                            "type": "string",
                            "enum": [
                              "record",
                              "agent"
                            ]
                          },
                          "entityId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reference": {
                            "$ref": "#/components/schemas/EntityReference"
                          }
                        },
                        "required": [
                          "entityType",
                          "entityId",
                          "reference"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "data",
                    "total",
                    "nextCursor",
                    "hasMore"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents": {
      "get": {
        "operationId": "listAgentsInOrg",
        "summary": "List agents in the caller's org (peer directory)",
        "tags": [
          "Agents"
        ],
        "description": "Returns a paginated directory of agents in the same org as the caller. Lean projection — no email or owner-identity fields; for those, agents read their own profile via GET /v1/agents/{id} or admins use GET /v1/admin/agents.\n\n**Use case:** delegation target discovery, A2A peer enumeration, AgentCard lookup.\n\n**Auth:** any authenticated key with `agents:read` scope. Org-scoped: agent keys see peers in their org; admin keys see their own org; platform sees all orgs only when no orgId filter is implied.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response)."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "displayName": {
                            "type": "string"
                          },
                          "agentCardUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Operator-supplied URL of the agent's externally-hosted public AgentCard (A2A spec). AGLedger does not host per-agent cards — set this via PATCH /v1/agents/{id} to wherever the agent's AgentCard JSON is reachable. Null means unset (no operator has provided one); the agent participates in the lifecycle either way. Use this when populated to discover declared capabilities; GET /v1/agents/{id} returns identity, not capability."
                          },
                          "agentClass": {
                            "type": "string",
                            "enum": [
                              "personal",
                              "system",
                              "team",
                              "ephemeral"
                            ]
                          },
                          "orgUnit": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "description": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/peer-agents": {
      "get": {
        "operationId": "listPeerAgents",
        "summary": "List federation-projected peer agents visible to the caller's org",
        "tags": [
          "Agents"
        ],
        "description": "Customer-readable peer-agent directory. Returns shadow agents (rows projected locally via `/federation/v1/peer/agent-sync`) so a customer at Server A can discover agentIds shared by federation peers without operator access to the s2s surface.\n\nScoped to the caller's org: each row represents an agent at a peer Server that this Server's federation relationship has surfaced. Use the `id` as `performerAgentId` or `principalAgentId` on records that span the boundary.\n\n**Auth:** any authenticated key with `agents:read` scope (`org-admin` or `org-member`).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response)."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "peerHubId",
            "required": false,
            "description": "Filter to agents shared by a specific peer Server."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "orgId",
                          "displayName",
                          "agentClass",
                          "originPeerHubId",
                          "createdAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Agent id at the peer Server. Use as `performerAgentId`/`principalAgentId` on records that should attribute work to this peer agent."
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Local org id the shadow row was projected into (the caller's org)."
                          },
                          "displayName": {
                            "type": "string",
                            "description": "Display name shared by the peer at agent-sync time. Defaults to `fed-<agentId>` when the peer did not supply one."
                          },
                          "agentClass": {
                            "type": "string",
                            "enum": [
                              "personal",
                              "system",
                              "team",
                              "ephemeral"
                            ]
                          },
                          "originPeerHubId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Peer Server hub id that shared this agent. Pair with `GET /federation/v1/admin/peers` (operator-only) to resolve to peer org metadata."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/agents/{id}": {
      "get": {
        "operationId": "getAgent",
        "summary": "Get agent details",
        "tags": [
          "Agents"
        ],
        "description": "Returns agent identity, enrichment fields, and attached references.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "agentCardUrl": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "agentClass": {
                      "type": "string",
                      "enum": [
                        "personal",
                        "system",
                        "team",
                        "ephemeral"
                      ]
                    },
                    "ownerRef": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "orgUnit": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "references": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateAgentIdentity",
        "summary": "Update agent identity fields",
        "tags": [
          "Agents"
        ],
        "description": "Update agent classification, owner, org unit, or description. Only the agent itself or an admin of the org that registered it can update these fields.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentClass": {
                    "type": "string",
                    "enum": [
                      "personal",
                      "system",
                      "team",
                      "ephemeral"
                    ],
                    "description": "Agent classification: personal (human-owned), system (always-on), team (shared), ephemeral (per-task)"
                  },
                  "ownerRef": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 320,
                    "description": "Owner identity (email or identity URI of responsible person/team)"
                  },
                  "orgUnit": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255,
                    "description": "Organizational unit (department, team, cost center)"
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000,
                    "description": "Plain-text description of what this agent does"
                  },
                  "agentCardUrl": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2048,
                    "description": "URL to the agent's public AgentCard (A2A spec). Used by peers and delegators to discover declared capabilities. Pass null to clear. Accepts the same strings as POST /v1/admin/agents, including bracketed query strings such as `?filter[id]=3`. Rejected: a non-http(s) scheme, a raw backslash, embedded control characters (tab/newline), an empty authority such as `https:///card`, and embedded credentials, because URL parsers silently reinterpret those into a different host than the one written. Percent-encode them instead."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "agentCardUrl": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "agentClass": {
                      "type": "string",
                      "enum": [
                        "personal",
                        "system",
                        "team",
                        "ephemeral"
                      ]
                    },
                    "ownerRef": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "orgUnit": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "references": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityReference"
                      }
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs": {
      "get": {
        "operationId": "adminListOrgs",
        "summary": "List all orgs",
        "tags": [
          "Admin"
        ],
        "description": "Returns a paginated list of all org accounts with record counts.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response). Overrides offset when provided."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset for offset-based pagination. Ignored when cursor is provided."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "search",
            "required": false,
            "description": "Search by name (ILIKE)"
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          },
                          "recordCount": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{id}/config": {
      "get": {
        "operationId": "adminGetOrgConfig",
        "summary": "Get org config",
        "tags": [
          "Admin"
        ],
        "description": "Returns the org's JSONB config.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Org config.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Org config.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "config": {
                      "type": "object",
                      "description": "Org configuration object.",
                      "properties": {
                        "enforcement": {
                          "type": "object",
                          "description": "Enforcement policy settings — gate modes, resource limits, override policies.",
                          "properties": {
                            "constraintInheritanceDefault": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "Default constraint inheritance mode for new delegated records. Default: none."
                            },
                            "maxDelegationDepth": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 10,
                              "description": "Maximum delegation chain depth (1-10). Default: 5."
                            },
                            "criteriaSizeLimitBytes": {
                              "type": "integer",
                              "minimum": 1024,
                              "maximum": 65536,
                              "description": "Maximum criteria payload size in bytes (1024-65536). Default: 10240 (10 KB)."
                            },
                            "advisoryMode": {
                              "type": "boolean",
                              "description": "When true, enforcement violations log warnings instead of blocking. Default: false."
                            },
                            "toleranceEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How tolerance-based gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "deadlineEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How deadline checks are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "schemaValidation": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How schema validation is enforced for record criteria and completion evidence. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "maxSubmissionsMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How the max_submissions completion cap is enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "expressionRuleMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How expression-based custom gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "maxContractTypes": {
                              "type": "integer",
                              "minimum": 10,
                              "maximum": 10000,
                              "description": "Maximum custom types this org can register (10-10000). Tested default: 50."
                            },
                            "maxVersionsPerType": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 1000,
                              "description": "Maximum versions per record_type (1-1000). Default: 50."
                            },
                            "maxFieldMappingsPerType": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 200,
                              "description": "Maximum fieldMappings on one type (1-200). Default: 50."
                            },
                            "maxToleranceEntriesPerRecord": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 500,
                              "description": "Maximum tolerance entries in one record (1-500). Default: 50."
                            },
                            "maxWebhookSubscriptions": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 1000,
                              "description": "Maximum active webhook subscriptions per org (1-1000). Default: 50."
                            },
                            "maxRecordReferences": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 200,
                              "description": "Maximum external references per record (5-200). Default: 50."
                            },
                            "maxAgentReferences": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 100,
                              "description": "Maximum external references per agent (5-100). Default: 25."
                            },
                            "maxApiKeysPerOwner": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 100,
                              "description": "Maximum active API keys per owner — org or agent (5-100). Default: 25."
                            },
                            "allowRecordOverrides": {
                              "type": "boolean",
                              "description": "Whether individual records can override org enforcement settings. Overrides can only relax, never tighten. Default: false."
                            }
                          },
                          "additionalProperties": false
                        },
                        "approvedSuppliers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Approved supplier IDs for the supplier_approved gate rule."
                        }
                      },
                      "additionalProperties": true
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for this org."
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Org not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "adminUpdateOrgConfig",
        "summary": "Update org config",
        "tags": [
          "Admin"
        ],
        "description": "Merges the provided fields into the org's JSONB config column. Existing keys not present in the request body are preserved. Set a key to `null` to remove it.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enforcement": {
                    "type": "object",
                    "description": "Org enforcement configuration. Controls verification modes, resource limits, and per-record override policies.",
                    "properties": {
                      "constraintInheritanceDefault": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "Default constraint inheritance mode for new delegated records. Default: none."
                      },
                      "maxDelegationDepth": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10,
                        "description": "Maximum delegation chain depth (1-10). Default: 5."
                      },
                      "criteriaSizeLimitBytes": {
                        "type": "integer",
                        "minimum": 1024,
                        "maximum": 65536,
                        "description": "Maximum criteria payload size in bytes (1024-65536). Default: 10240 (10 KB)."
                      },
                      "advisoryMode": {
                        "type": "boolean",
                        "description": "When true, enforcement violations log warnings instead of blocking. Default: false."
                      },
                      "toleranceEnforcement": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "How tolerance-based gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                      },
                      "deadlineEnforcement": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "How deadline checks are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                      },
                      "schemaValidation": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "How schema validation is enforced for record criteria and completion evidence. none=skip, advisory=warn, enforced=block. Default: enforced."
                      },
                      "maxSubmissionsMode": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "How the max_submissions completion cap is enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                      },
                      "expressionRuleMode": {
                        "type": "string",
                        "enum": [
                          "none",
                          "advisory",
                          "enforced"
                        ],
                        "description": "How expression-based custom gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                      },
                      "maxContractTypes": {
                        "type": "integer",
                        "minimum": 10,
                        "maximum": 10000,
                        "description": "Maximum custom types this org can register (10-10000). Tested default: 50."
                      },
                      "maxVersionsPerType": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1000,
                        "description": "Maximum versions per record_type (1-1000). Default: 50."
                      },
                      "maxFieldMappingsPerType": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 200,
                        "description": "Maximum fieldMappings on one type (1-200). Default: 50."
                      },
                      "maxToleranceEntriesPerRecord": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 500,
                        "description": "Maximum tolerance entries in one record (1-500). Default: 50."
                      },
                      "maxWebhookSubscriptions": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1000,
                        "description": "Maximum active webhook subscriptions per org (1-1000). Default: 50."
                      },
                      "maxRecordReferences": {
                        "type": "integer",
                        "minimum": 5,
                        "maximum": 200,
                        "description": "Maximum external references per record (5-200). Default: 50."
                      },
                      "maxAgentReferences": {
                        "type": "integer",
                        "minimum": 5,
                        "maximum": 100,
                        "description": "Maximum external references per agent (5-100). Default: 25."
                      },
                      "maxApiKeysPerOwner": {
                        "type": "integer",
                        "minimum": 5,
                        "maximum": 100,
                        "description": "Maximum active API keys per owner — org or agent (5-100). Default: 25."
                      },
                      "allowRecordOverrides": {
                        "type": "boolean",
                        "description": "Whether individual records can override org enforcement settings. Overrides can only relax, never tighten. Default: false."
                      }
                    },
                    "additionalProperties": false
                  },
                  "approvedSuppliers": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 255
                    },
                    "maxItems": 1000,
                    "description": "List of approved supplier IDs for the supplier_approved gate rule."
                  }
                },
                "additionalProperties": false,
                "description": "Org config update. Accepts enforcement settings and approvedSuppliers."
              }
            }
          },
          "description": "Org config update. Accepts enforcement settings and approvedSuppliers."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Updated org config.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Updated org config.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "config": {
                      "type": "object",
                      "description": "Org configuration object.",
                      "properties": {
                        "enforcement": {
                          "type": "object",
                          "description": "Enforcement policy settings — gate modes, resource limits, override policies.",
                          "properties": {
                            "constraintInheritanceDefault": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "Default constraint inheritance mode for new delegated records. Default: none."
                            },
                            "maxDelegationDepth": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 10,
                              "description": "Maximum delegation chain depth (1-10). Default: 5."
                            },
                            "criteriaSizeLimitBytes": {
                              "type": "integer",
                              "minimum": 1024,
                              "maximum": 65536,
                              "description": "Maximum criteria payload size in bytes (1024-65536). Default: 10240 (10 KB)."
                            },
                            "advisoryMode": {
                              "type": "boolean",
                              "description": "When true, enforcement violations log warnings instead of blocking. Default: false."
                            },
                            "toleranceEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How tolerance-based gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "deadlineEnforcement": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How deadline checks are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "schemaValidation": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How schema validation is enforced for record criteria and completion evidence. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "maxSubmissionsMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How the max_submissions completion cap is enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "expressionRuleMode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "advisory",
                                "enforced"
                              ],
                              "description": "How expression-based custom gate rules are enforced. none=skip, advisory=warn, enforced=block. Default: enforced."
                            },
                            "maxContractTypes": {
                              "type": "integer",
                              "minimum": 10,
                              "maximum": 10000,
                              "description": "Maximum custom types this org can register (10-10000). Tested default: 50."
                            },
                            "maxVersionsPerType": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 1000,
                              "description": "Maximum versions per record_type (1-1000). Default: 50."
                            },
                            "maxFieldMappingsPerType": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 200,
                              "description": "Maximum fieldMappings on one type (1-200). Default: 50."
                            },
                            "maxToleranceEntriesPerRecord": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 500,
                              "description": "Maximum tolerance entries in one record (1-500). Default: 50."
                            },
                            "maxWebhookSubscriptions": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 1000,
                              "description": "Maximum active webhook subscriptions per org (1-1000). Default: 50."
                            },
                            "maxRecordReferences": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 200,
                              "description": "Maximum external references per record (5-200). Default: 50."
                            },
                            "maxAgentReferences": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 100,
                              "description": "Maximum external references per agent (5-100). Default: 25."
                            },
                            "maxApiKeysPerOwner": {
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 100,
                              "description": "Maximum active API keys per owner — org or agent (5-100). Default: 25."
                            },
                            "allowRecordOverrides": {
                              "type": "boolean",
                              "description": "Whether individual records can override org enforcement settings. Overrides can only relax, never tighten. Default: false."
                            }
                          },
                          "additionalProperties": false
                        },
                        "approvedSuppliers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Approved supplier IDs for the supplier_approved gate rule."
                        }
                      },
                      "additionalProperties": true
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for this org."
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Org not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/agents": {
      "get": {
        "operationId": "adminListAgents",
        "summary": "List agents",
        "tags": [
          "Admin"
        ],
        "description": "Returns a paginated list of agent accounts with record counts. Admin keys see agents in their own org only; platform keys see all orgs and may filter by `orgId`.\n\n**Auth:** admin (`agents:read` scope) or platform role.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response). Overrides offset when provided."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset for offset-based pagination. Ignored when cursor is provided."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Filter agents to a single org."
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "in": "query",
            "name": "search",
            "required": false,
            "description": "Search by display name (ILIKE)"
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "displayName": {
                            "type": "string"
                          },
                          "agentCardUrl": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "recordCount": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "adminCreateAgent",
        "summary": "Create an agent account",
        "tags": [
          "Admin"
        ],
        "description": "Creates an agent account without generating an API key. Use POST /v1/admin/api-keys to create keys separately.\n\n**Auth:** admin (`agents:manage` scope, agent must be in caller's org) or platform role.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orgId"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Agent display name (unique within org)"
                  },
                  "displayName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Alias for `name` (accepted; canonical field is `name`)"
                  },
                  "orgId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Org that owns this agent. 1:1 FK — every agent belongs to exactly one org."
                  },
                  "agentCardUrl": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "URL to the agent's AgentCard for identity verification. Accepts the same strings as PATCH /v1/agents/{id}, including bracketed query strings such as `?filter[id]=3`. Rejected: a non-http(s) scheme, a raw backslash, embedded control characters (tab/newline), an empty authority such as `https:///card`, and embedded credentials, because URL parsers silently reinterpret those into a different host than the one written. Percent-encode them instead."
                  }
                },
                "anyOf": [
                  {
                    "required": [
                      "name"
                    ]
                  },
                  {
                    "required": [
                      "displayName"
                    ]
                  }
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Agent created.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Agent created.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "agentCardUrl": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "orgId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions to complete setup"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Agent display name already in use within this org.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/api-keys": {
      "get": {
        "operationId": "adminListApiKeys",
        "summary": "List API keys",
        "tags": [
          "Admin"
        ],
        "description": "Returns API keys. Never returns key hashes.\n\n**Two modes:**\n- `?ownerId=<id>` — list keys for a single owner.\n- Omit `ownerId` — list every key on the install, optionally filtered by `orgId`, `ownerType`, `role`, `isActive`, `createdBefore`. Day-2 ops surface.\n\n`orgId` is projected per-row only in cross-owner mode (it is implicit in single-owner mode).\n\n**Auth:** platform role with `admin:keys` scope.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "ownerId",
            "required": false,
            "description": "List keys owned by a specific owner. Omit for cross-owner mode (platform keys only)."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Cross-owner filter: only keys whose owning org matches."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "org",
                "agent",
                "platform"
              ]
            },
            "in": "query",
            "name": "ownerType",
            "required": false,
            "description": "Cross-owner filter."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "admin",
                "agent",
                "platform"
              ]
            },
            "in": "query",
            "name": "role",
            "required": false,
            "description": "Cross-owner filter."
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "isActive",
            "required": false,
            "description": "Cross-owner filter: true = active, false = revoked/disabled."
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "createdBefore",
            "required": false,
            "description": "Cross-owner filter: keys created strictly before this timestamp (use for paginating older rows)."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Maximum rows to return (cross-owner mode only)."
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyId": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Persistent key identifier — use on PATCH /v1/admin/api-keys/{keyId} and POST /v1/admin/api-keys/bulk-revoke.keyIds[]."
                          },
                          "orgId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "Owning org id. Present only in cross-owner (system-wide) reads; omitted in single-owner mode."
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "admin",
                              "agent",
                              "platform"
                            ]
                          },
                          "ownerId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "ownerType": {
                            "type": "string"
                          },
                          "label": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "isActive": {
                            "type": "boolean"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "lastUsedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "expiresAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "deactivatesAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "createdByKeyId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "environment": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ]
                          },
                          "scopes": {
                            "type": [
                              "null",
                              "array"
                            ],
                            "items": {
                              "type": "string"
                            }
                          },
                          "allowedIps": {
                            "type": [
                              "null",
                              "array"
                            ],
                            "items": {
                              "type": "string"
                            }
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "adminCreateApiKey",
        "summary": "Create an API key for any owner",
        "tags": [
          "Admin"
        ],
        "description": "Creates a new API key for the specified owner. Returns the plaintext key once — it cannot be retrieved again.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "role",
                  "ownerId",
                  "ownerType"
                ],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "agent",
                      "platform"
                    ]
                  },
                  "ownerId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "org",
                      "agent",
                      "platform"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "expiresAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Optional expiration timestamp"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "default": "live"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Explicit scopes for the key. If omitted, defaults to role-appropriate scope profile (agent-full for agents, admin-standard for admins)."
                  },
                  "scopeProfile": {
                    "type": "string",
                    "enum": [
                      "admin-observer",
                      "admin-standard",
                      "admin-iac",
                      "admin-schema",
                      "agent-full",
                      "agent-readonly",
                      "agent-performer-only"
                    ],
                    "description": "Convenience preset — expands to a predefined scope array. Takes precedence over scopes."
                  },
                  "allowedIps": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "IP allowlist. Requests from IPs not in this list will be rejected with 403."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "API key created. The apiKey field is shown once — store it securely.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "API key created. The apiKey field is shown once — store it securely.",
                  "type": "object",
                  "properties": {
                    "keyId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Persistent key identifier — store it to PATCH or revoke this key later."
                    },
                    "apiKey": {
                      "type": "string",
                      "description": "Plaintext API key (shown once)"
                    },
                    "role": {
                      "type": "string"
                    },
                    "ownerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "label": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "expiresAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ]
                    },
                    "scopes": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      }
                    },
                    "scopeProfile": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "allowedIps": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      },
                      "description": "IP allowlist applied to this key. null = any IP allowed."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions after creating the key"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Maximum active keys per owner exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scope-profiles": {
      "get": {
        "operationId": "listScopeProfiles",
        "summary": "List available scope profiles",
        "tags": [
          "Discovery"
        ],
        "description": "Returns all scope profiles with their descriptions, allowed roles, and scope lists. Use this to discover which profiles are available when creating API keys.\n\n**Auth:** none (public endpoint). Scope catalogue is published so agents can introspect available profiles before requesting a key.",
        "security": [],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "Profile identifier — use as scopeProfile when creating keys"
                          },
                          "description": {
                            "type": "string",
                            "description": "What this profile is designed for"
                          },
                          "allowedRoles": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "admin",
                                "agent",
                                "platform"
                              ]
                            },
                            "description": "Roles that can use this profile"
                          },
                          "scopes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Scopes granted by this profile"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total scope-profile count (always equals data.length — unpaginated)."
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Always null — unpaginated."
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Always false — unpaginated."
                    }
                  },
                  "required": [
                    "data",
                    "total",
                    "nextCursor",
                    "hasMore"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{id}/deactivate": {
      "post": {
        "operationId": "adminDeactivateOrg",
        "summary": "Deactivate an org",
        "tags": [
          "Admin"
        ],
        "description": "Soft-deactivates an org: bulk-revokes all active API keys owned by the org and records the action in system_audit_log. Does NOT delete data.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Org deactivated.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Org deactivated.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "accountType": {
                      "type": "string"
                    },
                    "keysRevoked": {
                      "type": "integer",
                      "description": "Number of API keys deactivated"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification actions after deactivation"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Org not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Org is provisioning-managed (reason=PROVISIONING_MANAGED) — config-as-code resources are immutable via the admin API. Remove it from the provisioning YAML and reload, or run a prune reconcile, then deactivate.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/agents/{id}/deactivate": {
      "post": {
        "operationId": "adminDeactivateAgent",
        "summary": "Deactivate an agent",
        "tags": [
          "Admin"
        ],
        "description": "Soft-deactivates an agent: bulk-revokes all active API keys owned by the agent and records the action in system_audit_log. Does NOT delete data.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Agent deactivated.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Agent deactivated.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "accountType": {
                      "type": "string"
                    },
                    "keysRevoked": {
                      "type": "integer",
                      "description": "Number of API keys deactivated"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification actions after deactivation"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Agent is provisioning-managed (reason=PROVISIONING_MANAGED) — config-as-code resources are immutable via the admin API. Remove it from the provisioning YAML and reload, or run a prune reconcile, then deactivate.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/api-keys/bulk-revoke": {
      "post": {
        "operationId": "adminBulkRevokeKeys",
        "summary": "Bulk revoke API keys",
        "tags": [
          "Admin"
        ],
        "description": "Deactivates API keys matching the specified filters. At least one filter is required.\nAccepts key IDs (max 100) and/or filter criteria (ownerId, role, createdBefore).\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keyIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 100,
                    "description": "Specific key IDs to revoke (max 100)"
                  },
                  "ownerId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Revoke all keys for this owner"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "agent",
                      "platform"
                    ],
                    "description": "Revoke all keys with this role"
                  },
                  "createdBefore": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Revoke keys created before this timestamp"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Reason for revocation (audit trail)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Bulk revocation result.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Bulk revocation result.",
                  "type": "object",
                  "required": [
                    "revoked",
                    "alreadyInactive",
                    "notFound",
                    "nextSteps"
                  ],
                  "properties": {
                    "revoked": {
                      "type": "integer",
                      "description": "Number of keys deactivated"
                    },
                    "alreadyInactive": {
                      "type": "integer",
                      "description": "Number of keys that were already inactive"
                    },
                    "notFound": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "description": "Subset of `keyIds` from the request that did not match any row. Empty when the caller used filter-only revocation (ownerId/role/createdBefore without keyIds). Lets the caller distinguish \"key existed but already inactive\" from \"key never existed\" — both look like `alreadyInactive: 0` otherwise."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification actions after bulk revoke"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/api-keys/{keyId}": {
      "patch": {
        "operationId": "adminToggleApiKey",
        "summary": "Update API key status or scopes",
        "tags": [
          "Admin"
        ],
        "description": "Enable/disable an API key or update its scopes. Cannot disable the last active platform key.\n\nTo update scopes, provide a `scopes` array of valid scope strings or a `scopeProfile` name. Scope escalation rules apply: the caller's key must have all scopes being granted.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "isActive": {
                    "type": "boolean"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "New scope set for the key. Scope escalation rules apply."
                  },
                  "scopeProfile": {
                    "type": "string",
                    "enum": [
                      "admin-observer",
                      "admin-standard",
                      "admin-iac",
                      "admin-schema",
                      "agent-full",
                      "agent-readonly",
                      "agent-performer-only"
                    ],
                    "description": "Scope profile name. Resolved to scopes."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "keyId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "API key updated.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "API key updated.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "isActive": {
                      "type": "boolean"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "nullable": true
                    },
                    "scopeProfile": {
                      "type": "string",
                      "nullable": true
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification + inverse actions"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "API key not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/agents/{agentId}/capabilities": {
      "put": {
        "operationId": "adminSetAgentCapabilities",
        "summary": "Set agent capabilities (admin)",
        "tags": [
          "Admin"
        ],
        "description": "Admin override to set the accepted types for any agent.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contractTypes"
                ],
                "properties": {
                  "contractTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 50
                    },
                    "maxItems": 100,
                    "description": "Types the agent accepts."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "agentId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Updated agent capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "declaredAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reputation": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "properties": {
                              "compositeScore": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "confidenceLevel": {
                                "type": [
                                  "null",
                                  "number"
                                ]
                              },
                              "lifetimeRecords": {
                                "type": "integer"
                              },
                              "lifetimeAccepted": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false,
                  "description": "Updated agent capabilities."
                }
              }
            }
          },
          "400": {
            "description": "Invalid type.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/agents/capabilities": {
      "get": {
        "operationId": "adminGetFleetCapabilities",
        "summary": "Get fleet capability overview",
        "tags": [
          "Admin"
        ],
        "description": "Returns all agents that have declared capabilities, with optional type filter.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50
            },
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Filter agents by accepted type"
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Fleet capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Fleet capabilities.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "agentId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "displayName": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "contractTypes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid type filter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/webhook-dlq": {
      "get": {
        "operationId": "adminListDlq",
        "summary": "List webhook dead letter queue",
        "tags": [
          "Admin"
        ],
        "description": "Returns failed webhook deliveries from the DLQ.\n\n**Auth:** platform (sees all orgs) or admin (sees only subscriptions in own org — owned directly or by an agent in the org).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Pagination cursor (opaque, from previous response). Overrides offset when provided."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset for offset-based pagination. Ignored when cursor is provided."
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "subscriptionId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "subscriptionUrl": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "eventId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "eventType": {
                            "type": "string"
                          },
                          "recordId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "Correlation key for the affected record (null for federation peer events that have no record context)."
                          },
                          "errorMessage": {
                            "type": "string"
                          },
                          "attempts": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/system-health": {
      "get": {
        "operationId": "adminSystemHealth",
        "summary": "System health overview",
        "tags": [
          "Admin"
        ],
        "description": "Returns service health indicators including database connectivity and latency, queue depths, connection pool stats, and process memory usage.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "System health status.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "System health status.",
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded"
                      ]
                    },
                    "uptime": {
                      "type": "number",
                      "description": "Process uptime in seconds"
                    },
                    "database": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "healthy",
                            "degraded"
                          ]
                        },
                        "latencyMs": {
                          "type": [
                            "null",
                            "number"
                          ],
                          "description": "SELECT 1 round-trip latency in ms"
                        },
                        "pool": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer",
                              "description": "Total connections in pool"
                            },
                            "idle": {
                              "type": "integer",
                              "description": "Idle connections available"
                            },
                            "waiting": {
                              "type": "integer",
                              "description": "Queued connection requests"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "queues": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "waiting": {
                            "type": "integer"
                          },
                          "active": {
                            "type": "integer"
                          },
                          "delayed": {
                            "type": "integer"
                          },
                          "failed": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": false
                      },
                      "description": "Job counts per queue (pg-boss)"
                    },
                    "process": {
                      "type": "object",
                      "properties": {
                        "rssMb": {
                          "type": "number",
                          "description": "Resident set size in MB"
                        },
                        "heapUsedMb": {
                          "type": "number",
                          "description": "V8 heap used in MB"
                        },
                        "heapTotalMb": {
                          "type": "number",
                          "description": "V8 heap total in MB"
                        }
                      },
                      "additionalProperties": false
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/ops-summary": {
      "get": {
        "operationId": "adminGetOpsSummary",
        "summary": "Aggregate Day-2 ops snapshot",
        "tags": [
          "Admin"
        ],
        "description": "Single-call SRE dashboard refresh. Merges license validity, system-health, federation peer counts, vault signing-key counts, and webhook circuit-breaker rollup into one payload so a dashboard does NOT need 12 parallel reads to render. Drill-down endpoints stay (the full system-health / per-peer detail / per-subscription circuit state remain on their detailed endpoints). Cheap aggregate — each component is an indexed scan or in-memory read. `partitions` reports audit-log partition runway for capacity planning — days until the latest monthly partition per table, plus DEFAULT-partition row counts (should be ~0).\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "timestamp",
                    "license",
                    "system",
                    "queues",
                    "federation",
                    "vault",
                    "webhooks",
                    "partitions"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "license": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "tier",
                        "validity",
                        "licensedThrough"
                      ],
                      "properties": {
                        "tier": {
                          "type": "string"
                        },
                        "validity": {
                          "type": "string"
                        },
                        "licensedThrough": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date"
                        }
                      }
                    },
                    "system": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "status",
                        "uptimeSeconds",
                        "databaseLatencyMs"
                      ],
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "healthy",
                            "degraded"
                          ]
                        },
                        "uptimeSeconds": {
                          "type": "number"
                        },
                        "databaseLatencyMs": {
                          "type": [
                            "null",
                            "number"
                          ]
                        }
                      }
                    },
                    "queues": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "waiting": {
                            "type": "integer"
                          },
                          "active": {
                            "type": "integer"
                          },
                          "delayed": {
                            "type": "integer"
                          },
                          "failed": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "federation": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "peers"
                      ],
                      "properties": {
                        "peers": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "active",
                            "suspended",
                            "revoked"
                          ],
                          "properties": {
                            "active": {
                              "type": "integer"
                            },
                            "suspended": {
                              "type": "integer"
                            },
                            "revoked": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    },
                    "vault": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "signingKeys",
                        "anchoring"
                      ],
                      "properties": {
                        "signingKeys": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "active",
                            "retired"
                          ],
                          "properties": {
                            "active": {
                              "type": "integer"
                            },
                            "retired": {
                              "type": "integer"
                            }
                          }
                        },
                        "anchoring": {
                          "type": "object",
                          "additionalProperties": false,
                          "description": "External vault-anchoring posture. `enabled: false` means signed checkpoints exist only in the application database — strongly recommended for production: anchor to an object-lock bucket in a separately-administered account (VAULT_ANCHOR_ENABLED=true). `intervalMinutes` (VAULT_ANCHOR_INTERVAL_MINUTES, 5–2880, default 360) is the tamper-exposure window between checkpoint+anchor sweeps. `enabled`/`bucket`/`intervalMinutes` reflect THIS (API) process's config; `workerEnabled` is the observed posture of the worker that actually runs the sweep. When `reconciled: false` the two disagree (env drift between API and worker services) — the worker is authoritative for whether anchoring really happens. `workerEnabled`/`reconciled: null` means the worker posture could not be determined.",
                          "required": [
                            "enabled",
                            "intervalMinutes",
                            "bucket",
                            "workerEnabled",
                            "reconciled"
                          ],
                          "properties": {
                            "enabled": {
                              "type": "boolean"
                            },
                            "intervalMinutes": {
                              "type": "integer"
                            },
                            "bucket": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "workerEnabled": {
                              "type": [
                                "null",
                                "boolean"
                              ]
                            },
                            "reconciled": {
                              "type": [
                                "null",
                                "boolean"
                              ]
                            }
                          }
                        }
                      }
                    },
                    "webhooks": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "circuitBreakers"
                      ],
                      "properties": {
                        "circuitBreakers": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "closed",
                            "half_open",
                            "open"
                          ],
                          "properties": {
                            "closed": {
                              "type": "integer"
                            },
                            "half_open": {
                              "type": "integer"
                            },
                            "open": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    },
                    "partitions": {
                      "type": "array",
                      "description": "Audit-log partition runway, one entry per monthly-partitioned table. runwayDays = days until the latest partition upper bound (null if no monthly partition); defaultRows = rows in the catch-all DEFAULT partition (should be ~0).",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "table",
                          "runwayDays",
                          "defaultRows"
                        ],
                        "properties": {
                          "table": {
                            "type": "string"
                          },
                          "runwayDays": {
                            "type": [
                              "null",
                              "integer"
                            ]
                          },
                          "defaultRows": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/webhook-dlq/{dlqId}/retry": {
      "post": {
        "operationId": "adminRetryDlq",
        "summary": "Retry a DLQ entry",
        "tags": [
          "Admin"
        ],
        "description": "Re-enqueues a failed webhook delivery for retry and removes it from the DLQ.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "dlqId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "DLQ entry retried successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "DLQ entry retried successfully.",
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification actions after retry"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "DLQ entry not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/webhook-dlq/retry-all": {
      "post": {
        "operationId": "adminRetryAllDlq",
        "summary": "Retry all DLQ entries",
        "tags": [
          "Admin"
        ],
        "description": "Re-enqueues up to 100 failed webhook deliveries for retry.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Bulk retry result.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Bulk retry result.",
                  "type": "object",
                  "properties": {
                    "retried": {
                      "type": "integer",
                      "description": "Number of entries successfully retried"
                    },
                    "failed": {
                      "type": "integer",
                      "description": "Number of entries that failed to retry"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification actions after bulk retry"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/rate-limit-exemptions/{ownerId}": {
      "put": {
        "operationId": "adminAddRateLimitExemption",
        "summary": "Add rate-limit exemption for an owner",
        "tags": [
          "Admin"
        ],
        "description": "Adds an owner ID to the runtime rate-limit exemption set (100k req/min).\n\n**Scope and lifetime (read before relying on this on an HA install).** The change is applied on the replica that serves the call and broadcast to every other running replica over PostgreSQL LISTEN/NOTIFY, so a multi-replica install normally converges within milliseconds and the read-back is consistent. It is held in process memory and is not persisted or replayed, which leaves two gaps worth knowing: a replica that starts *after* this call (rolling restart, scale-out, crash-loop) seeds its exempt set from `RATE_LIMIT_EXEMPT_OWNERS` alone, and a replica whose LISTEN connection is down at the moment of the call (a PG failover, a few seconds of reconnect backoff) never receives the message and stays out of step until it is restarted. Re-issue the call if a failover overlapped it, and confirm with the list endpoint. Use this endpoint for a bounded operational window; use the `RATE_LIMIT_EXEMPT_OWNERS` env var (needs a rollout) for an exemption that must survive restarts, new pods, and connection loss.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "ownerId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Exemption added.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Exemption added.",
                  "type": "object",
                  "properties": {
                    "ownerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "exempt": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification + inverse actions"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "adminRemoveRateLimitExemption",
        "summary": "Remove rate-limit exemption for an owner",
        "tags": [
          "Admin"
        ],
        "description": "Removes an owner ID from the runtime rate-limit exemption set. Broadcast to every running replica over PostgreSQL LISTEN/NOTIFY, same as the add path. An owner listed in `RATE_LIMIT_EXEMPT_OWNERS` comes back on the next process start, since the env var is re-read at boot.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "ownerId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Exemption removed (or was not present).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Exemption removed (or was not present).",
                  "type": "object",
                  "properties": {
                    "ownerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "exempt": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested verification + inverse actions"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/rate-limit-exemptions": {
      "get": {
        "operationId": "adminListRateLimitExemptions",
        "summary": "List rate-limit exempt owners",
        "tags": [
          "Admin"
        ],
        "description": "Returns all owner IDs currently exempt from rate limiting (env var + runtime additions), as held by the replica that answers this call. Runtime add/remove is broadcast to every running replica, so the answer is normally uniform across an HA install. It can still differ per replica in the two cases the add endpoint documents: a replica started after a runtime add, and a replica whose LISTEN connection was down when the add was broadcast. Repeat the call a few times if you are diagnosing uneven throttling.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of exempt owner IDs.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "List of exempt owner IDs.",
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/auth-cache/flush": {
      "post": {
        "operationId": "adminFlushAuthCache",
        "summary": "Flush auth cache",
        "tags": [
          "Admin"
        ],
        "description": "Clears all entries from the auth LRU cache. Subsequent requests will query the database.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cache flushed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cache flushed successfully.",
                  "type": "object",
                  "properties": {
                    "flushed": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "flushed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/auth-cache/stats": {
      "get": {
        "operationId": "adminAuthCacheStats",
        "summary": "Auth cache statistics",
        "tags": [
          "Admin"
        ],
        "description": "Returns current auth LRU cache size, max capacity, and TTL.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cache statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Cache statistics.",
                  "type": "object",
                  "properties": {
                    "size": {
                      "type": "integer",
                      "description": "Current number of entries in cache"
                    },
                    "max": {
                      "type": "integer",
                      "description": "Maximum cache capacity"
                    },
                    "ttl": {
                      "type": "integer",
                      "description": "TTL in milliseconds"
                    }
                  },
                  "required": [
                    "size",
                    "max",
                    "ttl"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/records": {
      "get": {
        "operationId": "adminListRecords",
        "summary": "List records cross-org",
        "tags": [
          "Admin"
        ],
        "description": "Returns a paginated list of records across all orgs. Supports filtering by org, status, type, agent, and date range.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Cursor for cursor-based pagination (overrides offset when provided). Returned as nextCursor in previous response."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false,
            "description": "Filter by org ID"
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by record status"
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "type",
            "required": false,
            "description": "Filter by type"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "agentId",
            "required": false,
            "description": "Filter by performer agent ID"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "updatedAt"
              ],
              "default": "createdAt"
            },
            "in": "query",
            "name": "sort",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "in": "query",
            "name": "order",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "from",
            "required": false,
            "description": "Filter: created after"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "to",
            "required": false,
            "description": "Filter: created before"
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "agentId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "principalAgentId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "operatingMode": {
                            "type": "string",
                            "enum": [
                              "cleartext",
                              "encrypted"
                            ]
                          },
                          "gateMode": {
                            "type": "string",
                            "enum": [
                              "auto",
                              "principal"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/webhooks/health": {
      "get": {
        "operationId": "adminGetWebhooksHealth",
        "summary": "Webhook subscription health overview",
        "tags": [
          "Admin"
        ],
        "description": "Lists active webhook subscriptions with circuit breaker state, sorted by failure count.\n\n**Auth:** platform (sees all orgs) or admin (sees own org only). admin:system scope.",
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "url": {
                            "type": "string"
                          },
                          "ownerId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "ownerType": {
                            "type": "string"
                          },
                          "isActive": {
                            "type": "boolean"
                          },
                          "isPaused": {
                            "type": "boolean"
                          },
                          "circuitState": {
                            "type": "string",
                            "enum": [
                              "closed",
                              "open",
                              "half_open"
                            ]
                          },
                          "consecutiveFailures": {
                            "type": "integer"
                          },
                          "lastSuccessfulAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "circuitOpenedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/webhooks/{webhookId}/circuit-breaker": {
      "patch": {
        "operationId": "adminOverrideWebhookCircuitBreaker",
        "summary": "Override webhook circuit breaker state",
        "tags": [
          "Admin"
        ],
        "description": "Manually set the circuit breaker state for a subscription. Setting to \"closed\" resets consecutive failures.\n\n**Auth:** platform (any subscription) or admin (subscriptions in own org). admin:system scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "state"
                ],
                "properties": {
                  "state": {
                    "type": "string",
                    "enum": [
                      "closed",
                      "open",
                      "half_open"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "webhookId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "circuitState": {
                      "type": "string"
                    },
                    "consecutiveFailures": {
                      "type": "integer"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found -- the referenced resource does not exist (or is not visible to this caller). The detail names the missing resource; check identifiers before retrying.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/signing-keys": {
      "get": {
        "operationId": "adminListVaultSigningKeys",
        "summary": "List vault signing keys",
        "tags": [
          "Admin"
        ],
        "description": "Returns all vault signing keys in the registry with their lifecycle status.\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyId": {
                            "type": "string",
                            "description": "SHA-256 fingerprint (16 hex chars)"
                          },
                          "algorithm": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "retired"
                            ]
                          },
                          "activatedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "retiredAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/signing-keys/rotate": {
      "post": {
        "operationId": "adminRotateVaultSigningKey",
        "summary": "Rotate vault signing key",
        "tags": [
          "Admin"
        ],
        "description": "Activates the current VAULT_SIGNING_KEY env var as the new active key and retires the previous one. The operator must update the env var before calling this endpoint.\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "previousKeyId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "newKeyId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "rotated",
                        "already_active"
                      ]
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/anchors": {
      "get": {
        "operationId": "adminListVaultAnchors",
        "summary": "List anchored checkpoints for a record",
        "tags": [
          "Admin"
        ],
        "description": "Lists S3-anchored vault checkpoints for a given record. Requires vault anchoring to be enabled.\n\n**Auth:** platform role with `admin:system` scope.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "query",
            "name": "recordId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "lastModified": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "size": {
                            "type": [
                              "null",
                              "integer"
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of matching records (-1 when using cursor pagination)"
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Cursor for the next page (null if no more results)"
                    },
                    "hasMore": {
                      "type": "boolean",
                      "description": "Whether more results exist beyond this page"
                    },
                    "recordRead": {
                      "type": "object",
                      "properties": {
                        "leafIndex": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "leafHash": {
                          "type": "string",
                          "minLength": 64,
                          "maxLength": 64
                        },
                        "signedCheckpointRef": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "leafIndex",
                        "leafHash",
                        "signedCheckpointRef"
                      ],
                      "additionalProperties": false,
                      "description": "SCITT-style inclusion-proof completion for org_admin_reads. Present only when the caller is a org-admin reading cross-party data."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/anchors/verify": {
      "post": {
        "operationId": "adminVerifyVaultAnchors",
        "summary": "Verify vault checkpoint anchors",
        "tags": [
          "Admin"
        ],
        "description": "Compares DB checkpoints against their S3 anchors for a given record. Detects tampering if the DB checkpoint has been modified after anchoring.\n\n**Auth:** platform role with `admin:system` scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recordId"
                ],
                "properties": {
                  "recordId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "chainPosition": {
                    "type": "integer",
                    "description": "Specific chain position to verify (omit for latest 10)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "chainPosition": {
                            "type": "integer"
                          },
                          "match": {
                            "type": "boolean"
                          },
                          "detail": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Record not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/scan": {
      "post": {
        "operationId": "adminStartVaultScan",
        "summary": "Start a full vault integrity scan",
        "tags": [
          "Admin"
        ],
        "description": "Enqueues a background job that verifies every vault chain in the database. Returns a job ID for status polling. Use after DB restores or incident response.\n\nCross-checks each record against `vault_checkpoints`: a record with surviving checkpoints but no audit_vault rows (or with a chain shorter than the latest checkpoint position) is reported as broken with reason `audit_vault_row_missing_for_checkpoint` — the canonical signal that audit data was wiped out-of-band.\n\nA per-org schema chain wiped to empty when no checkpoint survives (deleted inside the pre-checkpoint window, or with its checkpoint rows also removed) is caught by a checkpoint-independent backstop: if the org still has registered schema subjects, the empty chain is reported as broken with reason `schema_chain_missing_for_subjects`.\n\n**Auth:** platform role with `admin:system` scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recordIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 1000,
                    "description": "Optional list of record IDs to scan. Omit to scan all records."
                  },
                  "recordId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Convenience: scan a single record. Merged into recordIds if both are given."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "202": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId",
                    "state"
                  ],
                  "properties": {
                    "jobId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "created"
                      ],
                      "description": "pg-boss state at enqueue. Always `created`; moves to `active`, then `completed`/`failed`, or back to `retry` when an attempt fails. Poll GET /v1/admin/vault/scan/{jobId}."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: a scan covering this scope is already in flight. `reason` is VAULT_SCAN_IN_FLIGHT and `jobId` names the blocking scan, so poll GET /v1/admin/vault/scan/{jobId} rather than parsing `detail`. `retryable` is true: the slot frees the moment that scan reaches completed, cancelled or failed, so the next request is accepted immediately after.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "adminListVaultScans",
        "summary": "List recent vault integrity scans + active lock status",
        "tags": [
          "Admin"
        ],
        "description": "Returns the active scan job (if any), the most recent completed scan, and up to 10 recent jobs (any state). Use for Day-2 ops: \"is anything running? when did the last one finish?\" without having to remember a jobId. The lock is released on completion, so a finished scan never blocks the next one.\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "active",
                    "lastCompleted",
                    "recent"
                  ],
                  "properties": {
                    "active": {
                      "type": "object",
                      "nullable": true,
                      "required": [
                        "jobId",
                        "state"
                      ],
                      "properties": {
                        "jobId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "state": {
                          "type": "string"
                        },
                        "startedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "additionalProperties": false
                    },
                    "lastCompleted": {
                      "type": "object",
                      "nullable": true,
                      "required": [
                        "jobId"
                      ],
                      "properties": {
                        "jobId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "completedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "result": {
                          "type": "object",
                          "additionalProperties": true,
                          "nullable": true
                        }
                      },
                      "additionalProperties": false
                    },
                    "recent": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "jobId",
                          "state"
                        ],
                        "properties": {
                          "jobId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "state": {
                            "type": "string"
                          },
                          "startedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "completedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/vault/scan/{jobId}": {
      "get": {
        "operationId": "adminGetVaultScanStatus",
        "summary": "Get vault integrity scan status",
        "tags": [
          "Admin"
        ],
        "description": "Polls the status of a vault integrity scan job.\n\n**Auth:** platform role with `admin:system` scope.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "jobId",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId",
                    "state"
                  ],
                  "properties": {
                    "jobId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "created",
                        "active",
                        "retry",
                        "completed",
                        "cancelled",
                        "failed"
                      ],
                      "description": "pg-boss job state. Terminal: completed, cancelled or failed. `retry` means an attempt failed and another is scheduled, so the scan is still unfinished and POST /v1/admin/vault/scan keeps refusing for that scope. There is no `expired` state."
                    },
                    "startedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "completedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "result": {
                      "type": "object",
                      "nullable": true,
                      "description": "Populated when state=`completed`. `healthy` is the single pass/fail signal an SRE can branch on; `recordsScanned: 0` plus `healthy: true` is unambiguously \"empty install / clean,\" not the previous opaque `null`.",
                      "properties": {
                        "recordsScanned": {
                          "type": "integer",
                          "description": "Total record chains the scan covered (post-filter by recordIds, if supplied)."
                        },
                        "verified": {
                          "type": "integer",
                          "description": "Chains that round-tripped clean."
                        },
                        "broken": {
                          "type": "integer",
                          "description": "Chains with chain-integrity failures."
                        },
                        "signatureErrors": {
                          "type": "integer",
                          "description": "Chains broken specifically on per-entry signature verification: a COSE signature failed against its resolved key, the entry named a signing key the registry cannot resolve, or the key's registered algorithm is one this build or host cannot compute (unsupported_algorithm; remedy is a build upgrade or verifying off-host with the offline verifiers, e.g. Ed25519 history on a FIPS host; not tamper forensics). Subset of `broken`; signature failures fail the chain."
                        },
                        "healthy": {
                          "type": "boolean",
                          "description": "True iff broken === 0 AND signatureErrors === 0 AND globalChains.broken === 0. The single field an SRE branches on; a full scan folds the record-less chains into it."
                        },
                        "brokenRecords": {
                          "type": "array",
                          "description": "Capped at 100 entries; brokenRecordsTruncated=true means more failures exist on the chain — re-run scoped per recordId or pull /audit-export.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "recordId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "brokenAt": {
                                "type": "integer"
                              },
                              "reason": {
                                "type": "string",
                                "enum": [
                                  "chain_broken_at",
                                  "payload_drift",
                                  "oidc_actor_drift",
                                  "cert_actor_drift",
                                  "cert_expired",
                                  "cert_missing",
                                  "agent_signature_invalid",
                                  "signature_invalid",
                                  "signing_key_unknown",
                                  "unsupported_algorithm",
                                  "signing_key_drift",
                                  "audit_vault_row_missing_for_checkpoint",
                                  "checkpoint_hash_mismatch",
                                  "schema_chain_missing_for_subjects",
                                  "verification_error"
                                ],
                                "description": "Failure category. `chain_broken_at` is the generic hash/link/decode mismatch; entry-localized classes (payload_drift, oidc_actor_drift, cert_*, signature_invalid, signing_key_unknown, unsupported_algorithm) pass through verbatim so the failing invariant is visible without pulling /audit-export. `audit_vault_row_missing_for_checkpoint` and `checkpoint_hash_mismatch` indicate the live chain disagrees with a previously-signed checkpoint (strong tamper signal even when the in-place chain hashes self-validate). For `signing_key_unknown`, check the key registry before treating as tamper."
                              },
                              "expectedEntries": {
                                "type": "integer",
                                "description": "Set when reason is checkpoint-related — the chain length the latest checkpoint anchors."
                              }
                            }
                          }
                        },
                        "brokenRecordsTruncated": {
                          "type": "boolean"
                        },
                        "globalChains": {
                          "type": "object",
                          "description": "The record-less chains a full scan walks: the platform-ops chain (admin key + account events) and each org's schema-registration chain. These have no `records` row, so the per-record scan cannot see them; a tamper here is folded into `healthy`. Absent/zeroed on a `recordIds`-scoped scan.",
                          "properties": {
                            "total": {
                              "type": "integer",
                              "description": "Record-less chains walked (buckets with at least one entry)."
                            },
                            "verified": {
                              "type": "integer"
                            },
                            "broken": {
                              "type": "integer"
                            },
                            "signatureErrors": {
                              "type": "integer",
                              "description": "Subset of `broken`, broken on per-entry signature verification."
                            },
                            "brokenChains": {
                              "type": "array",
                              "description": "Capped at 100 entries; brokenChainsTruncated=true means more broke.",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "chain": {
                                    "type": "string",
                                    "enum": [
                                      "admin",
                                      "schema"
                                    ],
                                    "description": "`admin` is the single platform-ops chain; `schema` is one org's schema chain."
                                  },
                                  "orgId": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "The org whose schema chain broke; null for the platform-ops chain and for platform-level schema events."
                                  },
                                  "brokenAt": {
                                    "type": "integer"
                                  },
                                  "reason": {
                                    "type": "string",
                                    "enum": [
                                      "chain_broken_at",
                                      "payload_drift",
                                      "oidc_actor_drift",
                                      "cert_actor_drift",
                                      "cert_expired",
                                      "cert_missing",
                                      "agent_signature_invalid",
                                      "signature_invalid",
                                      "signing_key_unknown",
                                      "unsupported_algorithm",
                                      "signing_key_drift",
                                      "audit_vault_row_missing_for_checkpoint",
                                      "checkpoint_hash_mismatch",
                                      "schema_chain_missing_for_subjects",
                                      "verification_error"
                                    ],
                                    "description": "Same failure taxonomy as `brokenRecords[].reason`. Both the platform-ops (admin) chain and each per-org schema chain are checkpointed, so both can report the checkpoint classes (`audit_vault_row_missing_for_checkpoint` / `checkpoint_hash_mismatch`), which catch a terminal-row deletion the hash-walk cannot. `schema_chain_missing_for_subjects` is schema-chain only: the org still has registered schema subjects but its schema chain has no surviving rows or checkpoint, i.e. the chain was truncated to empty and any anchor deleted."
                                  }
                                }
                              }
                            },
                            "brokenChainsTruncated": {
                              "type": "boolean"
                            }
                          },
                          "additionalProperties": false
                        },
                        "checkpointing": {
                          "type": "object",
                          "description": "When the checkpoint sweep runs, as the worker that ran this scan has it scheduled. A scan cross-checks the live chain against signed checkpoints, so `healthy: true` on an install with none yet means \"nothing contradicts the chain\", not \"verified against an anchor\". A fresh install has no checkpoints until the first sweep fires (up to VAULT_ANCHOR_INTERVAL_MINUTES after boot, 6h by default), so compare `nextRunAt` against the install age before reading an empty vault as a gap. GET /v1/audit-vault/checkpoints lists the checkpoints themselves and reports `lastCheckpointAt` alongside this same cadence.",
                          "properties": {
                            "cron": {
                              "type": "string",
                              "description": "Cron expression the sweep runs on, in UTC."
                            },
                            "intervalMinutes": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "description": "Cadence in minutes, derived from `cron` (VAULT_ANCHOR_INTERVAL_MINUTES). Null when the schedule is not a fixed interval."
                            },
                            "nextRunAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "description": "Next scheduled sweep. Null when the schedule names no reachable next run, or is registered in a non-UTC timezone."
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "worker",
                                "config"
                              ],
                              "description": "`worker` = read from the registered schedule, which is the normal answer here because the process that ran the scan is the one that owns it. `config` = that read failed and this is the worker process's own configuration instead."
                            },
                            "anchoringEnabled": {
                              "type": "boolean",
                              "description": "Whether checkpoints are also anchored off-box (VAULT_ANCHOR_ENABLED)."
                            }
                          },
                          "additionalProperties": false
                        },
                        "scannedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Job not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/license": {
      "get": {
        "operationId": "adminGetLicense",
        "summary": "License status",
        "tags": [
          "Admin"
        ],
        "description": "Returns current license validation status, tier, expiry, and entitlements.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current license status.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Current license status.",
                  "type": "object",
                  "properties": {
                    "validity": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "unlicensed",
                        "lapsed",
                        "invalid_signature",
                        "invalid_format",
                        "instance_mismatch",
                        "version_too_new",
                        "marketplace_unreachable"
                      ]
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "developer",
                        "enterprise"
                      ]
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "pem",
                        "marketplace",
                        "none"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "customerId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "customerName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "instanceId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "licensedThrough": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date"
                    },
                    "releaseDate": {
                      "type": "string",
                      "format": "date"
                    },
                    "licenseId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "error": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "validity",
                    "tier",
                    "features",
                    "checkedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/license/instance-id": {
      "get": {
        "operationId": "adminGetInstanceId",
        "summary": "Database instance ID",
        "tags": [
          "Admin"
        ],
        "description": "Returns the database instance_id used for license binding. Customer copies this to send to sales or enter in the activation portal.\n\n**Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instanceId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "instanceId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/license/reload": {
      "post": {
        "operationId": "adminReloadLicense",
        "summary": "Reload license",
        "tags": [
          "Admin"
        ],
        "description": "Re-validates and updates the server license status without restarting. Call with no body to reload from AGLEDGER_LICENSE / AGLEDGER_LICENSE_KEY / AGLEDGER_LICENSE_KEY_FILE env vars (useful after K8s secret rotation). Or pass `{ \"license\": \"agl_ent_v1_...\" }` (compact string) or `{ \"licenseKey\": \"-----BEGIN LICENSE...\" }` (PEM) to hot-reload from the request body.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "license": {
                    "type": "string",
                    "description": "Compact activation string, format `agl_<tier>_v1_<base64url>`."
                  },
                  "licenseKey": {
                    "type": "string",
                    "description": "Full PEM-wrapped license file contents, including headers."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "validity": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "unlicensed",
                        "lapsed",
                        "invalid_signature",
                        "invalid_format",
                        "instance_mismatch",
                        "version_too_new",
                        "marketplace_unreachable"
                      ]
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "developer",
                        "enterprise"
                      ]
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "pem",
                        "marketplace",
                        "none"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "customerId": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "customerName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "instanceId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "licensedThrough": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date"
                    },
                    "releaseDate": {
                      "type": "string",
                      "format": "date"
                    },
                    "licenseId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "error": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "validity",
                    "tier",
                    "features",
                    "checkedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/support-bundle": {
      "get": {
        "operationId": "adminExportSupportBundle",
        "summary": "Export support bundle",
        "tags": [
          "Admin"
        ],
        "description": "Generates a JSON diagnostic report for self-hosted support. Admin inspects the bundle before sharing with AGLedger support. No secrets, credentials, or URLs are included. Every generation is audit-logged with the caller's API key ID for leak traceability.\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Support bundle exported.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Support bundle exported.",
                  "type": "object",
                  "properties": {
                    "manifest": {
                      "type": "object",
                      "properties": {
                        "bundleVersion": {
                          "type": "integer"
                        },
                        "generatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "generatedBy": {
                          "type": "string"
                        },
                        "generatedFor": {
                          "type": "string",
                          "description": "Caller API key ID for leak traceability"
                        },
                        "sections": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "description": {
                                "type": "string"
                              },
                              "fieldCount": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "version": {
                      "type": "object",
                      "properties": {
                        "app": {
                          "type": "string"
                        },
                        "releaseDate": {
                          "type": "string"
                        },
                        "node": {
                          "type": "string"
                        },
                        "pgBundled": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    },
                    "license": {
                      "type": "object",
                      "properties": {
                        "tier": {
                          "type": "string"
                        },
                        "validity": {
                          "type": "string"
                        },
                        "instanceId": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "licensedThrough": {
                          "type": [
                            "null",
                            "string"
                          ]
                        }
                      },
                      "additionalProperties": false
                    },
                    "health": {
                      "description": "System health status.",
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "healthy",
                            "degraded"
                          ]
                        },
                        "uptime": {
                          "type": "number",
                          "description": "Process uptime in seconds"
                        },
                        "database": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "healthy",
                                "degraded"
                              ]
                            },
                            "latencyMs": {
                              "type": [
                                "null",
                                "number"
                              ],
                              "description": "SELECT 1 round-trip latency in ms"
                            },
                            "pool": {
                              "type": "object",
                              "properties": {
                                "total": {
                                  "type": "integer",
                                  "description": "Total connections in pool"
                                },
                                "idle": {
                                  "type": "integer",
                                  "description": "Idle connections available"
                                },
                                "waiting": {
                                  "type": "integer",
                                  "description": "Queued connection requests"
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "additionalProperties": false
                        },
                        "queues": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "waiting": {
                                "type": "integer"
                              },
                              "active": {
                                "type": "integer"
                              },
                              "delayed": {
                                "type": "integer"
                              },
                              "failed": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": false
                          },
                          "description": "Job counts per queue (pg-boss)"
                        },
                        "process": {
                          "type": "object",
                          "properties": {
                            "rssMb": {
                              "type": "number",
                              "description": "Resident set size in MB"
                            },
                            "heapUsedMb": {
                              "type": "number",
                              "description": "V8 heap used in MB"
                            },
                            "heapTotalMb": {
                              "type": "number",
                              "description": "V8 heap total in MB"
                            }
                          },
                          "additionalProperties": false
                        },
                        "timestamp": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "authCache": {
                      "type": "object",
                      "properties": {
                        "size": {
                          "type": "integer"
                        },
                        "max": {
                          "type": "integer"
                        },
                        "ttl": {
                          "type": "integer"
                        }
                      },
                      "additionalProperties": false
                    },
                    "config": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Allowlisted config keys only — no secrets, credentials, or URLs"
                    },
                    "database": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "migrations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "appliedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "tableStats": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "table": {
                                "type": "string"
                              },
                              "rowEstimate": {
                                "type": "integer"
                              },
                              "sizeBytes": {
                                "type": [
                                  "null",
                                  "integer"
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "environment": {
                      "type": "object",
                      "properties": {
                        "platform": {
                          "type": "string"
                        },
                        "arch": {
                          "type": "string"
                        },
                        "cpuCount": {
                          "type": "integer"
                        },
                        "totalMemoryMb": {
                          "type": "integer"
                        },
                        "freeMemoryMb": {
                          "type": "integer"
                        }
                      },
                      "additionalProperties": false
                    },
                    "guidance": {
                      "type": "object",
                      "properties": {
                        "notIncluded": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "hint": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/support-bundle/upload": {
      "post": {
        "operationId": "adminUploadSupportBundle",
        "summary": "Upload support bundle",
        "tags": [
          "Admin"
        ],
        "description": "Generates a fresh support bundle and uploads it to AGLedger support (support.agledger.ai). Returns a bundle ID for support ticket reference. The admin should review the bundle contents via GET /admin/support-bundle before uploading.\n\n**Auth:** platform role with `admin:system` scope.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Support bundle uploaded successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Support bundle uploaded successfully.",
                  "type": "object",
                  "properties": {
                    "bundleId": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Unique bundle ID — reference this in support tickets"
                    },
                    "receivedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "sizeBytes": {
                      "type": "integer",
                      "description": "Size of the uploaded bundle in bytes"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/records/import": {
      "post": {
        "operationId": "adminImportRecords",
        "summary": "Backfill historical records (bulk import)",
        "tags": [
          "Admin"
        ],
        "description": "Import pre-existing record records from a legacy system into AGLedger's audit trail.\n\nEach item is inserted in its declared terminal state with backdated `createdAt`/`activatedAt`/`fulfilledAt` timestamps. Every imported row gets a single Signed Statement of type `BACKFILL_IMPORT` stamped with `imported: true` + the declared `source`, so compliance crosschecks can distinguish historical data from live activity.\n\n**No side effects:** webhooks do not fire, federation does not propagate, reputation is not scored, no background jobs enqueue. This endpoint is strictly archival.\n\n**Atomicity:** the batch is one transaction. Any per-item validation failure rolls back every insertion, so partial imports never leave the org in an ambiguous state.\n\n**Auth:** platform role + `admin:backfill` scope. Agent keys cannot hold this scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orgId",
                  "source",
                  "records"
                ],
                "properties": {
                  "orgId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Org to import into. Must already exist."
                  },
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128,
                    "description": "Free-form label identifying the source system (e.g. \"SAP-S4-HANA\", \"salesforce-export-2024-Q4\"). Recorded in every imported Signed Statement."
                  },
                  "records": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "required": [
                        "principalAgentId",
                        "type",
                        "platform",
                        "criteria",
                        "terminalStatus",
                        "createdAt"
                      ],
                      "properties": {
                        "principalAgentId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "performerAgentId": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 50
                        },
                        "publisher": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Publisher label pinning WHICH registration of `type` this item binds to. Only needed when two publishers offer the same `record_type` in this org (e.g. an imported peer manifest alongside a local registration). That case returns 422 `/problems/ambiguous-publisher` with the candidate list rather than picking one, the same as `POST /v1/records`. The imported record binds to the registration named here, so it reads back with that `publisher` and a `schemaUrl` scoped to it."
                        },
                        "contractVersion": {
                          "type": "string",
                          "maxLength": 10
                        },
                        "platform": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 50
                        },
                        "platformRef": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "maxLength": 255
                        },
                        "criteria": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "tolerance": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "deadline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "terminalStatus": {
                          "type": "string",
                          "enum": [
                            "FULFILLED",
                            "REMEDIATED",
                            "REJECTED",
                            "PENDING_ARBITRATION",
                            "RECORDED",
                            "EXPIRED",
                            "CANCELLED",
                            "FAILED"
                          ],
                          "description": "Terminal state for the imported record. Display tokens only — same set surfaced everywhere else in the API (FULFILLED, REMEDIATED, REJECTED, PENDING_ARBITRATION, RECORDED, EXPIRED, CANCELLED, FAILED). The internal state machine has wider granularity (TIMED_OUT, VERDICT_REJECTED, CANCELLED_PRE_WORK, CANCELLED_IN_PROGRESS) but the import API normalizes on the way in: EXPIRED → TIMED_OUT, FAILED → VERDICT_REJECTED, CANCELLED → CANCELLED_PRE_WORK (set `cancelledAfterCompletion: true` to land at CANCELLED_IN_PROGRESS instead). RECORDED is the terminal state for notarize-only Types (no completion schema) — the documented \"90% case\"."
                        },
                        "cancelledAfterCompletion": {
                          "type": "boolean",
                          "default": false,
                          "description": "Only meaningful when `terminalStatus` is CANCELLED. False (default) imports as CANCELLED_PRE_WORK (cancelled before any completion was submitted). True imports as CANCELLED_IN_PROGRESS (cancelled after a completion was submitted but before terminalization). Setting this `true` on a non-CANCELLED row is a 400 — the field is meaningless there and a silent ignore would mask the operator's misunderstanding."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "activatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "fulfilledAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "verdict": {
                          "type": "object",
                          "required": [
                            "outcome"
                          ],
                          "properties": {
                            "outcome": {
                              "type": "string",
                              "enum": [
                                "accept",
                                "reject"
                              ]
                            },
                            "reason": {
                              "type": "string",
                              "maxLength": 2000
                            }
                          },
                          "additionalProperties": false
                        },
                        "metadata": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true
                        }
                      },
                      "additionalProperties": false
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Batch imported successfully. `imported[]` is aligned 1:1 with the request `records[]`.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Batch imported successfully. `imported[]` is aligned 1:1 with the request `records[]`.",
                  "type": "object",
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "imported": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Position in the request records[] array"
                          },
                          "recordId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "chainPosition": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Vault chain position of the BACKFILL_IMPORT entry"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Validation failed. Whole batch rolled back — no records were imported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Referenced `orgId` or `principalAgentId` does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "An item names a `type` offered by more than one publisher in this org, so it is ambiguous (`/problems/ambiguous-publisher`, body carries `publishers`). Re-send with a `publisher` on that item. Whole batch rolled back; no records were imported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/trusted-issuers": {
      "get": {
        "operationId": "adminListTrustedIssuers",
        "summary": "List trusted OIDC issuers",
        "tags": [
          "Admin"
        ],
        "description": "Paginated list of OIDC IdP allow-list rows. Filters: appliesTo, orgId, enabled, managedBy.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "principal",
                "admin",
                "any"
              ]
            },
            "in": "query",
            "name": "appliesTo",
            "required": false
          },
          {
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "format": "uuid"
            },
            "in": "query",
            "name": "orgId",
            "required": false
          },
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "enabled",
            "required": false
          },
          {
            "schema": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "provisioning",
                null
              ]
            },
            "in": "query",
            "name": "managedBy",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "orgId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "NULL means the row applies to every org; non-null scopes it."
                          },
                          "issuerUrl": {
                            "type": "string",
                            "minLength": 1,
                            "description": "OIDC iss claim (exact match)."
                          },
                          "jwksUri": {
                            "type": "string",
                            "minLength": 1,
                            "description": "JWKS endpoint URL. Resolved via OIDC discovery on insert if the admin omits it."
                          },
                          "expectedAudience": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Required value for the token aud claim."
                          },
                          "expectedAzp": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "For multi-audience tokens (aud is a length > 1 array), the helper requires azp == expectedAzp per OIDC Core §3.1.3.7."
                          },
                          "appliesTo": {
                            "type": "string",
                            "enum": [
                              "agent",
                              "principal",
                              "admin",
                              "any"
                            ]
                          },
                          "claimMapping": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                          },
                          "allowedAlgs": {
                            "type": [
                              "null",
                              "array"
                            ],
                            "items": {
                              "type": "string"
                            },
                            "description": "Override of DEFAULT_ALLOWED_ALGS for this issuer; null means inherit defaults."
                          },
                          "maxCredentialTtlSeconds": {
                            "type": "integer",
                            "minimum": 60,
                            "maximum": 3600
                          },
                          "label": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Human-readable label, e.g. \"Auth0 production\"."
                          },
                          "enabled": {
                            "type": "boolean"
                          },
                          "managedBy": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "provisioning",
                              null
                            ],
                            "description": "null = admin-managed; \"provisioning\" = YAML-managed."
                          },
                          "createdBy": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedBy": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "orgId",
                          "issuerUrl",
                          "jwksUri",
                          "expectedAudience",
                          "expectedAzp",
                          "appliesTo",
                          "claimMapping",
                          "allowedAlgs",
                          "maxCredentialTtlSeconds",
                          "label",
                          "enabled",
                          "managedBy",
                          "createdBy",
                          "createdAt",
                          "updatedBy",
                          "updatedAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "data",
                    "total",
                    "nextCursor",
                    "hasMore"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "adminCreateTrustedIssuer",
        "summary": "Create a trusted OIDC issuer",
        "tags": [
          "Admin"
        ],
        "description": "Registers a new trust anchor. If `jwksUri` is omitted, the Server fetches `${issuerUrl}/.well-known/openid-configuration` and resolves it automatically. 422 if the issuer URL is unreachable or the discovery document is malformed.\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "orgId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "issuerUrl": {
                    "type": "string",
                    "minLength": 1
                  },
                  "jwksUri": {
                    "type": "string",
                    "minLength": 1
                  },
                  "expectedAudience": {
                    "type": "string",
                    "minLength": 1
                  },
                  "expectedAzp": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "appliesTo": {
                    "type": "string",
                    "enum": [
                      "agent",
                      "principal",
                      "admin",
                      "any"
                    ]
                  },
                  "claimMapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                  },
                  "allowedAlgs": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "maxCredentialTtlSeconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 3600
                  },
                  "label": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "issuerUrl",
                  "expectedAudience"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "NULL means the row applies to every org; non-null scopes it."
                    },
                    "issuerUrl": {
                      "type": "string",
                      "minLength": 1,
                      "description": "OIDC iss claim (exact match)."
                    },
                    "jwksUri": {
                      "type": "string",
                      "minLength": 1,
                      "description": "JWKS endpoint URL. Resolved via OIDC discovery on insert if the admin omits it."
                    },
                    "expectedAudience": {
                      "type": "string",
                      "minLength": 1,
                      "description": "Required value for the token aud claim."
                    },
                    "expectedAzp": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "For multi-audience tokens (aud is a length > 1 array), the helper requires azp == expectedAzp per OIDC Core §3.1.3.7."
                    },
                    "appliesTo": {
                      "type": "string",
                      "enum": [
                        "agent",
                        "principal",
                        "admin",
                        "any"
                      ]
                    },
                    "claimMapping": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                    },
                    "allowedAlgs": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      },
                      "description": "Override of DEFAULT_ALLOWED_ALGS for this issuer; null means inherit defaults."
                    },
                    "maxCredentialTtlSeconds": {
                      "type": "integer",
                      "minimum": 60,
                      "maximum": 3600
                    },
                    "label": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Human-readable label, e.g. \"Auth0 production\"."
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "managedBy": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "provisioning",
                        null
                      ],
                      "description": "null = admin-managed; \"provisioning\" = YAML-managed."
                    },
                    "createdBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "id",
                    "orgId",
                    "issuerUrl",
                    "jwksUri",
                    "expectedAudience",
                    "expectedAzp",
                    "appliesTo",
                    "claimMapping",
                    "allowedAlgs",
                    "maxCredentialTtlSeconds",
                    "label",
                    "enabled",
                    "managedBy",
                    "createdBy",
                    "createdAt",
                    "updatedBy",
                    "updatedAt",
                    "nextSteps"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Body validation failed (invalid URL, out-of-range TTL, reserved claim_mapping key, etc.); see recoveryHint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A trusted_issuers row with the same (issuer_url, expected_audience, applies_to, org_id) already exists.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "OIDC discovery failed (IdP unreachable, returned non-OK, malformed JSON, missing jwks_uri); supply jwksUri explicitly.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/trusted-issuers/{id}": {
      "get": {
        "operationId": "adminGetTrustedIssuer",
        "summary": "Get a single trusted issuer",
        "tags": [
          "Admin"
        ],
        "description": "Fetch one row by id. 404 when no row matches.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "NULL means the row applies to every org; non-null scopes it."
                    },
                    "issuerUrl": {
                      "type": "string",
                      "minLength": 1,
                      "description": "OIDC iss claim (exact match)."
                    },
                    "jwksUri": {
                      "type": "string",
                      "minLength": 1,
                      "description": "JWKS endpoint URL. Resolved via OIDC discovery on insert if the admin omits it."
                    },
                    "expectedAudience": {
                      "type": "string",
                      "minLength": 1,
                      "description": "Required value for the token aud claim."
                    },
                    "expectedAzp": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "For multi-audience tokens (aud is a length > 1 array), the helper requires azp == expectedAzp per OIDC Core §3.1.3.7."
                    },
                    "appliesTo": {
                      "type": "string",
                      "enum": [
                        "agent",
                        "principal",
                        "admin",
                        "any"
                      ]
                    },
                    "claimMapping": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                    },
                    "allowedAlgs": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      },
                      "description": "Override of DEFAULT_ALLOWED_ALGS for this issuer; null means inherit defaults."
                    },
                    "maxCredentialTtlSeconds": {
                      "type": "integer",
                      "minimum": 60,
                      "maximum": 3600
                    },
                    "label": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Human-readable label, e.g. \"Auth0 production\"."
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "managedBy": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "provisioning",
                        null
                      ],
                      "description": "null = admin-managed; \"provisioning\" = YAML-managed."
                    },
                    "createdBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "orgId",
                    "issuerUrl",
                    "jwksUri",
                    "expectedAudience",
                    "expectedAzp",
                    "appliesTo",
                    "claimMapping",
                    "allowedAlgs",
                    "maxCredentialTtlSeconds",
                    "label",
                    "enabled",
                    "managedBy",
                    "createdBy",
                    "createdAt",
                    "updatedBy",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "adminUpdateTrustedIssuer",
        "summary": "Update a trusted OIDC issuer",
        "tags": [
          "Admin"
        ],
        "description": "Partial update. Changing `issuerUrl` without supplying `jwksUri` triggers re-discovery. 409 if the row is provisioning-managed (PATCH `managedBy: null` first to take admin ownership).\n\n**Auth:** platform role only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "issuerUrl": {
                    "type": "string",
                    "minLength": 1
                  },
                  "jwksUri": {
                    "type": "string",
                    "minLength": 1
                  },
                  "expectedAudience": {
                    "type": "string",
                    "minLength": 1
                  },
                  "expectedAzp": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "appliesTo": {
                    "type": "string",
                    "enum": [
                      "agent",
                      "principal",
                      "admin",
                      "any"
                    ]
                  },
                  "claimMapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                  },
                  "allowedAlgs": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "maxCredentialTtlSeconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 3600
                  },
                  "label": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "managedBy": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "provisioning",
                      null
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "orgId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid",
                      "description": "NULL means the row applies to every org; non-null scopes it."
                    },
                    "issuerUrl": {
                      "type": "string",
                      "minLength": 1,
                      "description": "OIDC iss claim (exact match)."
                    },
                    "jwksUri": {
                      "type": "string",
                      "minLength": 1,
                      "description": "JWKS endpoint URL. Resolved via OIDC discovery on insert if the admin omits it."
                    },
                    "expectedAudience": {
                      "type": "string",
                      "minLength": 1,
                      "description": "Required value for the token aud claim."
                    },
                    "expectedAzp": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "For multi-audience tokens (aud is a length > 1 array), the helper requires azp == expectedAzp per OIDC Core §3.1.3.7."
                    },
                    "appliesTo": {
                      "type": "string",
                      "enum": [
                        "agent",
                        "principal",
                        "admin",
                        "any"
                      ]
                    },
                    "claimMapping": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Logical-name → IdP-claim-name map, e.g. {\"scopes\":\"groups\",\"role\":\"agledger_role\"}. Reserved logical names (__proto__/prototype/constructor) are rejected."
                    },
                    "allowedAlgs": {
                      "type": [
                        "null",
                        "array"
                      ],
                      "items": {
                        "type": "string"
                      },
                      "description": "Override of DEFAULT_ALLOWED_ALGS for this issuer; null means inherit defaults."
                    },
                    "maxCredentialTtlSeconds": {
                      "type": "integer",
                      "minimum": 60,
                      "maximum": 3600
                    },
                    "label": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Human-readable label, e.g. \"Auth0 production\"."
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "managedBy": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "provisioning",
                        null
                      ],
                      "description": "null = admin-managed; \"provisioning\" = YAML-managed."
                    },
                    "createdBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedBy": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "id",
                    "orgId",
                    "issuerUrl",
                    "jwksUri",
                    "expectedAudience",
                    "expectedAzp",
                    "appliesTo",
                    "claimMapping",
                    "allowedAlgs",
                    "maxCredentialTtlSeconds",
                    "label",
                    "enabled",
                    "managedBy",
                    "createdBy",
                    "createdAt",
                    "updatedBy",
                    "updatedAt",
                    "nextSteps"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Body validation failed (invalid URL, out-of-range TTL, reserved claim_mapping key, etc.); see recoveryHint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Row is provisioning-managed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "OIDC discovery failed on issuerUrl change; supply jwksUri explicitly.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "adminDeleteTrustedIssuer",
        "summary": "Delete a trusted OIDC issuer",
        "tags": [
          "Admin"
        ],
        "description": "Removes the row. 409 if provisioning-managed.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "required": [
                    "deleted",
                    "id",
                    "nextSteps"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict. Either the row is provisioning-managed (reason PROVISIONING_MANAGED — remove it from the provisioning YAML or PATCH managedBy=null first), or it has already issued ephemeral certs and delete is blocked for audit-trail integrity (reason ROW_HAS_DEPENDENT_RECORDS — use PATCH enabled:false to soft-revoke; the recoveryHint carries the exact call).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/trusted-issuers/{id}/revoke-certs": {
      "post": {
        "operationId": "adminRevokeTrustedIssuerCerts",
        "summary": "Revoke all active ephemeral certs minted by a trusted issuer",
        "tags": [
          "Admin"
        ],
        "description": "IdP-compromise response: revokes every currently-active ephemeral cert this issuer minted, so they stop authenticating within the cert-auth cache TTL (~60s). Does NOT stop NEW mints — PATCH `enabled:false` for that (do both for a full compromise response). Already-revoked / already-expired certs are left as-is and not counted. 404 if the issuer does not exist.\n\n**Auth:** platform role only.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "issuerId",
                    "revokedCount",
                    "nextSteps"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "issuerId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "revokedCount": {
                      "type": "integer",
                      "description": "Count of active certs revoked by this call (already-revoked/expired excluded)."
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No trusted issuer with this id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/provisioning/status": {
      "get": {
        "operationId": "adminProvisioningStatus",
        "summary": "Inspect provisioning configuration and managed resource counts",
        "tags": [
          "Admin"
        ],
        "description": "Returns whether YAML provisioning is configured, current settings (dry-run, prune), managed resource counts, and last reload timestamp. **Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configured": {
                      "type": "boolean"
                    },
                    "configPath": {
                      "type": "string"
                    },
                    "dryRun": {
                      "type": "boolean"
                    },
                    "prune": {
                      "type": "boolean"
                    },
                    "lastReloadAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "managed": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "orgs": {
                          "type": "integer"
                        },
                        "agents": {
                          "type": "integer"
                        },
                        "webhooks": {
                          "type": "integer"
                        },
                        "schemas": {
                          "type": "integer"
                        }
                      }
                    },
                    "loadErrors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Files in the provisioning directory that cannot be loaded right now, one entry per failure (empty when the directory is clean). A file that fails to parse is skipped whole and its resources are silently absent, while the rest of the reconcile succeeds and the Server boots healthy. Re-read from disk on each call: a non-empty list means the files on disk will not fully apply, so fix them and POST /v1/admin/provisioning/reload."
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/provisioning/reload": {
      "post": {
        "operationId": "adminProvisioningReload",
        "summary": "Hot-reload provisioning config from YAML directory",
        "tags": [
          "Admin"
        ],
        "description": "Re-reads YAML files from the provisioning directory and reconciles resources. Returns counts and slugs of created/updated/pruned resources, plus any newly generated API keys. **Auth:** platform role only.",
        "security": [
          {
            "platformAuth": []
          },
          {
            "adminOidcJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orgs": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "updated": {
                          "type": "integer"
                        },
                        "pruned": {
                          "type": "integer"
                        },
                        "createdNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "updatedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "prunedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "agents": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "updated": {
                          "type": "integer"
                        },
                        "pruned": {
                          "type": "integer"
                        },
                        "createdNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "updatedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "prunedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "webhooks": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "updated": {
                          "type": "integer"
                        },
                        "pruned": {
                          "type": "integer"
                        },
                        "createdNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "updatedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "prunedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "schemas": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "updated": {
                          "type": "integer"
                        },
                        "pruned": {
                          "type": "integer"
                        },
                        "createdNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "updatedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "prunedNames": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "apiKeys": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "skipped": {
                          "type": "integer"
                        },
                        "generated": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                              "ownerName": {
                                "type": "string"
                              },
                              "ownerType": {
                                "type": "string"
                              },
                              "label": {
                                "type": "string"
                              },
                              "apiKey": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "resource": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "error": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "dryRun": {
                      "type": "boolean"
                    },
                    "nextSteps": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NextStepAction"
                      },
                      "description": "Suggested next actions for AI agents and automation workflows"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/siem/stream": {
      "get": {
        "operationId": "getAuditStream",
        "summary": "Pull audit events as OCSF NDJSON",
        "tags": [
          "Audit"
        ],
        "description": "Returns audit events in OCSF v1.4.0 format as NDJSON. Designed for SIEM ingestion (Splunk, Sentinel, QRadar, CrowdStrike, Elastic). Use `X-AGLedger-Stream-Cursor` response header for efficient polling. Results are scoped by role: orgs see events for their own records, agents see records where they are performer or principal, platform sees everything.\n\n**Auth:** admin, agent, platform\n**Scope:** `audit:read`",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "in": "query",
            "name": "since",
            "required": true,
            "description": "Return events created after this timestamp (required)"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Maximum events to return"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ocsf",
                "raw"
              ],
              "default": "ocsf"
            },
            "in": "query",
            "name": "format",
            "required": false,
            "description": "Output format: ocsf (OCSF v1.4.0) or raw (AGLedger native)"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "NDJSON stream of audit events. Each line is a self-contained JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "NDJSON stream of audit events. Each line is a self-contained JSON object.",
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — request failed JSON Schema validation (querystring / path params / body).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scitt/entries": {
      "post": {
        "operationId": "scrapiRegisterEntry",
        "summary": "Register a Signed Statement (SCRAPI POST /entries)",
        "tags": [
          "SCITT"
        ],
        "description": "SCITT Transparency Service registration per `draft-ietf-scitt-scrapi-09`. Body is a customer-prepared COSE_Sign1 over an in-toto v1 Statement (or any predicate the customer chooses; the TS is content-agnostic). Response: `201 Created` with `Content-Type: application/cose` carrying the issued Receipt. Errors are returned as `application/concise-problem-details+cbor` per RFC 9290. Sync only — async (303+Location) is forward work.\n\n**No payload-hash dedup; no `Idempotency-Key` support.** Identical statement bytes resubmitted create distinct entries — each gets its own leaf index in the per-org Merkle tree. Clients must not blindly retry on 5xx without consulting `GET /v1/scitt/entries/{location}` first. The new entry id is returned in the `Location` header on 201; treat 5xx outcomes as \"may or may not have landed\".",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "201": {
            "description": "Receipt as tagged COSE_Sign1 bytes (application/cose).",
            "content": {
              "application/cose": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Receipt as tagged COSE_Sign1 bytes (application/cose)."
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Receipt as tagged COSE_Sign1 bytes (application/cose)."
                }
              },
              "application/problem+json": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Receipt as tagged COSE_Sign1 bytes (application/cose)."
                }
              }
            }
          },
          "400": {
            "description": "Bad request. Framework validation / malformed body → RFC 9457 JSON; handler protocol errors (bad COSE) send CBOR (application/concise-problem-details+cbor).",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/cose": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported media type. Framework content-type rejection → RFC 9457 JSON; handler bad-content-type sends CBOR.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error (RFC 9457 JSON).",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/cose": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scitt/checkpoint": {
      "get": {
        "operationId": "scrapiGetCheckpoint",
        "summary": "Signed tree head for the caller's per-org SCITT log",
        "tags": [
          "SCITT"
        ],
        "description": "Returns the current per-org Merkle root + tree size, signed with the vault key. Lets consumers ask \"is the log alive, what's its current state?\" without registering a new entry. JSON for V1 (a SCITT-spec CBOR checkpoint is forward work). Signature input: `${logId}:${treeSize}:${rootHex}:${iat}` — verifier re-builds it from response fields and verifies against the public key at /.well-known/scitt-keys/{kid}. **Cost:** O(N) in the org's SCITT entry count — every call loads all leaves and re-walks the Merkle tree. High-volume consumers polling this endpoint at sub-second cadence on a 1M+-entry log should cache the last response rather than re-poll (telemetry: `agledger_merkle_rebuild_*{surface=\"scrapi-checkpoint\"}`).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "treeSize",
                    "rootHex",
                    "logId",
                    "iat",
                    "kid",
                    "signature"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "treeSize": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Number of entries in the per-org SCITT log at the moment of the call."
                    },
                    "rootHex": {
                      "type": "string",
                      "pattern": "^[0-9a-f]+$",
                      "description": "SHA-256 hex of the Merkle root (empty tree yields hex of SHA-256(\"\"))."
                    },
                    "logId": {
                      "type": "string",
                      "description": "Per-org log identifier (= the caller's org id). Bound into the signature input so a checkpoint cannot be substituted across orgs."
                    },
                    "iat": {
                      "type": "integer",
                      "description": "Unix epoch seconds at which the checkpoint was signed."
                    },
                    "kid": {
                      "type": "string",
                      "description": "Key id used to sign — resolve at /.well-known/scitt-keys/{kid}."
                    },
                    "signature": {
                      "type": "string",
                      "description": "Hex signature over UTF-8 bytes of `${logId}:${treeSize}:${rootHex}:${iat}`, under the signing key's algorithm (resolve `kid` at /.well-known/scitt-keys/{kid}; Ed25519 raw bytes by default, P1363 r||s on an ES256-opted Server)."
                    }
                  }
                }
              },
              "application/problem+json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "treeSize",
                    "rootHex",
                    "logId",
                    "iat",
                    "kid",
                    "signature"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "treeSize": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Number of entries in the per-org SCITT log at the moment of the call."
                    },
                    "rootHex": {
                      "type": "string",
                      "pattern": "^[0-9a-f]+$",
                      "description": "SHA-256 hex of the Merkle root (empty tree yields hex of SHA-256(\"\"))."
                    },
                    "logId": {
                      "type": "string",
                      "description": "Per-org log identifier (= the caller's org id). Bound into the signature input so a checkpoint cannot be substituted across orgs."
                    },
                    "iat": {
                      "type": "integer",
                      "description": "Unix epoch seconds at which the checkpoint was signed."
                    },
                    "kid": {
                      "type": "string",
                      "description": "Key id used to sign — resolve at /.well-known/scitt-keys/{kid}."
                    },
                    "signature": {
                      "type": "string",
                      "description": "Hex signature over UTF-8 bytes of `${logId}:${treeSize}:${rootHex}:${iat}`, under the signing key's algorithm (resolve `kid` at /.well-known/scitt-keys/{kid}; Ed25519 raw bytes by default, P1363 r||s on an ES256-opted Server)."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. Framework validation / malformed body → RFC 9457 JSON; handler protocol errors (bad COSE) send CBOR (application/concise-problem-details+cbor).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported media type. Framework content-type rejection → RFC 9457 JSON; handler bad-content-type sends CBOR.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error (RFC 9457 JSON).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scitt/entries/{entryId}": {
      "get": {
        "operationId": "scrapiGetEntry",
        "summary": "Fetch a Transparent Statement by entry id",
        "tags": [
          "SCITT"
        ],
        "description": "Returns the original Signed Statement with a freshly-issued Receipt attached at unprotected label 394 (per SCITT-arch §3.2). The Receipt commits to the per-org Merkle root at the moment of the call — consumers always see a Receipt anchored to the latest state. Cross-org reads are reported as 404 (deliberately indistinguishable from missing) to defend against UUID-guessing across orgs.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "entryId",
            "required": true
          }
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "agentEphemeralCert": []
          }
        ],
        "responses": {
          "200": {
            "description": "Transparent Statement as tagged COSE_Sign1 bytes.",
            "content": {
              "application/cose": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Transparent Statement as tagged COSE_Sign1 bytes."
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Transparent Statement as tagged COSE_Sign1 bytes."
                }
              },
              "application/problem+json": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Transparent Statement as tagged COSE_Sign1 bytes."
                }
              }
            }
          },
          "400": {
            "description": "Bad request. Framework validation / malformed body → RFC 9457 JSON; handler protocol errors (bad COSE) send CBOR (application/concise-problem-details+cbor).",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized -- missing or invalid Bearer token.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden -- authenticated but insufficient permissions for this resource.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/cose": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported media type. Framework content-type rejection → RFC 9457 JSON; handler bad-content-type sends CBOR.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. This is temporary — retry the same request after retryAfterSeconds. Agent keys: 500 req/min. Admin keys: 1,000 req/min. Defaults tunable via RATE_LIMIT_AGENT / RATE_LIMIT_ADMIN.",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error (RFC 9457 JSON).",
            "content": {
              "application/cose": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
            "content": {
              "application/cose": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/concise-problem-details+cbor": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/problem+json": {
                "schema": {
                  "description": "Error envelope as application/concise-problem-details+cbor (RFC 9290).",
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "AGLedger API (root — includes /v1 business routes and /.well-known, /a2a, /healthz protocol/health routes)"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Auth",
      "description": "Authenticated key introspection and rotation. Use `GET /v1/auth/me` to look up the role/org the current key is bound to, and `POST /v1/auth/keys/rotate` to roll the credential (the new key is shown once — store it). AGLedger is self-hosted only; accounts are provisioned by an operator via `POST /v1/admin/orgs` + `POST /v1/admin/api-keys` (or via the `provisioning/` YAML config-as-code directory)."
    },
    {
      "name": "Health",
      "description": "Service health check. No authentication required."
    },
    {
      "name": "Schemas",
      "description": "Type schema registry (public, no authentication required). Lists customer-registered types and returns the JSON Schema definitions for record criteria and completion evidence. The engine ships with no built-in types — register your own with `POST /v1/schemas` before issuing records against a type. See agledger.ai/docs/schemas for guidance on shaping a custom record + completion schema pair."
    },
    {
      "name": "Records",
      "description": "RecordRow lifecycle management: create, read, update, search, and state transitions. Records progress through an 11-state customer-facing lifecycle: CREATED → ACTIVE → PROCESSING → FULFILLED / FAILED / REVISION_REQUESTED → REMEDIATED. Additional states: PROPOSED and REJECTED (agent-to-agent negotiation), EXPIRED, and CANCELLED. Only records in CREATED status can be edited. Supports bulk creation (up to 100), agent-to-agent records (bilateral, proposal negotiation, delegation chains), two operating modes (cleartext / encrypted), and two gate modes (auto, principal). The principal verdict endpoint `POST /records/:id/verdict` is required for gateMode=principal and all encrypted records. Admin keys see all records in their org; agent keys see records where they are the principal or performer; platform keys see everything."
    },
    {
      "name": "Completions",
      "description": "Task attestation submission and retrieval. Agents submit completion evidence against active records. In cleartext + gateMode=auto, Phase 1 structural validation (JSON Schema conformance) runs synchronously and Phase 2 gate evaluation (field-by-field checks with tolerance bands) runs asynchronously via pg-boss with results delivered via webhook. In gateMode=principal, the record holds after completion acceptance for the principal verdict via `POST /records/:id/verdict` (the engine runs an advisory pass first when the schema has rules). In encrypted mode, completions skip structural validation entirely — the principal decrypts, evaluates locally, and submits the verdict via `/records/:id/verdict`."
    },
    {
      "name": "Webhooks",
      "description": "Webhook subscription management and delivery logs. Register HTTPS endpoints to receive real-time event notifications. Two signing schemes (see the \"Webhook Signatures\" section): `hmac` (default; server-side secret returned once on creation -- store it) and `ed25519` (opt-in RFC 9421, signed with the vault key, verifiable against /v1/verification-keys, no shared secret — the non-repudiable choice for Settlement Signals). Replay window: 300s. Dedup on the `X-AGLedger-Idempotency-Key` header (the event id, stable across retries); `X-AGLedger-Delivery` is a per-attempt id, not for dedup. Delivery retries follow exponential backoff: 1s, 5s, 30s, 5m, 30m, 2h, then dead-letter queue. A 410 response auto-disables the subscription. URLs are validated against SSRF (blocks RFC 1918, link-local, loopback, and AWS metadata IPs)."
    },
    {
      "name": "Events",
      "description": "Event reconciliation endpoint. Poll to catch events that may have been missed by webhooks. Admin keys see events for records in their org; platform keys see all events. Supports filtering by timestamp, record ID, and event type."
    },
    {
      "name": "Disputes",
      "description": "Three-tier dispute resolution system. Tier 1 performs automatic re-adjudication with expanded tolerance bands. If unresolved, disputes can be escalated to Tier 2 (manual review) and Tier 3 (binding arbitration with flat fee). Evidence can be submitted during the evidence window. Dispute outcomes feed back into the record lifecycle and agent reputation scores."
    },
    {
      "name": "Reputation",
      "description": "Agentic Reputation -- the \"credit bureau for agentic operations.\" Provides composite reputation scores across reliability, accuracy, and efficiency dimensions, with confidence intervals that tighten as transaction volume grows. Scores are broken down per type and auto-recalculated on verification and dispute events."
    },
    {
      "name": "A2A Protocol",
      "description": "Agent-to-Agent (A2A) protocol endpoints (Linux Foundation open standard). The AgentCard at `/.well-known/agent-card.json` enables standard A2A discovery. The `/a2a` endpoint accepts JSON-RPC 2.0 requests (`message/send`, `tasks/get`, `tasks/cancel`) that map to AGLedger records and completions. A2A Tasks correspond to records; A2A Artifacts correspond to completions."
    },
    {
      "name": "Compliance",
      "description": "EU AI Act deployer compliance record-keeping. Append-only attestation records for workplace notification (Art. 26(7)), affected persons notification (Art. 26(11)), input data quality review (Art. 26(4)), and fundamental rights impact assessment (Art. 27). Also provides structured audit exports in JSON, CSV, and NDJSON formats with chain integrity verification and Ed25519 signature data."
    },
    {
      "name": "Agent-to-Agent",
      "description": "Agent-to-agent record lifecycle: bilateral records, propose/accept/reject negotiation, delegation chains with cascading gates, and commission tracking. Supports three tiers: Tier 1 (direct bilateral), Tier 2 (proposal negotiation), and Tier 3 (delegation chains up to depth 5 with automatic cascading gates). RecordRow creation and proposal flow use the unified `POST /v1/records` endpoint — both admin and agent keys can drive A2A flows; accept/reject/counter-propose actions remain agent-only (the named performer must respond)."
    },
    {
      "name": "Federation",
      "description": "V1 federation: signed-message transport between sovereign Servers. Each Server is a peer; there is no Hub or Gateway role. Peers exchange public keys via the platform-authed `POST /federation/v1/peer` handshake; every subsequent request stands on its own per-request Ed25519 signature in the `X-AGLedger-*` header set (RFC 9421-inspired sign-input `agledger.federation.v1:METHOD:PATH:bodyHash:timestamp:nonce`). State transitions, Settlement Signals, and agent directories cross the wire; criteria values, evidence, and audit entries stay intra-org."
    },
    {
      "name": "Federation Admin",
      "description": "Federation administration (platform role required). Manage peer Server registrations, view peer detail, force-resync, and manage the outbound dead letter queue."
    },
    {
      "name": "SCITT",
      "description": "SCITT Transparency Service surface (`draft-ietf-scitt-scrapi-09`). `POST /v1/scitt/entries` registers a customer Signed Statement (COSE_Sign1 over an in-toto v1 Statement) and returns a Receipt (RFC 9162 inclusion proof). `GET /v1/scitt/entries/{id}` returns a Transparent Statement — the original Signed Statement with a freshly-issued Receipt attached at unprotected header label 394. Per-org lazy Merkle tree; Receipts re-issue against the current root on every read. 4xx/5xx responses use `application/concise-problem-details+cbor` (RFC 9290)."
    },
    {
      "name": "Discovery",
      "description": "Always-on, unauthenticated discovery surfaces. Agent grounding (`/llms.txt`, `/llms-full.txt`), machine-readable spec (`/openapi.json`), agent-protocol cards (`/.well-known/agent-card.json`), verification keys (`/v1/verification-keys`, `/.well-known/agledger-vault-keys.json`, `/.well-known/scitt-keys`), predicate schemas (`/predicates`, `/predicates/{kind}/v1`), and scope catalogue (`/v1/scope-profiles`). Never gated — agent success depends on predictable availability."
    },
    {
      "name": "Admin",
      "description": "Platform administration endpoints. List and manage orgs, agents, and API keys. View webhook dead letter queue and system health. All endpoints require platform role."
    }
  ]
}
