openapi: 3.1.0
info:
  title: ExecOS Externa API
  version: 2026-06-01
  summary: Agent-first outcome intake, executive orchestration, token-billing admission,
    and Neumont Fit Finder APIs.
  description: 'ExecOS Externa is the agent-first front door for Externa.ai. It starts
    with a

    Per Se outcome, progressively discloses capabilities and costs, and escalates

    to executive processes such as CPO only when useful.

    '
  contact:
    name: Bad Labels / Externa
    url: https://externa.ai/reference.html
jsonSchemaDialect: https://json-schema.org/draft/2020-12/schema
servers:
- url: https://externa.ai
  description: Externa production
- url: http://127.0.0.1:8000
  description: Local agent service
tags:
- name: Agent Context
  description: Public agent-readable front door resources.
- name: Outcome Admission
  description: Token-billing estimates and approval-gated admission.
- name: CPO
  description: Dry-run Chief Product Officer process.
- name: Executive Orchestration
  description: CEO and executive run planning with RAID/RACI, delegation, and approval
    events.
- name: Skill Runs
  description: Service-owned skill execution drafts with approval boundaries.
- name: Neumont
  description: Consent-first Neumont Fit Finder and source-intelligence guardrails.
- name: Annotations
  description: Targeted refinement requests for selected code, Markdown, Sites, documents,
    spreadsheets, slides, charts, and images.
- name: Authentication
  description: Entra-backed human session entrypoints for ExecOS teams.
- name: Live Voice
  description: Gemini Live session brokerage and policy for ExecOS voice workers.
- name: Devices
  description: Agent-readable device, skill, tool, and protocol registry.
- name: Per Se
  description: OutcomeContract compilation, profile, approval, and replay surfaces.
- name: Proof & Ledger
  description: Proof receipts, capability acquisition records, and auditable outcome ledger entries.
