{"openapi":"3.1.0","info":{"title":"Mnemom API","description":"Trust infrastructure for AI agents. Transparent alignment verification, behavioral drift detection, and accountability primitives.","version":"1.0.0","contact":{"name":"Mnemom","url":"https://mnemom.ai","email":"support@mnemom.ai"},"license":{"name":"Apache 2.0","url":"https://www.apache.org/licenses/LICENSE-2.0"}},"servers":[{"url":"https://api.mnemom.ai/v1","description":"Production"}],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"tags":[{"name":"A2A","description":"Public A2A AgentCard projection of the canonical alignment card, with embedded AAP attestation extension (cards-as-primitive Phase 5)."},{"name":"Agents","description":"Agent registration, lifecycle, and metadata."},{"name":"Agent Containment","description":"Containment policies and quarantine controls."},{"name":"Alignment","description":"Alignment manifest CRUD — canonical `/v1/alignment/<scope>/<scope_id>` surface across platform / org / team / agent (cards-as-primitive Phase 4)."},{"name":"Analyze","description":"Behavioral analysis endpoints."},{"name":"Attestation","description":"AAP attestation token JWKS surface and platform-admin signing-key rotation (cards-as-primitive Phase 5)."},{"name":"Auth","description":"Authentication, sessions, and access management."},{"name":"Billing","description":"Subscription, usage, and invoicing."},{"name":"Blog","description":"Public blog content."},{"name":"Card Templates","description":"Org-level alignment and protection card templates."},{"name":"Catalog","description":"Discovery surface for the 25-entry Mnemom value catalog v1 (cards-as-primitive Phase 4)."},{"name":"Checkpoints","description":"Integrity checkpoints and proof artifacts."},{"name":"Conscience Values","description":"Org-level conscience-value configuration."},{"name":"Drift","description":"Drift detection and resolution."},{"name":"Enforcement","description":"Enforcement-mode configuration and queries."},{"name":"Governance","description":"Operator-actionable governance signals (ADR-048)."},{"name":"Integrity","description":"AIP integrity checkpoints and verdicts."},{"name":"Intelligence","description":"Intelligence reports and queries."},{"name":"Licensing","description":"License management."},{"name":"Network","description":"Protection Network L4 thermometer read surface. Public-aggregate disclosure: any authenticated principal may read; rows carry no per-tenant identifiers."},{"name":"OAuth","description":"OAuth 2.1 authorization-code + PKCE flow for MCP clients (MNE-328). Identity delegated to Supabase GoTrue; mnemom-api mints its own short-lived MCP-scoped tokens. Includes RFC 7591 dynamic client registration and RFC 7009 revocation."},{"name":"On-Chain","description":"On-chain verification and proofs."},{"name":"Organizations","description":"Org-level resources and management."},{"name":"Policy","description":"Policy evaluation and configuration."},{"name":"Postures","description":"Trust posture management (ADR-045)."},{"name":"Protection","description":"Protection manifest CRUD — canonical `/v1/protection/<scope>/<scope_id>` surface across platform / org / team / agent (cards-as-primitive Phase 4)."},{"name":"Recipes","description":"Customer-facing detection-recipe surface — FN/FP reports. Distinct from the Admin recipe-promotion surface and the Internal seeding surface."},{"name":"Reclassification","description":"Reclassification workflows."},{"name":"Reputation","description":"Per-agent reputation scores."},{"name":"Risk","description":"Risk assessment endpoints."},{"name":"Safe House","description":"Safe House threat detection and quarantine."},{"name":"Sideband","description":"Sideband detection queries (legacy; sunsetting)."},{"name":"Team Reputation","description":"Team-level reputation aggregates."},{"name":"Teams","description":"Team-scope resources."},{"name":"Tools","description":"Mnemom-side tools registry — per-tool class+domain+schema metadata (cards-as-primitive Phase 4)."},{"name":"Traces","description":"AP-Trace artifacts and queries."},{"name":"Transparency","description":"Append-only public log of every canonical card identity ever composed. Signed Merkle root + per-row inclusion proofs (cards-as-primitive Phase 5)."},{"name":"Trust","description":"Protection Network L5 public-trust surface — security advisories, IoC feed (STIX 2.1), and platform-admin CMS for both."},{"name":"Verification","description":"Trace verification endpoints."},{"name":"Webhook Notifications","description":"Webhook event subscription management."},{"name":"Webhooks","description":"Webhook delivery and lifecycle."},{"name":"Misc","description":"Miscellaneous operator-facing endpoints (contact, enterprise inquiries, compliance)."},{"name":"Notifications","description":"Reactive notification channels — SSE stream + signed-webhook subscriptions for canonical card changes (cards-as-primitive Phase 5)."}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Supabase JWT token in Authorization: Bearer header"},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Mnemom-Api-Key","description":"Mnemom API key (mnm_... format)"},"ServiceRole":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Supabase service role bearer JWT. Used by /blog admin operations that talk directly to Supabase. NOT used by /internal/* or /v1/arena/internal/* — those use the custom-header schemes below."},"InternalKeyAuth":{"type":"apiKey","in":"header","name":"X-Internal-Key","description":"Internal service-to-service shared secret, timing-safe compared against INTERNAL_API_KEY. Used by /internal/* gateway routes (compose, agents, webhooks emit)."},"ServiceKeyAuth":{"type":"apiKey","in":"header","name":"X-Service-Key","description":"Service-to-service shared secret, timing-safe compared against MNEMOM_SERVICE_KEY. Used by /v1/arena/internal/*, /v1/on-chain/*, and the /v1/internal/* readers consumed by the reputation cron."},"CoherenceTokenAuth":{"type":"http","scheme":"bearer","description":"Per-cell coherence bearer token. Provisioned in 1Password vault `mnemom-coherence` (one item per receiver). Value compared against COHERENCE_<NAME>_SERVICE_TOKEN_EXPECTED. Used by /v1/internal/coherence/* and /v1/internal/governance/dispatch."},"ArenaCandidateTokenAuth":{"type":"http","scheme":"bearer","description":"Dedicated arena writer token (ADR-004 §\"Arena dedicated writer token\"). Compared against ARENA_RECIPE_CANDIDATE_TOKEN. The token's only capability is writing recipe candidates with writer_identity='arena-bypass' (stamped server-side). Used by POST /v1/internal/recipe-candidates."},"CookieAuth":{"type":"apiKey","in":"cookie","name":"mnemom_session","description":"HttpOnly, Secure, SameSite=Lax cookie issued by /v1/auth/sign-in (or the SSO / email-callback flows). The value is an AES-256-GCM-encrypted blob of {access_token, refresh_token, issued_at, auth_method}. Browser clients include this automatically with `credentials: \"include\"`."},"LicenseJwtAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"License JWT (HS256, HMAC-signed with LICENSE_SIGNING_SECRET). Used by self-hosted deployment instances to authenticate `/v1/deployments/heartbeat`. Not interchangeable with the Supabase user JWT."},"AgentAuth":{"type":"apiKey","in":"header","name":"X-Mnemom-Agent-Proof","description":"Agent possession proof: the full SHA-256 hex digest of `${apiKey}|${agentName}` (or `${apiKey}` for an unnamed singleton agent) — the same `hash_proof` primitive used by POST /v1/agents claim, link-agent, and verify-binding. The server resolves the agent by `agent_hash = proof[:16]`. The agent's *own* identity (ADR-API-001 third auth class) — distinct from ApiKeyAuth (`X-Mnemom-Api-Key`, which resolves a user/account, not an agent)."}},"parameters":{"AgentId":{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"},"description":"Agent identifier (e.g. smolt-abc123)"},"OrgId":{"name":"org_id","in":"path","required":true,"schema":{"type":"string"},"description":"Organization identifier (e.g. org-abc12345)"},"EndpointId":{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook endpoint identifier (e.g. whe-abc12345)"},"TeamId":{"name":"team_id","in":"path","required":true,"schema":{"type":"string"},"description":"Team identifier (UUID)"}},"responses":{"BadRequest":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PaymentRequired":{"description":"Paid feature gate — the caller's plan doesn't include this operation's feature flag. Emitted by `requireFeature` / `requireEntitlement` in `src/org/rbac.ts`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Server error — request was well-formed but the server failed to fulfill it. Typically a downstream dependency (DB / RPC / external API) returned an unexpected error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Resource conflict — the request cannot proceed because of a current state conflict (e.g., resource already exists, version mismatch, in-flight idempotency key with a different body).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnprocessableEntity":{"description":"Request was well-formed but semantically invalid (e.g., business-rule validation failure, malformed YAML inside a JSON payload).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"TooManyRequests":{"description":"Rate-limit exceeded. The global per-IP limiter (100 requests/minute, applied to every `/v1/*` route) rejected this request. Back off until the window resets — `Retry-After` carries the cooldown in seconds and `X-RateLimit-Reset` the absolute reset time.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Limit":{"description":"Requests permitted per window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window (0 on a 429).","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"BadGateway":{"description":"An upstream dependency returned an invalid response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PermanentRedirect":{"description":"Permanent Redirect (RFC 7538). This URL is deprecated; follow `Location` to the canonical `/v1/<resource>/<scope>/<scope_id>` shape. Method and body are preserved across the redirect — modern clients re-issue the same `PUT` / `POST` / `DELETE` against the target unchanged.","headers":{"Location":{"description":"Canonical URL to follow. Preserves the original query string.","schema":{"type":"string","format":"uri-reference"}},"Deprecation":{"description":"RFC 8594 — `true` for every legacy alignment / protection URL.","schema":{"type":"string","enum":["true"]}},"Sunset":{"description":"RFC 8594 — HTTP-date after which the legacy URL stops redirecting and returns 410 Gone. Currently `Fri, 15 Jan 2027 00:00:00 GMT`, aligned with the cards-as-primitive Phase 5 GA window.","schema":{"type":"string","format":"http-date"}},"Link":{"description":"RFC 8288 — points to the deprecation guide (`rel=\"deprecation\"`). Currently `<https://docs.mnemom.ai/concepts/cards-as-resources>; rel=\"deprecation\"; type=\"text/html\"`.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Always `cards/url-canonicalization/v1` on this response.","schema":{"type":"string","enum":["cards/url-canonicalization/v1"]}}}},"ServiceUnavailable":{"description":"An upstream dependency is currently unavailable. The request was not processed; retry after the cooldown window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PreconditionFailed":{"description":"The `If-Match` header carried a stale ETag (the spec was updated since the caller read it). Run `GET` to fetch the current ETag, splice your changes onto the latest state, and retry the write. Cards-as-primitive Phase 4 W3.1.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PreconditionRequired":{"description":"The `If-Match` header is missing on a sub-resource write. Sub-resource verbs use optimistic concurrency — read the current ETag via `GET`, then retry with `If-Match: \"sha256:...\"`. Cards-as-primitive Phase 4 W3.1.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RequestEntityTooLarge":{"description":"Request body exceeded the per-endpoint size cap. Cards-as-primitive sub-resource verbs cap each primitive body at 64 KiB; full-card PUTs cap at 128 KiB (alignment) / 64 KiB (protection).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Canonical error envelope (ADR-API-001 conv 1). `error` is always an object — never a bare string. Every 4xx/5xx response across the API conforms to this shape; the runtime helper is `src/http-errors.ts::buildErrorBody`.","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","pattern":"^[a-z][a-z0-9_]*$","description":"Stable, machine-matchable failure identifier (lowercase snake_case). Clients may branch on this; the string is part of the contract.\n\n**Status-class defaults** — emitted when no caller code is supplied (`errorCodeForStatus(status)`): `bad_request` (400), `unauthorized` (401), `forbidden` (403), `not_found` (404), `method_not_allowed` (405), `conflict` (409), `gone` (410), `precondition_failed` (412), `payload_too_large` (413), `unsupported_media_type` (415), `unprocessable_entity` (422), `precondition_required` (428), `rate_limited` (429), `internal_error` (500), `not_implemented` (501), `bad_gateway` (502), `service_unavailable` (503), `gateway_timeout` (504). Fallback `error` for unmapped statuses.\n\n**Caller-supplied codes** — handlers may pass an explicit `code` for a specific failure class. Examples: `agent_not_found`, `invalid_hash_proof`, `already_linked`, `idempotency_conflict`, `feature_gated`, `schema_validation_failed`, `no_token`, `bad_canonical_payload`.\n\n**Care-framed sub-resource codes** — the cards-as-primitive surface passes its stable care code-string straight through as `error.code`. Examples: `if_match_absent`, `if_match_stale`, `if_match_malformed`, `primitive_validation_failed`."},"message":{"type":"string","description":"Human-readable, care-framed explanation of the failure."},"details":{"description":"Optional structured context for the failure (any JSON value: object, array, or primitive). Common shapes: validation findings list, idempotency-conflict diff, `{presented_etag, current_etag}` on a stale `If-Match`, etc. Mirrors the helper's `details?: unknown`."}}}}},"Agent":{"type":"object","properties":{"id":{"type":"string"},"agent_hash":{"type":"string","description":"First 16 hex chars of `SHA256(apiKey + '|' + agentName)` for named agents, or `SHA256(apiKey)` for unnamed singleton agents. The gateway computes the same value on each request and uses it as the lookup key. See [Agent Identity](https://docs.mnemom.ai/concepts/agent-identity#agent_hash--the-canonical-identity-hash).","example":"a1b2c3d4e5f6a7b8"},"user_id":{"type":["string","null"]},"email":{"type":["string","null"]},"claimed_at":{"type":["string","null"],"format":"date-time"},"last_seen":{"type":["string","null"],"format":"date-time"},"name":{"type":["string","null"],"description":"Agent name (2-32 chars, alphanumeric + hyphens). Present on all list and get responses."},"containment_status":{"type":["string","null"],"enum":["active","paused","killed"],"description":"Containment state of the agent (ADR-053)."},"key_prefix":{"type":["string","null"],"description":"First 8 chars of the bound API key hash — useful for key-rotation debugging."},"status":{"type":"string","enum":["active","offline"]},"public":{"type":"boolean"},"aip_enforcement_mode":{"type":["string","null"],"enum":["observe","enforce","nudge"]},"billing_account_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}},"AlignmentCard":{"type":"object","properties":{"card_id":{"type":"string"},"agent_id":{"type":"string"},"is_active":{"type":"boolean"},"card_json":{"type":"object","description":"Full alignment card JSON per AAP spec"},"conscience_values":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ConscienceValue"}},"issued_at":{"type":"string","format":"date-time"}}},"APTrace":{"type":"object","properties":{"trace_id":{"type":"string"},"agent_id":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"action":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"}}},"decision":{"type":"object","properties":{"selected":{"type":"string"},"selection_reasoning":{"type":"string"},"values_applied":{"type":"array","items":{"type":"string"}},"confidence":{"type":["number","null"]}}},"verification":{"type":["object","null"],"properties":{"verified":{"type":"boolean"},"violations":{"type":"array","items":{"type":"string"}}}},"created_at":{"type":"string","format":"date-time"}}},"IntegrityScore":{"type":"object","properties":{"agent_id":{"type":"string"},"total_traces":{"type":"integer"},"verified_traces":{"type":"integer"},"violation_count":{"type":"integer"},"integrity_score":{"type":"number","description":"Value between 0 and 1"}}},"Checkpoint":{"type":"object","properties":{"checkpoint_id":{"type":"string"},"agent_id":{"type":"string"},"card_id":{"type":"string"},"session_id":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"thinking_block_hash":{"type":"string"},"provider":{"type":"string"},"model":{"type":"string"},"verdict":{"type":"string","enum":["clear","review_needed","boundary_violation"]},"concerns":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"severity":{"type":"string"},"description":{"type":"string"},"evidence":{"type":"string"}}}},"reasoning_summary":{"type":"string"},"conscience_context":{"type":"object"},"window_position":{"type":"object","properties":{"index":{"type":"integer"},"window_size":{"type":"integer"}}},"analysis_metadata":{"type":"object"},"linked_trace_id":{"type":["string","null"]},"re_evaluated_at":{"type":["string","null"],"format":"date-time"},"original_verdict":{"type":["string","null"]}}},"DriftAlert":{"type":"object","properties":{"alert_id":{"type":"string"},"agent_id":{"type":"string"},"session_id":{"type":"string"},"checkpoint_ids":{"type":"array","items":{"type":"string"}},"sustained_checks":{"type":"integer"},"severity":{"type":"string","enum":["low","medium","high"]},"drift_direction":{"type":"string"},"message":{"type":"string"},"detection_timestamp":{"type":"string","format":"date-time"}}},"ConscienceValue":{"type":"object","required":["type","name","content"],"properties":{"type":{"type":"string","enum":["BOUNDARY","FEAR","COMMITMENT","BELIEF","HOPE"]},"name":{"type":"string"},"content":{"type":"string"}}},"Subscription":{"type":"object","properties":{"subscription":{"type":["object","null"]},"plan_id":{"type":"string"},"status":{"type":"string"},"check_count_this_period":{"type":"integer"}}},"Invoice":{"type":"object","properties":{"id":{"type":"string"},"amount_due":{"type":"integer"},"amount_paid":{"type":"integer"},"currency":{"type":"string"},"status":{"type":"string"},"created":{"type":"integer"},"hosted_invoice_url":{"type":["string","null"]},"invoice_pdf":{"type":["string","null"]}}},"UsageMetrics":{"type":"object","properties":{"daily":{"type":"array","items":{"type":"object","properties":{"rollup_date":{"type":"string","format":"date"},"check_count":{"type":"integer"},"tokens_in":{"type":"integer"},"tokens_out":{"type":"integer"}}}},"summary":{"type":"object","properties":{"checks_used":{"type":"integer"},"checks_included":{"type":"integer"},"overage":{"type":"integer"},"estimated_overage_cost":{"type":"number"},"period_start":{"type":"string","format":"date-time"},"period_end":{"type":"string","format":"date-time"}}}}},"Plan":{"type":"object","properties":{"plan_id":{"type":"string"},"display_name":{"type":"string"},"description":{"type":"string"},"billing_model":{"type":"string","enum":["none","metered","subscription","subscription_plus_metered"]},"base_price_cents":{"type":"integer"},"annual_price_cents":{"type":"integer"},"per_check_price":{"type":"number"},"included_checks":{"type":"integer"},"trace_retention_days":{"type":"integer"},"feature_flags":{"type":"object","additionalProperties":{"type":"boolean"}},"limits":{"type":"object"},"sort_order":{"type":"integer"}}},"Organization":{"type":"object","properties":{"org_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"billing_account_id":{"type":"string"},"owner_user_id":{"type":"string"},"billing_email":{"type":["string","null"]},"company_name":{"type":["string","null"]},"member_count":{"type":"integer"},"role":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"OrgMember":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member","viewer","auditor"]},"accepted_at":{"type":"string","format":"date-time"}}},"OrgInvitation":{"type":"object","properties":{"invitation_id":{"type":"string"},"org_id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"token":{"type":"string","description":"Only returned on creation"},"status":{"type":"string","enum":["pending","accepted","revoked","expired"]},"invited_by":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"License":{"type":"object","properties":{"license_id":{"type":"string"},"account_id":{"type":"string"},"plan_id":{"type":"string"},"feature_flags":{"type":"object","additionalProperties":{"type":"boolean"}},"limits":{"type":"object"},"max_activations":{"type":"integer"},"is_offline":{"type":"boolean"},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"revoked_reason":{"type":["string","null"]},"notes":{"type":["string","null"]}}},"ApiKeyScope":{"type":"string","enum":["gateway","api:read","api:write","admin:org","admin:platform","api"],"description":"Capability-based scope (ADR-049). `gateway` permits gateway-worker traffic; `api:read` and `api:write` permit identity-scoped GET and write endpoints respectively; `admin:org` permits org-admin operations on orgs the bearer owns/admins (per-request membership re-check); `admin:platform` permits `/v1/admin/*` Mnemom-staff operations (per-request staff-role re-check). The legacy `api` scope is accepted for backward compatibility and aliased to `api:read` + `api:write` at the auth gate; new keys should use the canonical vocabulary."},"ApiKey":{"type":"object","properties":{"key_id":{"type":"string"},"key":{"type":"string","description":"Full secret key, only returned on creation"},"key_prefix":{"type":"string"},"name":{"type":"string"},"org_id":{"type":["string","null"]},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"},"description":"Capabilities granted to this key. Default for new keys is `[\"gateway\", \"api:read\", \"api:write\"]`. Admin scopes (`admin:org`, `admin:platform`) are opt-in and gated by the requester's role at mint time. See [API Keys → Scope vocabulary](https://docs.mnemom.ai/guides/api-keys#scope-vocabulary)."},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"}}},"WebhookEndpoint":{"type":"object","description":"Webhook endpoint with signing secret (only returned on creation and secret rotation)","properties":{"endpoint_id":{"type":"string","description":"Unique identifier (whe-xxxxxxxx)"},"billing_account_id":{"type":"string"},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"signing_secret":{"type":"string","description":"32-byte hex-encoded HMAC signing secret. Only returned on creation and rotation."},"event_types":{"type":"array","items":{"type":"string"},"description":"Subscribed event types. Empty array means all events."},"is_active":{"type":"boolean"},"consecutive_failures":{"type":"integer"},"disabled_at":{"type":["string","null"],"format":"date-time"},"disabled_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookEndpointPublic":{"type":"object","description":"Webhook endpoint without signing secret (used in list and get responses)","properties":{"endpoint_id":{"type":"string"},"billing_account_id":{"type":"string"},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"event_types":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"consecutive_failures":{"type":"integer"},"disabled_at":{"type":["string","null"],"format":"date-time"},"disabled_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","description":"Webhook delivery log entry","properties":{"delivery_id":{"type":"string","description":"Unique identifier (whd-xxxxxxxx)"},"event_id":{"type":"string"},"endpoint_id":{"type":"string"},"event_type":{"type":"string"},"status":{"type":"string","enum":["pending","delivering","delivered","failed","retrying"]},"attempt_count":{"type":"integer"},"max_attempts":{"type":"integer"},"last_response_status":{"type":["integer","null"],"description":"HTTP status code from last delivery attempt"},"last_error":{"type":["string","null"]},"latency_ms":{"type":["integer","null"],"description":"Round-trip latency in milliseconds"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"SigningKeyInfo":{"type":"object","description":"Ed25519 signing key metadata. Public keys are used to verify IntegrityCertificate signatures.","properties":{"key_id":{"type":"string","description":"Unique key identifier"},"public_key":{"type":"string","description":"Hex-encoded Ed25519 public key"},"algorithm":{"type":"string","description":"Signing algorithm (always Ed25519)"},"created_at":{"type":"string","format":"date-time","description":"When the key was created"},"is_active":{"type":"boolean","description":"Whether the key is currently in use for new signatures"}},"required":["key_id","public_key","algorithm","created_at","is_active"]},"IntegrityCertificate":{"type":"object","description":"Machine-readable cryptographic certificate for an integrity checkpoint. Modeled on C2PA content credentials and W3C Verifiable Credentials.","properties":{"@context":{"type":"string","description":"Namespace identifier","enum":["https://mnemom.ai/aip/v1"]},"type":{"type":"string","enum":["IntegrityCertificate"]},"version":{"type":"string","description":"Certificate format version"},"certificate_id":{"type":"string","description":"Unique certificate identifier (cert-{8 random chars})"},"issued_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of certificate issuance"},"subject":{"type":"object","description":"Identifies the checkpoint this certificate attests to","properties":{"checkpoint_id":{"type":"string","description":"Integrity checkpoint ID (ic-{uuid})"},"agent_id":{"type":"string"},"session_id":{"type":"string"},"card_id":{"type":"string"}},"required":["checkpoint_id","agent_id","session_id","card_id"]},"claims":{"type":"object","description":"Analysis verdict and supporting evidence","properties":{"verdict":{"type":"string","enum":["clear","review_needed","boundary_violation"]},"concerns":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"severity":{"type":"string"},"description":{"type":"string"}}}},"confidence":{"type":"number","description":"Extraction confidence (0.0-1.0)"},"reasoning_summary":{"type":"string"},"analysis_model":{"type":"string"},"analysis_duration_ms":{"type":"number"}}},"input_commitments":{"type":"object","description":"Cryptographic commitments to analysis inputs","properties":{"thinking_block_hash":{"type":"string","description":"SHA-256 hash of the thinking block"},"card_hash":{"type":"string","description":"SHA-256 hash of the Alignment Card"},"values_hash":{"type":"string","description":"SHA-256 hash of conscience values"},"context_hash":{"type":"string","description":"SHA-256 hash of window context"},"model_version":{"type":"string"},"combined_commitment":{"type":"string","description":"SHA-256 of all input fields concatenated"}}},"proofs":{"type":"object","description":"Cryptographic evidence supporting the claims","properties":{"signature":{"type":"object","properties":{"algorithm":{"type":"string","enum":["Ed25519"]},"key_id":{"type":"string"},"value":{"type":"string","description":"Base64-encoded Ed25519 signature"},"signed_payload":{"type":"string","description":"Deterministic JSON string that was signed"}}},"chain":{"type":"object","properties":{"chain_hash":{"type":"string"},"prev_chain_hash":{"type":["string","null"]},"position":{"type":"integer"}}},"merkle":{"type":["object","null"],"description":"Merkle inclusion proof. Null if not yet added to tree.","properties":{"leaf_hash":{"type":"string"},"leaf_index":{"type":"integer"},"root":{"type":"string"},"tree_size":{"type":"integer"},"inclusion_proof":{"type":"array","items":{"type":"object","properties":{"hash":{"type":"string"},"position":{"type":"string","enum":["left","right"]}}}}}},"verdict_derivation":{"type":["object","null"],"description":"SP1 STARK proof. Null if not yet proven.","properties":{"method":{"type":"string","enum":["SP1-STARK"]},"image_id":{"type":"string"},"receipt":{"type":"string","description":"Base64-encoded STARK proof receipt"},"journal":{"type":"string","description":"Base64-encoded public journal"},"verified_at":{"type":"string","format":"date-time"}}}}},"verification":{"type":"object","description":"URLs for independent verification","properties":{"keys_url":{"type":"string","format":"uri"},"certificate_url":{"type":"string","format":"uri"},"verify_url":{"type":"string","format":"uri"}}}},"required":["@context","type","version","certificate_id","issued_at","subject","claims","input_commitments","proofs","verification"]},"MerkleRootResponse":{"type":"object","description":"Current Merkle tree root and metadata for an agent","properties":{"agent_id":{"type":"string","description":"The agent ID"},"merkle_root":{"type":"string","description":"SHA-256 Merkle root hash (hex-encoded)"},"tree_depth":{"type":"integer","description":"Depth of the Merkle tree (ceil(log2(leaf_count)))"},"leaf_count":{"type":"integer","description":"Total number of checkpoint leaves in the tree"},"last_updated":{"type":"string","format":"date-time","description":"When the tree was last updated"}},"required":["agent_id","merkle_root","tree_depth","leaf_count","last_updated"]},"InclusionProofResponse":{"type":"object","description":"Merkle inclusion proof for a checkpoint","properties":{"checkpoint_id":{"type":"string","description":"The checkpoint ID"},"leaf_hash":{"type":"string","description":"SHA-256 leaf hash of this checkpoint"},"leaf_index":{"type":"integer","description":"Index of this leaf in the tree"},"siblings":{"type":"array","description":"O(log N) sibling hashes for proof verification","items":{"type":"object","properties":{"hash":{"type":"string","description":"Hex-encoded sibling hash"},"position":{"type":"string","enum":["left","right"],"description":"Position of sibling relative to the path node"}},"required":["hash","position"]}},"root":{"type":"string","description":"Current Merkle root (hex-encoded)"},"tree_size":{"type":"integer","description":"Total number of leaves in the tree"},"verified":{"type":"boolean","description":"Whether the proof was verified against the stored root"}},"required":["checkpoint_id","leaf_hash","leaf_index","siblings","root","tree_size","verified"]},"ProofStatusResponse":{"type":"object","description":"ZK proof status and metadata for a checkpoint","properties":{"proof_id":{"type":"string","description":"Proof identifier (prf-{8 random chars})"},"checkpoint_id":{"type":"string","description":"The checkpoint this proof is for"},"status":{"type":"string","enum":["pending","proving","completed","failed"],"description":"Current proof status"},"proof_type":{"type":"string","description":"Proof system (e.g., sp1-stark)"},"image_id":{"type":["string","null"],"description":"Guest program image ID (set when proving begins)"},"proving_duration_ms":{"type":["integer","null"],"description":"Wall-clock proving time in milliseconds (set when completed)"},"verified":{"type":"boolean","description":"Whether the proof has been verified"},"verified_at":{"type":["string","null"],"format":"date-time","description":"When the proof was verified (null if not yet verified)"},"created_at":{"type":"string","format":"date-time","description":"When the proof request was created"},"updated_at":{"type":"string","format":"date-time","description":"When the proof record was last updated"}},"required":["proof_id","checkpoint_id","status","proof_type","verified","created_at","updated_at"]},"VerifyCertificateResponse":{"type":"object","description":"Result of certificate verification","properties":{"valid":{"type":"boolean","description":"Whether all verification checks passed"},"checks":{"type":"object","description":"Individual verification check results","properties":{"signature":{"type":"object","properties":{"valid":{"type":"boolean"},"key_id":{"type":"string","description":"The signing key the certificate was verified against. Present when the certificate carries a key id; omitted otherwise (data-dependent)."}},"required":["valid"]},"chain":{"type":"object","properties":{"valid":{"type":"boolean"},"chain_hash":{"type":"string"}},"required":["valid","chain_hash"]},"merkle":{"type":["object","null"],"description":"Null if Merkle proof was not present in the certificate","properties":{"valid":{"type":"boolean"},"root":{"type":"string"}}},"input_commitment":{"type":"object","properties":{"valid":{"type":"boolean"},"commitment":{"type":"string"}},"required":["valid","commitment"]},"verdict_derivation":{"type":["object","null"],"description":"Null if verdict derivation proof was not present","properties":{"valid":{"type":"boolean"},"method":{"type":"string"}}}},"required":["signature","chain","input_commitment"]},"details":{"type":"string","description":"Semicolon-separated human-readable verification details"}},"required":["valid","checks","details"]},"OrgConscienceValue":{"type":"object","description":"A custom conscience value for an organization","properties":{"id":{"type":"string","description":"Value ID (cv-xxx)"},"org_id":{"type":"string"},"name":{"type":"string","maxLength":50},"description":{"type":"string","maxLength":500},"type":{"type":"string","enum":["BOUNDARY","FEAR","COMMITMENT","BELIEF","HOPE"]},"severity":{"type":"string","enum":["advisory","mandatory"]},"scope":{"type":"string"},"is_active":{"type":"boolean"},"sort_order":{"type":"integer"},"created_by":{"type":"string"},"updated_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","org_id","name","description","type","severity"]},"OrgConscienceAuditEntry":{"type":"object","description":"Audit log entry for conscience value changes","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"value_id":{"type":["string","null"]},"action":{"type":"string","enum":["create","update","delete","activate","deactivate","reorder","mode_change"]},"actor":{"type":"string"},"changes":{"type":"object"},"metadata":{"type":"object"},"created_at":{"type":"string","format":"date-time"}},"required":["id","org_id","action","actor","created_at"]},"OrgCardTemplate":{"type":"object","description":"Organization alignment card template that all agents inherit","properties":{"org_id":{"type":"string","description":"Organization ID"},"enabled":{"type":"boolean","description":"Whether the template is active"},"template":{"$ref":"#/components/schemas/AlignmentCard","description":"The alignment card template JSON"},"created_by":{"type":"string","description":"User ID who created the template"},"updated_by":{"type":"string","description":"User ID who last updated the template"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["org_id","enabled","template"]},"Team":{"type":"object","properties":{"id":{"type":"string","description":"Team identifier (UUID)"},"org_id":{"type":"string","description":"Organization that owns this team"},"name":{"type":"string","description":"Display name"},"description":{"type":["string","null"],"description":"Optional description"},"status":{"type":"string","enum":["active","archived"],"description":"Team status"},"metadata":{"type":"object","additionalProperties":true,"description":"Freeform metadata"},"member_count":{"type":"integer","description":"Number of active members"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"TeamMember":{"type":"object","properties":{"team_id":{"type":"string"},"agent_id":{"type":"string"},"agent_name":{"type":["string","null"]},"avatar_url":{"type":["string","null"]},"role":{"type":"string","description":"team_members.role — the agent's role inside the team (e.g. 'member', 'lead')."},"joined_at":{"type":"string","format":"date-time","description":"Alias for added_at, returned by the list endpoint for UI convenience."},"added_at":{"type":"string","format":"date-time"},"removed_at":{"type":["string","null"],"format":"date-time"},"reputation_score":{"type":["number","null"],"description":"Agent's reputation score, joined from reputation_scores at list time. `null` when no row exists OR the agent's visibility is private."},"reputation_grade":{"type":["string","null"],"description":"Agent's reputation grade (A+, A, B+, ..., NR). `null` under the same conditions as reputation_score."},"is_eligible":{"type":["boolean","null"],"description":"Whether the agent has crossed the eligibility threshold. The UI honors this to avoid rendering a misleading grade circle for agents that haven't accumulated enough checkpoints."}}},"TeamRosterChange":{"type":"object","properties":{"id":{"type":"string"},"team_id":{"type":"string"},"change_type":{"type":"string","enum":["agent_added","agent_removed"]},"agent_id":{"type":"string"},"actor_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}},"TeamReputationScore":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"score":{"type":"number","description":"0-1000"},"grade":{"type":"string","enum":["AAA","AA","A","BBB","BB","B","CCC","NR"]},"confidence":{"type":"string","enum":["insufficient","low","medium","high"]},"is_eligible":{"type":"boolean","description":"true when total_assessments >= 10"},"components":{"type":"array","items":{"$ref":"#/components/schemas/TeamReputationComponent"}},"total_assessments":{"type":"integer"},"last_assessed":{"type":["string","null"],"format":"date-time"},"trend_30d":{"type":"number"},"visibility":{"type":"string","enum":["public","unlisted","private"]},"computed_at":{"type":["string","null"],"format":"date-time"},"member_count":{"type":"integer"},"a2a_trust_extension":{"$ref":"#/components/schemas/A2ATeamTrustExtension"}}},"TeamReputationComponent":{"type":"object","properties":{"key":{"type":"string","enum":["coherence_history","member_quality","operational_record","structural_stability","assessment_density"]},"label":{"type":"string"},"score":{"type":"number","description":"Raw score 0-1000"},"weight":{"type":"number","description":"Weight 0-1"},"weighted_score":{"type":"number","description":"score * weight"},"factors":{"type":"array","items":{"type":"string"}}}},"A2ATeamTrustExtension":{"type":"object","properties":{"extension_uri":{"type":"string"},"provider":{"type":"string"},"score":{"type":"number"},"grade":{"type":"string"},"confidence":{"type":"string"},"member_count":{"type":"integer"},"verified_url":{"type":"string","format":"uri"},"badge_url":{"type":"string","format":"uri"},"methodology_url":{"type":"string","format":"uri"},"last_updated":{"type":"string","format":"date-time"}}},"TeamReputationSnapshot":{"type":"object","properties":{"team_id":{"type":"string"},"week_start":{"type":"string","format":"date"},"score":{"type":"number"},"grade":{"type":"string"},"components":{"type":"object","additionalProperties":{"type":"number"}},"created_at":{"type":"string","format":"date-time"}}},"PolicyMeta":{"type":"object","description":"Metadata for a CLPI policy including schema version, name, description, and scope.","properties":{"schema_version":{"type":"string","description":"Semantic version of the policy schema (e.g. '1.0.0')"},"name":{"type":"string","description":"Human-readable name of the policy"},"description":{"type":"string","description":"Detailed description of the policy's purpose"},"scope":{"type":"string","enum":["agent","org","global"],"description":"Scope at which the policy applies"}}},"CapabilityMapping":{"type":"object","description":"Maps a named capability to specific tools and alignment card actions.","properties":{"description":{"type":"string","description":"Human-readable description of what this capability represents"},"tools":{"type":"array","items":{"type":"string"},"description":"List of tool identifiers that belong to this capability"},"card_actions":{"type":"array","items":{"type":"string"},"description":"Alignment card action types associated with this capability"}}},"ForbiddenRule":{"type":"object","description":"A rule that forbids tools matching a specific pattern.","required":["pattern","reason"],"properties":{"pattern":{"type":"string","description":"Glob or regex pattern matching tool identifiers to forbid"},"reason":{"type":"string","description":"Human-readable reason why these tools are forbidden"},"severity":{"type":"string","enum":["low","medium","high","critical"],"default":"high","description":"Severity level when a forbidden tool is invoked"}}},"EscalationTrigger":{"type":"object","description":"Defines a condition that triggers an escalation action.","required":["condition","action"],"properties":{"condition":{"type":"string","description":"Expression or rule describing when this trigger fires (e.g. 'violation_count > 3')"},"action":{"type":"string","enum":["notify","pause","block","require_approval"],"description":"Action to take when the condition is met"},"reason":{"type":"string","description":"Human-readable explanation of why this escalation exists"}}},"PolicyDefaults":{"type":"object","description":"Default enforcement behavior for tools and situations not explicitly covered by the policy.","properties":{"unmapped_tool_action":{"type":"string","enum":["allow","warn","block","escalate"],"default":"warn","description":"Action to take when a tool is not mapped to any capability"},"unmapped_severity":{"type":"string","enum":["low","medium","high","critical"],"default":"medium","description":"Severity level assigned to unmapped tool invocations"},"fail_open":{"type":"boolean","default":false,"description":"If true, allow actions when the policy engine is unavailable. If false, block by default."},"enforcement_mode":{"type":"string","enum":["observe","enforce","nudge"],"default":"observe","description":"Default enforcement mode for the policy"},"grace_period_hours":{"type":"integer","default":0,"description":"Number of hours to allow violations before enforcement kicks in (for new policy rollouts)"}}},"Policy":{"type":"object","description":"A complete CLPI policy document defining capability mappings, forbidden tools, escalation triggers, and enforcement defaults.","properties":{"meta":{"$ref":"#/components/schemas/PolicyMeta"},"capability_mappings":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CapabilityMapping"},"description":"Map of capability names to their definitions"},"forbidden":{"type":"array","items":{"$ref":"#/components/schemas/ForbiddenRule"},"description":"List of forbidden tool rules"},"escalation_triggers":{"type":"array","items":{"$ref":"#/components/schemas/EscalationTrigger"},"description":"List of escalation trigger definitions"},"defaults":{"$ref":"#/components/schemas/PolicyDefaults"}}},"PolicyViolation":{"type":"object","description":"A single policy violation detected during evaluation.","properties":{"type":{"type":"string","enum":["forbidden","unmapped","escalation","capability_mismatch"],"description":"Type of policy violation"},"tool":{"type":"string","description":"Tool identifier that triggered the violation"},"capability":{"type":["string","null"],"description":"Capability the tool was mapped to, if any"},"rule":{"type":["string","null"],"description":"The specific rule or pattern that was matched"},"reason":{"type":"string","description":"Human-readable explanation of the violation"},"severity":{"type":"string","enum":["low","medium","high","critical"],"description":"Severity level of the violation"}}},"PolicyEvaluationResult":{"type":"object","description":"Result of evaluating a CLPI policy against a set of tools or traces.","properties":{"verdict":{"type":"string","enum":["pass","warn","fail"],"description":"Overall evaluation verdict"},"violations":{"type":"array","items":{"$ref":"#/components/schemas/PolicyViolation"},"description":"List of policy violations detected"},"warnings":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string"},"message":{"type":"string"}}},"description":"Non-blocking warnings about potential issues"},"card_gaps":{"type":"array","items":{"type":"object","properties":{"capability":{"type":"string"},"missing_card_field":{"type":"string"},"suggestion":{"type":"string"}}},"description":"Gaps between the policy and the alignment card"},"coverage":{"type":"number","minimum":0,"maximum":1,"description":"Fraction of tools covered by the policy (0.0 to 1.0)"}}},"ReclassificationRequest":{"type":"object","description":"Request to reclassify a checkpoint violation.","required":["checkpoint_id","reason"],"properties":{"checkpoint_id":{"type":"string","description":"Identifier of the checkpoint to reclassify"},"reason":{"type":"string","description":"Human-readable justification for the reclassification"},"card_amendment_id":{"type":["string","null"],"description":"Optional ID of an alignment card amendment that triggered this reclassification"}}},"ReclassificationResult":{"type":"object","description":"Result of a checkpoint violation reclassification.","properties":{"reclassification_id":{"type":"string","description":"Unique identifier for this reclassification"},"checkpoint_id":{"type":"string","description":"Identifier of the reclassified checkpoint"},"agent_id":{"type":"string","description":"Agent whose checkpoint was reclassified"},"original_type":{"type":"string","description":"Original violation type before reclassification"},"new_type":{"type":"string","description":"New violation type after reclassification"},"reason":{"type":"string","description":"Justification provided for the reclassification"},"score_impact":{"type":"object","properties":{"previous_score":{"type":"number"},"new_score":{"type":"number"},"delta":{"type":"number"}},"description":"Impact of the reclassification on the agent's score"}}},"FaultLine":{"type":"object","description":"A single fault line identified in team alignment analysis.","properties":{"id":{"type":"string","description":"Unique identifier for this fault line"},"value":{"type":"string","description":"The specific value, capability, or constraint that constitutes the fault line"},"classification":{"type":"string","enum":["capability_gap","value_mismatch","constraint_inconsistency","tool_divergence","policy_conflict"],"description":"Classification of the fault line type"},"severity":{"type":"string","enum":["low","medium","high","critical"],"description":"Severity of the fault line"},"agents_declaring":{"type":"array","items":{"type":"string"},"description":"Agent IDs that declare or satisfy this requirement"},"agents_missing":{"type":"array","items":{"type":"string"},"description":"Agent IDs that are missing this requirement"},"impact_score":{"type":"number","minimum":0,"maximum":1,"description":"Estimated impact of this fault line on team alignment (0.0 to 1.0)"},"resolution_hint":{"type":"string","description":"Suggested action to resolve this fault line"}}},"FaultLineAnalysis":{"type":"object","description":"Complete fault line analysis result for a team.","properties":{"team_id":{"type":"string","description":"Team that was analyzed"},"analysis_id":{"type":"string","description":"Unique identifier for this analysis run"},"fleet_score":{"type":"number","minimum":0,"maximum":100,"description":"Overall fleet alignment score (0-100)"},"fault_lines":{"type":"array","items":{"$ref":"#/components/schemas/FaultLine"},"description":"Identified fault lines sorted by severity"},"summary":{"type":"string","description":"Human-readable summary of the analysis findings"}}},"RiskForecast":{"type":"object","description":"Risk forecast for a team based on alignment trends and fault lines.","properties":{"forecast_id":{"type":"string","description":"Unique identifier for this forecast"},"failure_modes":{"type":"array","items":{"type":"object","properties":{"mode":{"type":"string","description":"Description of the potential failure mode"},"probability":{"type":"number","minimum":0,"maximum":1,"description":"Estimated probability of occurrence"},"impact":{"type":"string","enum":["low","medium","high","critical"],"description":"Estimated impact if the failure occurs"},"contributing_factors":{"type":"array","items":{"type":"string"},"description":"Factors contributing to this risk"},"mitigation":{"type":"string","description":"Suggested mitigation action"}}},"description":"Ranked list of potential failure modes"},"overall_risk_level":{"type":"string","enum":["low","medium","high","critical"],"description":"Overall risk level for the team"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence level of the forecast (0.0 to 1.0)"}}},"OnChainAnchorResult":{"type":"object","description":"Result of an on-chain Merkle root anchoring operation.","properties":{"anchor_id":{"type":"string","description":"Unique identifier for this anchor"},"merkle_root":{"type":"string","description":"Hex-encoded Merkle root hash that was anchored"},"tx_hash":{"type":"string","description":"Blockchain transaction hash"},"block_number":{"type":"integer","description":"Block number in which the transaction was included"},"gas_used":{"type":"integer","description":"Gas consumed by the anchoring transaction"},"chain":{"type":"string","enum":["ethereum","polygon","base"],"description":"Blockchain network where the anchor was created"},"agent_ids":{"type":"array","items":{"type":"string"},"description":"Agent IDs included in this anchor"},"anchored_at":{"type":"string","format":"date-time","description":"Timestamp when the anchor was created"}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"app_metadata":{"type":"object","additionalProperties":true},"user_metadata":{"type":"object","additionalProperties":true}},"description":"Supabase user shape. Fields beyond `id` and `email` are passthrough."},"PublicKeyCredentialCreationOptionsJSON":{"type":"object","description":"WebAuthn registration options (base64url-encoded per the WebAuthn Level 3 JSON serialization).","properties":{"rp":{"type":"object","required":["id","name"]},"user":{"type":"object","required":["id","name","displayName"]},"challenge":{"type":"string"},"pubKeyCredParams":{"type":"array"},"authenticatorSelection":{"type":"object"},"attestation":{"type":"string"},"excludeCredentials":{"type":"array"},"timeout":{"type":"integer"}},"additionalProperties":true},"PublicKeyCredentialRequestOptionsJSON":{"type":"object","description":"WebAuthn authentication options.","properties":{"rpId":{"type":"string"},"challenge":{"type":"string"},"userVerification":{"type":"string"},"allowCredentials":{"type":"array"},"timeout":{"type":"integer"}},"additionalProperties":true},"RegistrationResponseJSON":{"type":"object","description":"Browser's `navigator.credentials.create()` response, JSON-serialized per the WebAuthn Level 3 JSON form.","properties":{"id":{"type":"string"},"rawId":{"type":"string"},"type":{"type":"string","enum":["public-key"]},"response":{"type":"object"},"clientExtensionResults":{"type":"object"},"authenticatorAttachment":{"type":"string"}},"required":["id","rawId","type","response"],"additionalProperties":true},"AuthenticationResponseJSON":{"type":"object","description":"Browser's `navigator.credentials.get()` response, JSON-serialized.","properties":{"id":{"type":"string"},"rawId":{"type":"string"},"type":{"type":"string","enum":["public-key"]},"response":{"type":"object"},"clientExtensionResults":{"type":"object"},"authenticatorAttachment":{"type":"string"}},"required":["id","rawId","type","response"],"additionalProperties":true},"UnifiedAlignmentCard":{"type":"object","description":"Unified alignment card (ADR-008/ADR-039). Authored in YAML or JSON; composed server-side with platform defaults, org template, and active exemptions before storage. This schema matches the runtime validator at src/composition/validate.ts EXACTLY — a card authored strictly to it passes `PUT /v1/agents/{id}/alignment-card` and the preview-compose endpoint. Output-only fields (card_id, issued_at, expires_at, _composition) are server-assigned and must NOT be sent on a PUT.","required":["card_version","agent_id","autonomy_mode","integrity_mode","principal","values","autonomy","audit"],"properties":{"card_version":{"type":"string","minLength":1,"description":"Card schema version (required, non-empty). Current canonical value: `unified/2026-04-26`."},"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"],"description":"ADR-039 master switch for the action-policing pipeline (autonomy constraints). Required at the top level post-cutover; the legacy `enforcement.mode` location is rejected."},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"],"description":"ADR-039 master switch for the values/conscience pipeline (integrity constraints). Required at the top level post-cutover; the legacy `integrity.enforcement_mode` location is rejected."},"card_id":{"type":"string","description":"Card row id. Server-assigned on PUT (`ac-{uuid}`)."},"agent_id":{"type":"string","description":"Target agent id. On PUT, server overwrites to match the URL path."},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"principal":{"type":"object","description":"Required object describing whose authority the agent acts under (ADR-039 Decision 10).","properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string","minLength":1,"description":"Required (non-empty) when principal.type is not `unspecified`; identifies the human / organization / agent."},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}},"required":["type","relationship"],"allOf":[{"if":{"properties":{"type":{"not":{"const":"unspecified"}}}},"then":{"required":["identifier"]}}]},"values":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","minItems":1,"items":{"oneOf":[{"type":"string","minLength":1},{"type":"object","required":["id"],"properties":{"id":{"type":"string","minLength":1}},"additionalProperties":{"type":"string"}}]},"description":"Ordered list of declared values. Phase 1 cards-as-primitive: each entry is either a catalog-v1 ID string (e.g. `'accuracy'`) or a parameterized map carrying optional `intensity` / `domain` / `severity_on_violation` / `scope` (e.g. `{id: 'accuracy', domain: 'financial', severity_on_violation: 'critical'}`)."},"definitions":{"type":"object","additionalProperties":{"type":"object","properties":{"description":{"type":"string"},"priority":{"type":"integer"}}}},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"conscience":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object","required":["type","content"],"properties":{"type":{"type":"string","enum":["BOUNDARY","FEAR","COMMITMENT","BELIEF","HOPE"]},"content":{"type":"string"},"id":{"type":"string"},"severity":{"type":"string","enum":["advisory","mandatory"]}}}}},"required":["mode","values"]},"autonomy":{"type":"object","required":["bounded_actions"],"properties":{"bounded_actions":{"type":"array","minItems":1,"items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object","required":["condition","action","reason"],"properties":{"condition":{"type":"string"},"action":{"type":"string","enum":["escalate","deny","log"]},"reason":{"type":"string"}}}},"max_autonomous_value":{"type":"object","properties":{"amount":{"type":"number"},"currency":{"type":"string"}}}}},"capabilities":{"type":"object","additionalProperties":{"type":"object","properties":{"description":{"type":"string"},"tools":{"type":"array","items":{"type":"string"}},"required_actions":{"type":"array","items":{"type":"string"}}}}},"enforcement":{"type":"object","description":"Optional ADR-039 Decision-3 user-facing knobs for unmapped-tool handling. The legacy `mode`, `unmapped_tool_action` and `fail_open` keys are REJECTED by the validator (mode → top-level autonomy_mode; fail_open → gateway env config).","properties":{"allow_unmapped_tools":{"type":"boolean","description":"When true, tools not mapped to a capability are allowed by default."},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"],"description":"Severity assigned to an unmapped tool when allow_unmapped_tools is false."},"forbidden_tools":{"type":"array","items":{"type":"object","required":["pattern","reason","severity"],"properties":{"pattern":{"type":"string"},"reason":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]}}}},"grace_period_hours":{"type":"integer"}}},"audit":{"type":"object","required":["retention_days","queryable"],"allOf":[{"if":{"properties":{"queryable":{"const":true}},"required":["queryable"]},"then":{"required":["query_endpoint"]}}],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer","minimum":0},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string","description":"Required when audit.queryable is true."},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object","properties":{"type":{"type":"string","enum":["local","remote","distributed"]},"location":{"type":"string"}}}}},"extensions":{"type":"object","additionalProperties":true},"_composition":{"$ref":"#/components/schemas/CompositionMetadata"}}},"UnifiedProtectionCard":{"type":"object","description":"Unified protection card (ADR-037). Safe House thresholds + trusted-source policy for a single agent. Shape matches src/composition/types.ts::UnifiedProtectionCard (canonical) and what the runtime validator at src/composition/validate.ts accepts. The customer-facing docs at /concepts/protection-card and /specifications/protection-card-schema document this same shape.","required":["card_version","agent_id","mode","thresholds","screen_surfaces","trusted_sources"],"properties":{"card_version":{"type":"string"},"card_id":{"type":"string"},"agent_id":{"type":"string"},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"mode":{"type":"string","enum":["off","observe","nudge","enforce"],"description":"Strictest-wins composition: enforce > nudge > observe > off."},"thresholds":{"type":"object","description":"Score bands. Must satisfy warn <= quarantine <= block; each value in [0, 1].","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"screen_surfaces":{"type":"object","description":"Which request surfaces Safe House inspects. Composed across scopes by OR-per-field (any scope requiring inspection wins).","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean","description":"The user/principal prompt entering the agent."},"outgoing":{"type":"boolean","description":"The agent's response leaving the agent."},"tool_calls":{"type":"boolean","description":"Tool-use invocations the agent makes."},"tool_responses":{"type":"boolean","description":"Responses to tool calls returning to the agent."}}},"trusted_sources":{"type":"object","description":"Sources for which detectors short-circuit (each match logged in the trace). Composed as platform->agent intersection (compliance ceiling) with org+agent union inside that ceiling — an agent cannot widen trust beyond what the platform allows.","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"},"description":"DNS names or host:port entries."},"agent_ids":{"type":"array","items":{"type":"string"},"description":"Mnemom agent IDs (mnm-* / smolt-* prefixed)."},"ip_ranges":{"type":"array","items":{"type":"string"},"description":"IPv4 or IPv6 CIDR ranges."}}},"extensions":{"type":"object","additionalProperties":true,"description":"Free-form extension slot for non-canonical fields. Ignored by the composer; preserved on read for tooling that needs an audit-tail metadata bag."},"_composition":{"$ref":"#/components/schemas/CompositionMetadata"}}},"CompositionMetadata":{"type":"object","description":"System-managed block describing which scope sources merged into the canonical card. Only returned when `?include_composition=true`.","properties":{"canonical_id":{"type":"string"},"composed_at":{"type":"string","format":"date-time"},"scopes_applied":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","description":"`platform`, `org:<id>`, or `agent:<id>`."},"version":{"type":"integer"},"template_version":{"type":"integer"},"card_id":{"type":"string"}}}},"exemptions_applied":{"type":"array","items":{"type":"string"}},"source_card_id":{"type":"string"},"source_policy_id":{"type":"string"}}},"AgentExemption":{"type":"object","description":"A single exemption row relaxing an org-template floor for one agent (ADR-008).","required":["id","agent_id","exempt_section","reason","granted_by","granted_at","status"],"properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"exempt_section":{"type":"string","enum":["autonomy.forbidden_actions","enforcement.forbidden_tools","autonomy.max_autonomous_value"]},"exempt_patterns":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":"string"},"granted_by":{"type":"string"},"granted_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"status":{"type":"string","enum":["active"],"description":"Always `active` today (forward-compat stub for future dual-control approval workflow)."}}},"OrgCardTemplateResponse":{"type":"object","required":["org_id","template","enabled"],"properties":{"org_id":{"type":"string"},"template":{"oneOf":[{"$ref":"#/components/schemas/UnifiedAlignmentCard"},{"$ref":"#/components/schemas/UnifiedProtectionCard"},{"type":"null"}]},"enabled":{"type":"boolean"}}},"AgentSettings":{"type":"object","description":"Per-agent observability + enforcement knobs.","required":["agent_id","aap_enabled","aip_enabled","proof_enabled","proof_rate","nudge_strategy","ddr_mode","analyze_output"],"properties":{"agent_id":{"type":"string"},"aap_enabled":{"type":"boolean"},"aip_enabled":{"type":"boolean"},"proof_enabled":{"type":"boolean"},"proof_rate":{"type":"integer","minimum":0,"maximum":100},"nudge_strategy":{"type":"string","enum":["always","sampling","threshold","off"]},"ddr_mode":{"type":"string","enum":["off","flag","auto-suggest","auto-apply"]},"analyze_output":{"type":"boolean"}}},"DeletionRequestStatus":{"type":"object","description":"Tracks progress of the async GDPR Art. 17 deletion cascade (ADR-021).","required":["deletion_request_id","status","requested_at","retry_count"],"properties":{"deletion_request_id":{"type":"string"},"status":{"type":"string","enum":["tombstoned","phase_1_complete","phase_2_complete","phase_3_complete","phase_4_complete","kv_cleared","pseudonymized","complete","failed"]},"requested_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"failed_phase":{"type":["string","null"]},"failed_reason":{"type":["string","null"]},"retry_count":{"type":"integer","minimum":0}}},"DisagreementReview":{"type":"object","description":"Row from `disagreement_reviews` — a human-adjudicable action that failed to find consensus during enforcement.","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"status":{"type":"string","enum":["pending","review","applied","dismissed"]},"proposed_amendment":{"type":["object","null"],"properties":{"type":{"type":"string"},"action":{"type":"string","description":"Action the reviewer proposes to add to `autonomy_envelope.bounded_actions`."},"description":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"resolved_at":{"type":["string","null"],"format":"date-time"},"resolved_by":{"type":["string","null"]}},"additionalProperties":true},"ReputationScore":{"type":"object","description":"Agent reputation row computed by the reputation worker's 6-hour cron. Grade alphabet: `AAA AA+ AA A+ A B+ B C+ C D NR` (NR = not-rated, insufficient data). Score is an integer 0–1000.","required":["agent_id","score","grade","is_eligible","checkpoint_count","confidence","components","visibility"],"properties":{"agent_id":{"type":"string"},"score":{"type":["integer","null"],"minimum":0,"maximum":1000},"grade":{"type":["string","null"],"description":"AAA–D or NR."},"tier":{"type":["string","null"]},"is_eligible":{"type":"boolean"},"checkpoint_count":{"type":"integer"},"checkpoint_accounting":{"type":["object","null"],"description":"Structured breakdown of how checkpoints were counted toward the score. `analyzed` is the scoring population; `excluded` buckets are mutually exclusive and `analyzed + synthetic + insufficient_thinking + quarantined = total`. Null for legacy rows computed before this field existed.","required":["total","analyzed","excluded"],"properties":{"total":{"type":"integer","description":"All checkpoints recorded for the agent."},"analyzed":{"type":"integer","description":"Checkpoints that counted toward the score (drives the X/50 eligibility gauge)."},"excluded":{"type":"object","required":["synthetic","insufficient_thinking","quarantined"],"properties":{"synthetic":{"type":"integer","description":"Synthetic (`ic-synthetic-*`) checkpoints."},"insufficient_thinking":{"type":"integer","description":"Zero-analysis checkpoints (no extraction confidence, thinking tokens, or analysis duration)."},"quarantined":{"type":"integer","description":"Checkpoints referenced by a non-expired enforce advisory; excluded from scoring entirely."}}}}},"confidence":{"type":"string","enum":["insufficient","low","medium","high"]},"components":{"type":"array","items":{"type":"object","required":["key","score","weight","weighted_score"],"properties":{"key":{"type":"string","enum":["integrity_ratio","compliance","drift_stability","trace_completeness","coherence_compatibility"]},"label":{"type":"string"},"score":{"type":"number"},"weight":{"type":"number"},"weighted_score":{"type":"number"},"factors":{"type":"array"}}}},"computed_at":{"type":["string","null"],"format":"date-time"},"next_compute_at":{"type":["string","null"],"format":"date-time","description":"Next scheduled recompute — the 00/06/12/18 UTC cron slot strictly after `computed_at` (`floor(computed_at/6h)*6h + 6h`). Null when `computed_at` is null."},"trend_30d":{"type":["number","null"]},"visibility":{"type":"string","enum":["public","private"]},"claimed":{"type":"boolean"},"agent_name":{"type":["string","null"]},"a2a_trust_extension":{"type":"object","description":"A2A trust extension for interop. Only present on `GET /reputation/{agent_id}` (not on batch/compare rows).","properties":{"extension_uri":{"type":"string"},"provider":{"type":"string"},"score":{"type":"number"},"grade":{"type":"string"},"confidence":{"type":"string"},"verified_url":{"type":"string","format":"uri"},"badge_url":{"type":"string","format":"uri"},"methodology_url":{"type":"string","format":"uri"},"last_updated":{"type":"string","format":"date-time"}}}}},"RiskAssessment":{"type":"object","description":"Individual risk assessment row (`ra-…`). Produced by `POST /risk/assess`.","properties":{"assessment_id":{"type":"string"},"agent_id":{"type":"string"},"risk_score":{"type":"number","description":"0–1000 integer (higher = riskier)."},"risk_level":{"type":"string","enum":["low","moderate","high","critical"]},"recommendation":{"type":"string","enum":["proceed","proceed_with_caveats","require_approval","block"]},"confidence":{"type":"string","enum":["insufficient","low","medium","high"]},"contributing_factors":{"type":"array","items":{"type":"object","additionalProperties":true}},"suggested_thresholds":{"type":"object","additionalProperties":true},"explanation":{"type":"string"},"proof_id":{"type":["string","null"]},"proof_status":{"type":"string","enum":["none","pending","completed","failed"]},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"TeamRiskAssessment":{"type":"object","description":"Team risk assessment row (`tra-…`). Produced by `POST /risk/assess/team`. Three-pillar result (portfolio + coherence + concentration) with weakest-link and Shapley attribution per member.","properties":{"assessment_id":{"type":"string"},"team_id":{"type":["string","null"]},"agent_count":{"type":"integer"},"team_risk_score":{"type":"number"},"team_risk_level":{"type":"string"},"team_coherence_score":{"type":"number"},"team_recommendation":{"type":"string"},"portfolio_risk":{"type":"object","additionalProperties":true},"coherence_risk":{"type":"object","additionalProperties":true},"concentration_risk":{"type":"object","additionalProperties":true},"weakest_link_risk":{"type":"object","additionalProperties":true},"individual_assessments":{"type":"array","items":{"$ref":"#/components/schemas/RiskAssessment"}},"outliers":{"type":"array"},"clusters":{"type":"array"},"value_divergences":{"type":"array"},"shapley_values":{"type":"object","additionalProperties":{"type":"number"}},"synergy_type":{"type":"string"},"explanation":{"type":"string"},"proof_id":{"type":["string","null"]},"proof_status":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"QuarantineItem":{"type":"object","description":"Quarantined message row. Stores only `content_hash` — the original plaintext is not retained once the message is quarantined.","properties":{"quarantine_id":{"type":"string"},"agent_id":{"type":"string"},"status":{"type":"string","enum":["pending","released","deleted","confirmed_threat"]},"threat_type":{"type":"string"},"content_hash":{"type":"string"},"reviewed_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"SafeHousePattern":{"type":"object","description":"Row from `sh_threat_patterns`. `label: \"benign\"` patterns are used to suppress false positives; `label: \"malicious\"` patterns add to L1/L2 detection.","properties":{"id":{"type":"string"},"threat_type":{"type":"string"},"source":{"type":"string"},"label":{"type":"string","enum":["malicious","benign"]},"content":{"type":"string"},"minhash":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"SafeHouseCanary":{"type":"object","description":"Canary credential planted in an agent context. `canary_value` is only returned on creation.","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"canary_type":{"type":"string","enum":["api_key","password","database_url","ssh_key","oauth_token"]},"triggered":{"type":"boolean"},"triggered_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"SafeHouseEvaluation":{"type":"object","description":"Row from `sh_evaluations` — one screening decision (inbound or outbound). `threats` and `detector_scores` depend on detector config.","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"session_id":{"type":["string","null"]},"mode":{"type":"string"},"surface":{"type":["string","null"]},"verdict":{"type":"string","enum":["pass","warn","quarantine","block"]},"threats":{"type":["array","null"],"items":{"type":"object","properties":{"type":{"type":"string"},"confidence":{"type":"number"}}}},"overall_risk":{"type":"number"},"detector_scores":{"type":["object","null"],"additionalProperties":true},"detection_sources":{"type":["array","null"]},"session_multiplier":{"type":["number","null"]},"duration_ms":{"type":["integer","null"]},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"SafeHouseEvaluationPage":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SafeHouseEvaluation"}},"pagination":{"type":"object","properties":{"total":{"type":["integer","null"]},"limit":{"type":"integer"},"after":{"type":["string","null"]}}},"meta":{"type":"object","additionalProperties":true}}},"NetworkThreatBucket":{"type":"object","description":"One per-axis bucket in the Protection Network L4 thermometer. The `bucket_value` is the L0 fingerprint slice for the axis (substrate / vertical / pattern / source) and carries no per-tenant identifier — public-aggregate disclosure model per concept.md §\"Cross-tenant disclosure.\"","required":["bucket_value","state","state_changed_at","updated_at"],"properties":{"bucket_value":{"type":"string","description":"L0 fingerprint slice (e.g. substrate / vertical / pattern / source identifier)."},"state":{"type":"string","enum":["calm","elevated","high","under_attack"]},"prior_state":{"type":["string","null"],"enum":["calm","elevated","high","under_attack",null],"description":"Previous state if a transition has been observed; null until the bucket has changed state at least once."},"state_changed_at":{"type":"string","format":"date-time","description":"Wall-clock time of the most recent state transition."},"updated_at":{"type":"string","format":"date-time","description":"Wall-clock time the rolling-stats roll-up last touched this row."}},"additionalProperties":true},"SelfHostedDeployment":{"type":"object","description":"A self-hosted Mnemom deployment registered by an org.","properties":{"deployment_id":{"type":"string","description":"Prefixed `dep-…` identifier assigned on registration."},"org_id":{"type":"string"},"license_id":{"type":"string"},"instance_name":{"type":"string"},"instance_id":{"type":"string"},"region":{"type":["string","null"]},"status":{"type":"string","enum":["active","inactive","degraded"]},"version":{"type":["string","null"]},"heartbeat_data":{"type":"object","additionalProperties":true},"instance_metadata":{"type":"object","additionalProperties":true},"last_heartbeat_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"TrustEdge":{"type":"object","description":"Directed trust-relationship edge between two agents (CLPI Phase 3). Used by the trust-topology RPC and the team reputation scorer.","properties":{"id":{"type":"string","description":"Prefixed `te-…` identifier."},"from_agent":{"type":"string"},"to_agent":{"type":"string"},"weight":{"type":"number","minimum":0,"maximum":1},"reason":{"type":"string","description":"Free-form label (e.g. `manual`, `roster_coherence`, `co_deployment`)."},"created_at":{"type":"string","format":"date-time"}}},"GovernanceSignalScope":{"type":"string","enum":["platform","org","team","agent"],"description":"Scope at which the signal is produced and routed (ADR-048 §1)."},"GovernanceSignalSource":{"type":"string","enum":["sideband.drift","sideband.coherence","sideband.fault_line","sideband.fleet","network.threat_level.changed"],"description":"Source detector for the signal. Closed enum per ADR-048 §1. `network.threat_level.changed` added in migration 234."},"GovernanceSignalSeverity":{"type":"string","enum":["info","warn","high","critical"]},"GovernanceSignalStatus":{"type":"string","enum":["open","acknowledged","resolved","dismissed","expired"]},"GovernanceActorRole":{"type":"string","enum":["platform_admin","org_owner","org_admin","team_admin","member","system"],"description":"Audit-actor role per ADR-046."},"GovernanceResolutionStatus":{"type":"string","enum":["action_taken","wont_fix","duplicate","false_positive","self_resolved"]},"GovernanceNotificationChannel":{"type":"string","enum":["webhook","slack","email","pagerduty"]},"GovernanceNotificationChannelState":{"type":"object","additionalProperties":false,"required":["state","attempts"],"properties":{"state":{"type":"string","enum":["queued","delivered","failed","skipped"]},"attempts":{"type":"integer","minimum":0},"destination_id":{"type":["string","null"],"format":"uuid"},"delivered_at":{"type":["string","null"],"format":"date-time"},"last_error":{"type":["string","null"]}}},"GovernanceNotificationState":{"type":"object","description":"Per-channel dispatch state populated by the notification dispatcher.","additionalProperties":{"$ref":"#/components/schemas/GovernanceNotificationChannelState"},"properties":{"skipped":{"type":"boolean"}}},"GovernanceSignal":{"type":"object","description":"A governance signal row — operator-actionable observation per ADR-048.","required":["id","scope","scope_id","source","pattern_type","severity","detected_at","detected_by","org_id","agent_ids","detail","source_ref","status","notification_state","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^gs-[0-9a-f]{12}$"},"scope":{"$ref":"#/components/schemas/GovernanceSignalScope"},"scope_id":{"type":"string"},"source":{"$ref":"#/components/schemas/GovernanceSignalSource"},"pattern_type":{"type":"string","description":"Free-form per source."},"severity":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"detected_at":{"type":"string","format":"date-time"},"detected_by":{"type":"string"},"org_id":{"type":"string"},"team_id":{"type":["string","null"],"format":"uuid"},"agent_ids":{"type":"array","items":{"type":"string"}},"detail":{"type":"object","additionalProperties":true},"source_ref":{"type":"object","additionalProperties":true},"status":{"$ref":"#/components/schemas/GovernanceSignalStatus"},"acknowledged_by":{"type":["string","null"],"format":"uuid"},"acknowledged_at":{"type":["string","null"],"format":"date-time"},"acknowledged_actor_role":{"oneOf":[{"$ref":"#/components/schemas/GovernanceActorRole"},{"type":"null"}]},"resolution_status":{"oneOf":[{"$ref":"#/components/schemas/GovernanceResolutionStatus"},{"type":"null"}]},"action_taken":{"type":["string","null"]},"resolved_by":{"type":["string","null"],"format":"uuid"},"resolved_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"webhook_delivery_id":{"type":["string","null"],"format":"uuid"},"notification_state":{"$ref":"#/components/schemas/GovernanceNotificationState"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"GovernanceSignalsListResponse":{"type":"object","required":["signals"],"properties":{"signals":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceSignal"}},"total":{"type":"integer","minimum":0}}},"GovernanceDestinationFilter":{"type":"object","additionalProperties":false,"properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceSignalSource"}},"severities":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceSignalSeverity"}},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceSignalScope"}},"pattern_types":{"type":"array","items":{"type":"string"}}}},"GovernanceNotificationDestination":{"type":"object","required":["id","org_id","channel","config","filter","enabled","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"org_id":{"type":"string"},"channel":{"$ref":"#/components/schemas/GovernanceNotificationChannel"},"config":{"type":"object","additionalProperties":true},"filter":{"$ref":"#/components/schemas/GovernanceDestinationFilter"},"enabled":{"type":"boolean"},"display_name":{"type":["string","null"]},"created_by":{"type":["string","null"],"format":"uuid"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"last_tested_at":{"type":["string","null"],"format":"date-time"},"last_test_status":{"type":["string","null"],"enum":["ok","failed"]},"last_test_error":{"type":["string","null"]}}},"GovernanceEscalationPredicate":{"type":"object","additionalProperties":false,"properties":{"source":{"$ref":"#/components/schemas/GovernanceSignalSource"},"pattern_type":{"type":"string"},"severity_min":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"severity_max":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"scope":{"$ref":"#/components/schemas/GovernanceSignalScope"},"team_id":{"type":"string","format":"uuid"},"threshold_count":{"type":"integer","minimum":1},"window_minutes":{"type":"integer","minimum":1}}},"GovernanceEscalationRule":{"type":"object","required":["id","org_id","name","predicate","destination_ids","enabled","fire_count","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"org_id":{"type":"string"},"name":{"type":"string"},"predicate":{"$ref":"#/components/schemas/GovernanceEscalationPredicate"},"destination_ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1},"enabled":{"type":"boolean"},"last_fired_at":{"type":["string","null"],"format":"date-time"},"fire_count":{"type":"integer","minimum":0},"created_by":{"type":["string","null"],"format":"uuid"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"GovernanceCoverageReport":{"type":"object","description":"Coverage rollup across the org's teams.","required":["org_id","window_days","by_source","by_severity","totals"],"properties":{"org_id":{"type":"string"},"window_days":{"type":"integer","minimum":1},"by_source":{"type":"object","additionalProperties":{"type":"object","properties":{"fired":{"type":"integer","minimum":0},"acknowledged":{"type":"integer","minimum":0},"resolved":{"type":"integer","minimum":0},"dismissed":{"type":"integer","minimum":0},"open":{"type":"integer","minimum":0}}}},"by_severity":{"type":"object","additionalProperties":{"type":"integer","minimum":0}},"totals":{"type":"object","required":["fired","open"],"properties":{"fired":{"type":"integer","minimum":0},"open":{"type":"integer","minimum":0},"median_time_to_ack_seconds":{"type":["number","null"],"minimum":0}}}}},"PostureScope":{"type":"string","enum":["platform","org"]},"PostureBody":{"type":"object","description":"Trust posture body (PostureBody v1.0). Matches the runtime validator at src/composition/posture-validate.ts EXACTLY — strict-unknown-field rejection (additionalProperties:false) at every level, so adding a field requires a posture_schema_version bump (ADR-023/ADR-045). Used as the `body` of POST /v1/postures and PUT /v1/postures/{id}.","required":["posture_schema_version","sideband","fleet_identification","fan_out"],"additionalProperties":false,"properties":{"posture_schema_version":{"type":"string","const":"v1.0","description":"Schema version pin. Must be exactly `v1.0`."},"sideband":{"type":"object","required":["coherence","fault_line","fleet"],"additionalProperties":false,"properties":{"coherence":{"type":"object","required":["enabled","cadence_seconds","fire_on","severity_on_fire"],"additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"cadence_seconds":{"type":"integer","minimum":1},"severity_on_fire":{"type":"string","enum":["low","medium","high","critical"]},"fire_on":{"type":"object","required":["pairwise_governance_floor_below","conflict_edge_count_exceeds","outlier_agents_count_exceeds"],"additionalProperties":false,"properties":{"pairwise_governance_floor_below":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Fire when pairwise governance floor drops below this; null disables."},"conflict_edge_count_exceeds":{"type":["integer","null"],"minimum":0,"description":"Fire when conflict-edge count exceeds this; null disables."},"outlier_agents_count_exceeds":{"type":["integer","null"],"minimum":0,"description":"Fire when outlier-agent count exceeds this; null disables."}}}}},"fault_line":{"type":"object","required":["enabled","cadence_seconds","severity_floor","use_reputation_scores","severity_on_fire"],"additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"cadence_seconds":{"type":"integer","minimum":1},"severity_floor":{"type":"string","enum":["low","medium","high","critical"]},"use_reputation_scores":{"type":"boolean"},"severity_on_fire":{"type":"string","enum":["low","medium","high","critical"]}}},"fleet":{"type":"object","required":["enabled","cadence_seconds","patterns","severity_on_fire"],"additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"cadence_seconds":{"type":"integer","minimum":1},"severity_on_fire":{"type":"string","enum":["low","medium","high","critical"]},"patterns":{"type":"object","required":["outliers","cluster_partition","min_pair_score_below"],"additionalProperties":false,"properties":{"outliers":{"type":"boolean"},"cluster_partition":{"type":"boolean"},"min_pair_score_below":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Flag pairs scoring below this; null disables."}}}}}}},"fleet_identification":{"type":"object","required":["by"],"additionalProperties":false,"properties":{"by":{"type":"string","enum":["team_membership"]}}},"fan_out":{"type":"object","required":["rule"],"additionalProperties":false,"properties":{"rule":{"type":"string","enum":["per_named_affected_agent"]}}}}},"Posture":{"type":"object","description":"Trust posture row (mig 173). Library row; revisions are versioned bodies stored separately.","required":["posture_id","slug","name","scope","current_revision_id","is_default","created_at","updated_at"],"properties":{"posture_id":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"slug":{"type":"string","description":"URL-safe identifier (e.g., 'standard', 'banking-core')."},"name":{"type":"string"},"description":{"type":["string","null"]},"scope":{"$ref":"#/components/schemas/PostureScope"},"org_id":{"type":["string","null"],"description":"NULL for platform-scope postures."},"owner_user_id":{"type":["string","null"],"format":"uuid"},"is_default":{"type":"boolean","description":"True for Mnemom-shipped platform defaults."},"current_revision_id":{"type":["string","null"],"description":"FK to trust_posture_revisions; NULL only mid-create."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"deleted_at":{"type":["string","null"],"format":"date-time","description":"Soft-delete timestamp; NULL = live."}}},"PostureRevision":{"type":"object","description":"Versioned posture body. Immutable by handler discipline (forward-only).","required":["revision_id","posture_id","revision_number","body","created_at"],"properties":{"revision_id":{"type":"string","pattern":"^tpr-[0-9a-f]{8}$"},"posture_id":{"type":"string"},"revision_number":{"type":"integer","minimum":1},"body":{"type":"object","description":"Composition inputs: alignment_card, protection_card, integrity, autonomy, etc.","additionalProperties":true},"change_note":{"type":["string","null"]},"created_by":{"type":["string","null"],"format":"uuid"},"created_at":{"type":"string","format":"date-time"}}},"PostureAssignment":{"type":"object","description":"Team→posture binding (one active per team).","required":["team_id","posture_id","assigned_at"],"properties":{"team_id":{"type":"string","format":"uuid"},"posture_id":{"type":"string"},"assigned_revision_id":{"type":["string","null"],"description":"Revision pinned at assignment time (null = tracks current_revision_id)."},"revision_id":{"type":"string","description":"Pinned revision (optional; defaults to current)."},"assigned_by":{"type":["string","null"],"format":"uuid"},"assigned_at":{"type":"string","format":"date-time"},"replaced_prior":{"type":"boolean","description":"`true` when this assignment displaced a previously-active assignment on the team."}}},"PostureEffects":{"type":"object","description":"Analytics rollup: cells affected by this posture revision over a window.","required":["posture_id","window_hours","teams_using","agents_affected"],"properties":{"posture_id":{"type":"string"},"window_hours":{"type":"integer","minimum":1},"teams_using":{"type":"integer","minimum":0},"agents_affected":{"type":"integer","minimum":0},"events_emitted":{"type":"object","additionalProperties":{"type":"integer"},"description":"Per-event-type counts."}}},"PostureDiff":{"type":"object","description":"Structural diff between two revisions.","required":["posture_id","from_revision","to_revision","changes"],"properties":{"posture_id":{"type":"string"},"from_revision":{"type":"integer"},"to_revision":{"type":"integer"},"changes":{"type":"array","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"JSON pointer."},"kind":{"type":"string","enum":["added","removed","changed"]},"before":{},"after":{}}}}}},"TeamEffectivePosture":{"type":"object","description":"Composed posture currently in effect for a team (alignment + protection + integrity merged from posture body, team templates, and per-agent exemptions).","required":["team_id","posture_id","revision_number","composition"],"properties":{"team_id":{"type":"string","format":"uuid"},"posture_id":{"type":"string"},"revision_number":{"type":"integer"},"composition":{"type":"object","description":"Composed alignment + protection cards.","additionalProperties":true}}},"SidebandAdvisorySource":{"type":"string","enum":["sideband.coherence","sideband.fault_line","sideband.fleet","sideband.drift"]},"SidebandAdvisoryRow":{"type":"object","description":"Legacy pre-cutover sideband row. Post ADR-048 cutover, sideband.* sources are written to governance_signals; this query endpoint surveys what historical rows remain in pending_advisories. Sunsetting; clients should consume governance_signals directly.","required":["id","agent_id","source","status","created_at"],"properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"team_id":{"type":["string","null"],"format":"uuid"},"source":{"$ref":"#/components/schemas/SidebandAdvisorySource"},"status":{"type":"string","enum":["pending","delivered","consumed","expired"]},"nudge_content":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"}}},"SidebandAdvisoryListResponse":{"type":"object","required":["advisories"],"properties":{"advisories":{"type":"array","items":{"$ref":"#/components/schemas/SidebandAdvisoryRow"}}}},"SidebandCoverageReport":{"type":"object","description":"Per-team rollup of sideband.* finding counts over a window. Operator dashboard input.","required":["team_id","window_hours","by_source"],"properties":{"team_id":{"type":"string","format":"uuid"},"window_hours":{"type":"integer","minimum":1},"by_source":{"type":"object","additionalProperties":{"type":"integer","minimum":0}}}},"TeamAdmin":{"type":"object","description":"Team-admin grant — allows a non-org-admin user to administer one team.","required":["user_id","team_id","granted_at"],"properties":{"user_id":{"type":"string","format":"uuid"},"team_id":{"type":"string","format":"uuid"},"granted_by":{"type":["string","null"],"format":"uuid"},"granted_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time","description":"When the grant was revoked. `null` on active grants."},"idempotent_noop":{"type":"boolean","description":"Present on grant and revoke responses. `true` when the request was a no-op (grant already active / already revoked)."}}},"ApiKeyWhoAmI":{"type":"object","description":"Caller introspection — the principal authenticated for this request. Returned by `GET /v1/api-keys/whoami`. The handler is generalized across `cookie`, `jwt`, and `api_key` auth methods, so the API-key-specific fields (`key_id`, `account_id`, `scopes`) are null on cookie/JWT principals.","required":["user_id","auth_method"],"properties":{"user_id":{"type":"string","description":"Authenticated principal identifier (Supabase user UUID for cookie/JWT auth; api-key-bound user UUID for api_key auth)."},"email":{"type":["string","null"]},"auth_method":{"type":"string","enum":["cookie","jwt","api_key"]},"key_id":{"type":["string","null"],"description":"API key id (e.g. `mnk_...`), or null for cookie/JWT auth."},"account_id":{"type":["string","null"],"description":"Billing account id, or null for cookie/JWT auth."},"org_id":{"type":["string","null"]},"scopes":{"type":["array","null"],"items":{"type":"string"},"description":"Capability scopes (ADR-049) for api-key auth; null for cookie/JWT. e.g., ['gateway.send', 'gateway.observe']."},"is_admin":{"type":["boolean","null"]}}},"OperatorAttestationRequest":{"type":"object","description":"Sign an operator-issued attestation about a checkpoint, signal, or audit-relevant event. Returns an Ed25519-signed envelope binding the operator's identity to the asserted statement at the asserted time.","required":["subject","statement"],"properties":{"subject":{"type":"object","description":"What's being attested about (e.g., {type: 'governance_signal', id: 'gs-...'}).","additionalProperties":true},"statement":{"type":"string","description":"Free-form operator statement."},"actor_role":{"$ref":"#/components/schemas/GovernanceActorRole"}}},"OperatorAttestationResponse":{"type":"object","required":["attestation_id","signed_at","signature"],"properties":{"attestation_id":{"type":"string"},"signed_at":{"type":"string","format":"date-time"},"signed_by":{"type":"string","format":"uuid"},"actor_role":{"$ref":"#/components/schemas/GovernanceActorRole"},"subject":{"type":"object","additionalProperties":true},"statement":{"type":"string"},"signature":{"type":"string","description":"base64url Ed25519 signature."},"public_key":{"type":"string","description":"base64url Ed25519 public key."}}},"MyRole":{"type":["string","null"],"enum":["super_admin","org_owner","org_admin","team_admin","org_member","org_viewer","org_auditor",null],"description":"The caller's effective role on the resource. Computed server-side per ADR-053; frontends derive `canEdit` exclusively from this field. `team_admin` only appears on team-scope responses. `null` means the caller has no role on this resource (the request still authenticated, but no role applies — e.g. an org-scope response read by an unrelated user)."},"CardSourceScope":{"type":"object","required":["card_json","available"],"description":"One slice of a sources envelope. `card_json` carries the raw template at that scope (full UnifiedAlignment/Protection card, the org/team template, or the platform-defaults object). `available: false` means no card is configured at this scope.","properties":{"card_json":{"type":["object","null"],"additionalProperties":true},"available":{"type":"boolean"}}},"OrgCardSourceScope":{"allOf":[{"$ref":"#/components/schemas/CardSourceScope"},{"type":"object","properties":{"org_id":{"type":["string","null"]},"org_name":{"type":["string","null"]}}}]},"TeamCardSourceScope":{"allOf":[{"$ref":"#/components/schemas/CardSourceScope"},{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string"},"team_name":{"type":["string","null"]}}}]},"AlignmentCardSourcesEnvelope":{"type":"object","required":["platform","org","teams","agent","composed","composed_stale","my_role"],"description":"Four-scope sources envelope returned by `GET /v1/agents/{agent_id}/alignment-card?include=sources`. Per ADR-053 the envelope mirrors the composer cascade Platform → Org → Team(s) → Agent and carries the caller's effective role + a staleness signal.","properties":{"platform":{"$ref":"#/components/schemas/CardSourceScope"},"org":{"$ref":"#/components/schemas/OrgCardSourceScope"},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamCardSourceScope"},"description":"Zero-or-more team-scope contributions. Empty when the agent is in no teams (Charter §I11 amended). Ordered by `teams.created_at ASC` to match the composer's stable order."},"agent":{"$ref":"#/components/schemas/CardSourceScope"},"composed":{"$ref":"#/components/schemas/CardSourceScope"},"composed_stale":{"type":"boolean","description":"True when `composed.card_json._composition.scopes_applied` disagrees with the current `team_templates` set in `gather_composition_inputs` (the queue worker will reconverge via the existing `needs_recompose` flag)."},"my_role":{"$ref":"#/components/schemas/MyRole"}}},"ProtectionCardSourcesEnvelope":{"type":"object","required":["platform","org","teams","agent","composed","composed_stale","my_role"],"description":"Four-scope sources envelope returned by `GET /v1/agents/{agent_id}/protection-card?include=sources`. Identical shape to `AlignmentCardSourcesEnvelope`.","properties":{"platform":{"$ref":"#/components/schemas/CardSourceScope"},"org":{"$ref":"#/components/schemas/OrgCardSourceScope"},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamCardSourceScope"}},"agent":{"$ref":"#/components/schemas/CardSourceScope"},"composed":{"$ref":"#/components/schemas/CardSourceScope"},"composed_stale":{"type":"boolean"},"my_role":{"$ref":"#/components/schemas/MyRole"}}},"TeamTemplateSourcesEnvelope":{"type":"object","required":["platform","org","team","composed","composed_stale","my_role"],"description":"Three-scope sources envelope returned by `GET /v1/teams/{team_id}/{alignment,protection}-template?include=sources`. The team row is the editable scope; agent layer is omitted (team-scope has no specific agent above it).","properties":{"platform":{"$ref":"#/components/schemas/CardSourceScope"},"org":{"$ref":"#/components/schemas/OrgCardSourceScope"},"team":{"$ref":"#/components/schemas/TeamCardSourceScope"},"composed":{"$ref":"#/components/schemas/CardSourceScope"},"composed_stale":{"type":"boolean","description":"Always false at team-template scope today (team-scope composition is in-memory per request). Included for envelope symmetry with the agent-scope envelopes."},"my_role":{"$ref":"#/components/schemas/MyRole"}}},"OrgTemplateSourcesEnvelope":{"type":"object","required":["platform","org","composed","my_role"],"description":"Two-scope sources envelope returned by `GET /v1/orgs/{org_id}/{alignment,protection}-template?include=sources`. No team or agent layer (org templates compose only against the platform floor).","properties":{"platform":{"$ref":"#/components/schemas/CardSourceScope"},"org":{"$ref":"#/components/schemas/OrgCardSourceScope"},"composed":{"$ref":"#/components/schemas/CardSourceScope"},"my_role":{"$ref":"#/components/schemas/MyRole"}}},"TeamMyRoleResponse":{"type":"object","required":["team_id","my_role"],"description":"Response body of `GET /v1/teams/{team_id}/my-role`. Used by surfaces that don't load a template sources envelope (team roster tab, identity card tab, admins tab) to gate edit affordances from the same single source of truth as the editors.","properties":{"team_id":{"type":"string"},"my_role":{"$ref":"#/components/schemas/MyRole"}}}}},"paths":{"/.well-known/jwks.json":{"get":{"operationId":"getAttestationJwks","security":[],"summary":"Public JWKS for AAP attestation tokens.","description":"Returns the set of public keys verifying Mnemom-signed AAP attestation tokens. The active key signs new attestations; retired keys remain in the set for the token-TTL window plus grace. Unauthenticated; cacheable for 5 minutes. cards-as-primitive Phase 5 A1.","tags":["Attestation"],"responses":{"200":{"description":"Current key set.","content":{"application/json":{"schema":{"type":"object","required":["keys"],"properties":{"keys":{"type":"array","items":{"type":"object","required":["kty","crv","x","kid","alg","use"],"properties":{"kty":{"const":"OKP"},"crv":{"const":"Ed25519"},"x":{"type":"string","description":"base64url-encoded 32-byte Ed25519 public point."},"kid":{"type":"string","description":"Key identifier; matches the `kid` claim in tokens this key signs."},"alg":{"const":"EdDSA"},"use":{"const":"sig"},"mnemom_ext":{"type":"object","description":"Mnemom-specific JWK extension carrying rotation state. Standard JOSE verifiers ignore unknown fields; clients that want to surface rotation in the UI read this block.","properties":{"status":{"type":"string","enum":["active","retired"]},"activated_at":{"type":"string","format":"date-time"},"retired_at":{"type":"string","format":"date-time"},"rotation_reason":{"type":"string"}}}}}}}}}},"headers":{"Cache-Control":{"schema":{"type":"string","example":"public, max-age=300, stale-while-revalidate=600"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/agents":{"post":{"operationId":"registerAgent","summary":"Register a new agent","description":"Register a new agent with a name and hash proof. Optionally attach an alignment card and policy.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","hash_proof"],"properties":{"name":{"type":"string","description":"Agent name. 2-32 characters, alphanumeric and hyphens only, must start and end with alphanumeric.","pattern":"^[a-zA-Z0-9][a-zA-Z0-9-]{0,30}[a-zA-Z0-9]$","minLength":2,"maxLength":32,"example":"my-agent"},"hash_proof":{"type":"string","description":"SHA256 hex string used to derive the agent ID and hash.","minLength":16,"example":"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"},"card_json":{"type":"object","description":"Optional alignment card JSON to attach on creation.","additionalProperties":true},"policy_yaml":{"type":"string","description":"Optional YAML policy string to create alongside the agent."}}}}}},"responses":{"201":{"description":"Agent registered successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Agent ID (e.g. smolt-abc12345)","example":"smolt-a1b2c3d4"},"agent_hash":{"type":"string","description":"First 16 characters of the hash_proof"},"name":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"card_id":{"type":"string","description":"ID of the created alignment card"},"policy_created":{"type":"boolean","description":"Whether a policy was created from the provided policy_yaml"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"operationId":"listAgents","summary":"List your agents","description":"List all agents owned by the authenticated user. Supports pagination.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Maximum number of agents to return (max 100)"},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"Number of agents to skip for pagination"}],"responses":{"200":{"description":"Paginated list of agents","content":{"application/json":{"schema":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/Agent"}},"total":{"type":"integer","description":"Total number of agents owned by the user"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/topology":{"get":{"operationId":"getAgentTopology","summary":"Graph of the caller's agents + trust edges","description":"Returns a `{nodes, edges}` graph of every agent linked to the authenticated user, suitable for dashboard topology rendering. **Feature-gated:** requires the `trust_topology` feature flag on the caller's plan. Falls back to `{nodes: [], edges: []}` if the backing RPC fails.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"x-feature-gate":"trust_topology","responses":{"200":{"description":"Topology graph.","content":{"application/json":{"schema":{"type":"object","required":["nodes","edges"],"properties":{"nodes":{"type":"array","items":{"type":"object"}},"edges":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}":{"get":{"operationId":"getAgent","summary":"Get agent by ID","tags":["Agents"],"security":[{"BearerAuth":[]},{}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Agent details. Private agents return a limited response to non-owners.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Agent"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"updateAgent","summary":"Update agent name","description":"Update the name of an agent you own.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"New agent name. 2-32 characters, alphanumeric and hyphens only.","pattern":"^[a-zA-Z0-9][a-zA-Z0-9-]{0,30}[a-zA-Z0-9]$","minLength":2,"maxLength":32}}}}}},"responses":{"200":{"description":"Updated agent record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Agent"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteAgent","summary":"Delete agent (GDPR Art. 17 cascade)","description":"Tombstone an agent and asynchronously cascade deletion across all agent-owned records (traces, integrity checkpoints, drift alerts, reclassifications, etc.) per ADR-021. The request returns `202 Accepted` immediately with a `deletion_request_id`; poll [GET /v1/agents/{agent_id}/deletion-status](/api-reference/endpoint/get-agents-agent-id-deletion-status) or subscribe to the deletion webhook for cascade progress.\n\nIdempotent: re-DELETE on a tombstoned agent returns the existing `deletion_request_id` with the current status.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"202":{"description":"Deletion accepted; cascade will run asynchronously","content":{"application/json":{"schema":{"type":"object","required":["deletion_request_id","status","requested_at"],"properties":{"deletion_request_id":{"type":"string","description":"Stable identifier for this deletion request; pass to deletion-status to poll progress.","example":"del-7f3b9e2a-c41d-4b8e-9f0a-d5c2e8a17b3e"},"status":{"type":"string","enum":["tombstoned","in_progress","completed","failed"],"description":"Initial state is `tombstoned` (synchronous part); cascade transitions to `in_progress` then `completed` (or `failed`)."},"requested_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"Set once the async cascade finishes. `null` while in flight."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/a2a-agent-card":{"get":{"operationId":"getA2AAgentCard","security":[],"summary":"A2A AgentCard projection of the canonical alignment card.","description":"Public discovery surface. Returns the Mnemom-composed AgentCard in A2A v1.x envelope shape, with AAP alignment + attestation extensions. Gated per-agent by `agents.a2a_export_enabled` (opt-out agents return 404 to avoid enumeration). Unauthenticated; cacheable for 60 seconds; ETag = combined canonical content_hash. cards-as-primitive Phase 5 B2.","tags":["A2A"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A2A AgentCard.","content":{"application/json":{"schema":{"type":"object","required":["schemaVersion","name","description","url","version","capabilities","skills","extensions","metadata"],"properties":{"schemaVersion":{"const":"1.0"},"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string","format":"uri"},"version":{"type":"string"},"capabilities":{"type":"object","required":["streaming","pushNotifications"],"properties":{"streaming":{"type":"boolean"},"pushNotifications":{"type":"boolean"}}},"skills":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}},"extensions":{"type":"array","items":{"type":"object","required":["uri","required","body"],"properties":{"uri":{"type":"string","format":"uri"},"required":{"type":"boolean"},"body":{"type":"object","additionalProperties":true}}}},"metadata":{"type":"object","properties":{"content_hash":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"composed_at":{"type":"string","format":"date-time"}}}}}}},"headers":{"ETag":{"schema":{"type":"string","example":"\"sha256:<hex>\""}},"Cache-Control":{"schema":{"type":"string","example":"public, max-age=60, stale-while-revalidate=300"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/agents/{agent_id}/alignment-card":{"get":{"operationId":"getAlignmentCardLegacy","summary":"DEPRECATED — use GET /v1/alignment/agent/{agent_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/agent/{agent_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAlignmentCardLegacy","summary":"DEPRECATED — use PUT /v1/alignment/agent/{agent_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/agent/{agent_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/alignment-card/preview-compose":{"post":{"operationId":"postAlignmentCardPreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/alignment/agent/{agent_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/agent/{agent_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/avatar":{"put":{"operationId":"putAgentAvatar","summary":"Upload agent avatar","description":"Replace an agent's avatar image. Requires the authenticated principal to be the agent's owner (`agents.user_id == auth.sub`). Old avatar is replaced; storage cleanup happens server-side.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Avatar image. Validated for MIME type and size before upload."}}}}}},"responses":{"200":{"description":"Avatar uploaded; persistent URL returned","content":{"application/json":{"schema":{"type":"object","required":["avatar_url"],"properties":{"avatar_url":{"type":"string","format":"uri","description":"Public URL of the uploaded avatar (CDN-served).","example":"https://cdn.mnemom.ai/avatars/agents/mnm-7f3b9e2a/abc123.png"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/agents/{agent_id}/card-amendments":{"get":{"operationId":"listCardAmendments","summary":"List card amendment history","description":"Retrieve the history of all alignment card amendments for the specified agent. Card amendments are changes to the agent's alignment card that were triggered by reclassifications, policy changes, or manual edits.","tags":["Reclassification"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum number of amendments to return"},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Number of amendments to skip for pagination"}],"responses":{"200":{"description":"Card amendment history — a bare array of amendment records, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"amendment_id":{"type":"string"},"agent_id":{"type":"string"},"field_changed":{"type":"string"},"old_value":{},"new_value":{},"reason":{"type":"string"},"triggered_by":{"type":"string","enum":["reclassification","policy_change","manual"]},"created_at":{"type":"string","format":"date-time"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/checkpoints":{"get":{"operationId":"listCheckpoints","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"summary":"Paginated integrity checkpoints","tags":["Checkpoints"],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":1000}},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0}},{"name":"verdict","in":"query","schema":{"type":"string","enum":["clear","review_needed","boundary_violation"]}},{"name":"session_id","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated checkpoints","content":{"application/json":{"schema":{"type":"object","properties":{"checkpoints":{"type":"array","items":{"$ref":"#/components/schemas/Checkpoint"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/checkpoints/{checkpoint_id}":{"get":{"operationId":"getCheckpoint","security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"summary":"Get single checkpoint","tags":["Checkpoints"],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checkpoint details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Checkpoint"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/claim":{"post":{"operationId":"claimAgent","summary":"Claim an agent into an organization","description":"Binds an unclaimed (or legacy hash-claimed) agent to the authenticated caller and an organization. Requires authentication — the caller proves possession of the agent via `hash_proof`, and the agent's `org_id` is set to the resolved org (the authz + listing boundary, ADR-062). Supply `org_id` to claim into a specific org the caller is a member of (role floor: member); omit it to claim into the caller's personal org. Idempotent: re-claiming an agent the caller already owns returns 200 with the resolved org.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hash_proof"],"properties":{"hash_proof":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Agent possession proof: the full 64-hex SHA-256 digest of `${apiKey}|${agentName}` (or `${apiKey}` for an unnamed singleton agent)."},"org_id":{"type":"string","description":"Optional. The organization to claim the agent into (e.g. `org-...` or `pers-...`). The caller must be a member of this org (role floor: member). If omitted, the agent is claimed into the caller's personal org."}}}}}},"responses":{"200":{"description":"Agent claimed into the resolved organization","content":{"application/json":{"schema":{"type":"object","required":["claimed","agent_id","org_id","claimed_at"],"properties":{"claimed":{"type":"boolean"},"agent_id":{"type":"string"},"org_id":{"type":"string","description":"The organization the agent was claimed into (echoes the resolved org — the supplied `org_id`, or the caller's personal org when omitted)."},"claimed_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/agents/{agent_id}/compliance-export":{"get":{"operationId":"exportComplianceRecord","summary":"Export compliance record","description":"Export a comprehensive compliance record for the agent including all checkpoints, reclassifications, card amendments, and score history. Returns a structured document suitable for regulatory audits and compliance reviews.","tags":["Reclassification"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"format","in":"query","schema":{"type":"string","enum":["json","csv"],"default":"json"},"description":"Export format"},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Start of time range"},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"},"description":"End of time range"}],"responses":{"200":{"description":"Compliance export data","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"export_id":{"type":"string"},"generated_at":{"type":"string","format":"date-time"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"checkpoints":{"type":"array","items":{"type":"object"}},"reclassifications":{"type":"array","items":{"$ref":"#/components/schemas/ReclassificationResult"}},"card_amendments":{"type":"array","items":{"type":"object"}},"score_history":{"type":"array","items":{"type":"object"}}}}},"text/csv":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/conscience-values":{"get":{"operationId":"getConscienceValues","summary":"Get conscience values for agent","tags":["Enforcement"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Conscience values","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"conscience_values":{"type":"array","items":{"$ref":"#/components/schemas/ConscienceValue"}},"is_default":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"updateConscienceValues","summary":"Update conscience values","tags":["Enforcement"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["conscience_values"],"properties":{"conscience_values":{"type":"array","items":{"$ref":"#/components/schemas/ConscienceValue"}}}}}}},"responses":{"200":{"description":"Values updated","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"conscience_values":{"type":"array","items":{"$ref":"#/components/schemas/ConscienceValue"}},"updated":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"resetConscienceValues","summary":"Reset conscience values to defaults","tags":["Enforcement"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Values reset to defaults","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"reset_to_defaults":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/deletion-status":{"get":{"operationId":"getDeletionStatus","summary":"Poll the status of a pending agent deletion","description":"Returns the most-recent `deletion_request` row for the agent. Status progresses: `tombstoned` → `phase_N_complete` → `kv_cleared` → `pseudonymized` → `complete` (or `failed` at any phase). Used to track the async GDPR Art. 17 cascade kicked off by `DELETE /agents/{agent_id}`. See ADR-021.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Deletion request status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletionRequestStatus"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/drift/aip":{"get":{"operationId":"getAipDrift","security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"summary":"Get AIP drift alerts","tags":["Drift"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"AIP drift alerts","content":{"application/json":{"schema":{"type":"object","properties":{"alerts":{"type":"array","items":{"$ref":"#/components/schemas/DriftAlert"}},"agent_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/exemptions":{"get":{"operationId":"listAgentExemptions","summary":"List active exemptions for an agent","description":"Exemptions relax an org-level template floor for a single agent (replaces the old coarse `org_card_exempt` boolean). Only non-expired, status=active entries are returned. Any org member (owner/admin/member/viewer/auditor) may read. See ADR-008.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Active exemptions.","content":{"application/json":{"schema":{"type":"object","required":["agent_id","exemptions","total"],"properties":{"agent_id":{"type":"string"},"exemptions":{"type":"array","items":{"$ref":"#/components/schemas/AgentExemption"}},"total":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"grantAgentExemption","summary":"Grant an exemption to an agent","description":"Requires org `owner` or `admin` of the agent's org. Personal agents (no org) cannot have exemptions and receive 400. Reason is required (20–500 chars). `expires_at` defaults to +90 days if omitted; pass `null` for permanent (opt-in only). Requires `Idempotency-Key`. Emits a `agent.exemption.granted` webhook and writes a governance audit row. Triggers a recompose of the agent's canonical cards. See ADR-008.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["exempt_section","reason"],"properties":{"exempt_section":{"type":"string","enum":["autonomy.forbidden_actions","enforcement.forbidden_tools","autonomy.max_autonomous_value"],"description":"Template section this exemption relaxes."},"exempt_patterns":{"type":["array","null"],"items":{"type":"string","maxLength":256},"maxItems":50,"description":"Specific patterns to exempt within the section. `null` exempts the entire section."},"reason":{"type":"string","minLength":20,"maxLength":500,"description":"Business justification for the exemption (required, ≥20 chars)."},"expires_at":{"type":["string","null"],"format":"date-time","description":"Expiry. Omit for default +90 days. `null` = permanent (explicit opt-in)."}}}}}},"responses":{"201":{"description":"Exemption granted; canonical cards recomposed.","content":{"application/json":{"schema":{"type":"object","required":["exemption","agent_id","recomposed"],"properties":{"exemption":{"$ref":"#/components/schemas/AgentExemption"},"agent_id":{"type":"string"},"recomposed":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/exemptions/{exemption_id}":{"delete":{"operationId":"revokeAgentExemption","summary":"Revoke an active exemption","description":"Hard-deletes the exemption row (the governance audit log is the permanent record). Requires org `owner`/`admin`. Idempotency-Key required. Emits `agent.exemption.revoked` and recomposes the agent. See ADR-008.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"exemption_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Exemption revoked; agent recomposed.","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"},"exemption_id":{"type":"string"},"recomposed":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/governance/signals":{"get":{"operationId":"listAgentGovernanceSignals","summary":"List governance signals affecting a specific agent","description":"Returns governance signals whose `agent_ids` array contains the given agent. Operator dashboard's per-agent slice. Any org member of the agent's org may read.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"source","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSource"},"description":"Filter by source detector."},{"name":"severity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"description":"Filter by severity."},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalStatus"},"description":"Filter by workflow status."},{"name":"pattern_type","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by pattern_type within the source's taxonomy."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Governance signals listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignalsListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/integrity/aip":{"get":{"operationId":"getAipIntegrityScore","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"summary":"AIP integrity score","tags":["Integrity"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"AIP integrity score","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"total_checks":{"type":"integer"},"clear_count":{"type":"integer"},"review_count":{"type":"integer"},"violation_count":{"type":"integer"},"integrity_ratio":{"type":"number"},"latest_verdict":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/link":{"post":{"operationId":"linkAgent","summary":"Link claimed agent to authenticated user","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hash_proof"],"properties":{"hash_proof":{"type":"string"}}}}}},"responses":{"200":{"description":"Agent linked","content":{"application/json":{"schema":{"type":"object","properties":{"linked":{"type":"boolean"},"agent_id":{"type":"string"},"user_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/merkle-root":{"get":{"operationId":"getAgentMerkleRoot","summary":"Get Merkle root","description":"Get the current Merkle tree root for an agent. The root is a SHA-256 hash that commits to the complete set of integrity checkpoints for this agent. Public endpoint, no authentication required.","tags":["Verification"],"security":[{}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"},"description":"The agent ID"}],"responses":{"200":{"description":"Merkle tree root and metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleRootResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/agents/{agent_id}/notifications/webhook":{"post":{"operationId":"registerCardChangedWebhook","summary":"Register a webhook subscription for an agent's card changes.","description":"Creates (or updates) a webhook subscription. The HMAC-SHA256 shared secret is returned **once** in the response — store it; subsequent verifications use the stored hash on Mnemom's side. Idempotent on (agent_id, consumer_id, webhook_url). cards-as-primitive Phase 5 C1.","tags":["Notifications"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhook_url"],"properties":{"webhook_url":{"type":"string","format":"uri"},"consumer_id":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"Subscription created or updated.","content":{"application/json":{"schema":{"type":"object","required":["subscription_id","webhook_url","secret","expires_at"],"properties":{"subscription_id":{"type":"string"},"webhook_url":{"type":"string","format":"uri"},"secret":{"type":"string","description":"Shown exactly once; store it server-side."},"expires_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/agents/{agent_id}/notifications/{subscription_id}":{"delete":{"operationId":"deleteCardChangedSubscription","summary":"Unsubscribe from card-change notifications.","description":"Removes the subscription row. Idempotent — repeated calls return 404 after the first. cards-as-primitive Phase 5 C1.","tags":["Notifications"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Subscription removed."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/protection-card":{"get":{"operationId":"getProtectionCardLegacy","summary":"DEPRECATED — use GET /v1/protection/agent/{agent_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/agent/{agent_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putProtectionCardLegacy","summary":"DEPRECATED — use PUT /v1/protection/agent/{agent_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/agent/{agent_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/protection-card/preview-compose":{"post":{"operationId":"postProtectionCardPreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/protection/agent/{agent_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/agent/{agent_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Agents"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reclassifications":{"get":{"operationId":"listReclassifications","summary":"List reclassification history","description":"Retrieve the history of all checkpoint reclassifications for the specified agent. Each entry includes the original and reclassified type, reason, and score impact.","tags":["Reclassification"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum number of records to return"},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Number of records to skip for pagination"}],"responses":{"200":{"description":"Reclassification history — a bare array of reclassification records, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReclassificationResult"}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reclassify":{"post":{"operationId":"reclassifyViolation","summary":"Reclassify a checkpoint violation","description":"Reclassify a previously recorded AIP checkpoint violation. This allows operators to correct false positives or adjust severity after manual review. The reclassification is recorded in the audit trail and can trigger a score recomputation.","tags":["Reclassification"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReclassificationRequest"}}}},"responses":{"200":{"description":"Reclassification result with score impact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReclassificationResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/rekey":{"post":{"operationId":"rekeyAgent","summary":"Re-bind agent to a new API key","description":"Updates the agent's key binding to a new provider API key hash. The agent ID, traces, alignment card, integrity score, and trust edges are fully preserved.\n\n**Security model**: Your API key is hashed on your device (SHA-256) before transmission — the raw key is never sent to Mnemom servers.\n\n**Named agents**: If this agent was registered with a name (via `x-mnemom-agent`), hash the new key as `SHA256(newKey + '|' + agentName)` before submitting.\n\n**Conflict**: If the new key was already used and auto-created a new agent, the endpoint returns `409` with the conflicting agent ID.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["new_key_hash"],"properties":{"new_key_hash":{"type":"string","pattern":"^[0-9a-f]{16}$","description":"First 16 hex characters of SHA256(newApiKey) for unnamed agents, or SHA256(newApiKey + '|' + agentName) for named agents. Compute client-side — do not transmit the raw key.","example":"a3f8c1d9e7b2045f"},"key_prefix":{"type":"string","description":"First 16 characters of the new provider API key. Stored for display — not sensitive. If provided, returned in the response.","example":"sk-ant-api03-xx"}}}}}},"responses":{"200":{"description":"Agent successfully re-bound to the new key.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"agent_id":{"type":"string","example":"smolt-a1b2c3d4"},"rekeyed_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/resolutions":{"get":{"operationId":"listResolutions","security":[],"summary":"List resolutions for an agent","tags":["Enforcement"],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"List of resolutions.","content":{"application/json":{"schema":{"type":"object","properties":{"resolutions":{"type":"array","items":{"type":"object"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/resolve":{"post":{"operationId":"resolveViolation","summary":"Resolve a concern or violation","tags":["Enforcement"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_type","target_id","resolution_type"],"properties":{"target_type":{"type":"string","enum":["checkpoint","trace"]},"target_id":{"type":"string"},"resolution_type":{"type":"string","enum":["acknowledged","allow_action","add_value"]},"action_name":{"type":"string","description":"Required when resolution_type is allow_action"},"value_name":{"type":"string","description":"Required when resolution_type is add_value"}}}}}},"responses":{"200":{"description":"Resolution created","content":{"application/json":{"schema":{"type":"object","properties":{"resolution_id":{"type":"string"},"resolution_type":{"type":"string"},"resolved_by":{"type":"string"},"card_modified":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/restore":{"post":{"operationId":"restoreAgent","summary":"Restore a tombstoned agent","description":"Resurrects a tombstoned agent by clearing `deleted_at` — the counterpart to [POST /v1/agents/{agent_id}/tombstone](/api-reference/endpoint/post-agents-agent-id-tombstone). Lets an org owner/admin override a tombstone (e.g. a key agent a dev removed), or a creator undo their own. Authorized for an org owner/admin OR the agent's creator. Returns 409 for agents that went through GDPR erasure (`DELETE`), whose data was permanently cascaded away and cannot be restored.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Agent restored (or already active)","content":{"application/json":{"schema":{"type":"object","required":["id","tombstoned"],"properties":{"id":{"type":"string"},"deleted_at":{"type":"string","format":"date-time","nullable":true},"tombstoned":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Agent was permanently erased (GDPR Art.17) and cannot be restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reverify":{"post":{"operationId":"reverifyTraces","summary":"Re-verify AAP traces against updated card","tags":["Checkpoints"],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":40,"maximum":40}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Re-verification results","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"card_id":{"type":"string"},"total_traces_in_batch":{"type":"integer"},"offset":{"type":"integer"},"limit":{"type":"integer"},"reverified":{"type":"integer"},"still_violating":{"type":"integer"},"now_clean":{"type":"integer"},"errors":{"type":["array","null"],"items":{"type":"string"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reverify/aip":{"post":{"operationId":"reverifyAipCheckpoints","summary":"Re-evaluate AIP checkpoints against updated card","tags":["Checkpoints"],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Re-evaluation results","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"card_id":{"type":"string"},"total_in_batch":{"type":"integer"},"offset":{"type":"integer"},"limit":{"type":"integer"},"re_evaluated":{"type":"integer"},"resolved_to_clear":{"type":"integer"},"kept_non_clear":{"type":"integer"},"results":{"type":"array","items":{"type":"object"}},"errors":{"type":["array","null"],"items":{"type":"string"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reviews":{"get":{"operationId":"listReviews","summary":"List disagreement reviews for an agent","description":"Lists review records created when an action was disagreed-with enough to require human adjudication. Filter by `status` (`pending`, `review`, `applied`, `dismissed`). Reviews propose a card amendment that can be accepted or rejected via the apply/dismiss endpoints.","tags":["Enforcement"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","review","applied","dismissed"]}}],"responses":{"200":{"description":"Reviews, newest first.","content":{"application/json":{"schema":{"type":"object","required":["reviews"],"properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/DisagreementReview"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reviews/{review_id}":{"get":{"operationId":"getReview","summary":"Get a single review","tags":["Enforcement"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"review_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Review detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisagreementReview"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reviews/{review_id}/apply":{"post":{"operationId":"applyReview","summary":"Apply a review's proposed amendment","description":"Applies the review's `proposed_amendment.action` to the agent's active alignment card by appending it to `autonomy_envelope.bounded_actions`. Updates the review status to `applied`. Only reviews in `pending` or `review` status may be applied.","tags":["Enforcement"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"review_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Amendment applied.","content":{"application/json":{"schema":{"type":"object","required":["review_id","status","card_modified"],"properties":{"review_id":{"type":"string"},"status":{"type":"string","enum":["applied"]},"resolved_by":{"type":"string"},"card_modified":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/reviews/{review_id}/dismiss":{"post":{"operationId":"dismissReview","summary":"Dismiss a review without applying","tags":["Enforcement"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"review_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Review dismissed.","content":{"application/json":{"schema":{"type":"object","required":["review_id","status"],"properties":{"review_id":{"type":"string"},"status":{"type":"string","enum":["dismissed"]},"resolved_by":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/settings":{"get":{"operationId":"getAgentSettings","summary":"Get agent observability + enforcement settings","description":"Returns per-agent AAP/AIP toggles, proof settings, nudge strategy, DDR (drift-detection response) mode, and analyze-output opt-in.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Current settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettings"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAgentSettings","summary":"Update agent settings","description":"Partial update — include only the fields to change. Enabling `proof_enabled` requires the `zk_proofs` feature flag on the agent's plan (403 otherwise). Enabling any `ddr_mode` other than `off` requires the `reconciliation` feature flag.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"aap_enabled":{"type":"boolean"},"aip_enabled":{"type":"boolean"},"proof_enabled":{"type":"boolean","description":"Requires `zk_proofs` feature flag."},"proof_rate":{"type":"integer","minimum":0,"maximum":100,"description":"Percentage of checkpoints to prove (0–100)."},"nudge_strategy":{"type":"string","enum":["always","sampling","threshold","off"]},"ddr_mode":{"type":"string","enum":["off","flag","auto-suggest","auto-apply"],"description":"Non-`off` values require `reconciliation` feature flag."},"analyze_output":{"type":"boolean"}},"minProperties":1}}}},"responses":{"200":{"description":"Settings updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/AgentSettings"},{"type":"object","properties":{"updated":{"type":"boolean"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/sideband-advisories":{"get":{"operationId":"listAgentSidebandAdvisories","summary":"List historical sideband advisories for an agent (legacy)","description":"Pre-cutover sideband.* rows still present in pending_advisories. Sunsetting after the ADR-048 D+30 cleanup; consume governance_signals instead for forward-going observations.","tags":["Sideband"],"deprecated":true,"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivered","consumed","expired"]}}],"responses":{"200":{"description":"Sideband advisories listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidebandAdvisoryListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/state":{"get":{"operationId":"getAgentState","summary":"Runtime composite — alignment + protection + capabilities in one call","description":"Returns the agent's complete operational envelope as a single response: composed alignment card, composed protection card, and a `capabilities[]` array of full tool definitions (from the W1.1 tools registry — `{name, class, domain, description, schema, source_connector, grant_provenance}`, NOT bare name strings). SDK consumers (first-party SDKs, future Tier-1 customers, OSC instances) call this instead of assembling the envelope client-side. ETag-driven 304 short-circuit; `Cache-Control: private, max-age=60`. cards-as-primitive Phase 4 W2.3.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Runtime state envelope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the combined alignment + protection + capabilities hash.","schema":{"type":"string"}},"X-Card-Version":{"description":"`max(alignment.version, protection.version)`.","schema":{"type":"integer","minimum":1}},"Cache-Control":{"description":"`private, max-age=60`.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Always `agent-state/v1`.","schema":{"type":"string","enum":["agent-state/v1"]}}},"content":{"application/json":{"schema":{"type":"object","required":["alignment","protection","capabilities","content_hash","version","composed_at","expires_at"],"properties":{"alignment":{"$ref":"#/components/schemas/UnifiedAlignmentCard"},"protection":{"$ref":"#/components/schemas/UnifiedProtectionCard"},"capabilities":{"type":"array","items":{"type":"object","required":["name","class","domain","grant_provenance"],"properties":{"name":{"type":"string"},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string"},"domain":{"type":"string"},"schema":{"type":["object","null"]},"source_connector":{"type":["string","null"]},"grant_provenance":{"type":"object","required":["layer"],"properties":{"layer":{"type":"string","enum":["platform","org","team","agent","derived"]},"layer_id":{"type":"string"},"kind":{"type":"string"}}}}}},"content_hash":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"version":{"type":"integer","minimum":1},"composed_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current combined ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/stream":{"get":{"operationId":"streamAgentCardChanges","summary":"Server-Sent Events stream of canonical card changes.","description":"Returns a `text/event-stream` connection. Each new `card_attestations` row for the agent emits a `card_changed` SSE frame. Per-connection cap of 5 minutes; clients reconnect with `Last-Event-ID` (the log_index of the last seen frame) to resume. cards-as-primitive Phase 5 C1.","tags":["Notifications"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","required":false,"schema":{"type":"integer","minimum":0},"description":"log_index cursor; omit to start at the current head."},{"name":"Last-Event-ID","in":"header","required":false,"schema":{"type":"integer","minimum":0},"description":"SSE reconnect convention; takes precedence over `since` when both are present."}],"responses":{"200":{"description":"SSE stream (`text/event-stream`). Each frame is `event: card_changed\\nid: <log_index>\\ndata: {...}\\n\\n`.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/timeline":{"get":{"operationId":"getTimeline","security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"summary":"Unified dual-rail AIP + AAP timeline","tags":["Checkpoints"],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"Timeline events","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"events":{"type":"array","items":{"type":"object"}},"total":{"type":"integer"},"summary":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/tombstone":{"post":{"operationId":"tombstoneAgent","summary":"Tombstone (reversible soft-delete) an agent","description":"Soft-deletes an agent: sets `deleted_at` so it disappears from the org fleet/dashboard while KEEPING all data (traces, checkpoints, proofs) for audit. Reversible via [POST /v1/agents/{agent_id}/restore](/api-reference/endpoint/post-agents-agent-id-restore). Distinct from `DELETE /v1/agents/{agent_id}`, which is the irreversible GDPR Art.17 erasure cascade. Authorized for an org owner/admin of the agent's org OR the agent's own creator. Idempotent: tombstoning an already-tombstoned agent returns 200.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Agent tombstoned (or already tombstoned)","content":{"application/json":{"schema":{"type":"object","required":["id","tombstoned"],"properties":{"id":{"type":"string"},"deleted_at":{"type":"string","format":"date-time","nullable":true},"tombstoned":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/traces":{"get":{"operationId":"getAgentTraces","summary":"Get traces for agent (AAP query alias)","tags":["Traces"],"security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"minimum":1,"maximum":1000}},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0}}],"responses":{"200":{"description":"List of traces","content":{"application/json":{"schema":{"type":"object","properties":{"traces":{"type":"array","items":{"$ref":"#/components/schemas/APTrace"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/trust-edges":{"get":{"operationId":"listTrustEdges","summary":"List trust edges from or to an agent","description":"Returns trust-relationship edges that the agent participates in. `direction=outbound` returns edges originating from this agent; `inbound` returns edges pointing at this agent; `both` (default) deduplicates.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["outbound","inbound","both"],"default":"both"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Edges.","content":{"application/json":{"schema":{"type":"object","required":["agent_id","direction","edges","count"],"properties":{"agent_id":{"type":"string"},"direction":{"type":"string"},"edges":{"type":"array","items":{"$ref":"#/components/schemas/TrustEdge"}},"count":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createTrustEdge","summary":"Create a trust edge from this agent to another","description":"Caller must own the `from` agent (or be an admin). `weight` is clamped to [0, 1] with default 0.5. Returns 409 if an edge already exists in the same direction.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to_agent"],"properties":{"to_agent":{"type":"string"},"weight":{"type":"number","minimum":0,"maximum":1,"default":0.5},"reason":{"type":"string","default":"manual"}}}}}},"responses":{"201":{"description":"Edge created.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/TrustEdge"},{"type":"object","properties":{"created":{"type":"boolean"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/trust-edges/{edge_id}":{"delete":{"operationId":"deleteTrustEdge","summary":"Delete a trust edge","description":"Caller must own the source agent (`from_agent`) or be an admin. Either source or target agent id may appear in the path.","tags":["Agents"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"edge_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/verify-binding":{"post":{"operationId":"verifyAgentBinding","summary":"Verify key binding","description":"Checks whether a given API key hash matches the key currently bound to this agent. The raw key is hashed client-side — only the hash is transmitted.\n\n**Named agents**: hash as `SHA256(key + '|' + agentName)` before submitting.\n\n**Public anti-impersonation check (anon-allowed).** A relying party that holds an agent's id + key can confirm the binding without being a member of the agent's org. Anonymous / cross-org callers receive **only** `bound` (the boolean leaks nothing they didn't already supply). `key_prefix` is returned **only** to callers who are members of the agent's org.","tags":["Agents"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key_hash"],"properties":{"key_hash":{"type":"string","pattern":"^[0-9a-f]{16}$","description":"First 16 hex chars of SHA256(apiKey) or SHA256(apiKey + '|' + agentName) for named agents.","example":"a3f8c1d9e7b2045f"}}}}}},"responses":{"200":{"description":"Binding check result.","content":{"application/json":{"schema":{"type":"object","properties":{"bound":{"type":"boolean","description":"True if the submitted hash matches the registered key."},"key_prefix":{"type":["string","null"],"description":"First 16 chars of the registered key (or null if not yet captured). Returned ONLY to callers who are members of the agent's org; omitted for anonymous / cross-org callers.","example":"sk-ant-api03-xx"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/agents/{agent_id}/zk-proof-count":{"get":{"operationId":"getZkProofCount","summary":"Count completed ZK proofs for an agent","description":"Public endpoint. Returns the count of `verdict_proofs` rows in `completed` state across all of the agent's checkpoints. Intended for embeddable verification widgets.","tags":["Verification"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Count of completed ZK proofs.","content":{"application/json":{"schema":{"type":"object","required":["count"],"properties":{"count":{"type":"integer","minimum":0}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/aip/webhooks":{"post":{"operationId":"registerAipWebhook","summary":"Register AIP webhook","tags":["Webhooks"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id","callback_url","secret","events"],"properties":{"agent_id":{"type":"string"},"callback_url":{"type":"string","format":"uri"},"secret":{"type":"string"},"events":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Webhook registered","content":{"application/json":{"schema":{"type":"object","properties":{"registration_id":{"type":"string"},"agent_id":{"type":"string"},"callback_url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/aip/webhooks/{registration_id}":{"delete":{"operationId":"deleteAipWebhook","summary":"Remove AIP webhook","tags":["Webhooks"],"parameters":[{"name":"registration_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Webhook deleted"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}":{"get":{"operationId":"getAlignmentByAgent","summary":"Get this layer's alignment manifest","description":"Returns the agent-scope alignment spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific (the four-scope `{teams[], agent}` body is the agent variant consumed by the dashboard editor). ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the four-scope envelope `{platform, org, teams[], agent, composed, composed_stale, my_role}` (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Alignment manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAlignmentByAgent","summary":"Publish or replace the alignment manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedAlignmentCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Honors an optional `If-Match` for optimistic concurrency (stale → 412). Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."},{"name":"If-Match","in":"header","required":false,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optional optimistic-concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape) to make the write conditional: a stale ETag returns `412 Precondition Failed`, a malformed one `400`. Omit it to publish unconditionally."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Composed canonical card after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/audit":{"put":{"operationId":"putAlignmentAuditByAgent","summary":"Replace audit settings","description":"PUT replaces the entire `audit` block (trace format, retention window, query endpoint). The current spec at the agent scope is read; the new `audit` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAuditByAgent","summary":"Update audit settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `audit` block (trace format, retention window, query endpoint). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/autonomy":{"put":{"operationId":"putAlignmentAutonomyByAgent","summary":"Replace autonomy settings","description":"PUT replaces the entire `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). The current spec at the agent scope is read; the new `autonomy` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAutonomyByAgent","summary":"Update autonomy settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/capabilities":{"put":{"operationId":"putAlignmentCapabilitiesByAgent","summary":"Replace capabilities settings","description":"PUT replaces the entire `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). The current spec at the agent scope is read; the new `capabilities` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"application/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"text/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentCapabilitiesByAgent","summary":"Update capabilities settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/conscience":{"put":{"operationId":"putAlignmentConscienceByAgent","summary":"Replace conscience settings","description":"PUT replaces the entire `conscience` block (augment-vs-replace + the conscience values list). The current spec at the agent scope is read; the new `conscience` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"application/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"text/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentConscienceByAgent","summary":"Update conscience settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `conscience` block (augment-vs-replace + the conscience values list). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/effective":{"get":{"operationId":"getAlignmentEffectiveByAgent","summary":"Get effective (composed) alignment with provenance","description":"Returns the composed canonical alignment card (platform → org → team → agent cascade applied) with `_composition.field_provenance` always populated. The provenance map carries per-key `{layer, layer_id?, kind?}` entries showing which authoring scope contributed each leaf. Caller-aware redaction: layer labels (`platform` / `org` / `team` / `agent` / `derived`) are always visible; `layer_id` is only revealed to callers who can read that scope. cards-as-primitive Phase 4 W2.2.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Composed effective card with per-key field_provenance.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the composed body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/enforcement":{"put":{"operationId":"putAlignmentEnforcementByAgent","summary":"Replace enforcement settings","description":"PUT replaces the entire `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). The current spec at the agent scope is read; the new `enforcement` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"application/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"text/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentEnforcementByAgent","summary":"Update enforcement settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/explain":{"post":{"operationId":"explainAlignmentByAgent","summary":"Explain policy evaluation for the alignment card","description":"Calls the policy engine in dry-run mode against the agent's composed alignment card and returns a structured trace + care-framed remediations. Optional `enrich: true` runs an LLM pass over the structured remediations to produce long-form prose; off by default. Read-style POST — no state mutation, no Idempotency-Key.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"turn_id":{"type":"string","description":"Optional — bind to a specific gateway turn."},"request_snippet":{"type":"object","description":"Optional — hypothetical tool call to explain.","properties":{"tool_name":{"type":"string"},"tool_args":{"type":"object","additionalProperties":true}}},"enrich":{"type":"boolean","description":"When true, runs an LLM pass over the structured remediations. Off by default."}}}}}},"responses":{"200":{"description":"Policy evaluation trace + remediations.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","reasoning","suggested_remediations","enriched"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["alignment"]},"trace":{"type":"object","description":"EvaluationResult from @mnemom/policy-engine. Null for protection in V1.","nullable":true},"reasoning":{"type":"string","description":"Care-framed prose summary."},"suggested_remediations":{"type":"array","items":{"type":"object","required":["for","index","remediation"],"properties":{"for":{"type":"string","enum":["violation","warning","card_gap"]},"index":{"type":"integer"},"remediation":{"type":"string"},"method":{"type":"string"},"url":{"type":"string"}}}},"enriched":{"type":"boolean","description":"True when the LLM enrichment ran."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/modes":{"put":{"operationId":"putAlignmentModesByAgent","summary":"Replace modes settings","description":"PUT replaces the entire `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). The current spec at the agent scope is read; the new `modes` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"application/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"text/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentModesByAgent","summary":"Update modes settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/preview-compose":{"post":{"operationId":"previewComposeAlignmentByAgent","summary":"Preview composed alignment (dry run)","description":"Composes the cascade against a hypothetical body at the agent layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedAlignmentCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/principal":{"put":{"operationId":"putAlignmentPrincipalByAgent","summary":"Replace principal settings","description":"PUT replaces the entire `principal` block (who-the-agent-is identity block). The current spec at the agent scope is read; the new `principal` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"application/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"text/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentPrincipalByAgent","summary":"Update principal settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `principal` block (who-the-agent-is identity block). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/simulate":{"post":{"operationId":"simulateAlignmentByAgent","summary":"Simulate gateway evaluation against the alignment card","description":"Pure-sync simulation: calls @mnemom/policy-engine twice (once with `context: \"gateway\"`, once with `context: \"observer\"`) using `dryRun: true` against the agent's current composed alignment card. Returns `{allowed, conditions, suggestions, gateway_decision, observer_assessment}`. Never crosses worker boundaries — no real gateway / observer state change.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"candidate_input":{"type":"object","description":"Hypothetical conversation snippet.","properties":{"messages":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"candidate_tool_call":{"type":"object","description":"Hypothetical tool invocation. Synthesized into an assistant message with a toolUses block when `candidate_input.messages` is absent.","properties":{"tool_name":{"type":"string"},"tool_args":{"type":"object","additionalProperties":true}}}}}}}},"responses":{"200":{"description":"Simulation result.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","allowed","conditions","suggestions","gateway_decision","observer_assessment","evaluated_at"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["alignment"]},"allowed":{"type":"string","enum":["true","false","conditional"]},"conditions":{"type":"array","items":{"type":"string"}},"suggestions":{"type":"array","items":{"type":"string"}},"gateway_decision":{"type":"object","properties":{"verdict":{"type":"string","enum":["pass","warn","fail"]},"violations":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}},"missing_receipts":{"type":"array","items":{"type":"string"}}}},"observer_assessment":{"type":"object","properties":{"verdict":{"type":"string","enum":["pass","warn","fail"]},"violations":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}}}},"evaluated_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/agent/{agent_id}/values":{"put":{"operationId":"putAlignmentValuesByAgent","summary":"Replace values settings","description":"PUT replaces the entire `values` block (declared catalog entries + definitions / hierarchy / conflicts). The current spec at the agent scope is read; the new `values` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"application/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"text/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentValuesByAgent","summary":"Update values settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `values` block (declared catalog entries + definitions / hierarchy / conflicts). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}":{"get":{"operationId":"getAlignmentByOrg","summary":"Get this layer's alignment manifest","description":"Returns the org-scope alignment spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Alignment manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAlignmentByOrg","summary":"Publish or replace the alignment manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedAlignmentCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Stored template wrapper after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteAlignmentByOrg","summary":"Clear this alignment layer","description":"Removes the org-scope alignment authoring; downstream scopes fall through to the next layer up in the cascade.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Cleared. Returns the deletion confirmation (`deleted: true`, `template: null`) and the count of agents flagged for recompose; the next read returns the composed view without this layer. (The handler returns this 200-with-body, not 204.)","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/audit":{"put":{"operationId":"putAlignmentAuditByOrg","summary":"Replace audit settings","description":"PUT replaces the entire `audit` block (trace format, retention window, query endpoint). The current spec at the org scope is read; the new `audit` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAuditByOrg","summary":"Update audit settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `audit` block (trace format, retention window, query endpoint). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/autonomy":{"put":{"operationId":"putAlignmentAutonomyByOrg","summary":"Replace autonomy settings","description":"PUT replaces the entire `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). The current spec at the org scope is read; the new `autonomy` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAutonomyByOrg","summary":"Update autonomy settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/capabilities":{"put":{"operationId":"putAlignmentCapabilitiesByOrg","summary":"Replace capabilities settings","description":"PUT replaces the entire `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). The current spec at the org scope is read; the new `capabilities` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"application/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"text/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentCapabilitiesByOrg","summary":"Update capabilities settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/conscience":{"put":{"operationId":"putAlignmentConscienceByOrg","summary":"Replace conscience settings","description":"PUT replaces the entire `conscience` block (augment-vs-replace + the conscience values list). The current spec at the org scope is read; the new `conscience` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"application/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"text/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentConscienceByOrg","summary":"Update conscience settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `conscience` block (augment-vs-replace + the conscience values list). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/enforcement":{"put":{"operationId":"putAlignmentEnforcementByOrg","summary":"Replace enforcement settings","description":"PUT replaces the entire `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). The current spec at the org scope is read; the new `enforcement` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"application/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"text/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentEnforcementByOrg","summary":"Update enforcement settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/modes":{"put":{"operationId":"putAlignmentModesByOrg","summary":"Replace modes settings","description":"PUT replaces the entire `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). The current spec at the org scope is read; the new `modes` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"application/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"text/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentModesByOrg","summary":"Update modes settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/preview-compose":{"post":{"operationId":"previewComposeAlignmentByOrg","summary":"Preview composed alignment (dry run)","description":"Composes the cascade against a hypothetical body at the org layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedAlignmentCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/principal":{"put":{"operationId":"putAlignmentPrincipalByOrg","summary":"Replace principal settings","description":"PUT replaces the entire `principal` block (who-the-agent-is identity block). The current spec at the org scope is read; the new `principal` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"application/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"text/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentPrincipalByOrg","summary":"Update principal settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `principal` block (who-the-agent-is identity block). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/org/{org_id}/values":{"put":{"operationId":"putAlignmentValuesByOrg","summary":"Replace values settings","description":"PUT replaces the entire `values` block (declared catalog entries + definitions / hierarchy / conflicts). The current spec at the org scope is read; the new `values` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"application/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"text/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentValuesByOrg","summary":"Update values settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `values` block (declared catalog entries + definitions / hierarchy / conflicts). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}":{"get":{"operationId":"getAlignmentByPlatform","summary":"Get this layer's alignment manifest","description":"Returns the platform-scope alignment spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Alignment manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAlignmentByPlatform","summary":"Publish or replace the alignment manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedAlignmentCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Composed canonical card after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/audit":{"put":{"operationId":"putAlignmentAuditByPlatform","summary":"Replace audit settings","description":"PUT replaces the entire `audit` block (trace format, retention window, query endpoint). The current spec at the platform scope is read; the new `audit` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAuditByPlatform","summary":"Update audit settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `audit` block (trace format, retention window, query endpoint). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/autonomy":{"put":{"operationId":"putAlignmentAutonomyByPlatform","summary":"Replace autonomy settings","description":"PUT replaces the entire `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). The current spec at the platform scope is read; the new `autonomy` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAutonomyByPlatform","summary":"Update autonomy settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/capabilities":{"put":{"operationId":"putAlignmentCapabilitiesByPlatform","summary":"Replace capabilities settings","description":"PUT replaces the entire `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). The current spec at the platform scope is read; the new `capabilities` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"application/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"text/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentCapabilitiesByPlatform","summary":"Update capabilities settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/conscience":{"put":{"operationId":"putAlignmentConscienceByPlatform","summary":"Replace conscience settings","description":"PUT replaces the entire `conscience` block (augment-vs-replace + the conscience values list). The current spec at the platform scope is read; the new `conscience` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"application/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"text/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentConscienceByPlatform","summary":"Update conscience settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `conscience` block (augment-vs-replace + the conscience values list). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/enforcement":{"put":{"operationId":"putAlignmentEnforcementByPlatform","summary":"Replace enforcement settings","description":"PUT replaces the entire `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). The current spec at the platform scope is read; the new `enforcement` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"application/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"text/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentEnforcementByPlatform","summary":"Update enforcement settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/modes":{"put":{"operationId":"putAlignmentModesByPlatform","summary":"Replace modes settings","description":"PUT replaces the entire `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). The current spec at the platform scope is read; the new `modes` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"application/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"text/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentModesByPlatform","summary":"Update modes settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/preview-compose":{"post":{"operationId":"previewComposeAlignmentByPlatform","summary":"Preview composed alignment (dry run)","description":"Composes the cascade against a hypothetical body at the platform layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedAlignmentCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/principal":{"put":{"operationId":"putAlignmentPrincipalByPlatform","summary":"Replace principal settings","description":"PUT replaces the entire `principal` block (who-the-agent-is identity block). The current spec at the platform scope is read; the new `principal` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"application/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"text/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentPrincipalByPlatform","summary":"Update principal settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `principal` block (who-the-agent-is identity block). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/platform/{scope_id}/values":{"put":{"operationId":"putAlignmentValuesByPlatform","summary":"Replace values settings","description":"PUT replaces the entire `values` block (declared catalog entries + definitions / hierarchy / conflicts). The current spec at the platform scope is read; the new `values` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"application/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"text/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentValuesByPlatform","summary":"Update values settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `values` block (declared catalog entries + definitions / hierarchy / conflicts). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/scaffold":{"post":{"operationId":"scaffoldAlignment","summary":"Scaffold alignment from a description","description":"Calls an LLM (Claude Haiku by default; opt into Sonnet via `model: \"sonnet\"`) with the catalog and tools-registry context, returns a YAML manifest scaffold + care-framed reasoning prose + suggested catalog entries + coverage gaps. Never auto-commits — the caller reviews and edits before PUT. Cached by (model + scope + description + hints) hash; 24-hour TTL.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["description"],"properties":{"description":{"type":"string","minLength":20,"maxLength":2000,"description":"Free-form description of the agent / scope. Untrusted input — the system prompt instructs the model not to follow embedded directives."},"scope":{"type":"string","enum":["platform","org","team","agent"],"description":"Hint to the model about which scope the manifest will live at."},"hints":{"type":"object","description":"Free-form key/value hints (industry, risk_appetite, existing_tools, etc).","additionalProperties":true},"model":{"type":"string","enum":["haiku","sonnet"],"description":"Claude model to invoke. `haiku` is the default; `sonnet` for prose-heavy reasoning."}}}}}},"responses":{"200":{"description":"Scaffold ready. Editable; never auto-commits.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","manifest","reasoning","cached","model"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["alignment"]},"manifest":{"type":"string","description":"YAML body of the scaffolded manifest."},"reasoning":{"type":"string","description":"Care-framed prose explanation."},"suggested_catalog_entries":{"type":"array","items":{"type":"string"}},"coverage_gaps":{"type":"array","items":{"type":"object","properties":{"axis":{"type":"string"},"note":{"type":"string"}},"required":["note"]}},"parse_warnings":{"type":"array","items":{"type":"string"}},"cached":{"type":"boolean","description":"True when the response was served from the description-hash cache."},"model":{"type":"string","description":"Claude model id used for the call."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"},"504":{"$ref":"#/components/responses/BadGateway"}}}},"/alignment/team/{team_id}":{"get":{"operationId":"getAlignmentByTeam","summary":"Get this layer's alignment manifest","description":"Returns the team-scope alignment spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Alignment manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putAlignmentByTeam","summary":"Publish or replace the alignment manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedAlignmentCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Stored template wrapper after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteAlignmentByTeam","summary":"Clear this alignment layer","description":"Removes the team-scope alignment authoring; downstream scopes fall through to the next layer up in the cascade.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Cleared. Returns the deletion confirmation (`deleted: true`, `template: null`) and the count of agents flagged for recompose; the next read returns the composed view without this layer. (The handler returns this 200-with-body, not 204.)","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/audit":{"put":{"operationId":"putAlignmentAuditByTeam","summary":"Replace audit settings","description":"PUT replaces the entire `audit` block (trace format, retention window, query endpoint). The current spec at the team scope is read; the new `audit` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAuditByTeam","summary":"Update audit settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `audit` block (trace format, retention window, query endpoint). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}}}}},"responses":{"200":{"description":"The `audit` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["audit"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["retention_days","queryable"],"properties":{"trace_format":{"type":"string"},"retention_days":{"type":"integer"},"queryable":{"type":"boolean"},"query_endpoint":{"type":"string"},"tamper_evidence":{"type":["string","null"],"enum":["append_only","signed","merkle",null]},"storage":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/autonomy":{"put":{"operationId":"putAlignmentAutonomyByTeam","summary":"Replace autonomy settings","description":"PUT replaces the entire `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). The current spec at the team scope is read; the new `autonomy` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"application/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}},"text/yaml":{"schema":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentAutonomyByTeam","summary":"Update autonomy settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `autonomy` block (bounded_actions[] + forbidden_actions[] + escalation_triggers[] + max_autonomous_value). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}}}}},"responses":{"200":{"description":"The `autonomy` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["autonomy"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["bounded_actions","escalation_triggers"],"properties":{"bounded_actions":{"type":"array","items":{"type":"string"}},"forbidden_actions":{"type":"array","items":{"type":"string"}},"escalation_triggers":{"type":"array","items":{"type":"object"}},"max_autonomous_value":{"type":"object"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/capabilities":{"put":{"operationId":"putAlignmentCapabilitiesByTeam","summary":"Replace capabilities settings","description":"PUT replaces the entire `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). The current spec at the team scope is read; the new `capabilities` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"application/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}},"text/yaml":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentCapabilitiesByTeam","summary":"Update capabilities settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `capabilities` block (the keyed-map of `{capability_name -> CardCapability}` tool grants). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"responses":{"200":{"description":"The `capabilities` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["capabilities"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","additionalProperties":{"type":"object"}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/conscience":{"put":{"operationId":"putAlignmentConscienceByTeam","summary":"Replace conscience settings","description":"PUT replaces the entire `conscience` block (augment-vs-replace + the conscience values list). The current spec at the team scope is read; the new `conscience` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"application/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}},"text/yaml":{"schema":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentConscienceByTeam","summary":"Update conscience settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `conscience` block (augment-vs-replace + the conscience values list). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"The `conscience` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["conscience"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["mode","values"],"properties":{"mode":{"type":"string","enum":["augment","replace"]},"values":{"type":"array","items":{"type":"object"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/enforcement":{"put":{"operationId":"putAlignmentEnforcementByTeam","summary":"Replace enforcement settings","description":"PUT replaces the entire `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). The current spec at the team scope is read; the new `enforcement` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"application/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}},"text/yaml":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentEnforcementByTeam","summary":"Update enforcement settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `enforcement` block (fine-grained tool-use policy (forbidden patterns, unmapped severity, grace window)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}}}}},"responses":{"200":{"description":"The `enforcement` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["enforcement"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","properties":{"allow_unmapped_tools":{"type":"boolean"},"default_unmapped_severity":{"type":"string","enum":["low","medium","high","critical"]},"forbidden_tools":{"type":"array","items":{"type":"object"}},"grace_period_hours":{"type":"number"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/modes":{"put":{"operationId":"putAlignmentModesByTeam","summary":"Replace modes settings","description":"PUT replaces the entire `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). The current spec at the team scope is read; the new `modes` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"application/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"text/yaml":{"schema":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentModesByTeam","summary":"Update modes settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `modes` block (the two top-level master switches `autonomy_mode` + `integrity_mode`). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}}}}},"responses":{"200":{"description":"The `modes` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["modes"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["autonomy_mode","integrity_mode"],"properties":{"autonomy_mode":{"type":"string","enum":["off","observe","nudge","enforce"]},"integrity_mode":{"type":"string","enum":["off","observe","nudge","enforce"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/preview-compose":{"post":{"operationId":"previewComposeAlignmentByTeam","summary":"Preview composed alignment (dry run)","description":"Composes the cascade against a hypothetical body at the team layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedAlignmentCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedAlignmentCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/principal":{"put":{"operationId":"putAlignmentPrincipalByTeam","summary":"Replace principal settings","description":"PUT replaces the entire `principal` block (who-the-agent-is identity block). The current spec at the team scope is read; the new `principal` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"application/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}},"text/yaml":{"schema":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentPrincipalByTeam","summary":"Update principal settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `principal` block (who-the-agent-is identity block). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}}}}},"responses":{"200":{"description":"The `principal` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["principal"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["type","relationship"],"properties":{"type":{"type":"string","enum":["human","organization","agent","unspecified"]},"identifier":{"type":"string"},"relationship":{"type":"string","enum":["delegated_authority","advisory","autonomous"]},"escalation_contact":{"type":"string"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/alignment/team/{team_id}/values":{"put":{"operationId":"putAlignmentValuesByTeam","summary":"Replace values settings","description":"PUT replaces the entire `values` block (declared catalog entries + definitions / hierarchy / conflicts). The current spec at the team scope is read; the new `values` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"application/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}},"text/yaml":{"schema":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchAlignmentValuesByTeam","summary":"Update values settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `values` block (declared catalog entries + definitions / hierarchy / conflicts). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Alignment"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}}}}},"responses":{"200":{"description":"The `values` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["alignment"]},"primitive":{"type":"string","enum":["values"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{}},"definitions":{"type":"object","additionalProperties":true},"conflicts_with":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"string","enum":["lexicographic","weighted","contextual"]}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/analyze":{"post":{"operationId":"analyze","summary":"Run single integrity analysis","tags":["Analyze"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["thinking_block","thinking_metadata","agent_id","session_id","card"],"properties":{"thinking_block":{"type":"string"},"thinking_metadata":{"type":"object","required":["provider","model"],"properties":{"provider":{"type":"string"},"model":{"type":"string"}}},"agent_id":{"type":"string"},"session_id":{"type":"string"},"card":{"type":"object","required":["card_id","values"],"properties":{"card_id":{"type":"string"},"values":{"type":"array","items":{"type":"object"}}}},"conscience_values":{"type":"array","items":{"$ref":"#/components/schemas/ConscienceValue"}},"window_context":{"type":"array","items":{"type":"object"}},"task_context":{"type":"string"},"store_checkpoint":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Analysis result","content":{"application/json":{"schema":{"type":"object","properties":{"checkpoint":{"$ref":"#/components/schemas/Checkpoint"},"proceed":{"type":"boolean"},"recommended_action":{"type":"string"},"window_summary":{"type":"object"},"metering":{"type":"object","properties":{"event_id":{"type":"string"},"account_id":{"type":"string"},"billed":{"type":"boolean"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/analyze/batch":{"post":{"operationId":"analyzeBatch","summary":"Run batch integrity analysis (1-50 items)","tags":["Analyze"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object"},"minItems":1,"maxItems":50,"description":"Array of analysis requests (same shape as POST /analyze body)"}}}}}},"responses":{"200":{"description":"Batch analysis results","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object"}},"metering":{"type":"object","properties":{"total_events":{"type":"integer"},"account_id":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/api-keys":{"post":{"operationId":"createApiKey","summary":"Create a personal API key","description":"Mints a new personal API key. The full secret is returned in the `key` field — capture it now, it is not retrievable again. Scopes use the capability-based vocabulary (ADR-049); the default scope set is `[\"gateway\", \"api:read\", \"api:write\"]`. Admin scopes (`admin:org`, `admin:platform`) are opt-in and rejected at mint time if the requester does not hold the corresponding role.","tags":["Billing"],"security":[{"BearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"default":"Default","description":"Friendly name for the key (e.g., \"ci-prod\", \"local-dev\"). Capped at 100 characters; longer names are truncated server-side."},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"},"default":["gateway","api:read","api:write"],"description":"Capability set for this key. If omitted, the API substitutes the default. Admin scopes (`admin:org`, `admin:platform`) are gated by the requester's current role and return HTTP 403 at mint time if the requester is not eligible."}}}}}},"responses":{"201":{"description":"API key created (secret shown once)","content":{"application/json":{"schema":{"type":"object","required":["key_id","key","key_prefix","name","scopes","created_at"],"properties":{"key_id":{"type":"string"},"key":{"type":"string","description":"Full secret. Capture now — never returned again."},"key_prefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"created_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"operationId":"listApiKeys","summary":"List active API keys","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"API key list","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api-keys/whoami":{"get":{"operationId":"apiKeyWhoAmI","summary":"Inspect the calling API key (caller introspection)","description":"Returns the resolved API key's identity: its scopes (capabilities), bound user/agent/org, and last-used metadata. Useful for clients to confirm scope and identity before issuing privileged calls.","tags":["Auth"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Caller identity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyWhoAmI"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api-keys/{key_id}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","tags":["Billing"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"},"key_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api-keys/{key_id}/rotate":{"post":{"operationId":"rotateApiKey","summary":"Rotate a personal API key","description":"Atomically mints a replacement key with the same `name` and `scopes` as the original, then immediately revokes the old key. The full new secret is returned in the response — this is your only chance to capture it. Old key is invalid as soon as the response is returned; if you need overlap with an in-flight deploy, **create a second key first** via `POST /api-keys`, ship your code, then `DELETE` the old key. Rotation is for the suspect/compromised-key case where overlap is the opposite of what you want.","tags":["Billing"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"New key minted, old key revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"key_id":{"type":"string"},"key":{"type":"string","description":"Full secret. Capture now — never returned again."},"key_prefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"rotated_from":{"type":"string","description":"key_id of the now-revoked predecessor"},"old_key_revoked_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/callback":{"get":{"operationId":"emailCallback","summary":"Email-link landing (confirmation / recovery / magic link)","description":"Handles Supabase-hosted email links. Verifies the token via GoTrue, issues `mnemom_session` when the flow returns tokens (signup confirm, magic link), or redirects without a session for recovery flows where the SPA performs the next step.","tags":["Auth"],"security":[],"parameters":[{"name":"token_hash","in":"query","required":true,"schema":{"type":"string"}},{"name":"type","in":"query","required":true,"schema":{"type":"string","enum":["signup","recovery","magiclink","email_change","invite"]}},{"name":"redirect_after","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"302":{"description":"Redirects to the SPA. Sets `mnemom_session` when tokens are issued.","headers":{"Location":{"schema":{"type":"string","format":"uri"}},"Set-Cookie":{"schema":{"type":"string"},"description":"Optional; only when tokens are issued."}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/cli-exchange":{"post":{"operationId":"cliExchange","summary":"Exchange a cookie session for raw Supabase tokens","description":"One-shot endpoint called by the SPA during the CLI login flow (browser → localhost handoff). Requires a valid `mnemom_session`. Returns access + refresh tokens in the JSON body. Does not modify cookies.","tags":["Auth"],"security":[{"CookieAuth":[]}],"responses":{"200":{"description":"Tokens returned.","content":{"application/json":{"schema":{"type":"object","required":["access_token","refresh_token","expires_in","user_id"],"properties":{"access_token":{"type":"string","description":"Supabase JWT."},"refresh_token":{"type":"string"},"expires_in":{"type":"integer","description":"Seconds until access_token expires."},"user_id":{"type":"string","format":"uuid"},"user_email":{"type":["string","null"],"format":"email"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/delete-account":{"delete":{"operationId":"deleteAccount","summary":"Delete authenticated user account and unlink agents","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Account deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/login":{"post":{"operationId":"authLogin","summary":"CLI password login — returns bearer tokens in JSON body","description":"Legacy CLI-targeted endpoint. Unlike `/auth/sign-in`, this does NOT set cookies — it returns Supabase access + refresh tokens in the JSON body for the CLI to persist at `~/.mnemom/auth.json`. Rate-limited.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Tokens returned.","content":{"application/json":{"schema":{"type":"object","required":["access_token","refresh_token"],"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"integer"},"user":{"$ref":"#/components/schemas/User"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/me":{"get":{"operationId":"getMe","summary":"Get authenticated user info and linked agents","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"agents":{"type":"array","items":{"$ref":"#/components/schemas/Agent"}},"billing_account_id":{"type":["string","null"]},"plan_id":{"type":["string","null"]},"org":{"type":["object","null"],"properties":{"org_id":{"type":"string"},"org_name":{"type":"string"},"role":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/me/avatar":{"put":{"operationId":"putMyAvatar","summary":"Upload current user's avatar","description":"Replace the authenticated user's profile avatar. The user identity is taken from the JWT/`mnm_*` auth context — there is no path parameter. Old avatar is replaced; storage cleanup happens server-side.","tags":["Auth"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Avatar image. Validated for MIME type and size before upload."}}}}}},"responses":{"200":{"description":"Avatar uploaded; persistent URL returned","content":{"application/json":{"schema":{"type":"object","required":["avatar_url"],"properties":{"avatar_url":{"type":"string","format":"uri","description":"Public URL of the uploaded avatar (CDN-served).","example":"https://cdn.mnemom.ai/avatars/agents/mnm-7f3b9e2a/abc123.png"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/auth/me/personal-org":{"get":{"operationId":"getMyPersonalOrg","summary":"Get the authenticated user's personal organization","description":"Returns the authenticated user's personal-org-of-one (per ADR-044 Piece 1). Idempotent. If the user does not yet have a personal org (legacy account pre-dating migration 161, or a transient backfill miss), one is provisioned on the fly and `just_provisioned` is set to `true`.","tags":["Auth"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"responses":{"200":{"description":"Personal org accessor.","content":{"application/json":{"schema":{"type":"object","required":["org_id","is_personal"],"properties":{"org_id":{"type":"string"},"is_personal":{"type":"boolean","enum":[true]},"just_provisioned":{"type":"boolean","description":"True only when this call provisioned the personal org (lazy backfill path)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/mfa/challenge":{"post":{"operationId":"mfaChallenge","summary":"Issue a challenge for a TOTP factor","description":"Called during the sign-in MFA step-up flow (using the `mnemom_mfa_pending` cookie) or during enrollment verification (using the existing `mnemom_session`). Returns a `challenge_id` to pass to `/auth/mfa/verify`.","tags":["Auth"],"security":[{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["factor_id"],"properties":{"factor_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Challenge issued.","content":{"application/json":{"schema":{"type":"object","properties":{"challenge_id":{"type":"string"}},"required":["challenge_id"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/mfa/enroll":{"post":{"operationId":"mfaEnroll","summary":"Enroll a new TOTP factor","description":"Returns the TOTP secret + provisioning URI for a QR code. Factor starts in `unverified` state until `/auth/mfa/verify` is called against it.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"friendly_name":{"type":"string"}}}}}},"responses":{"200":{"description":"Factor enrolled (unverified). Supabase passthrough.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["totp"]},"totp":{"type":"object","properties":{"qr_code":{"type":"string","description":"SVG QR code."},"secret":{"type":"string"},"uri":{"type":"string","format":"uri"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/mfa/factors":{"get":{"operationId":"mfaListFactors","summary":"List the current user's TOTP factors","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"TOTP factor list (Supabase passthrough).","content":{"application/json":{"schema":{"type":"object","properties":{"totp":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"friendly_name":{"type":["string","null"]},"status":{"type":"string","enum":["unverified","verified"]},"created_at":{"type":"string","format":"date-time"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/mfa/unenroll":{"post":{"operationId":"mfaUnenroll","summary":"Unenroll a TOTP factor","description":"Requires an aal2 session (freshly MFA-verified). Returns 403 `code: aal2_required` if the session isn't aal2.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["factor_id"],"properties":{"factor_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/mfa/verify":{"post":{"operationId":"mfaVerify","summary":"Complete MFA step-up or enrollment","description":"Sign-in flow: consumes the `mnemom_mfa_pending` cookie, verifies the TOTP code, and issues a full `mnemom_session`. Enrollment flow: verifies a freshly-enrolled factor using the current session and upgrades it to aal2.","tags":["Auth"],"security":[{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["factor_id","challenge_id","code"],"properties":{"factor_id":{"type":"string"},"challenge_id":{"type":"string"},"code":{"type":"string","description":"6-digit TOTP code."}}}}}},"responses":{"200":{"description":"Full session issued. Response sets `mnemom_session` cookie.","headers":{"Set-Cookie":{"schema":{"type":"string"},"description":"Sets `mnemom_session` (HttpOnly, Secure, SameSite=Lax)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}},"required":["user"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/passkey/challenge":{"post":{"operationId":"passkeyChallenge","summary":"Begin passkey sign-in — return WebAuthn assertion options","description":"Unauthenticated. Returns `PublicKeyCredentialRequestOptions` with an empty `allowCredentials` list (discoverable-credentials flow). The browser surfaces any matching passkey for this RP without needing the user to enter an email. Rate-limited.","tags":["Auth"],"security":[],"responses":{"200":{"description":"WebAuthn assertion options.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicKeyCredentialRequestOptionsJSON"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/passkey/enroll":{"post":{"operationId":"passkeyEnroll","summary":"Begin passkey enrollment — return WebAuthn creation options","description":"Authenticated endpoint. Returns `PublicKeyCredentialCreationOptions` for the SPA to pass to `navigator.credentials.create()`. Stores the challenge in KV with a 30-second TTL; the companion `/verify-enroll` endpoint consumes it. `excludeCredentials` is pre-populated with the user's existing passkeys so the authenticator prevents duplicate enrollment of the same key.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"WebAuthn creation options. Shape follows the WebAuthn Level 3 spec.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicKeyCredentialCreationOptionsJSON"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/passkey/verify-auth":{"post":{"operationId":"passkeyVerifyAuth","summary":"Verify a passkey assertion and issue a session","description":"Unauthenticated. Consumes the challenge issued by `/auth/passkey/challenge`, verifies the assertion via `@simplewebauthn/server`, mints Supabase tokens via `admin.generateLink(magiclink)` for the resolved user (same pattern T3-2c uses for SSO identity linking), and issues `mnemom_session` with `auth_method: 'passkey'`. Counter is enforced monotonically — a decrement rejects the assertion.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["response"],"properties":{"response":{"$ref":"#/components/schemas/AuthenticationResponseJSON"}}}}}},"responses":{"200":{"description":"Session issued.","headers":{"Set-Cookie":{"schema":{"type":"string"},"description":"`mnemom_session` (HttpOnly, Secure, SameSite=Lax)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/passkey/verify-enroll":{"post":{"operationId":"passkeyVerifyEnroll","summary":"Verify a passkey registration response + persist the credential","description":"Authenticated endpoint. Consumes the challenge issued by `/auth/passkey/enroll`, verifies the attestation via `@simplewebauthn/server`, and inserts a row into `user_passkeys`. A user-supplied `friendly_name` is stored alongside for UI display.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["response"],"properties":{"response":{"$ref":"#/components/schemas/RegistrationResponseJSON"},"friendly_name":{"type":"string","description":"User label (e.g. \"Alex's iPhone\")."}}}}}},"responses":{"200":{"description":"Passkey enrolled.","content":{"application/json":{"schema":{"type":"object","properties":{"credential_id":{"type":"string"},"friendly_name":{"type":["string","null"]},"device_type":{"type":"string","enum":["single_device","multi_device"]},"backed_up":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/passkeys":{"get":{"operationId":"passkeysList","summary":"List the current user's enrolled passkeys","description":"Returns the safe subset of `user_passkeys` for the authenticated user (omits public_key, counter, last_used_ip).","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Passkey list.","content":{"application/json":{"schema":{"type":"object","properties":{"passkeys":{"type":"array","items":{"type":"object","properties":{"credential_id":{"type":"string"},"friendly_name":{"type":["string","null"]},"device_type":{"type":"string","enum":["single_device","multi_device"]},"backed_up":{"type":"boolean"},"transports":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/passkeys/{credential_id}":{"delete":{"operationId":"passkeyDelete","summary":"Remove an enrolled passkey","description":"Requires aal2. Deleting a passkey does not affect other passkeys or the password/MFA fallback; those remain usable.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"credential_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Passkey removed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/password":{"post":{"operationId":"updatePassword","summary":"Update the authenticated user's password","description":"Authenticated password update. Used by both the `/reset-password` recovery flow (after the recovery email callback issues a session) and voluntary password changes from account settings. Cookie session auth required (`mnemom_session`); bearer tokens are not accepted on this route. After a successful update, every other session for the same user is revoked with audit reason `password_reset`.","tags":["Auth"],"security":[{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","minLength":12,"description":"New password. Must be at least 12 characters. The upstream identity provider applies additional weak-password and breach-list checks; failures surface as 400 with a `password_rejected` error code."}}}}}},"responses":{"200":{"description":"Password updated. Other sessions for the same user are revoked best-effort.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/password-reset-request":{"post":{"operationId":"passwordResetRequest","summary":"Request a password reset email","description":"Always returns 200 on 4xx upstream responses (to avoid user enumeration). 5xx upstream errors surface as 5xx to the caller.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"redirect_to":{"type":"string","format":"uri","description":"Allowlisted SPA path to return to after the user clicks the reset link."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/refresh":{"post":{"operationId":"authRefresh","summary":"CLI token refresh","description":"Legacy CLI-targeted refresh grant. Trades a refresh token for a new access + refresh token pair. Rate-limited.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}}}}},"responses":{"200":{"description":"New tokens.","content":{"application/json":{"schema":{"type":"object","required":["access_token","refresh_token"],"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/resend-confirmation":{"post":{"operationId":"resendConfirmation","summary":"Resend email confirmation","description":"Re-sends the signup confirmation email for a pending account.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"redirect_to":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/session":{"get":{"operationId":"getSession","summary":"Cookie-aware whoami","description":"Minimal whoami endpoint. Returns `{ user }` when the `mnemom_session` cookie is valid; returns 401 otherwise. Preferred over `GET /auth/me` for cookie-only browser sessions — `/auth/me` is bearer-only and preserves its legacy response shape unchanged.","tags":["Auth"],"security":[{"CookieAuth":[]}],"responses":{"200":{"description":"Authenticated session.","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/sessions":{"get":{"operationId":"listSessions","summary":"List the caller's active sessions","description":"Returns every non-revoked session for the authenticated user. Each row is safe to render in an \"Active sessions\" UI — no tokens are disclosed. The session matching the request cookie is marked `is_current: true`, and sessions originating from the same hashed source IP as the current request are marked `same_network_as_current: true`. See ADR-028.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Active sessions for the current user.","content":{"application/json":{"schema":{"type":"object","required":["sessions"],"properties":{"sessions":{"type":"array","items":{"type":"object","required":["sid","auth_method","device_label","issued_at","last_seen_at","is_current","same_network_as_current"],"properties":{"sid":{"type":"string","description":"Opaque session id. Pass to `DELETE /auth/sessions/{sid}` to revoke."},"auth_method":{"type":"string","enum":["password","sso","passkey"]},"device_label":{"type":"string","description":"Best-effort human label derived from the original User-Agent and IP at sign-in time (e.g. \"Safari on macOS — San Francisco\")."},"issued_at":{"type":"string","format":"date-time"},"last_seen_at":{"type":"string","format":"date-time"},"is_current":{"type":"boolean","description":"True for the session tied to the request cookie."},"same_network_as_current":{"type":"boolean","description":"True when this session's hashed source IP matches the current request's."}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"revokeAllOtherSessions","summary":"Revoke all other sessions","description":"Revokes every active session for the current user _except_ the one making this call. Requires aal2 (MFA-verified session). Sessions issued before per-session revocation (v=1 cookies) cannot identify themselves as \"current\" and receive `409 legacy_session_requires_reauth` — the user must sign in again to use this action. See ADR-028.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Optional idempotency key; repeated calls with the same key return the same result within 24 hours."}],"responses":{"200":{"description":"Number of sessions revoked.","content":{"application/json":{"schema":{"type":"object","required":["revoked"],"properties":{"revoked":{"type":"integer","description":"Count of sessions revoked (excludes the current session)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/sessions/revoke-via-email":{"post":{"operationId":"revokeSessionViaEmail","summary":"Revoke a session using a signed email token","description":"Consumes a signed token minted at email-send time by the new-device notification flow. Possession of the token is the auth factor — no existing session cookie is required, no MFA. Returns 200 on any verified-valid token even if the underlying sid is already revoked (idempotent, non-enumerating). Returns 400 on malformed, tampered, expired, or key-mismatched tokens. Public endpoint, rate-limited. See ADR-031.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"HS256-signed token from the new-device email link."}}}}}},"responses":{"200":{"description":"Session revocation accepted (idempotent — 200 returned even if the session was already gone).","content":{"application/json":{"schema":{"type":"object","required":["revoked_at"],"properties":{"revoked_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/sessions/{sid}":{"delete":{"operationId":"revokeSession","summary":"Revoke a specific session","description":"Revokes one non-current session by its `sid`. The KV blocklist is updated so the gateway rejects the next request bearing that session on its next hit. Cannot be used to revoke the session making this request — use `POST /auth/sign-out` for that. Requires aal2. Idempotent: a sid that is already revoked or never belonged to the user returns 404 (non-enumeration). See ADR-028.","tags":["Auth"],"security":[{"CookieAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"sid","in":"path","required":true,"schema":{"type":"string"},"description":"Session identifier returned by `GET /auth/sessions`."}],"responses":{"200":{"description":"Session revoked.","content":{"application/json":{"schema":{"type":"object","required":["revoked_at"],"properties":{"revoked_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/set-locale":{"post":{"operationId":"setLocale","summary":"Set the authenticated user's preferred email locale","description":"Updates `user_metadata.locale` on the Supabase auth user. Locale-aware send paths (billing webhooks, licensing expiry, auth send-email-hook) read this field to choose between English (default), French, German, Italian, and Spanish copy. Cookie session auth required; the change is effective immediately for subsequent email sends.","tags":["Auth"],"security":[{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["locale"],"properties":{"locale":{"type":"string","enum":["en","fr","de","it","es"],"description":"Preferred email locale. Values outside this enum are rejected with `unsupported_locale`."}}}}}},"responses":{"200":{"description":"Locale updated.","content":{"application/json":{"schema":{"type":"object","required":["ok","locale"],"properties":{"ok":{"type":"boolean"},"locale":{"type":"string","enum":["en","fr","de","it","es"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/sign-in":{"post":{"operationId":"signIn","summary":"Sign in with email + password","description":"Server-enforces SSO for org-enforced domains (returns 403 with `code: sso_required`). For users with a verified TOTP factor, returns 200 `{ mfa_required: true, factor_id }` and sets a short-lived `mnemom_mfa_pending` cookie; otherwise issues `mnemom_session` and returns `{ user }`.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Full session issued OR MFA step-up required.","headers":{"Set-Cookie":{"schema":{"type":"string"},"description":"`mnemom_session` on full session, or `mnemom_mfa_pending` on MFA step-up."}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}},"required":["user"]},{"type":"object","properties":{"mfa_required":{"type":"boolean","enum":[true]},"factor_id":{"type":"string"}},"required":["mfa_required","factor_id"]}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/sign-out":{"post":{"operationId":"signOut","summary":"Sign out and clear session cookies","description":"Revokes the refresh token upstream and clears `mnemom_session` + `mnemom_mfa_pending`. Idempotent and anon-callable by design — calling it without a session returns 200 + no-op cookie clear, so a logged-out client can safely re-issue the call without observing a 401.","tags":["Auth"],"security":[{},{"CookieAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Cookies cleared.","headers":{"Set-Cookie":{"schema":{"type":"string"},"description":"Clears session cookies."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/sign-up":{"post":{"operationId":"signUp","summary":"Sign up with email + password","description":"Creates a new user account. When email confirmation is required on the Supabase project, returns `{ user, email_confirmation_required: true }` without issuing a session cookie; the user must click the email link. When auto-confirm is on, issues `mnemom_session` and returns `{ user }`.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","format":"password","minLength":8},"redirect_to":{"type":"string","format":"uri","description":"Allowlisted SPA path to return to after email confirmation."}}}}}},"responses":{"200":{"description":"Account created. Either returns a full session (auto-confirm) or awaits email confirmation.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}},"required":["user"]},{"type":"object","properties":{"user":{"description":"`null` while email confirmation is pending — no session is issued until the user clicks the confirmation link.","anyOf":[{"$ref":"#/components/schemas/User"},{"type":"null"}]},"email_confirmation_required":{"type":"boolean","enum":[true]}},"required":["email_confirmation_required"]}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/sso/callback":{"get":{"operationId":"ssoCallback","summary":"IdP callback landing — issues session and redirects to SPA","description":"Validates the HMAC-signed state (from the `mnemom_sso_initiator` cookie), consumes the single-use nonce, exchanges the PKCE code, enforces domain + org binding, performs SSO identity linking (T3-2c), and issues `mnemom_session` via a 302 to the SPA's `redirect_after` path.","tags":["Auth"],"security":[],"parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"302":{"description":"Session issued. Redirects to the SPA.","headers":{"Location":{"schema":{"type":"string","format":"uri"}},"Set-Cookie":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/sso/check-domain":{"get":{"operationId":"checkSsoDomain","summary":"Check if email domain has SSO enabled","tags":["Auth"],"security":[],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"SSO domain check result","content":{"application/json":{"schema":{"type":"object","properties":{"sso_enabled":{"type":"boolean"},"org_id":{"type":"string"},"org_name":{"type":"string"},"provider_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/auth/sso/initiate":{"post":{"operationId":"ssoInitiate","summary":"Begin an SSO login flow","description":"Looks up the SSO provider for the email's domain, generates PKCE + HMAC-signed state, sets a short-lived `mnemom_sso_initiator` cookie, and returns the IdP URL for the SPA to `window.location.href` to.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"redirect_after":{"type":"string","description":"SPA path to return to after SSO completes (allowlisted)."}}}}}},"responses":{"200":{"description":"IdP URL returned. Also sets `mnemom_sso_initiator` cookie.","headers":{"Set-Cookie":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/auth/token-exchange":{"post":{"operationId":"tokenExchange","summary":"Exchange a GoTrue refresh token for a mnemom_session cookie","description":"Mirror of `/auth/cli-exchange` in the opposite direction. Called by the SPA after landing on a Supabase implicit-flow redirect (magic-link login), whose session tokens arrive in the URL fragment. The endpoint performs the GoTrue refresh grant server-side — proving possession and consuming the single-use refresh token — then registers a session and sets the HttpOnly `mnemom_session` cookie. JSON-only; no redirect parameter. Rate-limited like sibling auth endpoints.","tags":["Auth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string","description":"GoTrue refresh token from the implicit-flow fragment."}}}}}},"responses":{"200":{"description":"Session established. Sets `mnemom_session`.","headers":{"Set-Cookie":{"schema":{"type":"string"},"description":"HttpOnly `mnemom_session` cookie."}},"content":{"application/json":{"schema":{"type":"object","required":["user","aal"],"properties":{"user":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"},"email":{"type":["string","null"],"format":"email"}}},"aal":{"type":"string","enum":["aal1","aal2"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/billing/budget-alert":{"get":{"operationId":"getBudgetAlert","summary":"Get budget alert settings","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Budget alert settings","content":{"application/json":{"schema":{"type":"object","properties":{"threshold_cents":{"type":["integer","null"]},"last_alert_sent_at":{"type":["string","null"],"format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"setBudgetAlert","summary":"Set budget alert threshold","tags":["Billing"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"threshold_cents":{"type":["integer","null"],"minimum":0}}}}}},"responses":{"200":{"description":"Budget alert updated","content":{"application/json":{"schema":{"type":"object","properties":{"threshold_cents":{"type":["integer","null"]},"updated":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/cancel":{"post":{"operationId":"cancelSubscription","summary":"Cancel subscription at period end","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Cancellation confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"canceled":{"type":"boolean"},"cancel_at_period_end":{"type":"boolean"},"current_period_end":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/change-plan":{"post":{"operationId":"changePlan","summary":"Change subscription plan","tags":["Billing"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan_id"],"properties":{"plan_id":{"type":"string"},"annual":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Plan changed","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"boolean"},"plan_id":{"type":"string"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/checkout":{"post":{"operationId":"createCheckout","summary":"Create Stripe checkout session","tags":["Billing"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan_id"],"properties":{"plan_id":{"type":"string"},"annual":{"type":"boolean","default":false},"promo_code":{"type":"string"}}}}}},"responses":{"200":{"description":"Checkout session URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"session_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/export/usage":{"get":{"operationId":"exportUsage","summary":"Export usage data as CSV","tags":["Billing"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"Start date (YYYY-MM-DD)"},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"End date (YYYY-MM-DD)"}],"responses":{"200":{"description":"CSV file","content":{"text/csv":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/features":{"get":{"operationId":"getFeatures","summary":"Get plan feature flags for authenticated user","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Plan features","content":{"application/json":{"schema":{"type":"object","properties":{"plan_id":{"type":"string"},"feature_flags":{"type":"object","additionalProperties":{"type":"boolean"}},"limits":{"type":"object"},"included_checks":{"type":"integer"},"check_count_this_period":{"type":"integer"},"subscription_status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/invoices":{"get":{"operationId":"listInvoices","summary":"List invoices","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Invoice list","content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/me":{"get":{"operationId":"getMyBilling","summary":"Get authenticated user billing summary","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Billing summary","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/portal":{"post":{"operationId":"createPortalSession","summary":"Create Stripe billing portal session","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Portal session URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/reactivate":{"post":{"operationId":"reactivateSubscription","summary":"Reactivate a subscription scheduled for cancellation","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Reactivation confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"reactivated":{"type":"boolean"},"cancel_at_period_end":{"type":"boolean"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/subscription":{"get":{"operationId":"getSubscription","summary":"Get current subscription details","tags":["Billing"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Subscription details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/usage":{"get":{"operationId":"getMyUsage","summary":"Get usage metrics for current user","tags":["Billing"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":30,"minimum":1,"maximum":90}}],"responses":{"200":{"description":"Usage data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageMetrics"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/usage/agents":{"get":{"operationId":"getMyAgentUsage","summary":"Get per-agent usage breakdown","tags":["Billing"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":30,"minimum":1,"maximum":90}}],"responses":{"200":{"description":"Per-agent usage data","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/billing/validate-promo":{"post":{"operationId":"validatePromo","summary":"Validate a promo code","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}}}}},"responses":{"200":{"description":"Promo validation result","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"discount_percent":{"type":["number","null"]},"discount_amount_cents":{"type":["integer","null"]},"name":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/blog/authors/{agent_id}":{"get":{"operationId":"getBlogAuthor","security":[],"summary":"Get author profile and their posts","tags":["Blog"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Author and posts","content":{"application/json":{"schema":{"type":"object","properties":{"author":{"$ref":"#/components/schemas/Agent"},"posts":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/blog/posts":{"get":{"operationId":"listBlogPosts","security":[],"summary":"List published blog posts","tags":["Blog"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0}},{"name":"agent_id","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Blog post list","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createBlogPost","summary":"Create blog post (service role only)","description":"**Requires ServiceRole authentication.** This endpoint is only accessible to platform administrators with the Supabase service role key. Regular API keys and user tokens cannot access this endpoint.\n\nCreate a new blog post.","tags":["Blog"],"security":[{"ServiceRole":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id","slug","title","body"],"properties":{"agent_id":{"type":"string"},"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"title":{"type":"string"},"subtitle":{"type":"string"},"body":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"investigation_session_id":{"type":"string"},"trace_ids":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["draft","published"],"default":"draft"}}}}}},"responses":{"201":{"description":"Post created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/blog/posts/{slug}":{"get":{"operationId":"getBlogPost","security":[],"summary":"Get single blog post by slug","tags":["Blog"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blog post with linked traces","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"type":"object"},"linked_traces":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/catalog/values":{"get":{"operationId":"listCatalogValues","summary":"List the 25 Mnemom catalog values (filterable).","description":"Returns the 25-entry Mnemom value catalog v1 — the trans-industry universal value primitives. SDK consumers + dashboards use this for pickable lists and grouping. The runtime catalog is vendored in-process (no DB call); responses are highly cacheable (5-minute TTL with stale-while-revalidate). cards-as-primitive Phase 4 W2.4.","tags":["Catalog"],"security":[],"parameters":[{"name":"axis","in":"query","required":false,"schema":{"type":"string","maxLength":64},"description":"Filter to entries on this behavioral axis (e.g., `speed↔caution`)."},{"name":"category","in":"query","required":false,"schema":{"type":"string","enum":["cognitive","operational","relational","stewardship","identity","confidentiality"]},"description":"Filter to one of the six catalog categories."},{"name":"gateway_hookable","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]},"description":"When `true`, return only entries the dispatcher binds to a gateway hook."}],"responses":{"200":{"description":"Catalog list — `data[]` plus `count` and `total`.","headers":{"Cache-Control":{"description":"`public, max-age=300, stale-while-revalidate=600`.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Always `catalog-values-list/v1`.","schema":{"type":"string","enum":["catalog-values-list/v1"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data","count","total","catalog_version"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","axis","polarity","parameters","plain_definition","category","gateway_hookable"],"properties":{"id":{"type":"string","description":"Stable kebab-case identifier — the contract."},"axis":{"type":"string","description":"Where in the behavioral space the value sits (e.g., `\"speed↔caution\"`)."},"polarity":{"type":"string","enum":["positive","negative"],"description":"Whether the value is a do-this (positive) or don’t-do-that (negative)."},"parameters":{"type":"array","items":{"type":"string","enum":["domain","intensity","severity_on_violation","scope"]},"description":"Which manifest parameters this entry accepts."},"plain_definition":{"type":"string","description":"Care-framed prose definition (interpretive; translates per-locale)."},"category":{"type":"string","enum":["cognitive","operational","relational","stewardship","identity","confidentiality"]},"gateway_hookable":{"type":"boolean","description":"Whether the dispatcher binds this entry to a gateway hook."},"gateway_hook_disposition":{"type":["string","null"],"description":"Pass-2 detail — the gateway hook predicate disposition when applicable. `null` until mnemom-contracts publishes Pass-2 for this entry."},"observer_signals":{"type":["array","null"],"items":{"type":"string"},"description":"Pass-2 detail — the observer signals this entry binds on. `null` until Pass-2 ships."},"care_frame_template":{"type":["string","null"],"description":"Pass-2 detail — the care-framed error template when this entry fires. `null` until Pass-2 ships."}}}},"count":{"type":"integer","minimum":0},"total":{"type":"integer","minimum":0},"catalog_version":{"type":"string","enum":["v1"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/catalog/values/{id}":{"get":{"operationId":"getCatalogValue","summary":"Get a single catalog entry by id.","description":"Returns one entry from the Mnemom value catalog v1 by its stable kebab-case id. cards-as-primitive Phase 4 W2.4.","tags":["Catalog"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z][a-z0-9_]*$"},"description":"Stable catalog entry id (e.g., `policy_attentiveness`)."}],"responses":{"200":{"description":"Single catalog entry.","headers":{"Cache-Control":{"schema":{"type":"string"}},"X-Mnemom-Schema":{"schema":{"type":"string","enum":["catalog-value/v1"]}}},"content":{"application/json":{"schema":{"type":"object","required":["id","axis","polarity","parameters","plain_definition","category","gateway_hookable"],"properties":{"id":{"type":"string","description":"Stable kebab-case identifier — the contract."},"axis":{"type":"string","description":"Where in the behavioral space the value sits (e.g., `\"speed↔caution\"`)."},"polarity":{"type":"string","enum":["positive","negative"],"description":"Whether the value is a do-this (positive) or don’t-do-that (negative)."},"parameters":{"type":"array","items":{"type":"string","enum":["domain","intensity","severity_on_violation","scope"]},"description":"Which manifest parameters this entry accepts."},"plain_definition":{"type":"string","description":"Care-framed prose definition (interpretive; translates per-locale)."},"category":{"type":"string","enum":["cognitive","operational","relational","stewardship","identity","confidentiality"]},"gateway_hookable":{"type":"boolean","description":"Whether the dispatcher binds this entry to a gateway hook."},"gateway_hook_disposition":{"type":["string","null"],"description":"Pass-2 detail — the gateway hook predicate disposition when applicable. `null` until mnemom-contracts publishes Pass-2 for this entry."},"observer_signals":{"type":["array","null"],"items":{"type":"string"},"description":"Pass-2 detail — the observer signals this entry binds on. `null` until Pass-2 ships."},"care_frame_template":{"type":["string","null"],"description":"Pass-2 detail — the care-framed error template when this entry fires. `null` until Pass-2 ships."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/checkpoints/{checkpoint_id}/certificate":{"get":{"operationId":"getCheckpointCertificate","summary":"Get integrity certificate","description":"Retrieve or reconstruct the IntegrityCertificate for a checkpoint. Includes signature, chain proof, Merkle inclusion proof (if available), and verdict derivation proof (if completed). Public endpoint, no authentication required.","tags":["Verification"],"security":[{}],"parameters":[{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string"},"description":"The checkpoint ID (ic-{uuid} format)"}],"responses":{"200":{"description":"The integrity certificate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrityCertificate"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/checkpoints/{checkpoint_id}/inclusion-proof":{"get":{"operationId":"getInclusionProof","summary":"Get inclusion proof","description":"Generate and return a Merkle inclusion proof for a checkpoint. The proof contains O(log N) sibling hashes sufficient to recompute the Merkle root, proving the checkpoint is included in the agent's complete checkpoint history. Public endpoint, no authentication required.","tags":["Verification"],"security":[{}],"parameters":[{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string"},"description":"The checkpoint ID (ic-{uuid} format)"}],"responses":{"200":{"description":"Merkle inclusion proof","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InclusionProofResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/checkpoints/{checkpoint_id}/proof":{"get":{"operationId":"getProofStatus","summary":"Get proof status","description":"Get the ZK proof status and data for a checkpoint. Returns the most recent proof record including status, proof type, verification result, and timing metadata. Public endpoint, no authentication required.","tags":["Verification"],"security":[{}],"parameters":[{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string"},"description":"The checkpoint ID (ic-{uuid} format)"}],"responses":{"200":{"description":"Proof status and data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofStatusResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/checkpoints/{checkpoint_id}/prove":{"post":{"operationId":"requestZkProof","summary":"Request ZK proof","description":"Request a zero-knowledge proof for a checkpoint's verdict derivation. If a proof already exists, returns its current status. Otherwise, creates a pending proof request and dispatches it to the SP1 prover service. Requires API key authentication.","tags":["Verification"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string"},"description":"The checkpoint ID (ic-{uuid} format)"}],"responses":{"200":{"description":"Proof already exists for this checkpoint","content":{"application/json":{"schema":{"type":"object","properties":{"proof_id":{"type":"string"},"status":{"type":"string"},"message":{"type":"string"}}}}}},"202":{"description":"Proof request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"proof_id":{"type":"string","description":"Proof identifier (prf-{8 random chars})"},"status":{"type":"string","enum":["queued"],"description":"Initial status"},"estimated_completion_ms":{"type":"integer","description":"Estimated time to completion in milliseconds"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/compliance/safe-house-report":{"get":{"operationId":"safeHouseComplianceReport","summary":"Compliance-formatted Safe House report","description":"Phase-7 compliance report combining aggregate detection stats, retention state, and GDPR/SOC2-friendly formatting.","tags":["Safe House"],"responses":{"200":{"description":"Report.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/contact/submit":{"post":{"operationId":"submitContact","summary":"Proxied HubSpot Forms submission (non-enterprise contact + newsletter)","description":"Server-side replacement for the old browser→HubSpot Forms submission. Routes /contact (general/support/privacy) and newsletter signups through the Worker so they're gated by the anti-spam guard (honeypot + strict email/char/length validation + optional Cloudflare Turnstile verification) before anything reaches HubSpot. `form_type=contact` requires a Turnstile token (once `TURNSTILE_SECRET_KEY` is set on the Worker); `form_type=newsletter` runs honeypot + validation only. On success the Worker also performs the CRM upsert + hot-lead Slack alert (same as /contact/notify). Returns a non-2xx so the UI can keep the form open on rejection.","tags":["Misc"],"security":[],"x-rate-limit":"publicRateLimit","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"form_type":{"type":"string","enum":["contact","newsletter"],"description":"Which HubSpot form to submit. Defaults to `contact`. `contact` requires a Turnstile token when the Worker has TURNSTILE_SECRET_KEY set; `newsletter` does not."},"email":{"type":"string","format":"email","description":"Contact email address (required)."},"name":{"type":"string","description":"Contact's display name; split into firstname/lastname on the HubSpot side."},"reason":{"type":"string","description":"Contact-form reason (general/support/privacy). Stored as the HubSpot `contact_reason` field."},"message":{"type":"string","description":"Free-form message body."},"source":{"type":"string","description":"Origin surface. Defaults to `contact_page` for form_type=contact and `newsletter` for form_type=newsletter.","examples":["contact_page","newsletter","newsletter_blog_post"]},"turnstile_token":{"type":"string","description":"Cloudflare Turnstile token from the website widget. Required when form_type=contact AND the Worker has TURNSTILE_SECRET_KEY set; ignored otherwise."},"company_website":{"type":"string","description":"Honeypot — must be empty. Real users never see the field; any non-empty value silently rejects the submission as bot traffic."},"context":{"type":"object","description":"Optional HubSpot form context forwarded to the Forms API (preserves hutk / page attribution).","properties":{"hutk":{"type":"string","description":"HubSpot tracking cookie (hubspotutk)."},"pageUri":{"type":"string","description":"URL the form was submitted from."},"pageName":{"type":"string","description":"document.title of the submitting page."}}},"utms":{"type":"object","description":"UTM parameters merged into the HubSpot form fields for attribution.","additionalProperties":{"type":"string"}},"engagement":{"type":"object","description":"Optional engagement telemetry used for hot-lead scoring (same shape as /contact/notify).","additionalProperties":true}}}}}},"responses":{"200":{"description":"Submission accepted. The Worker performed the HubSpot Forms submission and the CRM upsert + Slack alert.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","const":true},"notified":{"type":"boolean","description":"True only when the hot-lead Slack alert fired."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"description":"Anti-spam guard rejected the submission (Turnstile failed / required token missing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Too many requests"}}}},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"description":"Upstream HubSpot Forms submission failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/deployments/heartbeat":{"post":{"operationId":"deploymentHeartbeat","summary":"Self-hosted deployment heartbeat","description":"Called periodically by a self-hosted Mnemom instance to report liveness, version, and metadata back to the managed control plane. Uses a **License JWT** bearer token (not a user JWT) — the token is issued during license validation. The response includes `next_heartbeat_seconds` telling the instance when to call back.","tags":["Licensing"],"security":[{"LicenseJwtAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["deployment_id","instance_id"],"properties":{"deployment_id":{"type":"string"},"instance_id":{"type":"string"},"version":{"type":"string"},"heartbeat_data":{"type":"object","additionalProperties":true,"description":"Free-form liveness telemetry (uptime, resource usage, component versions …)."}}}}}},"responses":{"200":{"description":"Heartbeat accepted.","content":{"application/json":{"schema":{"type":"object","required":["deployment_id","status","next_heartbeat_seconds","server_time"],"properties":{"deployment_id":{"type":"string"},"status":{"type":"string","enum":["active","inactive","degraded"]},"next_heartbeat_seconds":{"type":"integer","default":300},"server_time":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/drift/{agent_id}":{"get":{"operationId":"getAapDrift","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"summary":"Get AAP drift alerts for agent","tags":["Drift"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Drift detection results","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"analyzed_traces":{"type":"integer"},"drift":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/enterprise/contact":{"post":{"operationId":"enterpriseContact","summary":"Submit enterprise contact form","tags":["Billing"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email","company"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"role":{"type":"string"},"company_size":{"type":"string"},"message":{"type":"string"}}}}}},"responses":{"200":{"description":"Inquiry submitted","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/governance/signals":{"get":{"operationId":"listPlatformGovernanceSignals","summary":"List governance signals across the entire platform","description":"Cross-org listing for Mnemom platform admins. Optional `org_id` query narrows to one tenant. Other filters mirror the org-scope endpoint. Mnemom staff only (`app_metadata.is_admin = true`).","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"query","required":false,"schema":{"type":"string"},"description":"Optional: narrow to a single org."},{"name":"source","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSource"},"description":"Filter by source detector."},{"name":"severity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"description":"Filter by severity."},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalStatus"},"description":"Filter by workflow status."},{"name":"pattern_type","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by pattern_type within the source's taxonomy."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"Platform-scope governance signals listing.","content":{"application/json":{"schema":{"type":"object","required":["scope","signals"],"properties":{"scope":{"type":"string","enum":["platform"]},"signals":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceSignal"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/governance/signals/{signal_id}":{"get":{"operationId":"getGovernanceSignal","summary":"Get a single governance signal by ID","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gs-[0-9a-f]{12}$"},"description":"Governance signal ID (gs-{12-hex})."}],"responses":{"200":{"description":"Governance signal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignal"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/governance/signals/{signal_id}/acknowledge":{"post":{"operationId":"acknowledgeGovernanceSignal","summary":"Acknowledge a governance signal","description":"Records the actor + timestamp on the signal row. Captures `acknowledged_actor_role` per ADR-046 audit-actor model. Authorized: org_admin, org_owner, or team_admin grant for the signal's team.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gs-[0-9a-f]{12}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"action_taken":{"type":"string","description":"Optional note about what action is being taken."}}}}}},"responses":{"200":{"description":"Governance signal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignal"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/governance/signals/{signal_id}/dismiss":{"post":{"operationId":"dismissGovernanceSignal","summary":"Dismiss a governance signal as not actionable","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gs-[0-9a-f]{12}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Governance signal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignal"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/governance/signals/{signal_id}/resolve":{"post":{"operationId":"resolveGovernanceSignal","summary":"Resolve a governance signal","description":"Closes the signal with a `resolution_status` and optional `action_taken` note. Authorized: org_admin, org_owner, or team_admin.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gs-[0-9a-f]{12}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["resolution_status"],"properties":{"resolution_status":{"$ref":"#/components/schemas/GovernanceResolutionStatus"},"action_taken":{"type":"string"}}}}}},"responses":{"200":{"description":"Governance signal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignal"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/integrity/{agent_id}":{"get":{"operationId":"getIntegrityScore","security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"summary":"Compute AAP integrity score","tags":["Integrity"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Integrity score","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrityScore"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/keys":{"get":{"operationId":"getSigningKeys","summary":"List signing keys","description":"List all active Ed25519 signing public keys. Public endpoint, no authentication required. These keys are used to verify IntegrityCertificate signatures.","tags":["Verification"],"security":[{}],"responses":{"200":{"description":"List of active signing keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/SigningKeyInfo"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/license/validate":{"post":{"operationId":"validateLicense","summary":"Validate a license key (public)","tags":["Licensing"],"security":[{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["license","instance_id"],"properties":{"license":{"type":"string","description":"License JWT token"},"instance_id":{"type":"string","description":"Unique instance identifier"},"instance_metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"License valid","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"license_id":{"type":"string"},"plan_id":{"type":"string"},"feature_flags":{"type":"object","additionalProperties":{"type":"boolean"}},"limits":{"type":"object"},"expires_at":{"type":"string","format":"date-time"},"next_check_seconds":{"type":"integer"},"warning":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"410":{"description":"License expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/me/context":{"get":{"operationId":"getMyContext","summary":"Get the authenticated user's effective org-context envelope","description":"Returns the active org context, the full membership list, and any user preferences that affect the dashboard. Per ADR-044 Piece 1 / migration 164. The dashboard's authoritative endpoint for \"who am I, which org am I in, what are my memberships.\" `active` falls back to the most-recently-accepted multi-user org, then the personal org; `null` only if the user has zero memberships.","tags":["Auth"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"responses":{"200":{"description":"User context envelope.","content":{"application/json":{"schema":{"type":"object","required":["active","memberships","preferences"],"properties":{"active":{"oneOf":[{"type":"object","required":["org_id","name","slug","is_personal","is_owner","role"],"properties":{"org_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"avatar_url":{"type":["string","null"]},"is_personal":{"type":"boolean"},"is_owner":{"type":"boolean"},"role":{"type":"string"},"company_name":{"type":["string","null"]}}},{"type":"null"}]},"memberships":{"type":"array","items":{"type":"object","required":["org_id","name","slug","is_personal","is_owner","role"],"properties":{"org_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"avatar_url":{"type":["string","null"]},"is_personal":{"type":"boolean"},"is_owner":{"type":"boolean"},"role":{"type":"string"},"accepted_at":{"type":["string","null"],"format":"date-time"},"company_name":{"type":["string","null"]}}}},"preferences":{"type":"object","additionalProperties":true,"description":"User preferences blob (e.g., active_org_id, onboarding_completed_at)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"setMyActiveOrg","summary":"Set the authenticated user's active org","description":"Switches the user's active org via `set_user_active_org` RPC; the `active_org_id` is persisted to `user_preferences.preferences`. Body is `{ org_id: string }`. Returns the same envelope shape as `GET /me/context`. Returns 403 with `code: 'not_a_member'` if the user is not a member of the target org. Per ADR-044 Piece 1 / migration 164.","tags":["Auth"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["org_id"],"properties":{"org_id":{"type":"string","description":"Org ID to switch the active context to. The user must be a member."}}}}}},"responses":{"200":{"description":"Active org switched. Response envelope matches GET /me/context."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/network/threat-state":{"get":{"operationId":"getNetworkThreatState","summary":"Per-axis Protection Network threat state","description":"Returns the current aggregated `network_campaign_state` grouped by axis (substrate / vertical / pattern / source), plus per-state totals. Backs the customer-facing L4 thermometer page. Public-aggregate disclosure: any authenticated principal may read; rows carry no per-tenant identifiers (L0 fingerprints only).","tags":["Network"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"max_buckets","in":"query","required":false,"description":"Top-N most elevated buckets returned per axis. Clamped to [1, 50]; default 10.","schema":{"type":"integer","minimum":1,"maximum":50,"default":10}}],"responses":{"200":{"description":"Aggregated threat state snapshot.","content":{"application/json":{"schema":{"type":"object","required":["snapshot_at","totals","by_substrate","by_vertical","by_pattern","by_source"],"properties":{"snapshot_at":{"type":"string","format":"date-time","description":"RPC evaluation timestamp."},"totals":{"type":"object","required":["calm","elevated","high","under_attack","total"],"properties":{"calm":{"type":"integer"},"elevated":{"type":"integer"},"high":{"type":"integer"},"under_attack":{"type":"integer"},"total":{"type":"integer"}}},"by_substrate":{"type":"array","items":{"$ref":"#/components/schemas/NetworkThreatBucket"}},"by_vertical":{"type":"array","items":{"$ref":"#/components/schemas/NetworkThreatBucket"}},"by_pattern":{"type":"array","items":{"$ref":"#/components/schemas/NetworkThreatBucket"}},"by_source":{"type":"array","items":{"$ref":"#/components/schemas/NetworkThreatBucket"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/oauth/authorize":{"get":{"operationId":"oauthAuthorize","summary":"OAuth 2.1 authorization endpoint (renders the consent screen)","description":"Begins the authorization-code + PKCE flow. Identity is delegated to Supabase GoTrue via the Mnemom session cookie; an unauthenticated user is redirected to the hosted login and returns here. With a valid session, renders the server-side consent screen listing the requested scopes in product language. PKCE S256 is mandatory; redirect_uri must exactly match one registered for the client.","tags":["OAuth"],"security":[],"parameters":[{"name":"response_type","in":"query","required":true,"schema":{"type":"string","enum":["code"]}},{"name":"client_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","format":"uri"}},{"name":"scope","in":"query","required":true,"schema":{"type":"string","example":"mcp:read mcp:write"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","required":true,"schema":{"type":"string","enum":["S256"]}}],"responses":{"200":{"description":"Consent screen (HTML).","content":{"text/html":{"schema":{"type":"string"}}}},"302":{"description":"Redirect to the hosted login (unauthenticated) or back to the client's redirect_uri with an error per RFC 6749 §4.1.2.1."},"400":{"description":"Unknown client_id or unregistered redirect_uri — rendered as an HTML error page; never redirected (open-redirect guard).","content":{"text/html":{"schema":{"type":"string"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"oauthAuthorizeDecision","summary":"Submit the OAuth consent decision (Allow / Deny)","description":"Processes the consent form. On Allow, mints a single-use, 60-second authorization code bound to the client, the exact redirect_uri, and the PKCE challenge, then redirects back to the client with code + state. On Deny, redirects with error=access_denied. CSRF-protected (SameSite=Lax cookie + signed token); the acting org is bound here and is immutable for tokens minted from the code.","tags":["OAuth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["decision","client_id","redirect_uri","code_challenge","scope","org_id","csrf"],"properties":{"decision":{"type":"string","enum":["allow","deny"]},"client_id":{"type":"string"},"redirect_uri":{"type":"string","format":"uri"},"state":{"type":"string"},"code_challenge":{"type":"string"},"code_challenge_method":{"type":"string","enum":["S256"]},"response_type":{"type":"string","enum":["code"]},"scope":{"type":"string"},"org_id":{"type":"string"},"csrf":{"type":"string"}}}}}},"responses":{"302":{"description":"Redirect back to the client with code+state, or with an OAuth error."},"400":{"description":"Invalid client/redirect_uri/org selection (HTML).","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"Session expired during consent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid or missing CSRF token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/oauth/register":{"post":{"operationId":"oauthRegisterClient","summary":"OAuth 2.0 Dynamic Client Registration (RFC 7591)","description":"Registers a public OAuth client for the MCP flow. No client secret is issued (PKCE-protected public clients only). redirect_uris must be HTTPS, or an RFC 8252 loopback (http://127.0.0.1[:port]/..., http://[::1][:port]/..., or http://localhost[:port]/...), and are exact-matched at /authorize. Registration is abuse-guarded with per-IP and global daily caps.","tags":["OAuth"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["client_name","redirect_uris"],"properties":{"client_name":{"type":"string","maxLength":200},"redirect_uris":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":5}}}}}},"responses":{"201":{"description":"Client registered (RFC 7591 §3.2.1 client information response).","content":{"application/json":{"schema":{"type":"object","required":["client_id","redirect_uris"],"properties":{"client_id":{"type":"string"},"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string","enum":["none"]},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"client_id_issued_at":{"type":"integer"}}}}}},"400":{"description":"Invalid client metadata or redirect_uri.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"error_description":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/oauth/revoke":{"post":{"operationId":"oauthRevoke","summary":"OAuth token revocation (RFC 7009)","description":"Revokes the presented access or refresh token. Returns 200 even for an unknown token, per RFC 7009 §2.2.","tags":["OAuth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"]}}}}}},"responses":{"200":{"description":"Token revoked (or already unknown)."},"400":{"description":"Missing token parameter.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"error_description":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/oauth/token":{"post":{"operationId":"oauthToken","summary":"OAuth 2.1 token endpoint (code exchange + refresh)","description":"Exchanges an authorization code (+ PKCE code_verifier) for a short-lived opaque access token and a rotating refresh token, or rotates a refresh token. Authorization codes are single-use; refresh tokens are single-use (rotated on every exchange). Public-client posture: no client authentication (token_endpoint_auth_method=none).","tags":["OAuth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"]},"code":{"type":"string"},"redirect_uri":{"type":"string","format":"uri"},"client_id":{"type":"string"},"code_verifier":{"type":"string"},"refresh_token":{"type":"string"}}}}}},"responses":{"200":{"description":"Token response (RFC 6749 §5.1).","content":{"application/json":{"schema":{"type":"object","required":["access_token","token_type","expires_in"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"scope":{"type":"string"}}}}}},"400":{"description":"OAuth error (invalid_request / invalid_grant / unsupported_grant_type).","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"error_description":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/on-chain/history":{"get":{"operationId":"getOnChainHistory","summary":"Get on-chain history","description":"Retrieve the history of on-chain Merkle root anchoring events. Returns a paginated list of all anchors with their transaction details, included agents, and verification status.","tags":["On-Chain"],"security":[],"parameters":[{"name":"chain","in":"query","schema":{"type":"string","enum":["ethereum","polygon","base"]},"description":"Filter by blockchain network"},{"name":"agent_id","in":"query","schema":{"type":"string"},"description":"Filter anchors that include this agent"},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Start of time range"},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"},"description":"End of time range"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum number of records to return"},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Number of records to skip for pagination"}],"responses":{"200":{"description":"On-chain anchoring history","content":{"application/json":{"schema":{"type":"object","properties":{"anchors":{"type":"array","items":{"$ref":"#/components/schemas/OnChainAnchorResult"}},"total":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/on-chain/status/{agent_id}":{"get":{"operationId":"getOnChainStatus","summary":"Get on-chain status","description":"Get the current on-chain anchoring status for an agent. Returns the most recent anchor, pending publications, and overall on-chain coverage statistics.","tags":["On-Chain"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"On-chain status for the agent","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"latest_anchor":{"description":"The most recent on-chain anchor for the agent, or `null` when the agent has no anchors yet.","anyOf":[{"$ref":"#/components/schemas/OnChainAnchorResult"},{"type":"null"}]},"total_anchors":{"type":"integer"},"pending_publications":{"type":"integer"},"coverage":{"type":"object","properties":{"integrity_anchored":{"type":"boolean"},"reputation_anchored":{"type":"boolean"},"last_anchored_at":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/on-chain/verify-proof/{agent_id}":{"get":{"operationId":"verifyOnChainProof","summary":"Verify on-chain proof","description":"Verify an agent's integrity or score proof against the on-chain Merkle root. Checks that the provided proof correctly links the agent's data to an anchored root, confirming the data has not been tampered with since anchoring.","tags":["On-Chain"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"anchor_id","in":"query","schema":{"type":"string"},"description":"Specific anchor ID to verify against. If omitted, verifies against the most recent anchor."},{"name":"score_type","in":"query","schema":{"type":"string","enum":["integrity","reputation","compliance"]},"description":"Type of score proof to verify"}],"responses":{"200":{"description":"Proof verification result","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"agent_id":{"type":"string"},"anchor_id":{"type":"string"},"merkle_root":{"type":"string"},"proof":{"type":"array","items":{"type":"string"}},"score":{"type":"number"},"score_type":{"type":"string"},"anchored_at":{"type":"string","format":"date-time"},"tx_hash":{"type":"string"},"chain":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs":{"post":{"operationId":"createOrg","summary":"Create organization","tags":["Organizations"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","minLength":2,"maxLength":100},"slug":{"type":"string","minLength":3,"maxLength":48,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"}}}}}},"responses":{"201":{"description":"Organization created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"operationId":"listMyOrgs","summary":"List organizations for authenticated user","tags":["Organizations"],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Organizations list","content":{"application/json":{"schema":{"type":"object","properties":{"orgs":{"type":"array","items":{"$ref":"#/components/schemas/Organization"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/invitations/accept":{"post":{"operationId":"acceptInvitation","summary":"Accept an organization invitation","tags":["Organizations"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Invitation accepted","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"org_name":{"type":"string"},"role":{"type":"string"},"personal_subscription_warning":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}":{"get":{"operationId":"getOrg","summary":"Get organization details","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Organization details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"updateOrg","summary":"Update organization","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"billing_email":{"type":"string"},"company_name":{"type":"string"}}}}}},"responses":{"200":{"description":"Organization updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteOrg","summary":"Delete organization (owner only)","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Organization deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/agents":{"get":{"operationId":"getOrgAgents","summary":"List agents in organization","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"mine","in":"query","schema":{"type":"boolean","default":false},"description":"Filter to only current user's agents"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"minimum":1,"maximum":500},"description":"Opt-in pagination: max agents to return. Omit limit AND offset for the full (unpaginated) listing. When supplied, the response adds total/limit/offset."},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Opt-in pagination: number of agents to skip."}],"responses":{"200":{"description":"Organization agents. Includes total/limit/offset only when limit or offset was supplied.","content":{"application/json":{"schema":{"type":"object","required":["agents"],"properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/Agent"}},"total":{"type":"integer","description":"Total agents before pagination (present only when paginating)."},"limit":{"type":"integer","description":"Echoed page size (paginated only)."},"offset":{"type":"integer","description":"Echoed offset (paginated only)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/agents/safe-house-summary":{"get":{"operationId":"getOrgAgentsSafeHouseSummary","summary":"Fleet view of each member agent's Safe House posture","tags":["Safe House"],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Per-agent posture summary.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/agents/{agent_id}/containment":{"get":{"operationId":"getAgentContainment","summary":"Get agent containment status","description":"Returns the current containment status and recent audit log entries. Any org role.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Containment status","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"status":{"type":"string","enum":["active","paused","killed"]},"contained_at":{"type":["string","null"],"format":"date-time"},"contained_by":{"type":["string","null"]},"containment_reason":{"type":["string","null"]},"auto_containment_threshold":{"type":["integer","null"]},"log":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string"},"actor":{"type":"string"},"reason":{"type":["string","null"]},"previous_status":{"type":"string"},"new_status":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/agents/{agent_id}/containment-policy":{"put":{"operationId":"updateContainmentPolicy","summary":"Update auto-containment policy","description":"Set or disable the auto-containment threshold. When set, the agent will be automatically paused after N consecutive boundary violations. Requires owner or admin role.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["auto_containment_threshold"],"properties":{"auto_containment_threshold":{"type":["integer","null"],"minimum":2,"description":"Number of consecutive boundary violations before auto-pause. Set to null to disable."}}}}}},"responses":{"200":{"description":"Policy updated","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"auto_containment_threshold":{"type":["integer","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/agents/{agent_id}/kill":{"post":{"operationId":"killAgent","summary":"Kill an agent","description":"Permanently stop an agent. Requires explicit reactivation to restore. Owner only.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Reason for killing the agent"}}}}}},"responses":{"200":{"description":"Agent killed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"containment_status":{"type":"string","enum":["killed"]},"contained_at":{"type":"string","format":"date-time"},"contained_by":{"type":"string"},"containment_reason":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/agents/{agent_id}/pause":{"post":{"operationId":"pauseAgent","summary":"Pause an agent","description":"Temporarily stop an agent from making API requests. Requires owner or admin role.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Reason for pausing the agent"}}}}}},"responses":{"200":{"description":"Agent paused successfully","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"containment_status":{"type":"string","enum":["paused"]},"contained_at":{"type":"string","format":"date-time"},"contained_by":{"type":"string"},"containment_reason":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/agents/{agent_id}/reactivate":{"post":{"operationId":"reactivateAgent","summary":"Reactivate a killed agent","description":"Restore a killed agent back to active state. Owner only.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent reactivated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"containment_status":{"type":"string","enum":["active"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/agents/{agent_id}/resume":{"post":{"operationId":"resumeAgent","summary":"Resume a paused agent","description":"Resume a paused agent back to active state. Only works on paused agents. Requires owner or admin role.","tags":["Agent Containment"],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent resumed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"containment_status":{"type":"string","enum":["active"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/alignment-template":{"get":{"operationId":"getOrgAlignmentTemplateLegacy","summary":"DEPRECATED — use GET /v1/alignment/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putOrgAlignmentTemplateLegacy","summary":"DEPRECATED — use PUT /v1/alignment/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteOrgAlignmentTemplateLegacy","summary":"DEPRECATED — use DELETE /v1/alignment/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/alignment-template/preview-compose":{"post":{"operationId":"postOrgAlignmentTemplatePreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/alignment/org/{org_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/org/{org_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/api-keys":{"post":{"operationId":"createOrgApiKey","summary":"Create organization API key","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Friendly name for the key (e.g., \"ci-prod\")."},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"},"default":["gateway","api:read","api:write"],"description":"Capability set for this org key (ADR-049). If omitted, the API substitutes the default. The caller is already verified as owner/admin of this org by the route's RBAC gate, so `admin:org` is implicit-eligible here; `admin:platform` still requires Mnemom-staff role."}}}}}},"responses":{"201":{"description":"Org API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"operationId":"listOrgApiKeys","summary":"List organization API keys","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Org API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/api-keys/{key_id}":{"delete":{"operationId":"revokeOrgApiKey","summary":"Revoke organization API key","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"key_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"},"key_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/api-keys/{key_id}/rotate":{"post":{"operationId":"rotateOrgApiKey","summary":"Rotate an organization API key","description":"Atomic mint-new + immediately-revoke-old, with the same `name` and `scopes` as the original. The full new secret is returned only in this response. No grace period — old key is invalid immediately. If you need overlap with an in-flight deploy, create a second key first via `POST /orgs/{org_id}/api-keys`, ship, then `DELETE` the old key. Owners and admins may rotate any org key; members may rotate keys they created.","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"key_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"New key minted, old key revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"key_id":{"type":"string"},"key":{"type":"string","description":"Full secret. Capture now — never returned again."},"key_prefix":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"rotated_from":{"type":"string"},"old_key_revoked_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/audit-log":{"get":{"operationId":"getOrgAuditLog","summary":"Read the org audit log","description":"Returns request-level audit entries scoped to this org: events made with an org-level API key, plus any event on a `/v1/orgs/{org_id}/...` URL. Excludes Mnemom-staff actions on `/v1/admin/*` paths. Compliance-shaped — `owner`, `admin`, and `auditor` roles only.","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Audit entries, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"http_method":{"type":"string"},"path":{"type":"string"},"auth_method":{"type":"string","enum":["jwt","api_key"]},"principal_type":{"type":"string","enum":["user","org"]},"principal_id":{"type":"string"},"key_id":{"type":["string","null"]},"status_code":{"type":"integer"}}}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/avatar":{"put":{"operationId":"putOrgAvatar","summary":"Upload organization avatar","description":"Replace an organization's avatar image. Requires the authenticated principal to hold `owner` or `admin` role on the org.","tags":["Orgs"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Avatar image. Validated for MIME type and size before upload."}}}}}},"responses":{"200":{"description":"Avatar uploaded; persistent URL returned","content":{"application/json":{"schema":{"type":"object","required":["avatar_url"],"properties":{"avatar_url":{"type":"string","format":"uri","description":"Public URL of the uploaded avatar (CDN-served).","example":"https://cdn.mnemom.ai/avatars/agents/mnm-7f3b9e2a/abc123.png"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/orgs/{org_id}/billing/portal-session":{"post":{"operationId":"createOrgBillingPortalSession","summary":"Open the Stripe Customer Portal for this org","description":"Mints a single-use URL into Stripe's hosted Customer Portal where the org admin can view invoices, download PDFs, update payment methods, change billing details, and manage their subscription. The portal is the primary surface for invoice access — there is no direct invoice API. `owner` and `admin` only (the portal is a mixed read+mutate surface; auditors have a separate read-only path via `GET /orgs/{org_id}/billing/summary`).","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"return_url":{"type":"string","format":"uri","description":"Where Stripe redirects the customer after they finish in the portal. Must be `https://*.mnemom.ai`. Defaults to the dashboard billing page."}}}}}},"responses":{"200":{"description":"Portal session created. Redirect the customer to `url`.","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/billing/summary":{"get":{"operationId":"getOrgBillingSummary","summary":"Read-only billing summary for the org","description":"Plan + customer-safe account state + 30-day usage rollup. Does **not** include invoice history (use `POST /orgs/{org_id}/billing/portal-session` for that) or recent billing events (the org audit log covers events generally). Internal Stripe identifiers and Mnemom-staff notes are scrubbed from the response. `owner`, `admin`, and `auditor` only.","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Summary payload.","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"type":"object","additionalProperties":true},"plan":{"type":"object","additionalProperties":true},"usage_rollup":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"check_count":{"type":"integer"},"tokens_in":{"type":"integer"},"tokens_out":{"type":"integer"},"cost_estimate":{"type":"number"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/coherence":{"get":{"operationId":"getOrgCoherence","summary":"N-Way value coherence for the org fleet (with care-framed recommendations)","description":"Returns a dimensional team-coherence vector (pairwise_governance_median / floor / max, conflict_edge_count, outlier_agents, pairwise) computed from the active alignment cards of every agent in the org. The response also carries `recommendations[]` — care-framed actionable suggestions derived from the structural findings (cards-as-primitive Phase 4 W2.5). Requires at least 2 agents with alignment cards — returns `insufficient_agents` otherwise. Cached 5 minutes in `fleet_coherence_snapshots`; recommendations are recomputed on each read so older snapshots gain the field without backfill. Feature-gated: `nway_coherence`. See ADR-025 (E-05).","tags":["Organizations"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"x-feature-gate":"nway_coherence","parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Team-coherence result (or `insufficient_agents` stub).","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Team-coherence vector (v2 / ADR-025).","additionalProperties":true,"properties":{"pair_count":{"type":"integer"},"pairwise_governance_median":{"type":["number","null"]},"pairwise_governance_floor":{"type":["number","null"]},"conflict_edge_count":{"type":"integer"},"outlier_agents":{"type":"array"},"pairwise":{"type":"array"},"conscience_universal":{"type":["boolean","null"]},"recommendations":{"type":"array","description":"Care-framed actionable recommendations derived from the structural findings. Each entry carries a `for_finding` discriminator (`outlier_agents`, `pairwise_governance_floor`, `conflict_edges`) plus interpretive prose. cards-as-primitive Phase 4 W2.5.","items":{"type":"object","required":["for_finding","text"],"properties":{"for_finding":{"type":"string","enum":["outlier_agents","pairwise_governance_floor","conflict_edges"]},"text":{"type":"string"}}}}}},{"type":"object","properties":{"error":{"type":"string","enum":["insufficient_agents"]},"agent_count":{"type":"integer"},"message":{"type":"string"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/conscience-values":{"get":{"operationId":"listOrgConscienceValues","summary":"List org conscience values","description":"Returns all conscience values for the org, along with mode and enabled status. Requires Enterprise plan with custom_conscience_values feature flag.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Conscience values list","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"mode":{"type":"string","enum":["augment","replace"]},"enabled":{"type":"boolean"},"values":{"type":"array","items":{"$ref":"#/components/schemas/OrgConscienceValue"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"post":{"operationId":"createOrgConscienceValue","summary":"Create org conscience value","description":"Create a new custom conscience value. Max 20 per org. Requires owner or admin role.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","description","type"],"properties":{"name":{"type":"string","minLength":1,"maxLength":50},"description":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["BOUNDARY","FEAR","COMMITMENT","BELIEF","HOPE"]},"severity":{"type":"string","enum":["advisory","mandatory"],"default":"advisory"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgConscienceValue"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/conscience-values/log":{"get":{"operationId":"getOrgConscienceAuditLog","summary":"Get conscience values audit log","description":"Returns the audit trail for conscience value changes. Requires owner, admin, or auditor role.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Audit log entries","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/OrgConscienceAuditEntry"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/conscience-values/mode":{"put":{"operationId":"updateOrgConscienceMode","summary":"Update org conscience mode","description":"Set the conscience mode (augment/replace) and enabled flag.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["augment","replace"]},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"mode":{"type":"string","enum":["augment","replace"]},"enabled":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/conscience-values/order":{"put":{"operationId":"reorderOrgConscienceValues","summary":"Reorder org conscience values","description":"Set the sort order for all conscience values.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["order"],"properties":{"order":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Reordered","content":{"application/json":{"schema":{"type":"object","properties":{"reordered":{"type":"boolean"},"order":{"type":"array","items":{"type":"string"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/conscience-values/{value_id}":{"patch":{"operationId":"updateOrgConscienceValue","summary":"Update org conscience value","description":"Update fields on an existing conscience value. Requires owner or admin role.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"value_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":50},"description":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["BOUNDARY","FEAR","COMMITMENT","BELIEF","HOPE"]},"severity":{"type":"string","enum":["advisory","mandatory"]},"is_active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgConscienceValue"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"delete":{"operationId":"deleteOrgConscienceValue","summary":"Delete org conscience value","description":"Permanently delete a conscience value. Requires owner or admin role.","tags":["Conscience Values"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"value_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/costs":{"get":{"operationId":"getOrgCosts","summary":"Per-model cost rollup for the org","description":"Daily usage broken down by model with a USD cost estimate per row plus aggregate totals. Cost figures are estimates derived from Mnemom's published per-model pricing applied to your actual token volume; authoritative billing is in Stripe (see `POST /orgs/{org_id}/billing/portal-session`). Billing-shaped — `owner`, `admin`, and `auditor` only.","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Daily cost rows + totals.","content":{"application/json":{"schema":{"type":"object","properties":{"period":{"type":"string","example":"daily"},"days":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"model":{"type":"string"},"tokens_in":{"type":"integer"},"tokens_out":{"type":"integer"},"request_count":{"type":"integer"},"cost_usd":{"type":"number"}}}},"totals":{"type":"object","properties":{"total_cost_usd":{"type":"number"},"total_tokens_in":{"type":"integer"},"total_tokens_out":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/deployments":{"get":{"operationId":"listOrgDeployments","summary":"List self-hosted deployments for an org","description":"Any org member (owner / admin / member / viewer / auditor) may list deployments. Filter by `status` (`active`, `inactive`, `degraded`).","tags":["Licensing"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","inactive","degraded"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Deployment list.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/SelfHostedDeployment"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"registerOrgDeployment","summary":"Register a new self-hosted deployment","description":"Requires org `owner` or `admin`. The `license_id` must already exist and belong to this org (verified via `verify_org_license` RPC). The deployment starts in `active` status.","tags":["Licensing"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["instance_name","instance_id","license_id"],"properties":{"instance_name":{"type":"string"},"instance_id":{"type":"string"},"license_id":{"type":"string"},"region":{"type":["string","null"]},"version":{"type":["string","null"]},"instance_metadata":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Deployment registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelfHostedDeployment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/deployments/{deployment_id}":{"get":{"operationId":"getOrgDeployment","summary":"Get a self-hosted deployment","tags":["Licensing"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"deployment_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelfHostedDeployment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"updateOrgDeployment","summary":"Update a self-hosted deployment","description":"Partial update. Requires org `owner` or `admin`. Allowed fields: `instance_name`, `region`, `status` (`active`/`inactive`/`degraded`), `version`, `instance_metadata`.","tags":["Licensing"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"deployment_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"instance_name":{"type":"string"},"region":{"type":["string","null"]},"status":{"type":"string","enum":["active","inactive","degraded"]},"version":{"type":["string","null"]},"instance_metadata":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Update accepted.","content":{"application/json":{"schema":{"type":"object","properties":{"deployment_id":{"type":"string"},"updated":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteOrgDeployment","summary":"Delete a self-hosted deployment","description":"Requires org `owner` or `admin`. Hard-deletes the `self_hosted_deployments` row. The license remains valid — re-register to replace.","tags":["Licensing"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"deployment_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deployment_id":{"type":"string"},"deleted":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/drift":{"get":{"operationId":"getOrgDrift","summary":"Paginated drift alerts for an org fleet","description":"Returns active and recent drift alerts for every agent in the org, plus a summary block (total_active, agents_drifting, high_severity, trend). Any org member may read. Feature-gated: `fleet_dashboard`.","tags":["Drift"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"x-feature-gate":"fleet_dashboard","parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Drift alerts + summary.","content":{"application/json":{"schema":{"type":"object","properties":{"alerts":{"type":"array","items":{"$ref":"#/components/schemas/DriftAlert"}},"summary":{"type":"object","properties":{"total_active":{"type":"integer"},"agents_drifting":{"type":"integer"},"high_severity":{"type":"integer"},"trend":{"type":"string","enum":["stable","worsening","improving"]}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/drift/{alert_id}/acknowledge":{"post":{"operationId":"acknowledgeOrgDriftAlert","summary":"Acknowledge a drift alert","description":"Marks a drift alert as acknowledged. Only org owner / admin / member may acknowledge (viewers and auditors cannot). Emits a `drift.resolved` webhook (fail-open). Feature-gated: `fleet_dashboard`.","tags":["Drift"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"x-feature-gate":"fleet_dashboard","parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Acknowledged.","content":{"application/json":{"schema":{"type":"object","properties":{"acknowledged":{"type":"boolean"},"alert_id":{"type":"string"},"acknowledged_by":{"type":"string"},"acknowledged_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/export/fleet":{"get":{"operationId":"exportOrgFleet","summary":"Export a snapshot of the org's agent fleet","description":"Returns a fleet roster in CSV (default) or PDF format, suitable for compliance review / board reporting. Any org member may export. Feature-gated: `fleet_dashboard`.","tags":["Organizations"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"x-feature-gate":"fleet_dashboard","parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["csv","pdf"],"default":"csv"}}],"responses":{"200":{"description":"Fleet export.","content":{"text/csv":{"schema":{"type":"string"}},"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/governance/coverage":{"get":{"operationId":"getOrgGovernanceCoverage","summary":"30-day governance coverage rollup","description":"Aggregate metrics: signals fired vs. acknowledged vs. resolved per source + severity over a configurable window. Default window is 30 days.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":90,"default":30}}],"responses":{"200":{"description":"Coverage rollup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceCoverageReport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/escalation-rules":{"get":{"operationId":"listGovernanceEscalationRules","summary":"List escalation rules for an org","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Escalation rules listing.","content":{"application/json":{"schema":{"type":"object","required":["rules"],"properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceEscalationRule"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createGovernanceEscalationRule","summary":"Create an escalation rule","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name","predicate","destination_ids"],"properties":{"name":{"type":"string"},"predicate":{"$ref":"#/components/schemas/GovernanceEscalationPredicate"},"destination_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Allowed empty when enabled is false (Tier 4 §4.4 default rules)"},"enabled":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Escalation rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceEscalationRule"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/escalation-rules/{rule_id}":{"patch":{"operationId":"updateGovernanceEscalationRule","summary":"Update an escalation rule","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"predicate":{"$ref":"#/components/schemas/GovernanceEscalationPredicate"},"destination_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Allowed empty when enabled is false (Tier 4 §4.4 default rules)"},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Escalation rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceEscalationRule"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteGovernanceEscalationRule","summary":"Delete an escalation rule","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"additionalProperties":false,"properties":{"ok":{"type":"boolean","enum":[true]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/notification-destinations":{"get":{"operationId":"listGovernanceDestinations","summary":"List notification destinations for an org","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Notification destinations listing.","content":{"application/json":{"schema":{"type":"object","required":["destinations"],"properties":{"destinations":{"type":"array","items":{"$ref":"#/components/schemas/GovernanceNotificationDestination"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createGovernanceDestination","summary":"Create a notification destination","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["channel","config"],"properties":{"channel":{"$ref":"#/components/schemas/GovernanceNotificationChannel"},"config":{"type":"object","additionalProperties":true},"filter":{"$ref":"#/components/schemas/GovernanceDestinationFilter"},"enabled":{"type":"boolean","default":true},"display_name":{"type":"string"}}}}}},"responses":{"201":{"description":"Notification destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceNotificationDestination"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/notification-destinations/{destination_id}":{"patch":{"operationId":"updateGovernanceDestination","summary":"Update a notification destination","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"destination_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"config":{"type":"object","additionalProperties":true},"filter":{"$ref":"#/components/schemas/GovernanceDestinationFilter"},"enabled":{"type":"boolean"},"display_name":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Notification destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceNotificationDestination"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteGovernanceDestination","summary":"Delete a notification destination","description":"Authorized: org_admin or org_owner.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"destination_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"additionalProperties":false,"properties":{"ok":{"type":"boolean","enum":[true]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/notification-destinations/{destination_id}/test":{"post":{"operationId":"testGovernanceDestination","summary":"Send a synthetic signal through a destination","description":"Bypasses escalation rules and dispatches a test payload directly to the destination. Records `last_tested_at` + `last_test_status` on the row.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"destination_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Test outcome.","content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok","failed"]},"error":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/governance/signals":{"get":{"operationId":"listOrgGovernanceSignals","summary":"List governance signals for an org","description":"Returns governance signals scoped to the given org, filterable by source, severity, status, and pattern_type. Any org member may read.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"source","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSource"},"description":"Filter by source detector."},{"name":"severity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"description":"Filter by severity."},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalStatus"},"description":"Filter by workflow status."},{"name":"pattern_type","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by pattern_type within the source's taxonomy."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Governance signals listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignalsListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/invitations":{"post":{"operationId":"inviteMember","summary":"Invite member to organization","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","member","viewer","auditor"],"default":"member"}}}}}},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgInvitation"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"get":{"operationId":"listInvitations","summary":"List pending invitations","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Invitations list","content":{"application/json":{"schema":{"type":"object","properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/OrgInvitation"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/invitations/{invitation_id}":{"delete":{"operationId":"revokeInvitation","summary":"Revoke a pending invitation","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation revoked","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"},"invitation_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/members":{"get":{"operationId":"listMembers","summary":"List organization members","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Members list","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/OrgMember"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/members/{user_id}":{"patch":{"operationId":"updateMemberRole","summary":"Update member role (owner only)","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"user_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","member","viewer","auditor"]}}}}}},"responses":{"200":{"description":"Role updated","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"user_id":{"type":"string"},"old_role":{"type":"string"},"new_role":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"delete":{"operationId":"removeMember","summary":"Remove member or self-leave","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"user_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Member removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"},"org_id":{"type":"string"},"user_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/protection-template":{"get":{"operationId":"getOrgProtectionTemplateLegacy","summary":"DEPRECATED — use GET /v1/protection/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putOrgProtectionTemplateLegacy","summary":"DEPRECATED — use PUT /v1/protection/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteOrgProtectionTemplateLegacy","summary":"DEPRECATED — use DELETE /v1/protection/org/{org_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/org/{org_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/protection-template/preview-compose":{"post":{"operationId":"postOrgProtectionTemplatePreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/protection/org/{org_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/org/{org_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/safe-house/enable":{"post":{"operationId":"enableOrgSafeHouse","summary":"Enable or change the Safe House posture for an org","description":"Customer-admin entry point to set the Safe House mode for an organization. Mirrors the staff-only `POST /v1/admin/safe-house/enable` route; both call the same `enable_sh_for_org(p_org_id, p_mode)` RPC. Caller must be an `owner` or `admin` of the target org.","tags":["Safe House"],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["disabled","off","observe","enforce","enforce_sync"],"default":"observe","description":"Target Safe House mode. Defaults to `observe` when omitted."}}}}}},"responses":{"200":{"description":"Mode applied. Response shape mirrors the staff endpoint.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/sso":{"get":{"operationId":"getSsoConfig","summary":"Get SSO configuration for organization","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"SSO config or not configured","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"configureSso","summary":"Configure SAML SSO for organization (owner only)","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["metadata_url","allowed_domains"],"properties":{"metadata_url":{"type":"string","format":"uri"},"idp_name":{"type":"string"},"default_role":{"type":"string","enum":["admin","member","viewer","auditor"],"default":"member"},"allowed_domains":{"type":"array","items":{"type":"string"},"minItems":1},"enforced":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"SSO configured","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"removeSso","summary":"Remove SSO configuration (owner only)","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"SSO removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"},"note":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/sso/test":{"post":{"operationId":"testSso","summary":"Test SSO metadata URL validity","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"metadata_url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"SSO test result","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"error":{"type":["string","null"]},"metadata_url":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/teams":{"get":{"operationId":"listOrgTeams","summary":"List teams in organization","description":"List all teams belonging to an organization, filtered by status.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","archived"],"default":"active"},"description":"Filter by team status"},{"name":"page","in":"query","schema":{"type":"integer","default":1},"description":"Page number"},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200},"description":"Results per page (max 200)"}],"responses":{"200":{"description":"Paginated list of teams","content":{"application/json":{"schema":{"type":"object","properties":{"teams":{"type":"array","items":{"$ref":"#/components/schemas/Team"}},"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/trust-posture":{"get":{"operationId":"getOrgTrustPosture","summary":"Get the org's effective trust posture (Platform → Org cascade)","description":"Org-level shortcut for the Platform → Org cascade. Closes the T7-F4 agent-affordance gap — agents asking 'what trust posture has this org published?' can hit one endpoint instead of walking org → teams → per-team posture. Distinct from `/teams/{team_id}/effective-posture` which includes the team layer. Returns `effective` = the org's assigned posture when set, else the platform default (Charter §I13 floor `tp-platform-standard`).","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Org-level effective trust posture.","content":{"application/json":{"schema":{"type":"object","required":["org_id","org_name","gathered","effective"],"properties":{"org_id":{"type":"string"},"org_slug":{"type":["string","null"]},"org_name":{"type":"string"},"gathered":{"type":"object","properties":{"platform_default":{"type":["object","null"],"description":"Platform-default posture layer (always present in healthy state)."},"org_assigned":{"type":["object","null"],"description":"Org's explicitly-chosen default posture, or null if the org inherits the platform default."}}},"effective":{"type":["object","null"],"description":"Org-effective layer (org_assigned ?? platform_default)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/usage":{"get":{"operationId":"getOrgUsage","summary":"Daily request + token totals for the org","description":"Operational usage metrics — request count plus token volume per day. Dashboard-shaped: visible to all org roles except viewer (members and auditors retain access for self-monitoring and compliance respectively). For dollar-cost rollups see `GET /orgs/{org_id}/costs`.","tags":["Organizations"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Daily usage rows.","content":{"application/json":{"schema":{"type":"object","properties":{"period":{"type":"string","example":"daily"},"days":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"requests":{"type":"integer"},"tokens_in":{"type":"integer"},"tokens_out":{"type":"integer"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/webhooks":{"post":{"operationId":"createWebhookEndpoint","summary":"Create a webhook endpoint","description":"Create a new webhook endpoint for the organization. Returns the signing secret (shown only once). Maximum 5 endpoints per organization.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL that will receive webhook POST requests"},"description":{"type":"string","description":"Human-readable description of this endpoint"},"event_types":{"type":"array","items":{"type":"string","enum":["integrity.violation","integrity.checkpoint","drift.resolved","conscience.escalation","quota.warning","quota.exceeded","subscription.status_changed","agent.paused","agent.resumed","agent.killed","conscience.values_updated","reputation.score_changed","reputation.grade_changed","quota.risk_exceeded","quota.risk_warning","team.created","team.archived","team.member_added","team.member_removed","team.card_updated","quota.team_reputation_exceeded","quota.team_reputation_warning","quota.sh_warning","sh.evaluation.warn","sh.evaluation.quarantine","sh.evaluation.block","sh.canary.triggered","sh.session.escalated","sh.campaign.detected","recipe.promoted","recipe.retired","recipe.candidate.created","reviewer-mode.changed","trace.created","trace.verified","trace.failed","trace.escalation_required","policy.violation","transaction.completed","alignment_card.updated","protection_card.updated","org_alignment_template.updated","org_alignment_template.deleted","org_protection_template.updated","org_protection_template.deleted","agent.exemption.granted","agent.exemption.revoked","sideband.coherence.fired","sideband.fault_line.fired","sideband.fleet.fired","sideband.drift.fired","advisory.published","ioc.added","network.campaign.closed"]},"description":"Event types to subscribe to. Empty array means all events. See the webhook event catalog for the full list and per-event payload schemas."}}}}}},"responses":{"201":{"description":"Webhook endpoint created. Response includes signing_secret (shown only once).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"get":{"operationId":"listWebhookEndpoints","summary":"List webhook endpoints","description":"List all webhook endpoints for the organization. Signing secrets are not included.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"List of webhook endpoints","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpointPublic"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/webhooks/deliveries":{"get":{"operationId":"getWebhookDeliveryLog","summary":"Get webhook delivery log","description":"Paginated delivery log for the organization. Optionally filter by endpoint_id.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"endpoint_id","in":"query","schema":{"type":"string"},"description":"Filter deliveries to a specific endpoint"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Number of deliveries to return (max 100)"},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"Offset for pagination"}],"responses":{"200":{"description":"Delivery log entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/webhooks/deliveries/{delivery_id}/redeliver":{"post":{"operationId":"redeliverWebhookEvent","summary":"Redeliver a webhook event","description":"Create a new delivery attempt for a previously failed event. A new delivery row is created with next_attempt_at set to now.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string"},"description":"Delivery identifier (e.g. whd-abc12345)"}],"responses":{"201":{"description":"New delivery created","content":{"application/json":{"schema":{"type":"object","properties":{"delivery_id":{"type":"string"},"event_id":{"type":"string"},"status":{"type":"string","enum":["pending"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/webhooks/events/{event_id}/replay":{"post":{"operationId":"replayWebhookEvent","summary":"Replay a webhook event to its eligible endpoints","description":"Re-dispatches a previously recorded webhook event to all org endpoints subscribed to its event_type (or to the explicit subset supplied in the request body). Requires the `webhook_notifications` feature flag and owner/admin role on the target org. Cross-tenant access returns 404. Replay is idempotent on the `Idempotency-Key` header; a replayed key with a different body returns 422 and a conflicting in-flight key returns 409. When no endpoints are eligible the response is 200 with an empty `deliveries` array; when at least one delivery is enqueued the response is 201 with delivery descriptors (and an optional `failed_endpoints` list for endpoints that could not be enqueued).","tags":["Webhook Notifications"],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"event_id","in":"path","required":true,"description":"Identifier of the webhook event to replay. Must belong to the path org_id; cross-tenant lookups return 404.","schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Client-supplied key that makes replay idempotent. Re-sending the same key with the same body returns the original result; re-sending with a different body returns 422; a conflicting in-flight key returns 409.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"endpoint_ids":{"type":"array","description":"Optional explicit subset of endpoint ids to replay to. Endpoints not subscribed to the event's type are silently skipped. When omitted, all eligible endpoints are targeted.","items":{"type":"string","format":"uuid"},"maxItems":100,"uniqueItems":true}}}}}},"responses":{"200":{"description":"No eligible endpoints — nothing was enqueued. Returned when the event has no subscribers (or the supplied `endpoint_ids` subset matches none).","content":{"application/json":{"schema":{"type":"object","required":["event_id","event_type","deliveries","message"],"properties":{"event_id":{"type":"string","format":"uuid"},"event_type":{"type":"string"},"deliveries":{"type":"array","maxItems":0,"items":{}},"message":{"type":"string"}}}}}},"201":{"description":"One or more deliveries were enqueued for replay.","content":{"application/json":{"schema":{"type":"object","required":["event_id","event_type","deliveries"],"properties":{"event_id":{"type":"string","format":"uuid"},"event_type":{"type":"string"},"deliveries":{"type":"array","items":{"type":"object","required":["delivery_id","endpoint_id"],"properties":{"delivery_id":{"type":"string","format":"uuid"},"endpoint_id":{"type":"string","format":"uuid"}}}},"failed_endpoints":{"type":"array","description":"Endpoints that matched the event but could not be enqueued (e.g. transient infrastructure error). Each entry names the endpoint and the reason.","items":{"type":"object","required":["endpoint_id","reason"],"properties":{"endpoint_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/webhooks/health":{"get":{"operationId":"getOrgWebhookHealth","summary":"Webhook delivery health for this org","description":"Returns active + disabled endpoint counts, 24-hour delivery counts (success / failed / total), success rate, and the top event types delivered in the last 24 hours. Useful for Status-page-style dashboards or monitoring integrations. Read-only: `owner`, `admin`, and `auditor`.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Health metrics.","content":{"application/json":{"schema":{"type":"object","properties":{"active_endpoints":{"type":"integer"},"disabled_endpoints":{"type":"integer"},"deliveries_24h":{"type":"integer"},"success_24h":{"type":"integer"},"failed_24h":{"type":"integer"},"success_rate_24h":{"type":"number"},"top_event_types":{"type":"array","items":{"type":"object","properties":{"event_type":{"type":"string"},"count":{"type":"integer"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/orgs/{org_id}/webhooks/listen":{"get":{"operationId":"listenWebhookEvents","summary":"Stream webhook events for an org over Server-Sent Events","description":"Opens a Server-Sent Events stream that emits webhook events delivered to the org in near-real-time. Requires the `webhook_notifications` feature flag and owner/admin role on the target org. The cursor is resolved from the `since` query parameter, falling back to the `Last-Event-ID` header when `since` is absent — clients reconnecting after a drop should send the last event id they observed. The stream caps at 5 minutes per connection, polls the underlying queue every 1 second, and emits a keepalive comment every 15 seconds. Frame types emitted on the stream:\n\n- `ready` — sent immediately after the stream opens, carries the resolved cursor.\n- `webhook.event` — one frame per webhook event, payload mirrors the event record.\n- keepalive — SSE comment line (`:keepalive`) every 15s to keep intermediaries from idling the connection.\n- `close` — sent when the 5-minute cap is reached, before the server closes the socket.\n- `error` — sent on unrecoverable stream errors before the socket closes.","tags":["Webhook Notifications"],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"since","in":"query","required":false,"description":"Cursor (event id) to resume from. When omitted, the server falls back to the `Last-Event-ID` request header; when neither is supplied, the stream starts at the current tail.","schema":{"type":"string"}},{"name":"Last-Event-ID","in":"header","required":false,"description":"Standard SSE reconnection header. Used as the cursor when the `since` query parameter is not supplied.","schema":{"type":"string"}}],"responses":{"200":{"description":"Server-Sent Events stream of webhook events. The connection is capped at 5 minutes; clients should reconnect and resume via `Last-Event-ID` or `since`.","headers":{"Cache-Control":{"description":"Disables intermediary caching of the stream.","schema":{"type":"string","enum":["no-cache"]}},"X-Accel-Buffering":{"description":"Disables proxy response buffering (nginx-family) so frames flush immediately.","schema":{"type":"string","enum":["no"]}},"Connection":{"description":"Keeps the underlying TCP connection open for the duration of the stream.","schema":{"type":"string","enum":["keep-alive"]}}},"content":{"text/event-stream":{"schema":{"type":"string","description":"Sequence of SSE frames. Each non-keepalive frame has an `event:` line naming the frame type (`ready`, `webhook.event`, `close`, `error`), an `id:` line carrying the event cursor (for `webhook.event` frames), and a `data:` line containing a JSON payload. Keepalive frames are SSE comments (`:keepalive`)."}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"BearerAuth":[]}]}},"/orgs/{org_id}/webhooks/{endpoint_id}":{"get":{"operationId":"getWebhookEndpoint","summary":"Get webhook endpoint details","description":"Get details for a single webhook endpoint. Signing secret is not included.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"$ref":"#/components/parameters/EndpointId"}],"responses":{"200":{"description":"Webhook endpoint details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointPublic"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"patch":{"operationId":"updateWebhookEndpoint","summary":"Update webhook endpoint","description":"Update an existing webhook endpoint. Re-enabling a disabled endpoint resets the failure counter.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"$ref":"#/components/parameters/EndpointId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"New HTTPS URL"},"description":{"type":"string"},"event_types":{"type":"array","items":{"type":"string","enum":["integrity.violation","integrity.checkpoint","drift.resolved","conscience.escalation","quota.warning","quota.exceeded","subscription.status_changed","agent.paused","agent.resumed","agent.killed","conscience.values_updated","reputation.score_changed","reputation.grade_changed","quota.risk_exceeded","quota.risk_warning","team.created","team.archived","team.member_added","team.member_removed","team.card_updated","quota.team_reputation_exceeded","quota.team_reputation_warning","quota.sh_warning","sh.evaluation.warn","sh.evaluation.quarantine","sh.evaluation.block","sh.canary.triggered","sh.session.escalated","sh.campaign.detected","recipe.promoted","recipe.retired","recipe.candidate.created","reviewer-mode.changed","trace.created","trace.verified","trace.failed","trace.escalation_required","policy.violation","transaction.completed","alignment_card.updated","protection_card.updated","org_alignment_template.updated","org_alignment_template.deleted","org_protection_template.updated","org_protection_template.deleted","agent.exemption.granted","agent.exemption.revoked","sideband.coherence.fired","sideband.fault_line.fired","sideband.fleet.fired","sideband.drift.fired","advisory.published","ioc.added","network.campaign.closed"]}},"is_active":{"type":"boolean","description":"Set to true to re-enable a disabled endpoint (resets failure counter)"}}}}}},"responses":{"200":{"description":"Updated endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointPublic"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"delete":{"operationId":"deleteWebhookEndpoint","summary":"Delete webhook endpoint","description":"Permanently delete a webhook endpoint and all its delivery history.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"$ref":"#/components/parameters/EndpointId"}],"responses":{"200":{"description":"Endpoint deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"endpoint_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/webhooks/{endpoint_id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","summary":"Rotate webhook signing secret","description":"Generate a new signing secret for the endpoint. The new secret is returned once. Previous secret is immediately invalidated.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"$ref":"#/components/parameters/EndpointId"}],"responses":{"200":{"description":"New signing secret (shown only once)","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint_id":{"type":"string"},"signing_secret":{"type":"string","description":"New 32-byte hex-encoded signing secret. Store securely — not retrievable again."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/orgs/{org_id}/webhooks/{endpoint_id}/test":{"post":{"operationId":"testWebhookEndpoint","summary":"Send test webhook delivery","description":"Send a synchronous test delivery to the endpoint with a synthetic webhook.test event. Returns the delivery result immediately.","tags":["Webhook Notifications"],"security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"$ref":"#/components/parameters/EndpointId"}],"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":["integer","null"],"description":"HTTP response status code from the endpoint"},"latency_ms":{"type":["integer","null"],"description":"Round-trip time in milliseconds"},"error":{"type":["string","null"],"description":"Error message if delivery failed"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/plans":{"get":{"operationId":"listPublicPlans","security":[],"summary":"List public pricing plans","tags":["Billing"],"responses":{"200":{"description":"Public plans","content":{"application/json":{"schema":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/plans/public":{"get":{"operationId":"listPublicPlansAlias","summary":"List public pricing plans (alias of `/plans`)","description":"Returns non-archived, public-visibility plans sorted by `sort_order`. Identical to `GET /plans`; this alias exists for stable linking from marketing pages.","tags":["Billing"],"security":[],"responses":{"200":{"description":"Public plan list.","content":{"application/json":{"schema":{"type":"object","required":["plans"],"properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/policies/evaluate":{"post":{"operationId":"evaluatePolicy","summary":"Evaluate policy against tools","description":"Evaluate a CLPI policy against a list of tools to determine which are allowed, forbidden, or unmapped. Returns a verdict with detailed violations, warnings, card coverage gaps, and overall coverage percentage. Useful for dry-run validation before deploying a policy.","tags":["Policy"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["policy","tools"],"properties":{"policy":{"$ref":"#/components/schemas/Policy"},"tools":{"type":"array","items":{"type":"string"},"description":"List of tool identifiers to evaluate against the policy"},"agent_id":{"type":"string","description":"Optional agent ID to include agent-specific context in evaluation"}}}}}},"responses":{"200":{"description":"Policy evaluation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/policies/evaluate/historical":{"post":{"operationId":"evaluatePolicyHistorical","summary":"Evaluate policy against historical traces","description":"Evaluate a CLPI policy against historical AIP traces for an agent. Replays past tool invocations through the policy to identify what would have been blocked, escalated, or flagged. Useful for understanding the impact of a policy change before rolling it out.","tags":["Policy"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["policy","agent_id"],"properties":{"policy":{"$ref":"#/components/schemas/Policy"},"agent_id":{"type":"string","description":"Agent whose historical traces will be evaluated"},"from":{"type":"string","format":"date-time","description":"Start of time range for historical traces"},"to":{"type":"string","format":"date-time","description":"End of time range for historical traces"},"limit":{"type":"integer","default":100,"description":"Maximum number of traces to evaluate"}}}}}},"responses":{"200":{"description":"Historical evaluation result","content":{"application/json":{"schema":{"type":"object","properties":{"evaluation":{"$ref":"#/components/schemas/PolicyEvaluationResult"},"traces_evaluated":{"type":"integer"},"time_range":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures":{"get":{"operationId":"listPostures","summary":"List postures","tags":["Postures"],"description":"Returns platform-default postures plus, when org_id is supplied, the org's postures. Soft-deleted postures excluded by default.","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"query","schema":{"type":"string"},"description":"Limit to platform-defaults + this org's postures."},{"name":"include_platform","in":"query","schema":{"type":"boolean","default":true}},{"name":"include_deleted","in":"query","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"minimum":1,"maximum":200},"description":"Opt-in pagination: max postures to return. Omit limit AND offset for the full (unpaginated) listing. When supplied, the response adds total/limit/offset and only the returned page is body-hydrated."},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Opt-in pagination: number of postures to skip."}],"responses":{"200":{"description":"Postures listing. Includes total/limit/offset only when limit or offset was supplied.","content":{"application/json":{"schema":{"type":"object","required":["postures"],"properties":{"postures":{"type":"array","items":{"$ref":"#/components/schemas/Posture"}},"total":{"type":"integer","description":"Total postures before pagination (present only when paginating)."},"limit":{"type":"integer","description":"Echoed page size (paginated only)."},"offset":{"type":"integer","description":"Echoed offset (paginated only)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createPosture","summary":"Create a posture","description":"Authorized: org_admin / org_owner for org-scope; platform admins for platform-scope.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug","name","scope","body"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"scope":{"$ref":"#/components/schemas/PostureScope"},"org_id":{"type":"string","description":"Required when scope=org."},"body":{"$ref":"#/components/schemas/PostureBody"}}}}}},"responses":{"201":{"description":"Posture.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Posture"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}":{"get":{"operationId":"getPosture","summary":"Read a posture's current revision","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"responses":{"200":{"description":"Posture.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Posture"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putPosture","summary":"Write a new revision of a posture (forward-only)","description":"Creates a new immutable revision; updates current_revision_id pointer.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."},{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"$ref":"#/components/schemas/PostureBody"},"change_note":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated posture with new revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostureRevision"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deletePosture","summary":"Soft-delete a posture","description":"Sets deleted_at; revisions retained for audit.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."},{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"responses":{"200":{"description":"Soft-deleted (sets deleted_at; revisions retained for audit).","content":{"application/json":{"schema":{"type":"object","required":["posture_id","deleted"],"additionalProperties":false,"properties":{"posture_id":{"type":"string"},"deleted":{"type":"boolean","enum":[true]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/assign":{"post":{"operationId":"assignPosture","summary":"Assign a posture to a team","description":"Sets the team's active posture. One active posture per team. Authorized: org_admin / org_owner / team_admin.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."},{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","format":"uuid"},"revision_id":{"type":"string","description":"Pin to a specific revision (default: current_revision_id)."}}}}}},"responses":{"201":{"description":"Assignment created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostureAssignment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/assignments/{team_id}":{"delete":{"operationId":"unassignPosture","summary":"Unassign a team from a posture","description":"Authorized: org_admin / org_owner / team_admin.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."},{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."},{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Unassigned (the team's posture assignment was removed).","content":{"application/json":{"schema":{"type":"object","required":["posture_id","team_id","removed"],"additionalProperties":false,"properties":{"posture_id":{"type":"string"},"team_id":{"type":"string","format":"uuid"},"removed":{"type":"boolean","enum":[true]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/clone":{"post":{"operationId":"clonePosture","summary":"Clone a posture into an org","description":"Copies the posture and its current revision into the target org's scope. Authorized: org_admin / org_owner of the destination org.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied idempotency token (required). Replays within 24 hours return the stored result; reusing a key with a different body returns 409. See ADR-023."},{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_org_id"],"properties":{"target_org_id":{"type":"string"},"name":{"type":"string","description":"Optional override for the cloned posture's name."}}}}}},"responses":{"201":{"description":"Posture.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Posture"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/diff":{"get":{"operationId":"diffPostureRevisions","summary":"Structural diff between two revisions","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."},{"name":"from","in":"query","required":true,"schema":{"type":"integer","minimum":1}},{"name":"to","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Diff payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostureDiff"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/effects":{"get":{"operationId":"getPostureEffects","summary":"Analytics rollup for a posture","description":"Counts of teams using, agents affected, and events emitted under this posture revision over the configured window.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":720,"default":24}}],"responses":{"200":{"description":"Effects rollup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostureEffects"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/preview-compose":{"post":{"operationId":"previewComposePosture","summary":"Preview the composition this posture would produce for a team","description":"Composes alignment + protection cards using the posture body, the team's templates, and per-agent exemptions, without persisting. Useful for diff'ing before assigning.","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Composed preview.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamEffectivePosture"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/revisions":{"get":{"operationId":"listPostureRevisions","summary":"List all revisions of a posture","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."}],"responses":{"200":{"description":"Revisions in chronological order.","content":{"application/json":{"schema":{"type":"object","required":["revisions"],"properties":{"revisions":{"type":"array","items":{"$ref":"#/components/schemas/PostureRevision"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/postures/{posture_id}/revisions/{revision_number}":{"get":{"operationId":"getPostureRevision","summary":"Read a specific revision","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"posture_id","in":"path","required":true,"schema":{"type":"string","pattern":"^tp-[a-z0-9-]{1,64}$"},"description":"Posture ID (tp-{8-hex})."},{"name":"revision_number","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Posture revision body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostureRevision"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}":{"get":{"operationId":"getProtectionByAgent","summary":"Get this layer's protection manifest","description":"Returns the agent-scope protection spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific (the four-scope `{teams[], agent}` body is the agent variant consumed by the dashboard editor). ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the four-scope envelope `{platform, org, teams[], agent, composed, composed_stale, my_role}` (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Protection manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putProtectionByAgent","summary":"Publish or replace the protection manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedProtectionCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Honors an optional `If-Match` for optimistic concurrency (stale → 412). Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."},{"name":"If-Match","in":"header","required":false,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optional optimistic-concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape) to make the write conditional: a stale ETag returns `412 Precondition Failed`, a malformed one `400`. Omit it to publish unconditionally."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Composed canonical card after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/effective":{"get":{"operationId":"getProtectionEffectiveByAgent","summary":"Get effective (composed) protection with provenance","description":"Returns the composed canonical protection card (platform → org → team → agent cascade applied) with `_composition.field_provenance` always populated. The provenance map carries per-key `{layer, layer_id?, kind?}` entries showing which authoring scope contributed each leaf. Caller-aware redaction: layer labels (`platform` / `org` / `team` / `agent` / `derived`) are always visible; `layer_id` is only revealed to callers who can read that scope. cards-as-primitive Phase 4 W2.2.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Composed effective card with per-key field_provenance.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the composed body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/explain":{"post":{"operationId":"explainProtectionByAgent","summary":"Explain policy evaluation for the protection card","description":"Calls the policy engine in dry-run mode against the agent's composed protection card and returns a structured trace + care-framed remediations. Optional `enrich: true` runs an LLM pass over the structured remediations to produce long-form prose; off by default. Read-style POST — no state mutation, no Idempotency-Key.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"turn_id":{"type":"string","description":"Optional — bind to a specific gateway turn."},"request_snippet":{"type":"object","description":"Optional — hypothetical tool call to explain.","properties":{"tool_name":{"type":"string"},"tool_args":{"type":"object","additionalProperties":true}}},"enrich":{"type":"boolean","description":"When true, runs an LLM pass over the structured remediations. Off by default."}}}}}},"responses":{"200":{"description":"Policy evaluation trace + remediations.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","reasoning","suggested_remediations","enriched"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["protection"]},"trace":{"type":"object","description":"EvaluationResult from @mnemom/policy-engine. Null for protection in V1.","nullable":true},"reasoning":{"type":"string","description":"Care-framed prose summary."},"suggested_remediations":{"type":"array","items":{"type":"object","required":["for","index","remediation"],"properties":{"for":{"type":"string","enum":["violation","warning","card_gap"]},"index":{"type":"integer"},"remediation":{"type":"string"},"method":{"type":"string"},"url":{"type":"string"}}}},"enriched":{"type":"boolean","description":"True when the LLM enrichment ran."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/mode":{"put":{"operationId":"putProtectionModeByAgent","summary":"Replace mode settings","description":"PUT replaces the entire `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). The current spec at the agent scope is read; the new `mode` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"application/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"text/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionModeByAgent","summary":"Update mode settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/preview-compose":{"post":{"operationId":"previewComposeProtectionByAgent","summary":"Preview composed protection (dry run)","description":"Composes the cascade against a hypothetical body at the agent layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedProtectionCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/screen_surfaces":{"put":{"operationId":"putProtectionScreensurfacesByAgent","summary":"Replace screen surfaces settings","description":"PUT replaces the entire `screen_surfaces` block (which traffic surfaces the protection card inspects). The current spec at the agent scope is read; the new `screen_surfaces` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"application/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionScreensurfacesByAgent","summary":"Update screen surfaces settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `screen_surfaces` block (which traffic surfaces the protection card inspects). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/simulate":{"post":{"operationId":"simulateProtectionByAgent","summary":"Simulate gateway evaluation against the protection card","description":"Pure-sync simulation: calls @mnemom/policy-engine twice (once with `context: \"gateway\"`, once with `context: \"observer\"`) using `dryRun: true` against the agent's current composed alignment card. Returns `{allowed, conditions, suggestions, gateway_decision, observer_assessment}`. Never crosses worker boundaries — no real gateway / observer state change.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"candidate_input":{"type":"object","description":"Hypothetical conversation snippet.","properties":{"messages":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"candidate_tool_call":{"type":"object","description":"Hypothetical tool invocation. Synthesized into an assistant message with a toolUses block when `candidate_input.messages` is absent.","properties":{"tool_name":{"type":"string"},"tool_args":{"type":"object","additionalProperties":true}}}}}}}},"responses":{"200":{"description":"Simulation result.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","allowed","conditions","suggestions","gateway_decision","observer_assessment","evaluated_at"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["protection"]},"allowed":{"type":"string","enum":["true","false","conditional"]},"conditions":{"type":"array","items":{"type":"string"}},"suggestions":{"type":"array","items":{"type":"string"}},"gateway_decision":{"type":"object","properties":{"verdict":{"type":"string","enum":["pass","warn","fail"]},"violations":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}},"missing_receipts":{"type":"array","items":{"type":"string"}}}},"observer_assessment":{"type":"object","properties":{"verdict":{"type":"string","enum":["pass","warn","fail"]},"violations":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}}}},"evaluated_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/thresholds":{"put":{"operationId":"putProtectionThresholdsByAgent","summary":"Replace thresholds settings","description":"PUT replaces the entire `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). The current spec at the agent scope is read; the new `thresholds` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"application/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"text/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionThresholdsByAgent","summary":"Update thresholds settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/agent/{agent_id}/trusted_sources":{"put":{"operationId":"putProtectionTrustedsourcesByAgent","summary":"Replace trusted sources settings","description":"PUT replaces the entire `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). The current spec at the agent scope is read; the new `trusted_sources` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Sync recompose — the response carries the new canonical ETag + version.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"application/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"text/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionTrustedsourcesByAgent","summary":"Update trusted sources settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the agent scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter of the agent's canonical card.","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["agent"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"version":{"type":"integer","minimum":1},"field_provenance":{"type":"object"},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}":{"get":{"operationId":"getProtectionByOrg","summary":"Get this layer's protection manifest","description":"Returns the org-scope protection spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Protection manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putProtectionByOrg","summary":"Publish or replace the protection manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedProtectionCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Stored template wrapper after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteProtectionByOrg","summary":"Clear this protection layer","description":"Removes the org-scope protection authoring; downstream scopes fall through to the next layer up in the cascade.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Cleared. Returns the deletion confirmation (`deleted: true`, `template: null`) and the count of agents flagged for recompose; the next read returns the composed view without this layer. (The handler returns this 200-with-body, not 204.)","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}/mode":{"put":{"operationId":"putProtectionModeByOrg","summary":"Replace mode settings","description":"PUT replaces the entire `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). The current spec at the org scope is read; the new `mode` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"application/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"text/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionModeByOrg","summary":"Update mode settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}/preview-compose":{"post":{"operationId":"previewComposeProtectionByOrg","summary":"Preview composed protection (dry run)","description":"Composes the cascade against a hypothetical body at the org layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedProtectionCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}/screen_surfaces":{"put":{"operationId":"putProtectionScreensurfacesByOrg","summary":"Replace screen surfaces settings","description":"PUT replaces the entire `screen_surfaces` block (which traffic surfaces the protection card inspects). The current spec at the org scope is read; the new `screen_surfaces` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"application/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionScreensurfacesByOrg","summary":"Update screen surfaces settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `screen_surfaces` block (which traffic surfaces the protection card inspects). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}/thresholds":{"put":{"operationId":"putProtectionThresholdsByOrg","summary":"Replace thresholds settings","description":"PUT replaces the entire `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). The current spec at the org scope is read; the new `thresholds` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"application/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"text/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionThresholdsByOrg","summary":"Update thresholds settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/org/{org_id}/trusted_sources":{"put":{"operationId":"putProtectionTrustedsourcesByOrg","summary":"Replace trusted sources settings","description":"PUT replaces the entire `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). The current spec at the org scope is read; the new `trusted_sources` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"application/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"text/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionTrustedsourcesByOrg","summary":"Update trusted sources settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the org scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["org"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}":{"get":{"operationId":"getProtectionByPlatform","summary":"Get this layer's protection manifest","description":"Returns the platform-scope protection spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Protection manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putProtectionByPlatform","summary":"Publish or replace the protection manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedProtectionCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Composed canonical card after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}/mode":{"put":{"operationId":"putProtectionModeByPlatform","summary":"Replace mode settings","description":"PUT replaces the entire `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). The current spec at the platform scope is read; the new `mode` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"application/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"text/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionModeByPlatform","summary":"Update mode settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}/preview-compose":{"post":{"operationId":"previewComposeProtectionByPlatform","summary":"Preview composed protection (dry run)","description":"Composes the cascade against a hypothetical body at the platform layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedProtectionCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}/screen_surfaces":{"put":{"operationId":"putProtectionScreensurfacesByPlatform","summary":"Replace screen surfaces settings","description":"PUT replaces the entire `screen_surfaces` block (which traffic surfaces the protection card inspects). The current spec at the platform scope is read; the new `screen_surfaces` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"application/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionScreensurfacesByPlatform","summary":"Update screen surfaces settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `screen_surfaces` block (which traffic surfaces the protection card inspects). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}/thresholds":{"put":{"operationId":"putProtectionThresholdsByPlatform","summary":"Replace thresholds settings","description":"PUT replaces the entire `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). The current spec at the platform scope is read; the new `thresholds` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"application/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"text/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionThresholdsByPlatform","summary":"Update thresholds settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/platform/{scope_id}/trusted_sources":{"put":{"operationId":"putProtectionTrustedsourcesByPlatform","summary":"Replace trusted sources settings","description":"PUT replaces the entire `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). The current spec at the platform scope is read; the new `trusted_sources` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"application/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"text/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionTrustedsourcesByPlatform","summary":"Update trusted sources settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","enum":["default"]},"description":"Always `default` — the platform scope is a singleton; any other value returns 400 with care-framed guidance pointing at `default`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the platform scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["platform"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/scaffold":{"post":{"operationId":"scaffoldProtection","summary":"Scaffold protection from a description","description":"Calls an LLM (Claude Haiku by default; opt into Sonnet via `model: \"sonnet\"`) with the catalog and tools-registry context, returns a YAML manifest scaffold + care-framed reasoning prose + suggested catalog entries + coverage gaps. Never auto-commits — the caller reviews and edits before PUT. Cached by (model + scope + description + hints) hash; 24-hour TTL.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["description"],"properties":{"description":{"type":"string","minLength":20,"maxLength":2000,"description":"Free-form description of the agent / scope. Untrusted input — the system prompt instructs the model not to follow embedded directives."},"scope":{"type":"string","enum":["platform","org","team","agent"],"description":"Hint to the model about which scope the manifest will live at."},"hints":{"type":"object","description":"Free-form key/value hints (industry, risk_appetite, existing_tools, etc).","additionalProperties":true},"model":{"type":"string","enum":["haiku","sonnet"],"description":"Claude model to invoke. `haiku` is the default; `sonnet` for prose-heavy reasoning."}}}}}},"responses":{"200":{"description":"Scaffold ready. Editable; never auto-commits.","content":{"application/json":{"schema":{"type":"object","required":["ok","resource","manifest","reasoning","cached","model"],"properties":{"ok":{"type":"boolean","const":true},"resource":{"type":"string","enum":["protection"]},"manifest":{"type":"string","description":"YAML body of the scaffolded manifest."},"reasoning":{"type":"string","description":"Care-framed prose explanation."},"suggested_catalog_entries":{"type":"array","items":{"type":"string"}},"coverage_gaps":{"type":"array","items":{"type":"object","properties":{"axis":{"type":"string"},"note":{"type":"string"}},"required":["note"]}},"parse_warnings":{"type":"array","items":{"type":"string"}},"cached":{"type":"boolean","description":"True when the response was served from the description-hash cache."},"model":{"type":"string","description":"Claude model id used for the call."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"},"504":{"$ref":"#/components/responses/BadGateway"}}}},"/protection/team/{team_id}":{"get":{"operationId":"getProtectionByTeam","summary":"Get this layer's protection manifest","description":"Returns the team-scope protection spec as authored. Response is content-negotiated — YAML by default, or JSON with `Accept: application/json`. Pass `?include_composition=true` to include the `_composition` metadata block describing which scopes were merged. Pass `?include=sources` (see ADR-053) for the scope-resolution envelope — the contributing layers plus the composed result; the envelope shape is scope-specific. ETag is computed from `content_hash` (cards-as-primitive Phase 1); `If-None-Match` returns 304. For the composed view across scopes, use the `/effective` sub-resource (Wave 2).","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"include_composition","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include the `_composition` metadata block on the response body."},{"name":"Accept","in":"header","required":false,"schema":{"type":"string","enum":["text/yaml","application/yaml","application/json"]},"description":"Response format. YAML is canonical; JSON is returned only on explicit `application/json`. The `?include=sources` envelope is JSON-only."},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["sources"]},"description":"When `sources`, returns the scope-resolution envelope for this scope (the contributing layers + the composed result); the envelope shape is scope-specific (see ADR-053). The envelope is JSON-only."}],"responses":{"200":{"description":"Protection manifest at this scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the canonical body. Stable across reads; changes on PUT.","schema":{"type":"string"}},"X-Card-Version":{"description":"Monotonic version counter (cards-as-primitive Phase 1).","schema":{"type":"integer","minimum":1}},"X-Mnemom-Schema":{"description":"Schema identity.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"template":{"description":"The authored template JSON, or `null` when none is set."},"enabled":{"type":"boolean"}}}}}},"304":{"description":"Not Modified — the client's `If-None-Match` matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putProtectionByTeam","summary":"Publish or replace the protection manifest","description":"Accepts YAML (`text/yaml`, `application/yaml`) or JSON. Body is the full `UnifiedProtectionCard`; server-side composition merges it across the platform → org → team → agent cascade and writes the canonical composed card. Requires `Idempotency-Key`. Body cap 128 KiB. See ADR-008 and ADR-023.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result. See ADR-023."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Stored template wrapper after the write.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the new canonical body.","schema":{"type":"string"}},"X-Card-Version":{"description":"Bumped monotonically on every PUT that changes content_hash.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"description":"The stored template JSON after the write, or `null` when cleared."},"enabled":{"type":"boolean"},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteProtectionByTeam","summary":"Clear this protection layer","description":"Removes the team-scope protection authoring; downstream scopes fall through to the next layer up in the cascade.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Cleared. Returns the deletion confirmation (`deleted: true`, `template: null`) and the count of agents flagged for recompose; the next read returns the composed view without this layer. (The handler returns this 200-with-body, not 204.)","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}},"text/yaml":{"schema":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid"},"org_id":{"type":"string","format":"uuid"},"template":{"type":"null","description":"Always `null` after a delete."},"enabled":{"type":"boolean"},"deleted":{"type":"boolean","description":"Always `true`."},"agents_flagged_for_recompose":{"type":"integer","description":"Number of active member agents queued for re-composition."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/team/{team_id}/mode":{"put":{"operationId":"putProtectionModeByTeam","summary":"Replace mode settings","description":"PUT replaces the entire `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). The current spec at the team scope is read; the new `mode` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"application/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}},"text/yaml":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionModeByTeam","summary":"Update mode settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `mode` block (the protection master switch (`off` / `observe` / `nudge` / `enforce`)). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","enum":["off","observe","nudge","enforce"]}}}},"responses":{"200":{"description":"The `mode` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["mode"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"string","enum":["off","observe","nudge","enforce"]},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/team/{team_id}/preview-compose":{"post":{"operationId":"previewComposeProtectionByTeam","summary":"Preview composed protection (dry run)","description":"Composes the cascade against a hypothetical body at the team layer and returns conflicts + the composed view. No DB writes. Used by the dashboard editor for live conflict markers.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"application/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}},"text/yaml":{"schema":{"$ref":"#/components/schemas/UnifiedProtectionCard"}}}},"responses":{"200":{"description":"Preview-compose result: composed card + conflicts + coherence violations.","content":{"application/json":{"schema":{"type":"object","properties":{"composed":{"$ref":"#/components/schemas/UnifiedProtectionCard"},"conflicts":{"type":"array","items":{"type":"object"}},"coherence_violations":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/team/{team_id}/screen_surfaces":{"put":{"operationId":"putProtectionScreensurfacesByTeam","summary":"Replace screen surfaces settings","description":"PUT replaces the entire `screen_surfaces` block (which traffic surfaces the protection card inspects). The current spec at the team scope is read; the new `screen_surfaces` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"application/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}},"text/yaml":{"schema":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionScreensurfacesByTeam","summary":"Update screen surfaces settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `screen_surfaces` block (which traffic surfaces the protection card inspects). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The `screen_surfaces` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["screen_surfaces"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["incoming","outgoing","tool_calls","tool_responses"],"properties":{"incoming":{"type":"boolean"},"outgoing":{"type":"boolean"},"tool_calls":{"type":"boolean"},"tool_responses":{"type":"boolean"}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/team/{team_id}/thresholds":{"put":{"operationId":"putProtectionThresholdsByTeam","summary":"Replace thresholds settings","description":"PUT replaces the entire `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). The current spec at the team scope is read; the new `thresholds` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"application/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}},"text/yaml":{"schema":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionThresholdsByTeam","summary":"Update thresholds settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `thresholds` block (warn / quarantine / block trip points (warn ≤ quarantine ≤ block, ∈ [0, 1])). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}}}}},"responses":{"200":{"description":"The `thresholds` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["thresholds"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["warn","quarantine","block"],"properties":{"warn":{"type":"number","minimum":0,"maximum":1},"quarantine":{"type":"number","minimum":0,"maximum":1},"block":{"type":"number","minimum":0,"maximum":1}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/protection/team/{team_id}/trusted_sources":{"put":{"operationId":"putProtectionTrustedsourcesByTeam","summary":"Replace trusted sources settings","description":"PUT replaces the entire `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). The current spec at the team scope is read; the new `trusted_sources` is spliced in; the merged spec is validated; recompose is triggered. Requires `Idempotency-Key` and `If-Match`. Async fan-out — the response carries `agents_flagged_for_recompose`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"application/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}},"text/yaml":{"schema":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"patchProtectionTrustedsourcesByTeam","summary":"Update trusted sources settings","description":"PATCH applies RFC 7396 JSON Merge Patch to the `trusted_sources` block (domain / agent / IP-range allow-list bypassing screening). `null` deletes a key; missing keeps; present replaces. Arrays are replaced wholesale (not item-merged). Requires `Idempotency-Key` and `If-Match`.","tags":["Protection"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Client-supplied idempotency token. Replays within 24 hours return the stored result verbatim. See ADR-023."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"sha256:[0-9a-f]{64}\"$"},"description":"Optimistic concurrency token. Pass the `ETag` from a recent `GET` (`\"sha256:<hex64>\"` shape). A stale ETag returns `412 Precondition Failed`; a missing header returns `428 Precondition Required`. See RFC 9110 §13.1.1."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The `trusted_sources` primitive was updated at the team scope.","headers":{"ETag":{"description":"`\"sha256:<hex>\"` of the spec at this scope after the write.","schema":{"type":"string"}},"X-Mnemom-Schema":{"description":"Sub-resource response schema identifier.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","scope","scope_id","resource","primitive","verb","value","content_hash"],"properties":{"ok":{"type":"boolean","const":true},"scope":{"type":"string","enum":["team"]},"scope_id":{"type":"string"},"resource":{"type":"string","enum":["protection"]},"primitive":{"type":"string","enum":["trusted_sources"]},"verb":{"type":"string","enum":["put","patch"]},"value":{"type":"object","required":["domains","agent_ids","ip_ranges"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"agent_ids":{"type":"array","items":{"type":"string"}},"ip_ranges":{"type":"array","items":{"type":"string"}}}},"content_hash":{"type":"string","description":"New `sha256:<hex64>` of the spec at this scope after the write."},"agents_flagged_for_recompose":{"type":"integer","minimum":0},"_warnings":{"type":"object","description":"Pre-existing structural issues outside the modified primitive. Present only when the existing spec carries unrelated validation problems; never blocks the write."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"412":{"$ref":"#/components/responses/PreconditionFailed"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"428":{"$ref":"#/components/responses/PreconditionRequired"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/realtime/governance":{"get":{"operationId":"subscribeGovernanceRealtime","summary":"Subscribe to live governance signal updates (SSE)","description":"Server-Sent Events stream that emits one `event: signal` per `governance_signals` insert/update matching the caller's filter. RBAC mirrors the REST list endpoints: `scope=platform` requires Mnemom staff; `scope=org|team|agent` requires org membership. The stream emits an initial `event: ready` marker, then signal events as they arrive, plus periodic `:heartbeat` comments. Connection lifetime is capped at 5 minutes — clients should reconnect.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["platform","org","team","agent"],"default":"org"},"description":"Subscription scope. `platform` requires staff; the rest require the matching scope id."},{"name":"org_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"SSE stream of governance signal events.","content":{"text/event-stream":{"schema":{"type":"string","description":"Newline-delimited SSE frames: `event: ready` then `event: signal\\ndata: <GovernanceSignal JSON>` per update, plus `:heartbeat` comments."}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/recipes/{recipeId}/report":{"post":{"operationId":"reportRecipeFnFp","summary":"Report a false-positive or false-negative against a protection recipe","description":"Files a false-negative ('fn') or false-positive ('fp') report against an existing detection_recipes id. The customer is recorded as the 'created' identity on the recipe_review_actions chain; the candidate lands in `pending` state and awaits review. Requires customer-session auth (JWT cookie / bearer) OR an API key. **Idempotency-Key header is REQUIRED** — the body hash is folded into the reservation so a customer can re-submit with corrected details without 422'ing.","tags":["Recipes"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"recipeId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Client-supplied UUID (or comparable) for de-duplication. Same key + same body within 24h replays the prior response; same key + different body returns 422."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","summary"],"properties":{"type":{"type":"string","enum":["fn","fp"],"description":"'fn' (false negative — recipe should have fired) or 'fp' (false positive — recipe fired on legitimate behaviour)."},"summary":{"type":"string","minLength":1,"description":"Customer's description of what happened."},"evidence":{"type":"string","description":"Optional raw payload / log excerpt the admin reviewer can inspect."},"agent_id":{"type":"string","description":"Optional. Customer's agent id, when the report concerns a specific agent."},"checkpoint_id":{"type":"string","description":"Optional. Related integrity_checkpoints id (helps the reviewer correlate)."}}}}}},"responses":{"201":{"description":"Candidate created; awaiting review.","content":{"application/json":{"schema":{"type":"object","required":["ok","candidate_id","type","related_recipe_id"],"properties":{"ok":{"type":"boolean","enum":[true]},"candidate_id":{"type":"string"},"type":{"type":"string","enum":["fn","fp"]},"related_recipe_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/batch":{"post":{"operationId":"batchReputation","x-proxied":"REPUTATION_SERVICE","summary":"Batch reputation lookup (auth required)","description":"Returns reputation rows for up to 50 agent ids. Requires API key or bearer JWT (rate-limited as `search_batch` — 30/min per auth principal). Private-visibility agents return a stub row with `score: null`.","tags":["Reputation"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_ids"],"properties":{"agent_ids":{"type":"array","items":{"type":"string"},"maxItems":50,"minItems":0}}}}}},"responses":{"200":{"description":"Scores (private rows return stubs).","content":{"application/json":{"schema":{"type":"object","required":["scores"],"properties":{"scores":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/ReputationScore"},{"type":"object","properties":{"agent_id":{"type":"string"},"visibility":{"type":"string","enum":["private"]},"score":{"type":"null"},"grade":{"type":"null"}}}]}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/benchmarks":{"get":{"operationId":"getReputationBenchmarks","x-proxied":"REPUTATION_SERVICE","summary":"Aggregate reputation benchmarks","description":"Returns mean/median/p25/p75/p90 score and a grade-distribution histogram across every eligible agent. Cached. Public, rate-limited (`benchmarks` bucket).","tags":["Reputation"],"security":[],"responses":{"200":{"description":"Benchmark stats.","content":{"application/json":{"schema":{"type":"object","required":["total_eligible","mean_score","median_score","p25_score","p75_score","p90_score","grade_distribution"],"properties":{"total_eligible":{"type":"integer"},"mean_score":{"type":"number"},"median_score":{"type":"number"},"p25_score":{"type":"number"},"p75_score":{"type":"number"},"p90_score":{"type":"number"},"grade_distribution":{"type":"object","additionalProperties":{"type":"integer"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/compare":{"get":{"operationId":"compareReputation","x-proxied":"REPUTATION_SERVICE","summary":"Compare 2–10 agents' reputation scores","description":"Returns the reputation rows for the given agent ids (comma-separated, 2–10). Private-visibility agents are silently filtered out. Public endpoint, cached 5 min.","tags":["Reputation"],"security":[],"parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated list of 2–10 agent ids."}],"responses":{"200":{"description":"Comparison result.","content":{"application/json":{"schema":{"type":"object","required":["agents"],"properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/ReputationScore"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/search":{"get":{"operationId":"searchReputationDirectory","x-proxied":"REPUTATION_SERVICE","summary":"Search the public reputation directory","description":"Lists agents whose reputation visibility is `public`, with optional filters. `q` matches on agent name (or `smolt-`/`mnm-` ID prefix). Unclaimed, not-rated (NR) agents appear at the bottom when the filters permit. Page-based pagination.","tags":["Reputation"],"security":[],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Name search (ilike) or agent-id prefix match."},{"name":"grade","in":"query","required":false,"schema":{"type":"string"},"description":"Filter to one grade (e.g. `AAA`, `B`, `NR`)."},{"name":"confidence","in":"query","required":false,"schema":{"type":"string","enum":["high","medium","low","insufficient"]}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"score"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Directory page.","content":{"application/json":{"schema":{"type":"object","required":["agents","total","page","per_page"],"properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/ReputationScore"}},"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}":{"get":{"operationId":"getReputation","x-proxied":"REPUTATION_SERVICE","summary":"Get reputation score for an agent","description":"Returns the agent's current reputation: numeric score (0–1000), letter grade (AAA–D, NR for not-rated), tier, five-component breakdown, 30-day trend, and an A2A trust extension block for interop. Private-visibility agents return 403 to non-owners. Public endpoint, IP-rate-limited (lookup bucket).","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Reputation score with A2A trust extension.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReputationScore"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/badge.svg":{"get":{"operationId":"getReputationBadge","x-proxied":"REPUTATION_SERVICE","summary":"Embeddable SVG reputation badge","description":"Returns an SVG image (image/svg+xml) showing the agent's grade + score, suitable for embedding in GitHub README files, docs, or dashboards. Public, rate-limited (`badge` bucket).","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"SVG badge.","content":{"image/svg+xml":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/events":{"get":{"operationId":"getReputationEvents","x-proxied":"REPUTATION_SERVICE","summary":"List recent reputation events","description":"Returns up to 50 most-recent reputation events (violation detected, card amendment, reclassification applied, etc). Public endpoint.","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Recent events.","content":{"application/json":{"schema":{"type":"object","required":["events"],"properties":{"events":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/history":{"get":{"operationId":"getReputationHistory","x-proxied":"REPUTATION_SERVICE","summary":"Get weekly reputation snapshots","description":"Returns up to 52 weekly snapshots of the agent's reputation (most recent first). Public endpoint.","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Weekly snapshots.","content":{"application/json":{"schema":{"type":"object","required":["snapshots"],"properties":{"snapshots":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/og-image":{"get":{"operationId":"getReputationOgImage","x-proxied":"REPUTATION_SERVICE","summary":"Open Graph share-card image for an agent","description":"Returns a 1200×630 PNG (or rendered HTML fallback) suitable for `og:image` link previews when the agent's profile is shared.","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Share-card image.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"text/html":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/recompute":{"post":{"operationId":"recomputeReputationScore","summary":"Trigger score recomputation","description":"Trigger a full recomputation of the agent's reputation and compliance scores. This re-evaluates all checkpoints, reclassifications, and card amendments to produce an updated score. Useful after bulk reclassifications or policy changes.","tags":["Reclassification"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"},"description":"Agent identifier"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Reason for triggering recomputation"},"include_reclassifications":{"type":"boolean","default":true,"description":"Whether to include pending reclassifications in the recomputation"}}}}}},"responses":{"200":{"description":"Recomputation result with new scores","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"previous_score":{"type":"number"},"new_score":{"type":"number"},"delta":{"type":"number"},"reclassifications_applied":{"type":"integer"},"recomputed_at":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/reputation/{agent_id}/verify":{"get":{"operationId":"verifyReputation","x-proxied":"REPUTATION_SERVICE","summary":"Cryptographic verification bundle for an agent's reputation","description":"Returns the score plus a `verification` block containing: the latest certificate hash, the agent's Merkle root, checkpoint count, first/last checkpoint timestamps, and a `hash_chain_valid` flag. Response is Cache-Control 3600s. Public endpoint.","tags":["Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Verification bundle.","headers":{"Cache-Control":{"schema":{"type":"string","example":"public, max-age=3600, s-maxage=3600"}}},"content":{"application/json":{"schema":{"type":"object","required":["agent_id","score","grade","computed_at","verification"],"properties":{"agent_id":{"type":"string"},"score":{"type":"number"},"grade":{"type":"string"},"computed_at":{"type":"string","format":"date-time"},"verification":{"type":["object","null"],"properties":{"latest_certificate_hash":{"type":["string","null"]},"merkle_root":{"type":["string","null"]},"checkpoint_count":{"type":"integer"},"first_checkpoint":{"type":["string","null"],"format":"date-time"},"last_checkpoint":{"type":["string","null"],"format":"date-time"},"hash_chain_valid":{"type":"boolean"},"certificate_url":{"type":["string","null"]}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/assess":{"post":{"operationId":"assessRisk","x-proxied":"RISK_SERVICE","summary":"Assess risk for a single agent action","description":"Compute an individual risk assessment for an agent about to take an action. Requires JWT auth and the `risk_assessment` feature flag on the caller's plan. Dispatches a ZK proof request asynchronously (best-effort; check `/risk/proofs/{proof_id}` to retrieve). Cached for 5 minutes per `{agent_id, action_type, risk_tolerance, amount}` tuple.","tags":["Risk"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id","context"],"properties":{"agent_id":{"type":"string"},"source":{"type":"string","enum":["api","playground"],"default":"api"},"context":{"type":"object","required":["action_type"],"properties":{"action_type":{"type":"string","enum":["financial_transaction","data_access","task_delegation","tool_invocation","autonomous_operation","multi_agent_coordination"]},"amount":{"type":"number"},"counterparty_id":{"type":"string"},"use_case":{"type":"string"},"risk_tolerance":{"type":"string","enum":["conservative","moderate","aggressive"],"default":"moderate"}}}}}}}},"responses":{"200":{"description":"Risk assessment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskAssessment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/assess/team":{"post":{"operationId":"assessTeamRisk","x-proxied":"RISK_SERVICE","summary":"Assess risk for a team of agents","description":"Compute a team-level risk assessment given an explicit `agent_ids` list (or a `team_id` to resolve the roster). Produces three-pillar results: portfolio, coherence, concentration, plus weakest-link and Shapley attribution. Dispatches a team-coherence ZK proof asynchronously.","tags":["Risk"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["context"],"properties":{"agent_ids":{"type":"array","items":{"type":"string"},"description":"Explicit agent roster; required if `team_id` is not provided."},"team_id":{"type":"string","description":"Resolve roster from this team id; required if `agent_ids` is not provided."},"source":{"type":"string","enum":["api","playground"]},"context":{"type":"object","required":["action_type"],"properties":{"action_type":{"type":"string"},"amount":{"type":"number"},"use_case":{"type":"string"},"risk_tolerance":{"type":"string"},"team_task":{"type":"string"},"coordination_mode":{"type":"string"},"trigger":{"type":"string"},"governance_median":{"type":["number","null"]},"conflict_edge_count":{"type":"integer"},"conscience_universal":{"type":["boolean","null"]}}}}}}}},"responses":{"200":{"description":"Team risk assessment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRiskAssessment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/assessments/{assessment_id}":{"get":{"operationId":"getRiskAssessment","x-proxied":"RISK_SERVICE","summary":"Get a single risk assessment by id","tags":["Risk"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"assessment_id","in":"path","required":true,"schema":{"type":"string"},"description":"Individual assessment id (`ra-…`)."}],"responses":{"200":{"description":"Assessment row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskAssessment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/history/{agent_id}":{"get":{"operationId":"getRiskHistory","x-proxied":"RISK_SERVICE","summary":"List historical risk assessments for an agent","tags":["Risk"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/AgentId"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"include_playground","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"History page.","content":{"application/json":{"schema":{"type":"object","properties":{"assessments":{"type":"array","items":{"$ref":"#/components/schemas/RiskAssessment"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/proofs/{proof_id}":{"get":{"operationId":"getRiskProof","x-proxied":"RISK_SERVICE","summary":"Get a ZK proof for a risk assessment","description":"Retrieve a ZK proof artifact (individual or team-coherence) by its proof id. Proofs are generated fire-and-forget after `/risk/assess` and `/risk/assess/team` and may take tens of seconds to complete.","tags":["Risk"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"proof_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Proof row (status, artifact, metadata).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/team-assessments/{assessment_id}":{"get":{"operationId":"getTeamRiskAssessment","x-proxied":"RISK_SERVICE","summary":"Get a single team risk assessment by id","tags":["Risk"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"assessment_id","in":"path","required":true,"schema":{"type":"string"},"description":"Team assessment id (`tra-…`)."}],"responses":{"200":{"description":"Team assessment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRiskAssessment"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/risk/team-history/{team_id}":{"get":{"operationId":"getTeamRiskHistory","x-proxied":"RISK_SERVICE","summary":"List historical team risk assessments for a team","tags":["Risk"],"security":[{},{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"History page.","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string"},"assessments":{"type":"array","items":{"$ref":"#/components/schemas/TeamRiskAssessment"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/audit":{"get":{"operationId":"safeHouseAuditLog","summary":"Audit log for Safe House actions","tags":["Safe House"],"responses":{"200":{"description":"Audit entries.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/campaigns":{"get":{"operationId":"listSafeHouseCampaigns","summary":"List detected threat campaigns","tags":["Safe House"],"responses":{"200":{"description":"Campaigns.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/campaigns/{campaign_id}/resolve":{"post":{"operationId":"resolveSafeHouseCampaign","summary":"Resolve a detected campaign","tags":["Safe House"],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"resolution":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"200":{"description":"Resolved."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/canaries":{"get":{"operationId":"listSafeHouseCanaries","summary":"List canary credentials for an agent","tags":["Safe House"],"parameters":[{"name":"agent_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Canary list.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SafeHouseCanary"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createSafeHouseCanary","summary":"Create a canary credential","description":"Generates a format-valid but non-functional credential (api_key / password / database_url / ssh_key / oauth_token). The canary value is **only returned on creation** — plant it in the agent's context so exfiltration attempts trip it.","tags":["Safe House"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id","canary_type"],"properties":{"agent_id":{"type":"string"},"canary_type":{"type":"string","enum":["api_key","password","database_url","ssh_key","oauth_token"]}}}}}},"responses":{"201":{"description":"Canary created. `canary_value` is returned once and must be captured.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SafeHouseCanary"},{"type":"object","required":["canary_value"],"properties":{"canary_value":{"type":"string"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/canaries/{canary_id}/status":{"get":{"operationId":"getCanaryStatus","summary":"Check whether a canary has been triggered","tags":["Safe House"],"parameters":[{"name":"canary_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Canary status (no value returned).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseCanary"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/cbd/evaluations":{"get":{"operationId":"listCbdEvaluations","summary":"Query outbound (egress) Safe House evaluations","description":"Same shape as `/safe-house/evaluations`, but scoped to outbound (egress) screening — exfiltration detection on agent-originated traffic.","tags":["Safe House"],"deprecated":true,"responses":{"200":{"description":"Evaluation page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluationPage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/cbd/evaluations/{evaluation_id}":{"get":{"operationId":"getCbdEvaluation","summary":"Get a single outbound (egress) evaluation","tags":["Safe House"],"deprecated":true,"parameters":[{"name":"evaluation_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evaluation record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluation"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/config/bulk-apply":{"post":{"operationId":"safeHouseBulkApply","summary":"Bulk apply a Safe House config to up to 500 agents","tags":["Safe House"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_ids","config"],"properties":{"agent_ids":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":500},"config":{"type":"object","properties":{"mode":{"type":"string","enum":["disabled","off","observe","enforce","enforce_sync"]},"thresholds":{"type":"object","properties":{"warn":{"type":"number"},"quarantine":{"type":"number"},"block":{"type":"number"}}},"screen_surfaces":{"type":"array","items":{"type":"string"}},"trusted_sources":{"type":"array","items":{"type":"string"}},"settings":{"type":"object","additionalProperties":true}}}}}}}},"responses":{"200":{"description":"Applied.","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/context-cards":{"get":{"operationId":"safeHouseContextCards","summary":"List customer-authored context cards used for trust inference","tags":["Safe House"],"responses":{"200":{"description":"Context cards.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/evaluations":{"get":{"operationId":"listSafeHouseEvaluations","summary":"Query inbound Safe House evaluations","description":"Paginated query of `sh_evaluations` (inbound prompt screening). Time-bounded by `from`/`to` (default last 24h). Cursor-paginated via `after`.","tags":["Safe House"],"parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"verdict","in":"query","required":false,"schema":{"type":"string"}},{"name":"threat_type","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"min_risk","in":"query","required":false,"schema":{"type":"number"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"default":25}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evaluation page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluationPage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/evaluations/{evaluation_id}":{"get":{"operationId":"getSafeHouseEvaluation","summary":"Get a single Safe House evaluation","tags":["Safe House"],"parameters":[{"name":"evaluation_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evaluation record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluation"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/feed":{"get":{"operationId":"safeHouseFeed","summary":"Server-Sent Events stream of Safe House evaluations","description":"Long-lived SSE stream that pushes new Safe House evaluations in near-real-time. Polls internally every 2s, heartbeats every ~15s, and closes after 5 minutes (client should reconnect). Filter by agent, org, surface, verdict list (comma-separated), and minimum risk.","tags":["Safe House"],"parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"org_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"surface","in":"query","required":false,"schema":{"type":"string"}},{"name":"verdict","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated verdict filter (e.g. `quarantine,block`)."},{"name":"min_risk","in":"query","required":false,"schema":{"type":"number"}}],"responses":{"200":{"description":"SSE stream; each `data:` line is a JSON event (agent_id, verdict, overall_risk, top_threat, …).","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/ingest-pattern":{"post":{"operationId":"safeHouseIngestPattern","summary":"Ingest a customer-supplied threat pattern","description":"Customer-submitted patterns feed the L1/L2 detection pipeline. See also the arena's public pattern feed.","tags":["Safe House"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"Pattern ingested."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/metrics/risk-dist":{"get":{"operationId":"safeHouseMetricsRiskDist","summary":"Risk-score distribution over a window","tags":["Safe House"],"responses":{"200":{"description":"Distribution buckets.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/metrics/summary":{"get":{"operationId":"safeHouseMetricsSummary","summary":"Aggregate verdict counts over a window","tags":["Safe House"],"parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Summary counts.","content":{"application/json":{"schema":{"type":"object","properties":{"pass":{"type":"integer"},"warn":{"type":"integer"},"quarantine":{"type":"integer"},"block":{"type":"integer"},"total":{"type":"integer"},"block_rate":{"type":"number"},"warn_rate":{"type":"number"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/metrics/threats":{"get":{"operationId":"safeHouseMetricsThreats","summary":"Threat-type histogram over a window","tags":["Safe House"],"responses":{"200":{"description":"Histogram.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/metrics/timeseries":{"get":{"operationId":"safeHouseMetricsTimeseries","summary":"Time-series of verdict counts","tags":["Safe House"],"parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"bucket","in":"query","required":false,"schema":{"type":"string","enum":["hour","day"],"default":"hour"}}],"responses":{"200":{"description":"Buckets.","content":{"application/json":{"schema":{"type":"object","properties":{"buckets":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/outbound/evaluations":{"get":{"operationId":"listOutboundEvaluations","summary":"Query outbound (egress) Safe House evaluations","description":"Same shape as `/safe-house/evaluations`, but scoped to outbound (egress) screening — exfiltration detection on agent-originated traffic.","tags":["Safe House"],"responses":{"200":{"description":"Evaluation page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluationPage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/outbound/evaluations/{evaluation_id}":{"get":{"operationId":"getOutboundEvaluation","summary":"Get a single outbound (egress) evaluation","tags":["Safe House"],"parameters":[{"name":"evaluation_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evaluation record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHouseEvaluation"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/patterns":{"get":{"operationId":"listSafeHousePatterns","summary":"List active threat patterns","tags":["Safe House"],"parameters":[{"name":"threat_type","in":"query","required":false,"schema":{"type":"string"}},{"name":"source","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50}}],"responses":{"200":{"description":"Active patterns.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SafeHousePattern"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createSafeHousePattern","summary":"Add a new threat pattern","description":"Requires API key or bearer JWT. `label: \"benign\"` adds a known-safe pattern (reduces false positives).","tags":["Safe House"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["threat_type","content","label"],"properties":{"threat_type":{"type":"string"},"content":{"type":"string"},"label":{"type":"string","enum":["malicious","benign"]},"source":{"type":"string","default":"arena"},"minhash":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Pattern created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SafeHousePattern"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/quarantine":{"get":{"operationId":"listQuarantine","summary":"List quarantined messages","description":"Returns quarantined messages for the caller's org, filterable by status. Quarantine holds messages that **Safe House** flagged during inbound screening.","tags":["Safe House"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","released","deleted","confirmed_threat","all"],"default":"pending"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"default":25}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Quarantine page.","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/QuarantineItem"}},"total":{"type":["integer","null"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/quarantine/{quarantine_id}":{"get":{"operationId":"getQuarantineItem","summary":"Get a single quarantined message","tags":["Safe House"],"parameters":[{"name":"quarantine_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Quarantine record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuarantineItem"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteQuarantineItem","summary":"Delete a quarantine item without releasing","description":"Marks the item `deleted`. The underlying content hash is retained for audit. No refund of the original (blocked) prompt to the calling agent.","tags":["Safe House"],"parameters":[{"name":"quarantine_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"quarantine_id":{"type":"string"},"status":{"type":"string","enum":["deleted"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/quarantine/{quarantine_id}/release":{"post":{"operationId":"releaseQuarantineItem","summary":"Release a quarantined message back to the agent","description":"Flip status to `released`. Pass `is_false_positive: true` in the body to record a calibration signal and write a benign-labeled pattern (helps tune L1/L2 detection).","tags":["Safe House"],"parameters":[{"name":"quarantine_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"is_false_positive":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Released.","content":{"application/json":{"schema":{"type":"object","properties":{"quarantine_id":{"type":"string"},"status":{"type":"string","enum":["released"]},"false_positive_recorded":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/quarantine/{quarantine_id}/report":{"post":{"operationId":"reportQuarantineThreat","summary":"Confirm a quarantined message as a threat","description":"Marks the item `confirmed_threat` for arena sideband analysis. Does **not** write to `sh_threat_patterns` — the quarantine store holds only a content hash, and the pattern table requires plaintext.","tags":["Safe House"],"parameters":[{"name":"quarantine_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Confirmed.","content":{"application/json":{"schema":{"type":"object","properties":{"quarantine_id":{"type":"string"},"status":{"type":"string","enum":["confirmed_threat"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/report-incident":{"post":{"operationId":"safeHouseReportIncident","summary":"Report a security incident","description":"Agent self-reporting of a security incident. Authenticated by the agent's own possession proof (AgentAuth, `X-Mnemom-Agent-Proof`) — not a user/account api-key. 401 on absent/malformed/unmatched proof.","tags":["Safe House"],"security":[{"AgentAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"Incident recorded."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/sessions":{"get":{"operationId":"listSafeHouseSessions","summary":"List Safe House sessions (threat clusters)","tags":["Safe House"],"responses":{"200":{"description":"Session list.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/stats":{"get":{"operationId":"getSafeHouseStats","summary":"Aggregate Safe House evaluation stats","tags":["Safe House"],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"default":7}}],"responses":{"200":{"description":"Verdict counts + threat-type histogram.","content":{"application/json":{"schema":{"type":"object","properties":{"verdicts":{"type":"object","additionalProperties":{"type":"integer"}},"threat_types":{"type":"array"},"period_days":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/safe-house/threshold-suggestions":{"get":{"operationId":"safeHouseThresholdSuggestions","summary":"Adaptive threshold recommendations","description":"Returns suggested warn/quarantine/block thresholds based on recent evaluation history, to reduce false positives without losing threat coverage.","tags":["Safe House"],"responses":{"200":{"description":"Suggested thresholds (array; empty when no history accumulated yet or on internal fallback).","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/sign/operator-attestation":{"post":{"operationId":"signOperatorAttestation","summary":"Sign an operator attestation envelope","description":"Returns an Ed25519-signed envelope binding the operator's identity + role to a free-form statement about an asserted subject. Used for compliance attestation chains where an operator's signature is required (e.g., closing a critical governance signal with a note that's later shown in audit).","tags":["Verification"],"security":[{"BearerAuth":[]},{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatorAttestationRequest"}}}},"responses":{"201":{"description":"Signed attestation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatorAttestationResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/ssm/{agent_id}":{"get":{"operationId":"getSSM","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"summary":"Get traces with semantic similarity scores","tags":["Integrity"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}}],"responses":{"200":{"description":"Traces with similarity scores","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"trace_count":{"type":"integer"},"traces":{"type":"array","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/ssm/{agent_id}/timeline":{"get":{"operationId":"getSSMTimeline","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"summary":"Get similarity timeline data","tags":["Integrity"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","schema":{"type":"integer","default":7,"minimum":1,"maximum":30}}],"responses":{"200":{"description":"Similarity timeline","content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string"},"days":{"type":"integer"},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"trace_count":{"type":"integer"},"avg_similarity":{"type":"number"},"values_used":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams":{"post":{"operationId":"createTeam","summary":"Create a team","description":"Create a new team with at least 2 agent members. Team names must be unique within the organization.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["org_id","name","agent_ids"],"properties":{"org_id":{"type":"string","description":"Organization that owns this team"},"name":{"type":"string","maxLength":100,"description":"Display name"},"description":{"type":"string","description":"Optional description"},"agent_ids":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":50,"description":"Agent IDs to add as initial members"},"metadata":{"type":"object","additionalProperties":true,"description":"Freeform metadata"}}}}}},"responses":{"201":{"description":"Team created","content":{"application/json":{"schema":{"type":"object","properties":{"team":{"$ref":"#/components/schemas/Team"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/fault-lines":{"post":{"operationId":"analyzeTeamFaultLines","summary":"Analyze team fault lines","description":"Analyze alignment fault lines across a team of agents. Identifies capabilities, values, or constraints that some agents declare but others miss, creating potential alignment gaps. Returns a fleet-wide score with individual fault line details and resolution hints.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","description":"Team identifier to analyze"},"agent_ids":{"type":"array","items":{"type":"string"},"description":"Optional subset of agent IDs to analyze. If omitted, all team members are analyzed."},"dimensions":{"type":"array","items":{"type":"string","enum":["capabilities","values","constraints","tools","policies"]},"description":"Dimensions to analyze for fault lines"}}}}}},"responses":{"200":{"description":"Fault line analysis result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaultLineAnalysis"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/forecast":{"post":{"operationId":"forecastTeamRisks","summary":"Forecast team risks","description":"Forecast potential risks and failure modes for a team based on current alignment state, historical trends, and known fault lines. Returns ranked failure modes with probability estimates, impact assessments, and mitigation suggestions.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","description":"Team identifier to forecast"},"horizon_days":{"type":"integer","default":30,"description":"Forecast horizon in days"},"include_mitigations":{"type":"boolean","default":true,"description":"Whether to include mitigation suggestions"}}}}}},"responses":{"200":{"description":"Risk forecast result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskForecast"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/recommend-policy":{"post":{"operationId":"recommendTeamPolicy","summary":"Generate policy recommendation","description":"Generate a recommended CLPI policy for a team based on current agent capabilities, alignment cards, historical violations, and known fault lines. The recommendation aims to close coverage gaps while minimizing disruption to existing workflows.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","description":"Team identifier to generate recommendation for"},"strictness":{"type":"string","enum":["permissive","balanced","strict"],"default":"balanced","description":"Desired strictness level for the recommended policy"},"existing_policy":{"$ref":"#/components/schemas/Policy","description":"Optional existing policy to use as a starting point"}}}}}},"responses":{"200":{"description":"Policy recommendation","content":{"application/json":{"schema":{"type":"object","properties":{"recommended_policy":{"$ref":"#/components/schemas/Policy"},"rationale":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"reason":{"type":"string"},"confidence":{"type":"number","minimum":0,"maximum":1}}}},"expected_coverage":{"type":"number","minimum":0,"maximum":1},"fault_lines_addressed":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/reputation/batch":{"post":{"operationId":"batchTeamReputation","x-proxied":"REPUTATION_SERVICE","summary":"Batch team-reputation lookup (auth required)","tags":["Team Reputation"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_ids"],"properties":{"team_ids":{"type":"array","items":{"type":"string"},"maxItems":50}}}}}},"responses":{"200":{"description":"Scores.","content":{"application/json":{"schema":{"type":"object","properties":{"scores":{"type":"array","items":{"$ref":"#/components/schemas/TeamReputationScore"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/reputation/compare":{"get":{"operationId":"compareTeamReputation","x-proxied":"REPUTATION_SERVICE","summary":"Compare 2–10 teams' reputation scores","tags":["Team Reputation"],"security":[],"parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated team ids (2–10)."}],"responses":{"200":{"description":"Comparison.","content":{"application/json":{"schema":{"type":"object","properties":{"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamReputationScore"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/reputation/search":{"get":{"operationId":"searchTeamReputationDirectory","x-proxied":"REPUTATION_SERVICE","summary":"Search the public team-reputation directory","tags":["Team Reputation"],"security":[],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"grade","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Directory page.","content":{"application/json":{"schema":{"type":"object","properties":{"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamReputationScore"}},"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}":{"get":{"operationId":"getTeam","summary":"Get team by ID","description":"Retrieve a team and its current members.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team details with members","content":{"application/json":{"schema":{"type":"object","properties":{"team":{"$ref":"#/components/schemas/Team"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"patch":{"operationId":"updateTeam","summary":"Update team","description":"Update a team's name, description, or metadata.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name"},"description":{"type":["string","null"],"description":"Optional description"},"metadata":{"type":"object","additionalProperties":true,"description":"Freeform metadata"}}}}}},"responses":{"200":{"description":"Updated team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"delete":{"operationId":"archiveTeam","summary":"Archive team","description":"Archive a team. Archived teams are soft-deleted and can be listed with status=archived.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team archived","content":{"application/json":{"schema":{"type":"object","properties":{"archived":{"type":"boolean"},"team_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/admins":{"get":{"operationId":"listTeamAdmins","summary":"List team-admin grants","description":"Returns users with team-admin role on this team.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team-admin grants.","content":{"application/json":{"schema":{"type":"object","required":["admins"],"properties":{"admins":{"type":"array","items":{"$ref":"#/components/schemas/TeamAdmin"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"grantTeamAdmin","summary":"Grant team-admin role to a user","description":"Authorized: org_admin / org_owner.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Grant created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamAdmin"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/admins/{user_id}":{"delete":{"operationId":"revokeTeamAdmin","summary":"Revoke a team-admin grant","description":"Authorized: org_admin / org_owner.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Revoked (or idempotent no-op if already revoked).","content":{"application/json":{"schema":{"type":"object","required":["team_id","user_id","revoked"],"properties":{"team_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"revoked":{"type":"boolean","description":"`true` when the grant was revoked by this request; `false` on an idempotent no-op."},"revoked_at":{"type":"string","format":"date-time","description":"Timestamp of revocation. Present only when `revoked: true`."},"revoked_by":{"type":"string","format":"uuid","description":"Actor who revoked the grant. Present only when `revoked: true`."},"idempotent_noop":{"type":"boolean","description":"`true` when there was no active grant to revoke. `revoked` is `false` in this case."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/alignment-template":{"get":{"operationId":"getTeamAlignmentTemplateLegacy","summary":"DEPRECATED — use GET /v1/alignment/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putTeamAlignmentTemplateLegacy","summary":"DEPRECATED — use PUT /v1/alignment/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteTeamAlignmentTemplateLegacy","summary":"DEPRECATED — use DELETE /v1/alignment/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/alignment-template/preview-compose":{"post":{"operationId":"postTeamAlignmentTemplatePreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/alignment/team/{team_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/alignment/team/{team_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/avatar":{"put":{"operationId":"putTeamAvatar","summary":"Upload team avatar","description":"Replace a team's avatar image. Requires the authenticated principal to hold `owner` or `admin` role on the team's parent org.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Avatar image. Validated for MIME type and size before upload."}}}}}},"responses":{"200":{"description":"Avatar uploaded; persistent URL returned","content":{"application/json":{"schema":{"type":"object","required":["avatar_url"],"properties":{"avatar_url":{"type":"string","format":"uri","description":"Public URL of the uploaded avatar (CDN-served).","example":"https://cdn.mnemom.ai/avatars/agents/mnm-7f3b9e2a/abc123.png"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/teams/{team_id}/badge.svg":{"get":{"operationId":"getTeamBadge","x-proxied":"REPUTATION_SERVICE","summary":"Get embeddable team reputation badge","description":"Public endpoint. Returns an SVG badge displaying the team's reputation score or grade. Returns a 'Not Rated' badge for unknown teams.","tags":["Team Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"variant","in":"query","schema":{"type":"string","enum":["score","grade","score_grade","score_trend","score_tier","compact"],"default":"grade"},"description":"Badge variant"},{"name":"style","in":"query","schema":{"type":"string","enum":["light","dark"],"default":"light"},"description":"Badge color scheme"}],"responses":{"200":{"description":"SVG badge image","headers":{"Cache-Control":{"schema":{"type":"string"},"description":"public, max-age=3600"}},"content":{"image/svg+xml":{"schema":{"type":"string"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/card":{"get":{"operationId":"getTeamCard","summary":"Get team alignment card","description":"Retrieve the active alignment card for a team, or null if no card is set.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team alignment card or null","content":{"application/json":{"schema":{"type":"object","properties":{"card_id":{"type":"string"},"team_id":{"type":"string"},"card_json":{"type":"object"},"card_source":{"type":"string","enum":["manual","auto_derived","hybrid"]},"issued_at":{"type":"string","format":"date-time"},"is_active":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"put":{"operationId":"setTeamCard","summary":"Set team alignment card","description":"Manually set an alignment card for a team. The card must include principal, values, autonomy_envelope, and audit_commitment sections.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["principal","values","autonomy_envelope","audit_commitment"],"properties":{"principal":{"type":"object","description":"Principal section of the alignment card"},"values":{"type":"object","required":["declared"],"properties":{"declared":{"type":"array","items":{"type":"object"}}},"description":"Values section with declared values array"},"autonomy_envelope":{"type":"object","description":"Autonomy envelope section"},"audit_commitment":{"type":"object","description":"Audit commitment section"}}}}}},"responses":{"200":{"description":"Card set","content":{"application/json":{"schema":{"type":"object","properties":{"card_id":{"type":"string"},"team_id":{"type":"string"},"card_source":{"type":"string","enum":["manual"]},"issued_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/card/derive":{"post":{"operationId":"deriveTeamCard","summary":"Derive team alignment card from members","description":"Automatically derive a team alignment card from the individual cards of team members. Requires at least 2 members with active alignment cards.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Derived card","content":{"application/json":{"schema":{"type":"object","properties":{"derived_card":{"type":"object"},"card_source":{"type":"string","enum":["auto_derived"]},"member_count":{"type":"integer"},"members_with_cards":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/card/history":{"get":{"operationId":"getTeamCardHistory","summary":"Get team card history","description":"Retrieve the history of alignment cards for a team.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Card history","content":{"application/json":{"schema":{"type":"object","properties":{"cards":{"type":"array","items":{"type":"object","properties":{"card_id":{"type":"string"},"card_source":{"type":"string","enum":["manual","auto_derived","hybrid"]},"issued_at":{"type":"string","format":"date-time"},"is_active":{"type":"boolean"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/coherence-history":{"get":{"operationId":"getTeamCoherenceHistory","summary":"Get governance-median coherence history for a team","description":"Internal service-to-service endpoint for the mnemom-reputation cron. Returns the governance-median coherence history for a team. Authentication is via the `X-Internal-Key` header validated against the `INTERNAL_API_KEY` server secret; this is not a standard security scheme, so `security` is empty and the header is declared as a required parameter.","tags":["Teams"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"X-Internal-Key","in":"header","required":true,"description":"Internal service-to-service shared secret. Must match the server's `INTERNAL_API_KEY` value.","schema":{"type":"string"}}],"responses":{"200":{"description":"Governance-median coherence history for the team.","content":{"application/json":{"schema":{"type":"object","required":["team_id","governance_median_history","note"],"additionalProperties":false,"properties":{"team_id":{"type":"string","description":"The team identifier echoed from the path."},"governance_median_history":{"type":"array","description":"Time-ordered samples of the governance-median coherence value for the team.","items":{"type":"object","required":["value","at"],"additionalProperties":false,"properties":{"value":{"type":"number","description":"Governance-median coherence value at the sample timestamp."},"at":{"type":"string","format":"date-time","description":"Sample timestamp (ISO-8601 UTC)."}}}},"note":{"type":"string","description":"Human-readable note describing the history payload (e.g., data-source caveats)."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/effective-posture":{"get":{"operationId":"getTeamEffectivePosture","summary":"Get the team's currently-effective composed posture","description":"Returns the alignment + protection composition currently in effect for the team (assigned posture's body merged with the team's templates and agent exemptions).","tags":["Postures"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Effective posture.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamEffectivePosture"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/governance/signals":{"get":{"operationId":"listTeamGovernanceSignals","summary":"List governance signals for a team","description":"Returns governance signals scoped to the given team. Authorized to any member of the team's org.","tags":["Governance"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"source","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSource"},"description":"Filter by source detector."},{"name":"severity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalSeverity"},"description":"Filter by severity."},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GovernanceSignalStatus"},"description":"Filter by workflow status."},{"name":"pattern_type","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by pattern_type within the source's taxonomy."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Governance signals listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GovernanceSignalsListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/members":{"post":{"operationId":"addTeamMembers","summary":"Add members to team","description":"Add one or more agents to a team. Teams have a maximum of 50 members.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_ids"],"properties":{"agent_ids":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Agent IDs to add"}}}}}},"responses":{"200":{"description":"Members added","content":{"application/json":{"schema":{"type":"object","properties":{"added":{"type":"array","items":{"type":"string"}},"already_members":{"type":"array","items":{"type":"string"}},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"get":{"operationId":"getTeamMembers","summary":"List a team's current members","description":"Returns the current roster of agents on a team, along with each agent's join timestamp and individual reputation score (when available).","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team member list.","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/members/{agent_id}":{"delete":{"operationId":"removeTeamMember","summary":"Remove member from team","description":"Remove an agent from a team. Teams must retain a minimum of 2 members.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"$ref":"#/components/parameters/AgentId"}],"responses":{"200":{"description":"Member removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"},"agent_id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/my-role":{"get":{"operationId":"getTeamMyRole","summary":"Get the caller's effective role on this team","description":"Returns the caller's role on this team for UI gating. Computed via the same logic as `requireTeamRole` (ADR-046) and `getTeamRole`. Values: `super_admin` (Mnemom staff cookie), `org_owner` / `org_admin` (when the caller has that role on the team's org), `team_admin` (an active `team_admin_grants` row for the caller), `org_member` / `org_viewer` / `org_auditor` (read-only org membership), or `null` (no role). Surfaces that don't load a template-sources envelope (team roster, identity card, admins tab) use this to gate edit affordances from the same single source of truth as the editors. See ADR-053.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Caller's effective role on the team.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMyRoleResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/og-image":{"get":{"operationId":"getTeamReputationOgImage","x-proxied":"REPUTATION_SERVICE","summary":"Open Graph share-card image for a team","tags":["Team Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Share-card image.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"text/html":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/protection-template":{"get":{"operationId":"getTeamProtectionTemplateLegacy","summary":"DEPRECATED — use GET /v1/protection/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"putTeamProtectionTemplateLegacy","summary":"DEPRECATED — use PUT /v1/protection/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteTeamProtectionTemplateLegacy","summary":"DEPRECATED — use DELETE /v1/protection/team/{team_id}.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/team/{team_id}`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/protection-template/preview-compose":{"post":{"operationId":"postTeamProtectionTemplatePreviewComposeLegacy","summary":"DEPRECATED — use POST /v1/protection/team/{team_id}/preview-compose.","description":"Permanently redirects (HTTP 308, RFC 7538) to `/v1/protection/team/{team_id}/preview-compose`. Method and body are preserved across the redirect. Sunset: `Fri, 15 Jan 2027 00:00:00 GMT` — after that the legacy path returns 410 Gone. See [docs.mnemom.ai/concepts/cards-as-resources](https://docs.mnemom.ai/concepts/cards-as-resources) for the canonical Resources × Scope × Verb URL surface (cards-as-primitive Phase 4 W1.2b).","deprecated":true,"tags":["Card Templates"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"308":{"$ref":"#/components/responses/PermanentRedirect"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/reputation":{"get":{"operationId":"getTeamReputation","x-proxied":"REPUTATION_SERVICE","summary":"Get team reputation score","description":"Retrieve the current reputation score for a team, including component breakdown and A2A trust extension.","tags":["Team Reputation"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Team reputation score","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamReputationScore"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/reputation/history":{"get":{"operationId":"getTeamReputationHistory","x-proxied":"REPUTATION_SERVICE","summary":"Get team reputation history","description":"Retrieve weekly reputation score snapshots for a team.","tags":["Team Reputation"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Reputation history snapshots","content":{"application/json":{"schema":{"type":"object","properties":{"snapshots":{"type":"array","items":{"$ref":"#/components/schemas/TeamReputationSnapshot"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/reputation/verify":{"get":{"operationId":"verifyTeamReputation","x-proxied":"REPUTATION_SERVICE","summary":"Verify team reputation cryptographically","description":"Public endpoint. Returns the team's reputation score with a cryptographic proof hash for independent verification.","tags":["Team Reputation"],"security":[],"parameters":[{"$ref":"#/components/parameters/TeamId"}],"responses":{"200":{"description":"Reputation with verification proof","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string"},"score":{"type":"number"},"grade":{"type":"string"},"computed_at":{"type":"string","format":"date-time"},"verification":{"type":["object","null"],"properties":{"proof_hash":{"type":"string"},"computed_at":{"type":"string","format":"date-time"},"total_assessments":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/roster-history":{"get":{"operationId":"getTeamRosterHistory","summary":"Get team roster history","description":"Retrieve the history of member additions and removals for a team.","tags":["Teams"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"page","in":"query","schema":{"type":"integer","default":1},"description":"Page number"},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200},"description":"Results per page (max 200)"}],"responses":{"200":{"description":"Roster change history","content":{"application/json":{"schema":{"type":"object","properties":{"changes":{"type":"array","items":{"$ref":"#/components/schemas/TeamRosterChange"}},"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/teams/{team_id}/sideband-advisories":{"get":{"operationId":"listTeamSidebandAdvisories","summary":"List historical sideband advisories for a team (legacy)","description":"Sunsetting; see governance_signals.","tags":["Sideband"],"deprecated":true,"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivered","consumed","expired"]}}],"responses":{"200":{"description":"Sideband advisories listing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidebandAdvisoryListResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/teams/{team_id}/sideband-coverage":{"get":{"operationId":"getTeamSidebandCoverage","summary":"Sideband finding coverage rollup for a team","description":"Per-source counts over a window. Operator-facing.","tags":["Sideband"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/TeamId"},{"name":"hours","in":"query","schema":{"type":"integer","minimum":1,"maximum":720,"default":24}}],"responses":{"200":{"description":"Coverage rollup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SidebandCoverageReport"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/tools":{"get":{"operationId":"listTools","summary":"List registered tools","description":"Returns the active tools registry with optional filters. Reads accept any authenticated principal. Use `include_deprecated=true` to surface soft-deleted rows.","tags":["Tools"],"security":[],"parameters":[{"name":"class","in":"query","required":false,"schema":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"]},"description":"Filter by action class."},{"name":"domain","in":"query","required":false,"schema":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"]},"description":"Filter by operational domain."},{"name":"source_connector","in":"query","required":false,"schema":{"type":"string","maxLength":128},"description":"Filter by source connector name."},{"name":"include_deprecated","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include soft-deleted rows (deprecated_at IS NOT NULL)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Maximum rows to return; capped at 100."}],"responses":{"200":{"description":"Tools registry listing.","content":{"application/json":{"schema":{"type":"object","required":["data","count"],"properties":{"data":{"type":"array","items":{"type":"object","required":["name","class","domain","version","created_at","updated_at"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]},"deprecated_at":{"type":["string","null"],"format":"date-time"},"content_hash":{"type":["string","null"],"pattern":"^sha256:[a-f0-9]{64}$"},"version":{"type":"integer","minimum":1},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"count":{"type":"integer","minimum":0}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}},"post":{"operationId":"registerTool","summary":"Register a new tool","description":"Inserts a new tool row. Platform-admin only. Idempotency-Key is required. The composer sets content_hash + version=1; subsequent PATCH calls bump version only when content_hash changes.","tags":["Tools"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":255},"description":"Per-mutation idempotency key (RFC draft-ietf-httpapi-idempotency-key-header)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","class","domain"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"description":{"type":["string","null"]},"display_name":{"type":["string","null"]},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]}}}}}},"responses":{"201":{"description":"Tool registered.","headers":{"ETag":{"schema":{"type":"string"},"description":"sha256:<64-hex> over the canonical tool definition."},"X-Tool-Version":{"schema":{"type":"string"},"description":"Monotonic version (starts at 1)."},"X-Mnemom-Schema":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["name","class","domain","version","created_at","updated_at"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]},"deprecated_at":{"type":["string","null"],"format":"date-time"},"content_hash":{"type":["string","null"],"pattern":"^sha256:[a-f0-9]{64}$"},"version":{"type":"integer","minimum":1},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/tools/import":{"post":{"operationId":"importTools","summary":"Preview an import of tool definitions from an OpenAPI spec or connector YAML manifest.","description":"Parses the spec, extracts tool definitions, and optionally calls the LLM to infer class+domain. **Never auto-commits** — the caller iterates the `imported[]` array and writes each tool individually via `POST /v1/tools`. Platform-admin only. SSRF-defended (localhost / link-local / RFC-1918 blocked).","tags":["tools"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]},{"CookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["format","source"],"properties":{"format":{"type":"string","enum":["openapi","connector_yaml"]},"source":{"type":"string","enum":["inline","url"]},"content":{"type":"string","description":"Raw spec text. Required when `source=inline`."},"url":{"type":"string","description":"Public URL to fetch the spec. Required when `source=url`."},"infer_class_domain":{"type":"boolean","description":"When true (default), calls the LLM to infer class + domain per tool."}}}}}},"responses":{"200":{"description":"Preview of the imported tool definitions.","content":{"application/json":{"schema":{"type":"object","required":["ok","imported","inferred_class_domain","conflicts","commit_url","preview_token"],"properties":{"ok":{"type":"boolean","const":true},"imported":{"type":"array","items":{"type":"object","additionalProperties":true}},"inferred_class_domain":{"type":"object","additionalProperties":true},"conflicts":{"type":"array","items":{"type":"object","additionalProperties":true}},"commit_url":{"type":"string"},"preview_token":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"413":{"$ref":"#/components/responses/RequestEntityTooLarge"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/tools/{name}":{"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$"}}],"get":{"operationId":"getTool","summary":"Get a tool by name","description":"Returns the tool detail with ETag + X-Tool-Version. Supports 304 on If-None-Match.","tags":["Tools"],"security":[],"parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"},"description":"ETag returned from a prior GET; the server replies 304 when the tool is unchanged."}],"responses":{"200":{"description":"Tool detail.","headers":{"ETag":{"schema":{"type":"string"}},"X-Tool-Version":{"schema":{"type":"string"}},"X-Mnemom-Schema":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["name","class","domain","version","created_at","updated_at"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]},"deprecated_at":{"type":["string","null"],"format":"date-time"},"content_hash":{"type":["string","null"],"pattern":"^sha256:[a-f0-9]{64}$"},"version":{"type":"integer","minimum":1},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}},"304":{"description":"Not modified — the supplied If-None-Match matches the current content_hash.","headers":{"ETag":{"schema":{"type":"string"}},"X-Tool-Version":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","maxProperties":0}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"operationId":"updateTool","summary":"Update an existing tool","description":"Updates one or more user-editable fields. Platform-admin only. Idempotency-Key required. Version bumps only when content_hash changes. Immutable fields (name, version, content_hash, deprecated_at) are rejected with structured errors.","tags":["Tools"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"description":{"type":["string","null"]},"display_name":{"type":["string","null"]},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Tool updated.","headers":{"ETag":{"schema":{"type":"string"}},"X-Tool-Version":{"schema":{"type":"string"}},"X-Mnemom-Schema":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["name","class","domain","version","created_at","updated_at"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]},"deprecated_at":{"type":["string","null"],"format":"date-time"},"content_hash":{"type":["string","null"],"pattern":"^sha256:[a-f0-9]{64}$"},"version":{"type":"integer","minimum":1},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/tools/{name}/deprecate":{"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$"}}],"post":{"operationId":"deprecateTool","summary":"Soft-delete a tool","description":"Sets deprecated_at to the current time. Idempotent: re-deprecating an already-deprecated tool returns the existing row without an UPDATE. Platform-admin only.","tags":["Tools"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Tool marked deprecated (or already deprecated).","content":{"application/json":{"schema":{"type":"object","required":["name","class","domain","version","created_at","updated_at"],"properties":{"name":{"type":"string","pattern":"^([a-z][a-z0-9_]{1,127}|org:[a-z0-9-]{3,64}:[a-z][a-z0-9_]{1,127})$","description":"Globally unique tool name. Convention: `<connector>_<verb>_<noun>` (e.g. `campfire_create_chart_account`). Org-scoped tools use the reserved `org:<id>:` prefix."},"display_name":{"type":["string","null"]},"description":{"type":["string","null"]},"class":{"type":"string","enum":["read","internal_write","consequential_internal_write","consequential_external_write","comms_internal","comms_external","engineering_attestation","governance_write"],"description":"8-entry action class taxonomy per mnemom-contracts/tool-manifest/v1.yaml. V7 gateway hooks bind on this for class-scoped enforcement."},"domain":{"type":"string","enum":["financial","engineering","intelligence","growth","operations","governance","comms","identity","security"],"description":"9-entry domain taxonomy. Used by domain-scoped value declarations like policy_attentiveness(domain: financial)."},"schema":{"type":["object","null"],"description":"OpenAPI fragment / JSON Schema for the tool parameters. Populated when the tool is imported via OpenAPI spec."},"source_connector":{"type":["string","null"]},"deprecated_at":{"type":["string","null"],"format":"date-time"},"content_hash":{"type":["string","null"],"pattern":"^sha256:[a-f0-9]{64}$"},"version":{"type":"integer","minimum":1},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/traces":{"get":{"operationId":"queryTraces","summary":"Query traces with filters","tags":["Traces"],"security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"agent_id","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"minimum":1,"maximum":1000}},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0}}],"responses":{"200":{"description":"Filtered list of traces","content":{"application/json":{"schema":{"type":"object","properties":{"traces":{"type":"array","items":{"$ref":"#/components/schemas/APTrace"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/traces/{trace_id}":{"get":{"operationId":"getTrace","summary":"Get single trace by ID","tags":["Traces"],"security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]},{"CookieAuth":[]}],"parameters":[{"name":"trace_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trace details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APTrace"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/transactions":{"get":{"operationId":"listTransactions","summary":"List transactions","description":"Returns a paginated list of guarded transactions. Optionally filter by agent. Each transaction is annotated with a computed `status` field (`active` or `expired`) derived from `expires_at`.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"type":"string"},"description":"Filter transactions by agent ID"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum number of results to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"minimum":0},"description":"Number of results to skip"}],"responses":{"200":{"description":"Paginated list of transactions","content":{"application/json":{"schema":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"policy":{"type":"object"},"conscience_values":{"type":"array","items":{}},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["active","expired"],"description":"Computed from expires_at"}}}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"operationId":"createTransaction","summary":"Create transaction with guardrails","description":"Create a new guarded transaction. The transaction wraps one or more agent actions with CLPI policy guardrails, ensuring all tool invocations are evaluated against the effective policy before execution. Returns the transaction ID and initial evaluation status.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_id","actions"],"properties":{"agent_id":{"type":"string","description":"Agent performing the transaction"},"actions":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string","description":"Tool identifier"},"parameters":{"type":"object","description":"Tool parameters"},"justification":{"type":"string","description":"Why this action is needed"}}},"description":"List of actions to execute within the transaction"},"policy_override":{"$ref":"#/components/schemas/Policy","description":"Optional policy to use instead of the agent's effective policy"}}}}}},"responses":{"200":{"description":"Transaction created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"status":{"type":"string","enum":["pending","approved","blocked","escalated"]},"evaluation":{"$ref":"#/components/schemas/PolicyEvaluationResult"},"created_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/transactions/{id}":{"get":{"operationId":"getTransaction","summary":"Get transaction details","description":"Retrieve the details of a guarded transaction including its current status, policy evaluation result, and action outcomes.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Transaction identifier"}],"responses":{"200":{"description":"Transaction details","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"status":{"type":"string","enum":["pending","approved","blocked","escalated","completed","failed"]},"actions":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string"},"status":{"type":"string"},"result":{}}}},"evaluation":{"$ref":"#/components/schemas/PolicyEvaluationResult"},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteTransaction","summary":"Delete transaction","description":"Delete a guarded transaction. Only transactions in pending or completed status can be deleted. Active transactions must be completed or cancelled first.","tags":["Intelligence"],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Transaction identifier"}],"responses":{"200":{"description":"Transaction deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/transparency/log/{agent_id}":{"get":{"operationId":"getTransparencyLogEntryAt","security":[],"summary":"Point-in-time canonical posture lookup.","description":"Returns the transparency-log row whose `composed_at` is the greatest at-or-before the `at` query parameter, plus a freshly-computed Merkle inclusion proof. `card_kind` defaults to `alignment`. cards-as-primitive Phase 5 A2.","tags":["Transparency"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"at","in":"query","required":true,"schema":{"type":"string","format":"date-time"},"description":"ISO-8601 UTC timestamp."},{"name":"card_kind","in":"query","required":false,"schema":{"type":"string","enum":["alignment","protection"]},"description":"Defaults to `alignment`."}],"responses":{"200":{"description":"Log entry + inclusion proof.","content":{"application/json":{"schema":{"type":"object","required":["entry","inclusion_proof"],"properties":{"entry":{"type":"object","required":["log_index","agent_id","card_kind","content_hash","version","composed_at","signed_attestation","signing_key_id","merkle_leaf_hash","tree_size_after","integrated_time"],"properties":{"log_index":{"type":"integer","minimum":1},"agent_id":{"type":"string"},"card_kind":{"type":"string","enum":["alignment","protection"]},"content_hash":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"version":{"type":"integer","minimum":1},"composed_at":{"type":"string","format":"date-time"},"signed_attestation":{"type":"string","description":"JWS Compact serialization signed by Mnemom over the canonical identity tuple."},"signing_key_id":{"type":"string"},"merkle_leaf_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"tree_size_after":{"type":"integer","minimum":1},"integrated_time":{"type":"string","format":"date-time"}}},"inclusion_proof":{"type":"object","required":["leaf_hash","log_index","tree_size","hashes"],"properties":{"leaf_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"log_index":{"type":"integer","minimum":1},"tree_size":{"type":"integer","minimum":1},"hashes":{"type":"array","items":{"type":"object","required":["sibling","position"],"properties":{"sibling":{"type":"string","pattern":"^[0-9a-f]{64}$"},"position":{"type":"string","enum":["left","right"]}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/transparency/log/{agent_id}/{log_index}":{"get":{"operationId":"getTransparencyLogEntryByIndex","security":[],"summary":"Direct log entry by index, with Merkle inclusion proof.","description":"Returns the row at `log_index` (if it belongs to `agent_id`) plus a freshly-computed inclusion proof. cards-as-primitive Phase 5 A2.","tags":["Transparency"],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"log_index","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Log entry + inclusion proof.","content":{"application/json":{"schema":{"type":"object","required":["entry","inclusion_proof"],"properties":{"entry":{"type":"object","required":["log_index","agent_id","card_kind","content_hash","version","composed_at","signed_attestation","signing_key_id","merkle_leaf_hash","tree_size_after","integrated_time"],"properties":{"log_index":{"type":"integer","minimum":1},"agent_id":{"type":"string"},"card_kind":{"type":"string","enum":["alignment","protection"]},"content_hash":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"version":{"type":"integer","minimum":1},"composed_at":{"type":"string","format":"date-time"},"signed_attestation":{"type":"string","description":"JWS Compact serialization signed by Mnemom over the canonical identity tuple."},"signing_key_id":{"type":"string"},"merkle_leaf_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"tree_size_after":{"type":"integer","minimum":1},"integrated_time":{"type":"string","format":"date-time"}}},"inclusion_proof":{"type":"object","required":["leaf_hash","log_index","tree_size","hashes"],"properties":{"leaf_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"log_index":{"type":"integer","minimum":1},"tree_size":{"type":"integer","minimum":1},"hashes":{"type":"array","items":{"type":"object","required":["sibling","position"],"properties":{"sibling":{"type":"string","pattern":"^[0-9a-f]{64}$"},"position":{"type":"string","enum":["left","right"]}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/transparency/root":{"get":{"operationId":"getTransparencyRoot","security":[],"summary":"Signed current Merkle root for the canonical-card transparency log.","description":"Returns the current root + tree_size + published_at, signed by the active AAP signing key. Distinct `typ` from per-card attestations (`AAP-TransparencyRoot/v1`). Cacheable for 30 seconds; consumers refresh when they want a fresh root. cards-as-primitive Phase 5 A2.","tags":["Transparency"],"responses":{"200":{"description":"Signed root, or an empty-state payload when the log has no entries.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["tree_size","root_hash","published_at","signing_key_id","signature"],"properties":{"tree_size":{"type":"integer","minimum":0},"root_hash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"published_at":{"type":"string","format":"date-time"},"signing_key_id":{"type":"string"},"signature":{"type":"string","description":"Base64url Ed25519 signature over canonical_json({typ, tree_size, root_hash, published_at, kid})."}}},{"type":"object","required":["tree_size"],"properties":{"tree_size":{"const":0},"message":{"type":"string"}}}]}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/trust/advisories":{"get":{"operationId":"listTrustAdvisories","summary":"List published security advisories","description":"Returns the published advisories sorted by `published_at` desc. No authentication required — the surface is public trust messaging. Pagination via `limit` (default 20, max 100) and `offset`.","tags":["Trust"],"security":[],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Published advisories.","content":{"application/json":{"schema":{"type":"object","required":["advisories","limit","offset"],"properties":{"advisories":{"type":"array","items":{"type":"object","required":["id","slug","title","summary","body_markdown","severity","status","published_at","archived_at","post_mortem_for_campaign_id","synthetic","created_by","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","description":"URL-safe slug used as the customer-facing detail path."},"title":{"type":"string"},"summary":{"type":"string"},"body_markdown":{"type":"string"},"severity":{"type":"string","enum":["info","low","medium","high","critical"]},"status":{"type":"string","enum":["draft","published","archived"]},"published_at":{"type":["string","null"],"format":"date-time"},"archived_at":{"type":["string","null"],"format":"date-time"},"post_mortem_for_campaign_id":{"type":["string","null"],"format":"uuid"},"synthetic":{"type":"boolean"},"created_by":{"type":"string","format":"uuid"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/trust/advisories/{slug}":{"get":{"operationId":"getTrustAdvisoryBySlug","summary":"Fetch a published advisory by slug","description":"Returns the canonical advisory record for `{slug}`. Drafts and archived rows are not exposed on this surface — the CMS admin endpoints serve those.","tags":["Trust"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Advisory record.","content":{"application/json":{"schema":{"type":"object","required":["id","slug","title","summary","body_markdown","severity","status","published_at","archived_at","post_mortem_for_campaign_id","synthetic","created_by","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","description":"URL-safe slug used as the customer-facing detail path."},"title":{"type":"string"},"summary":{"type":"string"},"body_markdown":{"type":"string"},"severity":{"type":"string","enum":["info","low","medium","high","critical"]},"status":{"type":"string","enum":["draft","published","archived"]},"published_at":{"type":["string","null"],"format":"date-time"},"archived_at":{"type":["string","null"],"format":"date-time"},"post_mortem_for_campaign_id":{"type":["string","null"],"format":"uuid"},"synthetic":{"type":"boolean"},"created_by":{"type":"string","format":"uuid"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/trust/iocs":{"get":{"operationId":"listTrustIocs","summary":"STIX 2.1 Indicator-of-Compromise feed","description":"Public IoC feed returned as a STIX 2.1 Bundle. Per-indicator SDOs carry a Mnemom `extensions` block with internal type/TLP labelling. Rate-limited at the gateway and best-effort in-handler (1 req/min/IP). Pagination via `after=<ISO8601>` (resume from the last seen `last_seen_at`).","tags":["Trust"],"security":[],"parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["substrate_fingerprint","sha256","domain","url","technique_id"]}},{"name":"after","in":"query","required":false,"description":"Cursor — ISO-8601 timestamp; rows with `last_seen_at < after` are returned.","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}}],"responses":{"200":{"description":"STIX 2.1 Bundle (possibly empty at GA — see calm-at-GA contract).","content":{"application/json":{"schema":{"type":"object","required":["type","id","objects"],"properties":{"type":{"const":"bundle"},"id":{"type":"string","description":"STIX 2.1 bundle identifier (UUID-suffixed)."},"objects":{"type":"array","description":"STIX 2.1 indicator SDOs. Each carries a Mnemom extension with the internal indicator type + TLP + linkage to a related advisory.","items":{"type":"object"}},"next_after":{"type":"string","format":"date-time","description":"Mnemom-extension pagination cursor. Present iff the response was capped at `limit`. Pass as `?after=` to fetch the next page."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/verify":{"post":{"operationId":"verifyCertificate","summary":"Verify certificate","description":"Verify an IntegrityCertificate. Performs Ed25519 signature verification, chain hash verification, Merkle inclusion proof verification, input commitment check, and optional STARK proof verification. Public endpoint, no authentication required.","tags":["Verification"],"security":[{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["certificate"],"properties":{"certificate":{"$ref":"#/components/schemas/IntegrityCertificate"}}}}}},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCertificateResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}}}