openapi: 3.1.0
info:
  title: HUMMBL API
  version: 1.3.0
  description: |
    Mental models for AI agents — 120 governed reasoning operators with semantic search, recommendation, and workflow matching.

    **Security Features:**
    - Edge safety middleware with CAES validation and kill switch integration
    - Error sanitization layer preventing data leakage
    - Governance proof generation for all requests
    - Fail-closed behavior on safety engine errors
  contact:
    name: HUMMBL
    url: https://hummbl.io
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://api.hummbl.io
    description: Production (custom domain)
  - url: https://hummbl-api.hummbl.workers.dev
    description: Transport fallback (workers.dev)

tags:
  - name: Mental Models
    description: Base120 mental model catalog and transformations
  - name: Recommendation
    description: AI-powered model recommendation for a problem
  - name: Semantic Search
    description: 3-tier search (Workers AI + Vectorize, D1 cosine, BM25 fallback)
  - name: Workflows
    description: Multi-step reasoning workflows and matching
  - name: Validation
    description: Public text validation, sanitization, and PII detection
  - name: Compliance Analysis
    description: EU AI Act and governance framework analysis
  - name: Assessment
    description: Assessment capture, nurture sequence, and scorecard checkout
  - name: Agent Registry
    description: Agent heartbeats, fleet status, and tiered API key management (admin)
  - name: Task Queue
    description: Priority task queue with long-polling for the agent swarm (admin)
  - name: Safety
    description: Kill switch control and governance proofs (admin)
  - name: Security
    description: Arbiter governance validation and security event log (admin)
  - name: Observability
    description: Health, metrics, errors, slow requests, and funnel analytics
  - name: Webhooks
    description: Inbound webhook handlers for external service integrations

# HUMMBL API families (mirrors the docs hub grouping at https://hummbl.io/apis)
x-api-families:
  - name: HUMMBL Governed APIs (HGA)
    description: >
      The core reasoning surface: 120 governed mental models with semantic
      search, recommendation, and multi-step workflow matching.
    tags:
      [Mental Models, Recommendation, Semantic Search, Workflows, Validation]
  - name: Compliance & Assessment APIs
    description: >
      Analyze governance evidence against the EU AI Act and capture AI
      governance assessments with nurture and scorecard checkout.
    tags: [Compliance Analysis, Assessment]
  - name: Agent Control Plane APIs
    description: >
      Operate a fleet of agents: heartbeat registration, tiered API key
      management, and a priority task queue with long-polling.
    tags: [Agent Registry, Task Queue]
  - name: Safety & Observability APIs
    description: >
      The operational spine: kill switch control, governance proofs, security
      events, metrics, and funnel analytics.
    tags: [Safety, Security, Observability]
  - name: Resources
    description: Integration resources and inbound webhook handlers.
    tags: [Webhooks]