paths:
  /v1/auth/entra/session:
    get:
      tags:
      - Authentication
      operationId: getExecOSEntraSession
      summary: Get the current ExecOS Entra session.
      security:
      - BearerAuth: []
      responses:
        '200':
          description: Current authenticated team context, or an anonymous session.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSEntraSession'
  /v1/auth/entra/login:
    get:
      tags:
      - Authentication
      operationId: createExecOSEntraLogin
      summary: Start an Entra login flow for an ExecOS team.
      responses:
        '501':
          description: Entra BFF login is not implemented yet.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /v1/auth/entra/callback:
    get:
      tags:
      - Authentication
      operationId: completeExecOSEntraCallback
      summary: Complete an Entra authorization callback.
      responses:
        '501':
          description: Entra BFF callback is not implemented yet.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /v1/auth/entra/logout:
    post:
      tags:
      - Authentication
      operationId: logoutExecOSEntraSession
      summary: End the current ExecOS Entra session.
      security:
      - BearerAuth: []
      responses:
        '200':
          description: Logout result.
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                properties:
                  status:
                    type: string
                    enum:
                    - logged_out
  /v1/voice/execos/live/config:
    get:
      tags:
      - Live Voice
      operationId: getExecOSLiveVoiceConfig
      summary: Get live voice policy and provider configuration.
      security:
      - BearerAuth: []
      responses:
        '200':
          description: Provider, tool, and approval policy for live ExecOS voice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSLiveVoiceConfig'
  /v1/voice/execos/live/session:
    post:
      tags:
      - Live Voice
      operationId: createExecOSLiveVoiceSession
      summary: Create a short-lived ExecOS Gemini Live session.
      security:
      - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecOSLiveVoiceSessionRequest'
      responses:
        '200':
          description: Brokered live-session URL, token mode, and expiry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSLiveVoiceSession'
  /v1/execos/devices:
    get:
      tags:
      - Devices
      operationId: listExecOSDevices
      summary: List the ExecOS device registry.
      security:
      - BearerAuth: []
      responses:
        '200':
          description: Agent, skill, tool, API, protocol, and workspace registry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSDeviceRegistry'
  /v1/execos/devices/{device_id}:
    get:
      tags:
      - Devices
      operationId: getExecOSDevice
      summary: Get a full ExecOS device manifest by id.
      security:
      - BearerAuth: []
      parameters:
      - name: device_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Full registry entry for the requested device.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSDeviceRegistryEntry'
        '404':
          description: ExecOS device not found.
  /v1/execos/perse/profile:
    get:
      tags:
      - Per Se
      operationId: getExecOSPerSeProfile
      summary: Get the Per Se outcome profile and approval policy.
      responses:
        '200':
          description: Per Se profile for outcome compilation and replay.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSPerSeProfile'
  /v1/execos/outcomes/compile:
    post:
      tags:
      - Per Se
      operationId: compileExecOSOutcome
      summary: Compile an ambiguous request into an OutcomeContract.
      security:
      - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OutcomeContractCompileRequest'
      responses:
        '200':
          description: Compiled, approval-aware OutcomeContract.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutcomeContract'
  /v1/execos/outcomes:
    post:
      tags:
      - Per Se
      operationId: createExecOSOutcome
      summary: Create a durable Per Se outcome draft from intent or a full contract.
      security:
      - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OutcomeCreateRequest'
      responses:
        '200':
          description: Persisted outcome record in draft state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutcomeRecord'
    get:
      tags:
      - Per Se
      operationId: listExecOSOutcomes
      summary: List Per Se outcome records for a workspace.
      security:
      - BearerAuth: []
      parameters:
      - name: workspace_id
        in: query
        schema:
          type: string
      - name: include_archived
        in: query
        schema:
          type: boolean
      responses:
        '200':
          description: Outcome records, newest first; archived hidden by default.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OutcomeRecord'
  /v1/execos/outcomes/{outcome_id}:
    get:
      tags:
      - Per Se
      operationId: getExecOSOutcome
      summary: Get a Per Se outcome record.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Outcome record.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutcomeRecord'
        '404':
          description: Outcome not found.
  /v1/execos/outcomes/{outcome_id}/transition:
    post:
      tags:
      - Per Se
      operationId: transitionExecOSOutcome
      summary: Run a Per Se lifecycle transition with fail-closed approval gates.
      description: Approve, execute, observe, handoff, and archive require the ExecOS operator role and operator_approved=true. Approve additionally requires approval authority.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OutcomeTransitionRequest'
      responses:
        '200':
          description: Updated outcome record.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutcomeRecord'
        '403':
          description: Operator approval or role missing; the action fails closed.
        '404':
          description: Outcome not found.
        '409':
          description: Transition not allowed from the current lifecycle state.
  /v1/execos/outcomes/{outcome_id}/trace:
    get:
      tags:
      - Proof & Ledger
      operationId: getExecOSOutcomeTrace
      summary: Get the replayable audit trace for an outcome.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Ordered trace entries and proof receipts for replay.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutcomeTrace'
        '404':
          description: Outcome not found.
  /v1/execos/outcomes/{outcome_id}/proof-receipts:
    get:
      tags:
      - Proof & Ledger
      operationId: listExecOSOutcomeProofReceipts
      summary: List proof receipts for an outcome.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Proof receipts attached to the outcome.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProofReceipt'
    post:
      tags:
      - Proof & Ledger
      operationId: createExecOSOutcomeProofReceipt
      summary: Dry-run an operator-approved proof receipt for an outcome.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProofReceiptCreateRequest'
      responses:
        '200':
          description: Dry-run proof receipt. Persistence is not enabled until durable proof storage lands.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProofReceipt'
        '403':
          description: Operator approval required.
  /v1/execos/outcomes/{outcome_id}/ledger:
    get:
      tags:
      - Proof & Ledger
      operationId: listExecOSOutcomeLedger
      summary: List auditable outcome ledger entries.
      security:
      - BearerAuth: []
      parameters:
      - name: outcome_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Ledger entries for the outcome.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OutcomeLedgerEntry'
  /v1/execos/agent/context:
    get:
      tags:
      - Agent Context
      operationId: getExecOSAgentContext
      summary: Get the Externa agent context.
      responses:
        '200':
          description: Agent context for human and autonomous clients.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSAgentContext'
  /v1/execos/agent/bootstrap:
    get:
      tags:
      - Agent Context
      operationId: getExecOSAgentBootstrap
      summary: Get a compact startup prompt for Externa.
      parameters:
      - name: format
        in: query
        required: false
        schema:
          type: string
          enum:
          - json
          - markdown
          default: json
      responses:
        '200':
          description: Startup prompt and links.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSBootstrap'
  /v1/execos/agent/discovery:
    get:
      tags:
      - Agent Context
      operationId: getExecOSAgentDiscovery
      summary: Get discovery links for docs, specs, Postman, Swagger, and Redoc.
      responses:
        '200':
          description: Discovery payload.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSAgentDiscovery'
  /v1/execos/outcomes/estimate:
    post:
      tags:
      - Outcome Admission
      operationId: estimateExecOSOutcome
      summary: Estimate token/credit cost for an outcome route.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecOSOutcomeEstimateRequest'
            examples:
              productOutcome:
                value:
                  title: Lift new-user activation with an AI-assisted onboarding flow
                  route_hint: cpo
                  expected_input_tokens: 6000
                  expected_output_tokens: 4000
                  max_spend_usd: 25
      responses:
        '200':
          description: Estimate result. Unknown cost fails closed with approval_required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSOutcomeEstimateResponse'
  /v1/execos/outcomes/admit:
    post:
      tags:
      - Outcome Admission
      operationId: admitExecOSOutcome
      summary: Admit an outcome after estimate and operator approval.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecOSOutcomeAdmitRequest'
      responses:
        '200':
          description: Admission decision and dry-run reservation when applicable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSOutcomeAdmitResponse'
  /v1/execos/cpo/runs:
    post:
      tags:
      - CPO
      operationId: createExecOSCpoRun
      summary: Create an approval-gated CPO dry run.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecOSCpoRunRequest'
      responses:
        '200':
          description: CPO dry-run plan and trace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecOSCpoRun'
  /v1/execos/ceo/runs:
    post:
      tags:
      - Executive Orchestration
      operationId: createExecOSCeoRun
      summary: Create a CEO executive run with governance, delegation, and approval
        gates.
      requestBody:
        required: true
        content:
          application/json:
            schema: &id001
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
  /v1/execos/executives/{seat}/runs:
    post:
      tags:
      - Executive Orchestration
      operationId: createExecOSExecutiveRun
      summary: Create a deterministic executive run for a specific C-suite seat.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
      parameters:
      - name: seat
        in: path
        required: true
        schema:
          type: string
  /v1/execos/executives/delegate:
    post:
      tags:
      - Executive Orchestration
      operationId: delegateExecOSOutcome
      summary: Return the executive delegation graph for an outcome.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
  /v1/execos/runs/{run_id}:
    get:
      tags:
      - Executive Orchestration
      operationId: getExecOSRun
      summary: Get an ExecOS run by id.
      parameters:
      - name: run_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Run payload.
          content:
            application/json:
              schema: *id001
  /v1/execos/runs/{run_id}/events:
    get:
      tags:
      - Executive Orchestration
      operationId: getExecOSRunEvents
      summary: Get event trace for an ExecOS run.
      parameters:
      - name: run_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Run events.
          content:
            application/json:
              schema:
                type: array
                items: *id001
  /v1/execos/skills/{skillId}/runs:
    post:
      tags:
      - Skill Runs
      operationId: createExecOSSkillRun
      summary: Create a service-owned, approval-gated skill run draft.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
      parameters:
      - name: skillId
        in: path
        required: true
        schema:
          type: string
  /v1/neumont/fit-assessments:
    post:
      tags:
      - Neumont
      operationId: createNeumontFitAssessment
      summary: Create a consent-first Neumont fit guidance response.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
  /v1/neumont/consent-events:
    post:
      tags:
      - Neumont
      operationId: createNeumontConsentEvent
      summary: Record or echo a consent event for a student-owned workflow.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
  /v1/neumont/source-intel/validate:
    post:
      tags:
      - Neumont
      operationId: validateNeumontSourceIntel
      summary: Classify source intelligence as green, yellow, or red zone.
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Successful dry-run or validation response.
          content:
            application/json:
              schema: *id001
  /v1/execos/annotations/refine:
    post:
      tags:
      - Annotations
      operationId: createExecOSAnnotationRefinement
      summary: Capture a targeted annotation refinement request and route it to the
        smallest executive lens.
      requestBody:
        required: true
        content:
          application/json:
            schema: &id002
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Annotation route and next actions.
          content:
            application/json:
              schema: *id002
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: ExecOS human or service bearer token.
  schemas:
    ExecOSRole:
      type: string
      enum:
      - viewer
      - operator
      - admin
      - owner
    ExecOSTeam:
      type: object
      required:
      - team_id
      - name
      - tenant_id
      - created_at
      properties:
        team_id:
          type: string
          format: uuid
        name:
          type: string
        tenant_id:
          type: string
        entra_tenant_id:
          type: string
        created_at:
          type: string
          format: date-time
    ExecOSTeamMember:
      type: object
      required:
      - member_id
      - team_id
      - human_id
      - role
      - status
      properties:
        member_id:
          type: string
          format: uuid
        team_id:
          type: string
          format: uuid
        human_id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        display_name:
          type: string
        role:
          $ref: '#/components/schemas/ExecOSRole'
        status:
          type: string
          enum:
          - active
          - invited
          - suspended
    ExecOSEntraSession:
      type: object
      required:
      - authenticated
      properties:
        authenticated:
          type: boolean
        team:
          $ref: '#/components/schemas/ExecOSTeam'
        member:
          $ref: '#/components/schemas/ExecOSTeamMember'
        expires_at:
          type: string
          format: date-time
        roles:
          type: array
          items:
            type: string
    ExecOSEntraLoginRequest:
      type: object
      properties:
        redirect_uri:
          type: string
        team_hint:
          type: string
        state:
          type: string
    ExecOSEntraLoginResponse:
      type: object
      required:
      - authorization_url
      - state
      properties:
        authorization_url:
          type: string
        state:
          type: string
        expires_at:
          type: string
          format: date-time
    ExecOSEntraCallbackRequest:
      type: object
      required:
      - code
      - state
      properties:
        code:
          type: string
        state:
          type: string
        redirect_uri:
          type: string
    ExecOSLiveVoiceConfig:
      type: object
      required:
      - enabled
      - speech_provider
      - model_id
      - transport
      - websocket_path
      - live_ready
      - allowed_skill_slugs
      properties:
        enabled:
          type: boolean
        speech_provider:
          type: string
          default: gemini-live
        model_id:
          type: string
        transport:
          type: string
          enum:
          - server-relay
        websocket_path:
          type: string
        default_voice_id:
          type: string
        mock_mode:
          type: boolean
          default: false
        fallback_provider:
          type: string
        fallback_available:
          type: boolean
          default: false
        live_ready:
          type: boolean
          default: false
        input_sample_rate_hz:
          type: integer
          default: 16000
        output_sample_rate_hz:
          type: integer
          default: 24000
        allowed_skill_slugs:
          type: array
          items:
            type: string
        direct_ephemeral_allowed:
          type: boolean
          default: false
    ExecOSLiveVoiceSessionRequest:
      type: object
      properties:
        workspace_id:
          type: string
          default: execos-demo
        skill_id:
          type: string
          default: execos-externa-outcome-shaper
        mode:
          type: string
          default: outcome_shaping
        voice_id:
          type: string
        preferred_modality:
          type: string
          enum:
          - voice
          - chat
          default: voice
    ExecOSLiveVoiceSession:
      type: object
      required:
      - session_id
      - session_secret
      - speech_provider
      - model_id
      - websocket_path
      - expires_at
      - allowed_skill_slugs
      - system_prompt_hint
      properties:
        session_id:
          type: string
        session_secret:
          type: string
        speech_provider:
          type: string
        model_id:
          type: string
        websocket_path:
          type: string
        expires_at:
          type: string
          format: date-time
        allowed_skill_slugs:
          type: array
          items:
            type: string
        system_prompt_hint:
          type: string
        voice_id:
          type: string
        customer_context:
          type: object
          additionalProperties: true
    OutcomeContract:
      type: object
      required:
      - id
      - version
      - title
      properties:
        id:
          type: string
          format: uuid
        version:
          type: string
        title:
          type: string
        description:
          type: string
        outcome_type:
          type: string
          enum:
          - transactional
          - transformational
          - diagnostic
          - artifact
        audience:
          type: array
          items:
            type: string
        constraints:
          type: array
          items:
            type: object
            additionalProperties: true
        acceptance_oracle:
          type: object
          additionalProperties: true
        observation_window:
          type: object
          additionalProperties: true
        required_capabilities:
          type: array
          items:
            type: object
            additionalProperties: true
        hitl_policy:
          type: object
          additionalProperties: true
        attribution_policy:
          type: object
          additionalProperties: true
        metadata:
          type: object
          additionalProperties: true
    OutcomeContractCompileRequest:
      type: object
      required:
      - request
      properties:
        request:
          type: string
          minLength: 1
          maxLength: 2000
        title:
          type: string
        audience:
          type: array
          items:
            type: string
        constraints:
          type: array
          items:
            type: string
        acceptance_criteria:
          type: array
          items:
            type: string
        required_capabilities:
          type: array
          items:
            type: string
    CapabilityAcquisitionRecord:
      type: object
      required:
      - id
      - capability_id
      - protocol
      - driver
      properties:
        id:
          type: string
          format: uuid
        capability_id:
          type: string
        protocol:
          type: string
        driver:
          type: string
        conformance_status:
          type: string
        scopes:
          type: array
          items:
            type: string
        cost_model:
          type: object
          additionalProperties: true
        acquired_at:
          type: string
          format: date-time
    ProofReceipt:
      type: object
      required:
      - id
      - outcome_id
      - proof_tier
      properties:
        id:
          type: string
          format: uuid
        outcome_id:
          type: string
          format: uuid
        proof_tier:
          type: string
          enum:
          - P0
          - P1
          - P2
          - P3
          - P4
          - P5
        evidence_refs:
          type: array
          items:
            type: string
        verifier:
          type: string
        created_at:
          type: string
          format: date-time
    ProofReceiptCreateRequest:
      type: object
      properties:
        proof_tier:
          type: string
          enum:
          - P0
          - P1
          - P2
          - P3
          - P4
          - P5
          default: P1
        evidence_refs:
          type: array
          items:
            type: string
        verifier:
          type: string
          default: operator
        operator_approved:
          type: boolean
          default: false
    OutcomeRoute:
      type: object
      required:
      - target_kind
      - target_ref
      - rationale
      properties:
        target_kind:
          type: string
          enum:
          - skill
          - executive_seat
          - api
          - mcp
          - cli
          - human
        target_ref:
          type: string
        rationale:
          type: string
        approval_required:
          type: boolean
        deterministic_fallback:
          type: string
    OutcomeRecord:
      type: object
      required:
      - outcome_id
      - workspace_id
      - state
      - contract
      properties:
        outcome_id:
          type: string
          format: uuid
        workspace_id:
          type: string
        tenant_id:
          type: string
        state:
          type: string
          enum:
          - draft
          - validated
          - estimated
          - approved
          - executing
          - observed
          - handed_off
          - archived
        contract:
          $ref: '#/components/schemas/OutcomeContract'
        route:
          $ref: '#/components/schemas/OutcomeRoute'
        estimate:
          type: object
          additionalProperties: true
        approval_id:
          type: string
        handoff:
          type: object
          additionalProperties: true
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        archived_at:
          type: string
          format: date-time
    OutcomeCreateRequest:
      type: object
      required:
      - workspace_id
      properties:
        workspace_id:
          type: string
        message:
          type: string
          maxLength: 8000
        contract:
          $ref: '#/components/schemas/OutcomeContract'
        title:
          type: string
        audience:
          type: array
          items:
            type: string
        constraints:
          type: array
          items:
            type: string
        acceptance_criteria:
          type: array
          items:
            type: string
        required_capabilities:
          type: array
          items:
            type: string
    OutcomeTransitionRequest:
      type: object
      required:
      - action
      properties:
        action:
          type: string
          enum:
          - validate
          - estimate
          - approve
          - execute
          - observe
          - handoff
          - archive
        operator_approved:
          type: boolean
        note:
          type: string
        evidence_refs:
          type: array
          items:
            type: string
        handoff_target:
          type: string
        max_spend_usd:
          type: number
          minimum: 0
    OutcomeTraceEntry:
      type: object
      required:
      - sequence
      - entry_type
      properties:
        sequence:
          type: integer
          minimum: 0
        entry_type:
          type: string
        actor_type:
          type: string
        actor_id:
          type: string
        run_id:
          type: string
        amount_usd:
          type: number
        payload:
          type: object
          additionalProperties: true
        created_at:
          type: string
          format: date-time
    OutcomeTrace:
      type: object
      required:
      - outcome_id
      - state
      properties:
        outcome_id:
          type: string
          format: uuid
        state:
          type: string
        entries:
          type: array
          items:
            $ref: '#/components/schemas/OutcomeTraceEntry'
        proof_receipts:
          type: array
          items:
            $ref: '#/components/schemas/ProofReceipt'
    OutcomeLedgerEntry:
      type: object
      required:
      - id
      - outcome_id
      properties:
        id:
          type: string
          format: uuid
        outcome_id:
          type: string
          format: uuid
        cost_credits:
          type: integer
          minimum: 0
        cost_usd:
          type: number
          minimum: 0
        proof_receipt_ids:
          type: array
          items:
            type: string
            format: uuid
        attribution:
          type: object
          additionalProperties: true
    ExecOSPerSeProfile:
      type: object
      required:
      - protocol
      - version
      - supported_contracts
      - approval_boundaries
      properties:
        protocol:
          type: string
          default: per-se
        version:
          type: string
        supported_contracts:
          type: array
          items:
            type: string
        approval_boundaries:
          type: array
          items:
            type: string
        replay_supported:
          type: boolean
    ExecOSProtocolLink:
      type: object
      required:
      - id
      - name
      - status
      - summary
      properties:
        id:
          type: string
        name:
          type: string
        status:
          type: string
          enum:
          - current
          - partial
          - planned
        url:
          type: string
        summary:
          type: string
    ExecOSDeviceCost:
      type: object
      properties:
        unit_name:
          type: string
          default: run
        estimated_units:
          type: integer
          minimum: 0
          default: 1
        estimated_usd_min:
          type: number
          minimum: 0
        estimated_usd_max:
          type: number
          minimum: 0
        approval_required:
          type: boolean
          default: true
        notes:
          type: string
    ExecOSDeviceRegistryEntry:
      type: object
      required:
      - id
      - kind
      - name
      - summary
      - driver
      - disclosure
      properties:
        id:
          type: string
        kind:
          type: string
          enum:
          - agent
          - skill
          - tool
          - api
          - server
          - biome
          - plugin
          - workspace
          - protocol
        name:
          type: string
        summary:
          type: string
        driver:
          type: string
        disclosure:
          type: string
          enum:
          - summary
          - capability
          - cost
          - manifest
          - execution
        status:
          type: string
          enum:
          - current
          - partial
          - planned
          default: current
        capabilities:
          type: array
          items:
            type: string
        cost:
          $ref: '#/components/schemas/ExecOSDeviceCost'
        manifest_url:
          type: string
    ExecOSDeviceRegistry:
      type: object
      required:
      - devices
      properties:
        devices:
          type: array
          items:
            $ref: '#/components/schemas/ExecOSDeviceRegistryEntry'
        updated_at:
          type: string
          format: date-time
    ExecOSAgentContext:
      type: object
      required:
      - name
      - domain
      - version
      - summary
      - agent_posture
      - recommended_entrypoint
      - progressive_disclosure_layers
      - protocols
      - device_registry
      - trust_controls
      properties:
        name:
          type: string
          example: ExecOS Externa
        domain:
          type: string
          example: externa.ai
        version:
          type: string
          example: '2026-06-01'
        summary:
          type: string
        agent_posture:
          type: string
        recommended_entrypoint:
          type: string
        progressive_disclosure_layers:
          type: array
          items:
            type: string
        protocols:
          type: array
          items:
            $ref: '#/components/schemas/ExecOSProtocolLink'
        device_registry:
          type: array
          items:
            $ref: '#/components/schemas/ExecOSDeviceRegistryEntry'
        trust_controls:
          type: array
          items:
            type: string
        rate_limits:
          type: object
          additionalProperties:
            type: string
        billing:
          type: object
          additionalProperties:
            type: string
        links:
          type: object
          additionalProperties:
            type: string
    ExecOSBootstrap:
      type: object
      required:
      - format
      - prompt
      - context_url
      - discovery_url
      - openapi_url
      - recommended_first_action
      - progressive_disclosure_layers
      - capabilities
      properties:
        format:
          type: string
          enum:
          - json
          - markdown
        prompt:
          type: string
        context_url:
          type: string
        discovery_url:
          type: string
        openapi_url:
          type: string
        recommended_first_action:
          type: string
        progressive_disclosure_layers:
          type: array
          items:
            type: string
        capabilities:
          type: array
          items:
            type: string
    ExecOSAgentDiscovery:
      type: object
      required:
      - context
      - bootstrap_url
      - openapi_url
      - openapi_compat_url
      - docs_url
      - swagger_url
      - redoc_url
      - postman_collection_url
      properties:
        context:
          $ref: '#/components/schemas/ExecOSAgentContext'
        bootstrap_url:
          type: string
        openapi_url:
          type: string
        openapi_compat_url:
          type: string
        docs_url:
          type: string
        swagger_url:
          type: string
        redoc_url:
          type: string
        postman_collection_url:
          type: string
    ExecOSOutcomeEstimateRequest:
      type: object
      required:
      - title
      properties:
        outcome_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 1
        summary:
          type: string
        declared_outcome:
          type: object
          additionalProperties: true
        buyer_id:
          type: string
          format: uuid
        tenant_id:
          type: string
        route_hint:
          type: string
          enum:
          - externa
          - cpo
          - api
          - mcp
          - perse
          - ucp
          - a2a
          - ap2
          - human
          default: externa
        expected_input_tokens:
          type: integer
          minimum: 0
          default: 2000
        expected_output_tokens:
          type: integer
          minimum: 0
          default: 2000
        unit_count:
          type: integer
          minimum: 0
          default: 1
        max_spend_usd:
          type: number
          minimum: 0
    UsageEstimate:
      type: object
      additionalProperties: true
      description: Bad Labels billing estimate. See badlabels_contracts.billing.UsageEstimateV1.
    ExecOSBudgetReservation:
      type: object
      required:
      - reservation_id
      - estimated_total_usd
      - estimated_credits
      - status
      properties:
        reservation_id:
          type: string
          format: uuid
        outcome_id:
          type: string
          format: uuid
        buyer_id:
          type: string
          format: uuid
        estimated_total_usd:
          type: number
          minimum: 0
        estimated_credits:
          type: integer
          minimum: 0
        status:
          type: string
        expires_at:
          type: string
          format: date-time
        notes:
          type: string
    ExecOSOutcomeEstimateResponse:
      type: object
      required:
      - allowed
      - approval_required
      - reason
      - recommended_route
      - deterministic_fallback
      - trust_controls
      properties:
        allowed:
          type: boolean
        approval_required:
          type: boolean
        reason:
          type: string
        recommended_route:
          type: string
          enum:
          - externa
          - cpo
          - api
          - mcp
          - perse
          - ucp
          - a2a
          - ap2
          - human
        deterministic_fallback:
          type: string
        estimate:
          $ref: '#/components/schemas/UsageEstimate'
        reservation:
          $ref: '#/components/schemas/ExecOSBudgetReservation'
        trust_controls:
          type: array
          items:
            type: string
    ExecOSOutcomeAdmitRequest:
      allOf:
      - $ref: '#/components/schemas/ExecOSOutcomeEstimateRequest'
      - type: object
        properties:
          operator_approved:
            type: boolean
            default: false
    ExecOSOutcomeAdmitResponse:
      allOf:
      - $ref: '#/components/schemas/ExecOSOutcomeEstimateResponse'
      - type: object
        required:
        - admitted
        - approval_state
        properties:
          admitted:
            type: boolean
          admission_id:
            type: string
            format: uuid
          approval_state:
            type: string
            enum:
            - not_required
            - required
            - approved
            - denied
    ExecOSCpoRunRequest:
      type: object
      required:
      - outcome
      properties:
        outcome:
          $ref: '#/components/schemas/ExecOSOutcomeEstimateRequest'
        operator_approved:
          type: boolean
          default: false
        requested_persona:
          type: string
          default: cpo
    ExecOSCpoRun:
      type: object
      required:
      - run_id
      - status
      - persona_id
      - approval_state
      - outcome_title
      - recommended_route
      - estimate
      - next_actions
      - trace
      - created_at
      properties:
        run_id:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - dry_run
          - approval_required
          - ready
          - running
          - blocked
          - complete
        persona_id:
          type: string
        approval_state:
          type: string
          enum:
          - not_required
          - required
          - approved
          - denied
        outcome_title:
          type: string
        recommended_route:
          type: string
          enum:
          - externa
          - cpo
          - api
          - mcp
          - perse
          - ucp
          - a2a
          - ap2
          - human
        estimate:
          $ref: '#/components/schemas/ExecOSOutcomeEstimateResponse'
        next_actions:
          type: array
          items:
            type: string
        trace:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time