paths:
  /:
    get:
      summary: API info
      tags: [Observability]
      responses:
        "200":
          description: API metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  name: { type: string, example: HUMMBL API }
                  version: { type: string, example: 1.1.0 }
                  description: { type: string }

  /health:
    get:
      summary: Health check
      tags: [Observability]
      responses:
        "200":
          description: System health status
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: { type: string, enum: [healthy, degraded, critical] }
                  version: { type: string }
                  models_count: { type: integer, example: 120 }
                  uptime_ms: { type: integer }
                  open_brain: { type: boolean }
                  timestamp: { type: string, format: date-time }
                  rate_limit_status:
                    type: object
                    properties:
                      active_ips: { type: integer }
                      window_ms: { type: integer }
                      max_requests_per_minute: { type: integer }

  /v1/models:
    get:
      summary: List all 120 Base120 mental models
      tags: [Mental Models]
      responses:
        "200":
          description: Full model catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  count: { type: integer, example: 120 }
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Model"
        "403":
          description: CAES validation failed or insufficient tier
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "503":
          description: Kill switch engaged or safety engine error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /v1/models/{code}:
    get:
      summary: Get a single model by code
      tags: [Mental Models]
      parameters:
        - name: code
          in: path
          required: true
          schema: { type: string, example: P01 }
          description: Base120 model code (e.g. P01, DE05, SY18)
      responses:
        "200":
          description: Model details
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    $ref: "#/components/schemas/Model"
        "404":
          description: Model not found

  /v1/transformations:
    get:
      summary: List all model transformations
      tags: [Mental Models]
      responses:
        "200":
          description: Transformation catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  count: { type: integer }
                  data: { type: array, items: { type: object } }

  /v1/recommend:
    post:
      summary: Get model recommendations for a problem
      tags: [Recommendation]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [problem]
              properties:
                problem:
                  type: string
                  description: Natural language problem description
                  example: How do I decompose a complex system into manageable parts?
                limit:
                  type: integer
                  default: 5
                  maximum: 20
                  description: Maximum number of results to return
      responses:
        "200":
          description: Recommended models ranked by relevance
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Recommendation"
                  count: { type: integer }
                  algorithm: { type: string }
        "400":
          description: Invalid input or security validation failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: CAES validation failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "503":
          description: Kill switch engaged or safety engine error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /v1/semantic-search:
    post:
      summary: Semantic search for mental models
      description: |
        3-tier search: Workers AI + Vectorize → D1 cosine similarity → BM25 keyword fallback.
        Always returns results. Check `meta.source` for which tier served the response.
      tags: [Semantic Search]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [query]
              properties:
                query:
                  type: string
                  example: risk assessment frameworks
                limit:
                  type: integer
                  default: 10
                  maximum: 20
      responses:
        "200":
          description: Matched models (from vectorize, d1-cosine, or bm25-fallback)
        "400":
          description: Invalid input or security validation failed

  /v1/workflows:
    get:
      summary: List all reasoning workflows
      tags: [Workflows]
      responses:
        "200":
          description: Workflow catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    {
                      type: array,
                      items: { $ref: "#/components/schemas/Workflow" },
                    }
                  count: { type: integer }

  /v1/workflows/{id}:
    get:
      summary: Get a specific workflow
      tags: [Workflows]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Workflow details
        "404":
          description: Workflow not found

  /v1/workflows/match:
    post:
      summary: Match workflows to a problem
      tags: [Workflows]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [problem]
              properties:
                problem: { type: string }
                limit: { type: integer, default: 3 }
      responses:
        "200":
          description: Matched workflows
        "400":
          description: Invalid input

  /v1/validate:
    post:
      summary: Public text validation and sanitization
      tags: [Validation]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [input]
              properties:
                input: { type: string }
      responses:
        "200":
          description: Validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  validation: { type: object }
                  sanitized: { type: string }
                  pii: { type: object }
        "400":
          description: Invalid request body

  /security/validate:
    post:
      summary: Validate an agent operation via Arbiter governance
      tags: [Security]
      description: Admin-only; requires an X-API-Key and is suitable for operation-based governance decisions.
      security:
        - AdminApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [operation, agent_id]
              properties:
                operation: { type: string }
                agent_id: { type: string }
                context: { type: object }
      responses:
        "200":
          description: Governance decision
          content:
            application/json:
              schema:
                type: object
                properties:
                  verdict: { type: string, enum: [ALLOW, WARN, BLOCK] }
                  score: { type: number }
                  reason: { type: string }

  /security/events:
    get:
      summary: List security events (admin-only)
      tags: [Security]
      security:
        - AdminApiKey: []
      parameters:
        - name: type
          in: query
          schema: { type: string }
        - name: severity
          in: query
          schema: { type: string, enum: [LOW, MEDIUM, HIGH, CRITICAL] }
        - name: limit
          in: query
          schema: { type: integer, default: 100 }
      responses:
        "200":
          description: Recent security events
        "401":
          description: Unauthorized
        "503":
          description: ADMIN_API_KEY not configured

  /security/stats:
    get:
      summary: Security event statistics (admin-only)
      tags: [Security]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Aggregated security statistics
        "401":
          description: Unauthorized

  /metrics:
    get:
      summary: Request metrics and performance (admin-only)
      tags: [Observability]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Aggregated metrics
        "401":
          description: Unauthorized

  /metrics/errors:
    get:
      summary: Recent errors (admin-only)
      tags: [Observability]
      security:
        - AdminApiKey: []
      parameters:
        - name: limit
          in: query
          schema: { type: integer, default: 50 }
      responses:
        "200":
          description: Recent error list

  /metrics/slow:
    get:
      summary: Slow requests (admin-only)
      tags: [Observability]
      security:
        - AdminApiKey: []
      parameters:
        - name: threshold
          in: query
          schema: { type: integer, default: 1000 }
          description: Threshold in ms
        - name: limit
          in: query
          schema: { type: integer, default: 50 }
      responses:
        "200":
          description: Slow request list

  /analytics:
    get:
      summary: Usage analytics summary (admin-only)
      tags: [Observability]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Analytics summary
        "503":
          description: ANALYTICS_KV not configured

  /safety/kill-switch:
    get:
      summary: Get current kill switch state (admin-only)
      tags: [Safety]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Current kill switch state
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    enum: [DISENGAGED, HALT_NONCRITICAL, HALT_ALL, EMERGENCY]
                    description: Current kill switch state
                  last_updated:
                    type: string
                    format: date-time
                    description: Timestamp of last state change
                  reason:
                    type: string
                    description: Reason for current state
    post:
      summary: Update kill switch state (admin-only)
      tags: [Safety]
      security:
        - AdminApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [state]
              properties:
                state:
                  type: string
                  enum: [DISENGAGED, HALT_NONCRITICAL, HALT_ALL, EMERGENCY]
                  description: New kill switch state
                reason:
                  type: string
                  description: Reason for state change
      responses:
        "200":
          description: Kill switch state updated
        "400":
          description: Invalid state or parameters
        "401":
          description: Unauthorized

  /safety/governance-proofs:
    get:
      summary: List recent governance proofs (admin-only)
      tags: [Safety]
      security:
        - AdminApiKey: []
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 500
          description: Maximum number of proofs to return
        - name: path
          in: query
          schema:
            type: string
          description: Filter by API path
      responses:
        "200":
          description: Governance proof list
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
                  proofs:
                    type: array
                    items:
                      $ref: "#/components/schemas/GovernanceProof"
        "401":
          description: Unauthorized

  /agents/api-keys:
    post:
      summary: Create a new API key
      tags: [Agent Registry]
      security:
        - AdminApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name: { type: string, description: Human-readable label }
                tier:
                  { type: string, enum: [free, pro, enterprise], default: free }
                email: { type: string, description: Optional owner email }
      responses:
        "200":
          description: API key created (key shown once)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  key:
                    {
                      type: string,
                      description: Full API key (only shown at creation),
                    }
                  id: { type: string }
                  prefix: { type: string }
                  tier: { type: string }
    get:
      summary: List all API keys (without secrets)
      tags: [Agent Registry]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: API key list

  /agents/api-keys/{id}:
    delete:
      summary: Revoke an API key
      tags: [Agent Registry]
      security:
        - AdminApiKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Key revoked
        "404":
          description: Key not found or already revoked

  /v1/compliance/analyze:
    post:
      summary: Analyze governance evidence against EU AI Act
      tags: [Compliance Analysis]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [system_name, governance_evidence]
              properties:
                system_name:
                  type: string
                  description: Name of the AI system being assessed
                system_description:
                  type: string
                  description: Brief description of the system
                risk_level:
                  type: string
                  enum: [minimal, limited, high, unacceptable]
                  description: Self-declared risk classification
                governance_evidence:
                  type: object
                  description: Evidence per EU AI Act article
                  properties:
                    risk_management:
                      type: object
                      properties:
                        has_policy: { type: boolean }
                        is_documented: { type: boolean }
                        has_testing: { type: boolean }
                        has_monitoring: { type: boolean }
                    data_governance:
                      type: object
                      properties:
                        has_training_data_policy: { type: boolean }
                        addresses_bias: { type: boolean }
                        has_data_quality_checks: { type: boolean }
                    transparency:
                      type: object
                      properties:
                        has_user_disclosure: { type: boolean }
                        documents_capabilities: { type: boolean }
                        documents_limitations: { type: boolean }
                    human_oversight:
                      type: object
                      properties:
                        has_human_in_the_loop: { type: boolean }
                        has_override_capability: { type: boolean }
                        documents_oversight_procedures: { type: boolean }
                    accuracy:
                      type: object
                      properties:
                        has_accuracy_metrics: { type: boolean }
                        has_error_handling: { type: boolean }
                        tests_edge_cases: { type: boolean }
                    post_market:
                      type: object
                      properties:
                        has_monitoring_plan: { type: boolean }
                        has_incident_response: { type: boolean }
                        collects_feedback: { type: boolean }
                    record_keeping:
                      type: object
                      properties:
                        logs_decisions: { type: boolean }
                        retains_audit_trail: { type: boolean }
                        has_version_control: { type: boolean }
      responses:
        "200":
          description: Compliance analysis result
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  system_name: { type: string }
                  overall_score: { type: integer, description: "0-100" }
                  grade: { type: string, enum: [A, B, C, D, F] }
                  risk_level: { type: string }
                  article_scores:
                    type: array
                    items:
                      type: object
                      properties:
                        article: { type: string }
                        title: { type: string }
                        score: { type: integer }
                        max_score: { type: integer }
                        status:
                          {
                            type: string,
                            enum: [compliant, partial, non-compliant],
                          }
                        gaps:
                          type: array
                          items: { type: string }
                  critical_gaps:
                    type: array
                    items: { type: string }
                  recommendations:
                    type: array
                    items: { type: string }
                  estimated_remediation_effort: { type: string }
                  disclaimer: { type: string }
                  analyzed_at: { type: string, format: date-time }
        "400":
          description: Invalid request (missing system_name or bad JSON)

  /v1/compliance/frameworks:
    get:
      summary: List supported compliance frameworks
      tags: [Compliance Analysis]
      responses:
        "200":
          description: Framework list
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  frameworks:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: string }
                        name: { type: string }
                        reference: { type: string }
                        status: { type: string }
                        annex_iii_enforcement: { type: string }
                        articles_mapped:
                          type: array
                          items: { type: string }

  /v1/compliance/articles/{framework}:
    get:
      summary: Get article definitions for a framework
      tags: [Compliance Analysis]
      parameters:
        - name: framework
          in: path
          required: true
          schema: { type: string }
          description: Framework ID (e.g., eu_ai_act)
      responses:
        "200":
          description: Article definitions
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  framework: { type: string }
                  articles:
                    type: array
                    items:
                      type: object
                      properties:
                        article: { type: string }
                        title: { type: string }
                        max_score: { type: integer }
                        evidence_fields:
                          type: array
                          items: { type: string }
        "404":
          description: Framework not supported

  # ─── Assessment API (public, no admin auth) ───────────────────────────────
  /assessment/capture:
    post:
      summary: Capture assessment results and start nurture sequence
      tags: [Assessment]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, grade, score, categories]
              properties:
                email: { type: string, format: email }
                grade: { type: string }
                score: { type: integer }
                categories:
                  type: object
                  properties:
                    risk: { type: number }
                    transparency: { type: number }
                    oversight: { type: number }
                    data: { type: number }
                    agent: { type: number }
                    compliance: { type: number }
                top_gaps:
                  type: array
                  items:
                    type: object
                    properties:
                      name: { type: string }
                      score: { type: number }
                      description: { type: string }
      responses:
        "200":
          description: Capture receipt
        "400":
          description: Invalid request body

  /assessment/process-queue:
    post:
      summary: Cron-triggered nurture email queue processor
      tags: [Assessment]
      description: Sends due Email 2 / Email 3 from the KV queue. Intended for Cloudflare Cron Triggers.
      responses:
        "200":
          description: Queue processed

  /assessment/checkout:
    post:
      summary: Initiate Stripe checkout for a scorecard purchase
      tags: [Assessment]
      responses:
        "200":
          description: Checkout session created
        "503":
          description: Stripe not configured

  /assessment/calcom-webhook:
    post:
      summary: Cal.com booking webhook for assessment scheduling
      tags: [Assessment]
      responses:
        "200":
          description: Webhook acknowledged
        "401":
          description: Invalid webhook signature

  /assessment/reports/request-access-link:
    post:
      summary: Request a time-limited report access link
      tags: [Assessment]
      responses:
        "200":
          description: Access link generated

  /assessment/reports/access:
    get:
      summary: Redeem a report access link
      tags: [Assessment]
      responses:
        "200":
          description: Report access granted
        "404":
          description: Access link invalid or expired

  # ─── Agent Registry API (admin-only) ──────────────────────────────────────
  /agents/heartbeat:
    post:
      summary: Agent phone-home heartbeat
      tags: [Agent Registry]
      security:
        - AdminApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [agentId]
              properties:
                agentId:
                  type: string
                  pattern: "^[a-zA-Z0-9_-]{1,64}$"
                  description: Alphanumeric, hyphens, underscores; 1-64 chars
                ts: { type: string, format: date-time }
                status: { type: string }
      responses:
        "200":
          description: Heartbeat received
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  received: { type: string }
        "400":
          description: Missing or invalid agentId

  /agents/status:
    get:
      summary: All agent statuses
      tags: [Agent Registry]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Fleet status

  # ─── Task Queue API (admin-only) ──────────────────────────────────────────
  /tasks/enqueue:
    post:
      summary: Submit a task to the queue
      tags: [Task Queue]
      security:
        - AdminApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [type]
              properties:
                type: { type: string }
                payload: { type: object }
                priority: { type: integer, default: 5 }
                maxRetries: { type: integer, default: 3 }
                timeoutMs: { type: integer, default: 120000 }
      responses:
        "200":
          description: Task enqueued
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  task: { type: object }
        "400":
          description: Missing "type" field

  /tasks/poll:
    get:
      summary: Long-poll for the next task (agent calls this)
      tags: [Task Queue]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Next task or empty

  /tasks/{id}/complete:
    post:
      summary: Mark a task done
      tags: [Task Queue]
      security:
        - AdminApiKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Task completed
        "404":
          description: Task not found

  /tasks/stats:
    get:
      summary: Queue stats for the dashboard
      tags: [Task Queue]
      security:
        - AdminApiKey: []
      responses:
        "200":
          description: Queue statistics

  # ─── Observability: public funnel endpoints (no admin auth) ───────────────
  /analytics/event:
    post:
      summary: Lightweight funnel event tracking (no PII)
      tags: [Observability]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [event]
              properties:
                event:
                  type: string
                  pattern: "^[a-zA-Z0-9_-]+$"
                  maxLength: 64
      responses:
        "200":
          description: Event tracked
        "400":
          description: Missing or invalid event
        "503":
          description: Analytics not configured

  /analytics/funnel:
    get:
      summary: Funnel stats for the assessment / report loop
      tags: [Observability]
      responses:
        "200":
          description: Funnel stats
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  stats: { type: object }
        "503":
          description: Analytics not configured

  # ─── Webhooks (inbound, verified via per-service secrets) ─────────────────
  /webhooks/cal:
    post:
      summary: Cal.com booking webhook
      tags: [Webhooks]
      description: Verified via CAL_WEBHOOK_SECRET. Sends a booking alert email via Resend.
      responses:
        "200":
          description: Webhook acknowledged
        "401":
          description: Invalid webhook signature

  /webhooks/stripe:
    post:
      summary: Stripe payment webhook
      tags: [Webhooks]
      description: 5-minute timestamp tolerance, 1 MB max payload. Verified via STRIPE_WEBHOOK_SECRET.
      responses:
        "200":
          description: Webhook acknowledged
        "401":
          description: Invalid webhook signature
        "413":
          description: Payload too large

  /webhooks/resend:
    post:
      summary: Resend delivery webhook
      tags: [Webhooks]
      description: Verified via RESEND_WEBHOOK_SECRET.
      responses:
        "200":
          description: Webhook acknowledged
        "401":
          description: Invalid webhook signature

components:
  securitySchemes:
    AdminApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Admin API key (set via wrangler secret put ADMIN_API_KEY)
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Tiered API key (free/pro/enterprise) for /v1/* endpoints

  schemas:
    Model:
      type: object
      properties:
        code: { type: string, example: P01 }
        name: { type: string, example: "Perspective Anchoring (P01)" }
        family: { type: string, enum: [P, IN, CO, DE, RE, SY] }
        family_name: { type: string }
        description: { type: string }
        when_to_use: { type: string }
        examples: { type: array, items: { type: string } }

    Recommendation:
      type: object
      properties:
        code: { type: string }
        name: { type: string }
        relevance_score: { type: number }
        reason: { type: string }

    Workflow:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        description: { type: string }
        steps: { type: array, items: { type: object } }

    GovernanceProof:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
          description: When the request was processed
        path:
          type: string
          description: API endpoint path
        method:
          type: string
          description: HTTP method
        clientIp:
          type: string
          description: Client IP address
        userAgent:
          type: string
          description: User agent string
        safetyValidated:
          type: boolean
          description: Whether safety validation passed

    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Sanitized error message (no internal details)
        code:
          type: string
          enum:
            [
              INTERNAL_ERROR,
              EXTERNAL_SERVICE_ERROR,
              REQUEST_ERROR,
              CAES_VALIDATION_FAILED,
              KILL_SWITCH_ENGAGED,
              SAFETY_ENGINE_ERROR,
            ]
          description: Error code for programmatic handling
