openapi: 3.0.3
info:
  title: AWOS Shared System External API
  version: 0.2-draft
  summary: Shared Service facade API for identity, memory, capabilities, promotion,
    and system endpoints.
  description: 'This OpenAPI draft describes the external API contract exposed by
    AWOS Shared Service.


    Design constraints:

    - Node local callers only talk to Shared Service.

    - Shared Memory is backed by mem9 hosted API internally, but mem9 raw routes are
    not exposed here.

    - db9 stores AWOS-owned shared truth such as identity, capability registry, audit,
    idempotency, and memory-space config.

    '
servers:
- url: https://shared.example.com
  description: Production example
- url: https://shared-staging.example.com
  description: Staging example
security:
- bearerAuth: []
tags:
- name: System
- name: Identity
- name: Memory
- name: Capabilities
- name: Promotion
paths:
  /api/v1/system/health:
    get:
      tags:
      - System
      summary: Health check
      operationId: getSystemHealth
      security: []
      responses:
        '200':
          description: Health status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthEnvelope'
              examples:
                default:
                  $ref: '#/components/examples/HealthResponseExample'
      description: Health check for load balancers, probes, and quick runtime verification.
  /api/v1/system/capabilities:
    get:
      tags:
      - System
      summary: Get enabled system capabilities
      operationId: getSystemCapabilities
      security: []
      parameters:
      - $ref: '#/components/parameters/RequestIdHeader'
      responses:
        '200':
          description: Enabled capabilities
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/SystemCapabilitiesResult'
              examples:
                default:
                  $ref: '#/components/examples/SystemCapabilitiesResponseExample'
      description: Admin/debug API for feature discovery. Useful for SDK initialization,
        environment compatibility checks, and debugging.
  /api/v1/identity/nodes:
    post:
      tags:
      - Identity
      summary: Register or idempotently update a node identity
      operationId: registerNode
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        $ref: '#/components/requestBodies/RegisterNodeRequestBody'
      responses:
        '200':
          description: Node registered or updated
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/RegisterNodeResult'
        '400':
          $ref: '#/components/responses/ValidationError'
        '409':
          $ref: '#/components/responses/ConflictError'
      description: Used when a node first joins Shared Service, or when a migrated/replaced
        node rebinds to the same person identity.
  /api/v1/identity/nodes/{node_id}:
    get:
      tags:
      - Identity
      summary: Get node identity detail
      operationId: getNode
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - name: node_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Node detail
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/GetNodeResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Used for node self-check, admin inspection, and identity troubleshooting.
  /api/v1/identity/nodes/{node_id}/status:
    patch:
      tags:
      - Identity
      summary: Update node status
      operationId: updateNodeStatus
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      - name: node_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        $ref: '#/components/requestBodies/UpdateNodeStatusRequestBody'
      responses:
        '200':
          description: Node status updated
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/UpdateNodeStatusResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Used when a node is disabled, retired, or replaced and its lifecycle
        state must be updated.
  /api/v1/identity/memory-space:
    get:
      tags:
      - Identity
      summary: Get current org memory-space configuration summary
      operationId: getSharedMemorySpace
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      responses:
        '200':
          description: Memory space summary
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/GetSharedMemorySpaceResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Admin/debug API. Returns the current org's memory backend routing
        summary. Callers do not need to invoke it during normal memory read/write
        flows.
  /api/v1/memory/write-context:
    post:
      tags:
      - Memory
      summary: Prepare write context for shared-memory creation/update decisions
      operationId: prepareSharedMemoryWriteContext
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      requestBody:
        $ref: '#/components/requestBodies/PrepareWriteContextRequestBody'
      responses:
        '200':
          description: Prepared write context
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/PrepareWriteContextResult'
      description: 'Advanced helper API for write-before-decide flows. Typical use:
        task_completed/session_end/reflection jobs check candidates before create/update/ignore.'
  /api/v1/memory/entries:
    post:
      tags:
      - Memory
      summary: Create shared memory entry
      operationId: createSharedMemory
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        $ref: '#/components/requestBodies/CreateSharedMemoryRequestBody'
      responses:
        '200':
          description: Memory created
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/CreateSharedMemoryResult'
              examples:
                default:
                  $ref: '#/components/examples/CreateSharedMemoryResponseExample'
        '400':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimitedError'
        '503':
          $ref: '#/components/responses/DownstreamUnavailableError'
      description: 'Main business API for writing shared memory. Typical use: persist
        stable conclusions after task completion or reflection. Memory ownership is
        person-based, while records are queryable within the org by default.'
  /api/v1/memory/entries/search:
    post:
      tags:
      - Memory
      summary: Recall shared memory entries
      operationId: recallSharedMemory
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      requestBody:
        $ref: '#/components/requestBodies/RecallSharedMemoryRequestBody'
      responses:
        '200':
          description: Recall result
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/RecallSharedMemoryResult'
              examples:
                default:
                  $ref: '#/components/examples/RecallSharedMemoryResponseExample'
        '429':
          $ref: '#/components/responses/RateLimitedError'
        '503':
          $ref: '#/components/responses/DownstreamUnavailableError'
      description: 'Main business API for recalling shared memory. Typical use: person-level
        cross-node continuity and team-level shared lookup inside the same org.'
  /api/v1/memory/entries/{entry_id}:
    get:
      tags:
      - Memory
      summary: Get shared memory entry detail
      operationId: getSharedMemory
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - name: entry_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Memory detail
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/GetSharedMemoryResult'
              examples:
                default:
                  $ref: '#/components/examples/GetSharedMemoryResponseExample'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Used after recall hits, or during audit/debug when a caller needs
        the full memory record.
  /api/v1/memory/entries/{entry_id}/update:
    post:
      tags:
      - Memory
      summary: Update shared memory entry
      operationId: updateSharedMemory
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      - name: entry_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        $ref: '#/components/requestBodies/UpdateSharedMemoryRequestBody'
      responses:
        '200':
          description: Memory updated
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/UpdateSharedMemoryResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/RateLimitedError'
        '503':
          $ref: '#/components/responses/DownstreamUnavailableError'
      description: Used when an existing shared memory needs refinement, supersession,
        or revision-based correction.
  /api/v1/memory/entries/{entry_id}/archive:
    post:
      tags:
      - Memory
      summary: Archive shared memory entry
      operationId: archiveSharedMemory
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      - name: entry_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        $ref: '#/components/requestBodies/ArchiveSharedMemoryRequestBody'
      responses:
        '200':
          description: Memory archived
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/ArchiveSharedMemoryResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Used when an older shared memory becomes obsolete, superseded,
        or should be removed from normal recall.
  /api/v1/memory/imports:
    post:
      tags:
      - Memory
      summary: Create memory import job
      operationId: createMemoryImport
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        $ref: '#/components/requestBodies/CreateMemoryImportRequestBody'
      responses:
        '200':
          description: Import job created
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/CreateMemoryImportResult'
        '501':
          $ref: '#/components/responses/NotSupportedError'
      description: Used for bulk knowledge ingestion such as playbooks, postmortems,
        or imported documents.
  /api/v1/memory/session-messages:
    get:
      tags:
      - Memory
      summary: List session messages if enabled
      operationId: listSessionMessages
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - name: session_id
        in: query
        required: true
        schema:
          type: string
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 20
      - name: cursor
        in: query
        required: false
        schema:
          type: string
          nullable: true
      responses:
        '200':
          description: Session messages
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/ListSessionMessagesResult'
        '501':
          $ref: '#/components/responses/NotSupportedError'
      description: Capability-gated debug API for retrieving raw session messages
        when supported by the hosted memory backend.
  /api/v1/capabilities:
    post:
      tags:
      - Capabilities
      summary: Create shared capability package
      operationId: createSharedCapability
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        $ref: '#/components/requestBodies/CreateSharedCapabilityRequestBody'
      responses:
        '200':
          description: Capability package created
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/CreateSharedCapabilityResult'
              examples:
                default:
                  $ref: '#/components/examples/CreateSharedCapabilityResponseExample'
      description: Admin/internal direct-create API. For most business flows, prefer
        promoteLocalPackage.
  /api/v1/capabilities/search:
    post:
      tags:
      - Capabilities
      summary: Discover shared capability packages
      operationId: discoverSharedCapability
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscoverSharedCapabilityRequest'
      responses:
        '200':
          description: Capability search results
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/DiscoverSharedCapabilityResult'
      description: Main business API for package discovery. Used by package matching,
        mount preparation, and admin search.
  /api/v1/capabilities/{package_id}:
    get:
      tags:
      - Capabilities
      summary: Get shared capability package detail
      operationId: getSharedCapability
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - name: package_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Capability detail
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/GetSharedCapabilityResult'
              examples:
                default:
                  $ref: '#/components/examples/GetSharedCapabilityResponseExample'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Used after discovery hits, or before mount, to fetch full package
        content, contracts, and skill references.
  /api/v1/capabilities/{package_id}/update:
    post:
      tags:
      - Capabilities
      summary: Update shared capability package
      operationId: updateSharedCapability
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      - name: package_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        $ref: '#/components/requestBodies/UpdateSharedCapabilityRequestBody'
      responses:
        '200':
          description: Capability updated
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/UpdateSharedCapabilityResult'
        '404':
          $ref: '#/components/responses/NotFoundError'
      description: Admin/internal API for revising a shared capability package outside
        the main promotion flow.
  /api/v1/capabilities/{package_id}/archive:
    post:
      tags:
      - Capabilities
      summary: Archive shared capability package
      operationId: archiveSharedCapability
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      - name: package_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        $ref: '#/components/requestBodies/ArchiveSharedCapabilityRequestBody'
      responses:
        '200':
          description: Capability archived
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/ArchiveSharedCapabilityResult'
      description: Admin/internal API for archiving a shared capability package that
        is obsolete or superseded.
  /api/v1/capabilities/skill-assets/{asset_id}:
    get:
      tags:
      - Capabilities
      summary: Get shared skill asset detail
      description: Admin/debug/supporting API. Used when a capability package references
        advanced shared skill assets, especially agent-generated skill content that
        must be fetched as a stable snapshot. Used when a package references advanced
        shared skill assets and the caller needs the snapshot content.
      operationId: getSharedSkillAsset
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - name: asset_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Shared skill asset detail
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/GetSharedSkillAssetResult'
              examples:
                default:
                  $ref: '#/components/examples/GetSharedSkillAssetResponseExample'
        '404':
          $ref: '#/components/responses/NotFoundError'
  /api/v1/promotion/local-packages:
    post:
      tags:
      - Promotion
      summary: Promote local capability package into shared capability package
      operationId: promoteLocalPackage
      parameters:
      - $ref: '#/components/parameters/OrgIdHeader'
      - $ref: '#/components/parameters/NodeIdHeader'
      - $ref: '#/components/parameters/PersonIdHeader'
      - $ref: '#/components/parameters/RequestIdHeader'
      - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        $ref: '#/components/requestBodies/PromoteLocalPackageRequestBody'
      responses:
        '200':
          description: Promotion result
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ServiceEnvelope'
                - type: object
                  properties:
                    result:
                      $ref: '#/components/schemas/PromoteLocalPackageResult'
              examples:
                default:
                  $ref: '#/components/examples/PromoteLocalPackageResponseExample'
      description: Main business API for turning a local package into a shared reusable
        capability. Promotion decides ignore/create_shared/update_shared and may call
        direct capability write APIs internally. Main business API for promoting a
        local capability package into a shared reusable capability after task completion
        or package refinement.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  parameters:
    OrgIdHeader:
      name: X-Shared-Org-Id
      in: header
      required: true
      schema:
        type: string
      example: org_mcn
    NodeIdHeader:
      name: X-Shared-Node-Id
      in: header
      required: true
      schema:
        type: string
      example: node_ops_01
    PersonIdHeader:
      name: X-Shared-Person-Id
      in: header
      required: true
      schema:
        type: string
      example: person_wyatt
    RequestIdHeader:
      name: X-Request-Id
      in: header
      required: true
      schema:
        type: string
      example: req_20260421_001
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
      example: idem_20260421_001
  requestBodies:
    RegisterNodeRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RegisterNodeRequest'
          examples:
            default:
              $ref: '#/components/examples/RegisterNodeRequestExample'
    UpdateNodeStatusRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UpdateNodeStatusRequest'
          examples:
            default:
              $ref: '#/components/examples/UpdateNodeStatusRequestExample'
    PrepareWriteContextRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PrepareWriteContextRequest'
          examples:
            default:
              $ref: '#/components/examples/PrepareWriteContextRequestExample'
    CreateSharedMemoryRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CreateSharedMemoryRequest'
          examples:
            default:
              $ref: '#/components/examples/CreateSharedMemoryRequestExample'
    RecallSharedMemoryRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RecallSharedMemoryRequest'
          examples:
            default:
              $ref: '#/components/examples/RecallSharedMemoryRequestExample'
    UpdateSharedMemoryRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UpdateSharedMemoryRequest'
          examples:
            default:
              $ref: '#/components/examples/UpdateSharedMemoryRequestExample'
    ArchiveSharedMemoryRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ArchiveSharedMemoryRequest'
          examples:
            default:
              $ref: '#/components/examples/ArchiveSharedMemoryRequestExample'
    CreateMemoryImportRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CreateMemoryImportRequest'
          examples:
            default:
              $ref: '#/components/examples/CreateMemoryImportRequestExample'
    CreateSharedCapabilityRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CreateSharedCapabilityRequest'
          examples:
            default:
              $ref: '#/components/examples/CreateSharedCapabilityRequestExample'
    UpdateSharedCapabilityRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UpdateSharedCapabilityRequest'
          examples:
            default:
              $ref: '#/components/examples/UpdateSharedCapabilityRequestExample'
    ArchiveSharedCapabilityRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ArchiveSharedCapabilityRequest'
          examples:
            default:
              $ref: '#/components/examples/ArchiveSharedCapabilityRequestExample'
    PromoteLocalPackageRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PromoteLocalPackageRequest'
          examples:
            default:
              $ref: '#/components/examples/PromoteLocalPackageRequestExample'
  responses:
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            default:
              $ref: '#/components/examples/ValidationErrorExample'
    ConflictError:
      description: Conflict error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    NotFoundError:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RateLimitedError:
      description: Rate limited
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            default:
              $ref: '#/components/examples/RateLimitedErrorExample'
    DownstreamUnavailableError:
      description: Downstream unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            default:
              $ref: '#/components/examples/DownstreamUnavailableErrorExample'
    NotSupportedError:
      description: Not supported
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  examples:
    HealthResponseExample:
      value:
        ok: true
        operation: health_check
        changed: false
        result:
          status: ok
          service: shared_service
          version: v0.2
          time: '2026-04-21T09:30:45Z'
        error: null
        meta:
          request_id: req_health_001
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    SystemCapabilitiesResponseExample:
      value:
        ok: true
        operation: get_system_capabilities
        changed: false
        result:
          memory_backend: mem9_hosted
          memory_modes:
          - managed
          apis:
          - identity
          - memory
          - capabilities
          - promotion
          features:
            memory_write: true
            memory_recall: true
            memory_imports: true
            memory_sessions: false
            capability_discover: true
            promotion: true
        error: null
        meta:
          request_id: req_20260421_001
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    RegisterNodeRequestExample:
      value:
        node_id: node_ops_01
        person_id: person_wyatt
        display_name: Wyatt Fang
        role_label: ops
        team_label: mcn
        metadata:
          runtime: hermes
          region: cn-shanghai
    UpdateNodeStatusRequestExample:
      value:
        status: disabled
    PrepareWriteContextRequestExample:
      value:
        trigger: task_completed
        node_identity:
          node_id: node_ops_01
          person_id: person_wyatt
          role_label: ops
          team_label: mcn
        runtime_context:
          task_id: task_live_932
          container_id: container_live_campaign
          current_summary: 直播项目复盘归档
          source_messages:
          - role: system
            content: 这是一次任务完成后的归档写入
          - role: assistant
            content: 建议把脚本切换提前到 T-30 分钟
        policy:
          allow_content_types:
          - decision
          - summary
          deny_content_types:
          - scratchpad
          visibility_default: org_internal
    CreateSharedMemoryRequestExample:
      value:
        content: 直播项目复盘：高峰时段脚本切换要前置到 T-30 分钟，不要在开播后再调。
        content_type: decision
        summary: 直播脚本切换需前置到 T-30 分钟
        tags:
        - live
        - ops
        - playbook
        source_node_id: node_ops_01
        source_role_label: ops
        source_team_label: mcn
        source_task_id: task_live_932
        source_container_id: container_live_campaign
        write_reason: task_completed
        source_kind: task_capability_summary
        owner_person_id: person_wyatt
        owner_team_label: mcn
    UpdateSharedMemoryRequestExample:
      value:
        new_content: 复盘更新：脚本切换前置到 T-30 分钟，并在 T-10 分钟完成二次确认。
        new_summary: 直播脚本切换需前置到 T-30 分钟并做二次确认
        new_tags:
        - live
        - ops
        - playbook
        - v2
        supersede_previous: true
        update_reason: postmortem_refinement
    ArchiveSharedMemoryRequestExample:
      value:
        reason: superseded_by_new_revision
    RecallSharedMemoryRequestExample:
      value:
        query: 直播前脚本切换的最佳时间是什么
        limit: 5
        cursor: null
        recall_mode: hybrid
        content_types:
        - decision
        - summary
        source_node_ids: []
        include_archived: false
        owner_person_ids:
        - person_wyatt
        team_labels:
        - mcn
    CreateMemoryImportRequestExample:
      value:
        source_type: url
        source_ref: https://example.com/postmortem/live-campaign-932
        tags:
        - import
        - live
        metadata:
          initiated_by: node_ops_01
    CreateSharedCapabilityRequestExample:
      value:
        title: 直播大场控场 SOP
        slug: live-event-ops-sop
        summary: 用于大型直播场次的节奏控制和脚本切换 SOP
        frontmatter:
          domain: live_ops
          audience: operators
        body_markdown: '# 直播大场控场 SOP

          1. 开播前 T-30 分钟完成脚本切换

          2. 开播前 T-10 分钟进行二次确认

          '
        skill_refs: &id001
        - &id002
          ref_id: skill_asset_001
          skill_id: live-ops-checklist
          source_type: shared_asset
          version: '1'
          required: true
          mount_mode: snapshot
        - ref_id: builtin_lark_im
          skill_id: lark-im
          source_type: builtin
          version: builtin
          required: true
          mount_mode: reference
        input_contract:
          required_inputs:
          - campaign_goal
          - host_script
        output_contract:
          outputs:
          - ops_checklist
          - risk_flags
        onboarding_template: 你现在作为大场直播运营，请先确认脚本、节奏和风险项。
        creator_person_id: person_wyatt
        source_node_id: node_ops_01
        source_local_package_id: local_pkg_live_ops_01
        visibility: org_internal
    UpdateSharedCapabilityRequestExample:
      value:
        summary: 更新后的大型直播场次控场和脚本切换 SOP
        body_markdown: '# 直播大场控场 SOP v2

          1. 开播前 T-30 分钟完成脚本切换

          2. 开播前 T-10 分钟进行二次确认

          3. 高峰时段前完成异常预案广播

          '
        update_reason: refine_postmortem_rules
    ArchiveSharedCapabilityRequestExample:
      value:
        reason: superseded_by_revision_2
    PromoteLocalPackageRequestExample:
      value:
        local_package:
          package_id: local_pkg_live_ops_01
          title: 直播大场控场 SOP
          summary: 用于大型直播场次的节奏控制和脚本切换 SOP
          frontmatter:
            domain: live_ops
          body_markdown: '# 直播大场控场 SOP

            1. 开播前 T-30 分钟完成脚本切换

            '
          source_node_id: node_ops_01
          creator_person_id: person_wyatt
          package_hash: sha256:abc123
        task_capability_summary:
          title: 直播项目复盘
          highlights:
          - 脚本切换需前置到 T-30 分钟
        strategy:
          allow_create: true
          allow_update: true
    CreateSharedMemoryResponseExample:
      value:
        ok: true
        operation: create_shared_memory
        changed: true
        result:
          entry:
            entry_id: mem_7x2ab
            content: 直播项目复盘：高峰时段脚本切换要前置到 T-30 分钟，不要在开播后再调。
            summary: 直播脚本切换需前置到 T-30 分钟
            content_type: decision
            tags:
            - live
            - ops
            - playbook
            source_node_id: node_ops_01
            source_role_label: ops
            source_team_label: mcn
            source_task_id: task_live_932
            source_container_id: container_live_campaign
            write_reason: task_completed
            revision: 1
            state: active
            score: null
            confidence: null
            relative_age: null
            created_at: '2026-04-21T09:30:45Z'
            updated_at: '2026-04-21T09:30:45Z'
            owner_person_id: person_wyatt
            owner_team_label: mcn
          stored_in: mem9_hosted
        error: null
        meta:
          request_id: req_20260421_002
          downstream: mem9_hosted
          cursor: null
          next_cursor: null
          has_more: null
    RecallSharedMemoryResponseExample:
      value:
        ok: true
        operation: recall_shared_memory
        changed: false
        result:
          entries:
          - entry_id: mem_7x2ab
            content: 直播项目复盘：高峰时段脚本切换要前置到 T-30 分钟，不要在开播后再调。
            summary: 直播脚本切换需前置到 T-30 分钟
            content_type: decision
            tags:
            - live
            - ops
            - playbook
            source_node_id: node_ops_01
            source_role_label: ops
            source_team_label: mcn
            source_task_id: task_live_932
            source_container_id: container_live_campaign
            write_reason: task_completed
            revision: 1
            state: active
            score: 0.88
            confidence: 91
            relative_age: 2 days ago
            created_at: '2026-04-19T09:30:45Z'
            updated_at: '2026-04-19T09:30:45Z'
            owner_person_id: person_wyatt
            owner_team_label: mcn
          recall_meta:
            downstream: mem9_hosted
            mode_used: hybrid
            degraded: false
        error: null
        meta:
          request_id: req_20260421_003
          downstream: mem9_hosted
          cursor: null
          next_cursor: null
          has_more: false
    GetSharedMemoryResponseExample:
      value:
        ok: true
        operation: get_shared_memory
        changed: false
        result:
          entry:
            entry_id: mem_7x2ab
            content: 直播项目复盘：高峰时段脚本切换要前置到 T-30 分钟，不要在开播后再调。
            summary: 直播脚本切换需前置到 T-30 分钟
            content_type: decision
            tags:
            - live
            - ops
            - playbook
            source_node_id: node_ops_01
            source_role_label: ops
            source_team_label: mcn
            source_task_id: task_live_932
            source_container_id: container_live_campaign
            write_reason: task_completed
            revision: 1
            state: active
            score: null
            confidence: null
            relative_age: null
            created_at: '2026-04-19T09:30:45Z'
            updated_at: '2026-04-19T09:30:45Z'
            owner_person_id: person_wyatt
            owner_team_label: mcn
        error: null
        meta:
          request_id: req_20260421_004
          downstream: mem9_hosted
          cursor: null
          next_cursor: null
          has_more: null
    CreateSharedCapabilityResponseExample:
      value:
        ok: true
        operation: create_shared_capability
        changed: true
        result:
          package:
            package_id: cap_live_ops_01
            title: 直播大场控场 SOP
            slug: live-event-ops-sop
            summary: 用于大型直播场次的节奏控制和脚本切换 SOP
            revision: 1
            visibility: org_internal
            status: active
            source_node_id: node_ops_01
            creator_person_id: person_wyatt
            score: null
            updated_at: '2026-04-21T09:30:45Z'
            source_local_package_id: local_pkg_live_ops_01
            package_hash: sha256:abc123
            frontmatter:
              domain: live_ops
              audience: operators
            body_markdown: '# 直播大场控场 SOP 1. 开播前 T-30 分钟完成脚本切换 2. 开播前 T-10 分钟进行二次确认 '
            skill_refs: *id001
            input_contract:
              required_inputs:
              - campaign_goal
              - host_script
            output_contract:
              outputs:
              - ops_checklist
              - risk_flags
            onboarding_template: 你现在作为大场直播运营，请先确认脚本、节奏和风险项。
            created_at: '2026-04-21T09:30:45Z'
            archived_at: null
        error: null
        meta:
          request_id: req_20260421_005
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    GetSharedCapabilityResponseExample:
      value:
        ok: true
        operation: get_shared_capability
        changed: false
        result:
          package:
            package_id: cap_live_ops_01
            title: 直播大场控场 SOP
            slug: live-event-ops-sop
            summary: 用于大型直播场次的节奏控制和脚本切换 SOP
            revision: 1
            visibility: org_internal
            status: active
            source_node_id: node_ops_01
            creator_person_id: person_wyatt
            score: null
            updated_at: '2026-04-21T09:30:45Z'
            source_local_package_id: local_pkg_live_ops_01
            package_hash: sha256:abc123
            frontmatter:
              domain: live_ops
              audience: operators
            body_markdown: '# 直播大场控场 SOP 1. 开播前 T-30 分钟完成脚本切换 2. 开播前 T-10 分钟进行二次确认 '
            skill_refs: *id001
            input_contract:
              required_inputs:
              - campaign_goal
              - host_script
            output_contract:
              outputs:
              - ops_checklist
              - risk_flags
            onboarding_template: 你现在作为大场直播运营，请先确认脚本、节奏和风险项。
            created_at: '2026-04-21T09:30:45Z'
            archived_at: null
        error: null
        meta:
          request_id: req_20260421_006
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    PromoteLocalPackageResponseExample:
      value:
        ok: true
        operation: promote_local_package
        changed: true
        result:
          promotion:
            promotion_id: promo_001
            action: create_shared
            reason: stable cross-task reusable procedure
            shared_package_id: cap_live_ops_01
            revision: 1
            created_at: '2026-04-21T09:30:45Z'
        error: null
        meta:
          request_id: req_20260421_007
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    ValidationErrorExample:
      value:
        ok: false
        operation: create_shared_memory
        changed: false
        result: null
        error:
          code: validation_error
          message: content_type is required
          retryable: false
          details:
            field: content_type
        meta:
          request_id: req_20260421_008
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
    RateLimitedErrorExample:
      value:
        ok: false
        operation: recall_shared_memory
        changed: false
        result: null
        error:
          code: rate_limited
          message: mem9 hosted API rate limit exceeded
          retryable: true
          details:
            retry_after_ms: 3000
        meta:
          request_id: req_20260421_009
          downstream: mem9_hosted
          cursor: null
          next_cursor: null
          has_more: null
    DownstreamUnavailableErrorExample:
      value:
        ok: false
        operation: create_shared_memory
        changed: false
        result: null
        error:
          code: downstream_unavailable
          message: mem9 hosted API timed out
          retryable: true
          details:
            timeout_ms: 8000
        meta:
          request_id: req_20260421_010
          downstream: mem9_hosted
          cursor: null
          next_cursor: null
          has_more: null
    GetSharedSkillAssetResponseExample:
      value:
        ok: true
        operation: get_shared_skill_asset
        changed: false
        result:
          asset: &id003
            asset_id: skill_asset_001
            org_id: org_mcn
            title: Live Ops Checklist
            slug: live-ops-checklist
            source_type: agent_generated
            format: hermes_skill_md
            content_text: '# Live Ops Checklist

              1. 开播前 T-30 分钟完成脚本切换'
            content_json: null
            content_hash: sha256:skill123
            version: 1
            author_node_id: node_ops_01
            author_person_id: person_wyatt
            status: active
            created_at: '2026-04-21T09:30:45Z'
            updated_at: '2026-04-21T09:30:45Z'
        error: null
        meta:
          request_id: req_20260421_011
          downstream: null
          cursor: null
          next_cursor: null
          has_more: null
  schemas:
    ServiceEnvelope:
      type: object
      required:
      - ok
      - operation
      - changed
      - result
      - error
      - meta
      properties:
        ok:
          type: boolean
        operation:
          type: string
        changed:
          type: boolean
        result:
          type: object
          additionalProperties: true
          nullable: true
          description: Operation-specific payload. Concrete responses override this
            shape.
        error:
          allOf:
          - $ref: '#/components/schemas/ErrorObject'
          nullable: true
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    ErrorEnvelope:
      type: object
      required:
      - ok
      - operation
      - changed
      - result
      - error
      - meta
      properties:
        ok:
          type: boolean
          example: false
        operation:
          type: string
        changed:
          type: boolean
          example: false
        result:
          type: object
          additionalProperties: true
          nullable: true
        error:
          $ref: '#/components/schemas/ErrorObject'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    HealthEnvelope:
      allOf:
      - $ref: '#/components/schemas/ServiceEnvelope'
      - type: object
        properties:
          result:
            $ref: '#/components/schemas/HealthResult'
    ResponseMeta:
      type: object
      required:
      - request_id
      properties:
        request_id:
          type: string
        downstream:
          type: string
          nullable: true
        cursor:
          type: string
          nullable: true
        next_cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
          nullable: true
    ErrorObject:
      type: object
      required:
      - code
      - message
      - retryable
      properties:
        code:
          type: string
          enum:
          - validation_error
          - not_found
          - conflict
          - permission_error
          - idempotency_conflict
          - storage_error
          - embedding_error
          - downstream_unavailable
          - rate_limited
          - not_supported
        message:
          type: string
        retryable:
          type: boolean
        details:
          type: object
          additionalProperties: true
          nullable: true
    HealthResult:
      type: object
      properties:
        status:
          type: string
          enum:
          - ok
          example: ok
        service:
          type: string
        version:
          type: string
        time:
          type: string
          format: date-time
    SystemCapabilitiesResult:
      type: object
      properties:
        memory_backend:
          type: string
          enum:
          - mem9_hosted
        memory_modes:
          type: array
          items:
            type: string
            enum:
            - managed
            - self_hosted
        apis:
          type: array
          items:
            type: string
        features:
          type: object
          additionalProperties:
            type: boolean
    NodeIdentity:
      type: object
      example:
        node_id: node_ops_01
        person_id: person_wyatt
        display_name: Wyatt Fang
        role_label: ops
        team_label: mcn
        status: active
        metadata:
          runtime: hermes
        created_at: '2026-04-21T09:30:45Z'
        updated_at: '2026-04-21T09:30:45Z'
      required:
      - node_id
      - person_id
      - display_name
      - role_label
      - team_label
      - status
      - created_at
      - updated_at
      properties:
        node_id:
          type: string
        person_id:
          type: string
        display_name:
          type: string
        role_label:
          type: string
        team_label:
          type: string
        status:
          type: string
          enum:
          - active
          - disabled
          - archived
        metadata:
          type: object
          additionalProperties: true
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SharedMemorySpaceSummary:
      type: object
      required:
      - space_id
      - org_id
      - provider
      - api_base_url
      - mode
      - status
      - created_at
      - updated_at
      properties:
        space_id:
          type: string
        org_id:
          type: string
        provider:
          type: string
          enum:
          - mem9_hosted
        api_base_url:
          type: string
        mode:
          type: string
          enum:
          - managed
          - self_hosted
        status:
          type: string
          enum:
          - active
          - disabled
          - archived
        default_agent_id:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SharedMemoryEntry:
      type: object
      example:
        entry_id: mem_7x2ab
        content: 直播项目复盘：高峰时段脚本切换要前置到 T-30 分钟，不要在开播后再调。
        summary: 直播脚本切换需前置到 T-30 分钟
        content_type: decision
        tags:
        - live
        - ops
        - playbook
        source_node_id: node_ops_01
        source_role_label: ops
        source_team_label: mcn
        source_task_id: task_live_932
        source_container_id: container_live_campaign
        write_reason: task_completed
        revision: 1
        state: active
        score: 0.88
        confidence: 91
        relative_age: 2 days ago
        created_at: '2026-04-19T09:30:45Z'
        updated_at: '2026-04-19T09:30:45Z'
        owner_person_id: person_wyatt
        owner_team_label: mcn
      required:
      - entry_id
      - content
      - owner_person_id
      - source_node_id
      - revision
      - state
      - created_at
      - updated_at
      properties:
        entry_id:
          type: string
        owner_person_id:
          type: string
        owner_team_label:
          type: string
          nullable: true
        content:
          type: string
        summary:
          type: string
          nullable: true
        content_type:
          type: string
          enum:
          - summary
          - decision
          - risk
          - question
          - handoff_note
          - status_snapshot
          - insight
          nullable: true
        tags:
          type: array
          items:
            type: string
        source_node_id:
          type: string
        source_role_label:
          type: string
          nullable: true
        source_team_label:
          type: string
          nullable: true
        source_task_id:
          type: string
          nullable: true
        source_container_id:
          type: string
          nullable: true
        write_reason:
          type: string
          nullable: true
        revision:
          type: integer
        state:
          type: string
          enum:
          - active
          - archived
          - deleted
          - superseded
        score:
          type: number
          nullable: true
        confidence:
          type: integer
          nullable: true
        relative_age:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SharedMemoryEntrySummary:
      type: object
      required:
      - entry_id
      - owner_person_id
      - source_node_id
      - revision
      - state
      - updated_at
      properties:
        entry_id:
          type: string
        owner_person_id:
          type: string
        owner_team_label:
          type: string
          nullable: true
        summary:
          type: string
          nullable: true
        content_type:
          type: string
          nullable: true
        source_node_id:
          type: string
        source_task_id:
          type: string
          nullable: true
        revision:
          type: integer
        state:
          type: string
        score:
          type: number
          nullable: true
        updated_at:
          type: string
          format: date-time
    SharedCapabilityPackageSummary:
      type: object
      required:
      - package_id
      - title
      - slug
      - summary
      - revision
      - visibility
      - status
      - source_node_id
      - creator_person_id
      - updated_at
      properties:
        package_id:
          type: string
        title:
          type: string
        slug:
          type: string
        summary:
          type: string
        revision:
          type: integer
        visibility:
          type: string
          enum:
          - org_internal
        status:
          type: string
          enum:
          - active
          - superseded
          - archived
        source_node_id:
          type: string
        creator_person_id:
          type: string
        score:
          type: number
          nullable: true
        updated_at:
          type: string
          format: date-time
    SharedCapabilityPackageDetail:
      example:
        package_id: cap_live_ops_01
        title: 直播大场控场 SOP
        slug: live-event-ops-sop
        summary: 用于大型直播场次的节奏控制和脚本切换 SOP
        revision: 1
        visibility: org_internal
        status: active
        source_node_id: node_ops_01
        creator_person_id: person_wyatt
        score: null
        updated_at: '2026-04-21T09:30:45Z'
        source_local_package_id: local_pkg_live_ops_01
        package_hash: sha256:abc123
        frontmatter:
          domain: live_ops
        body_markdown: '# 直播大场控场 SOP'
        skill_refs: *id001
        input_contract:
          required_inputs:
          - campaign_goal
          - host_script
        output_contract:
          outputs:
          - ops_checklist
          - risk_flags
        onboarding_template: 你现在作为大场直播运营，请先确认脚本、节奏和风险项。
        created_at: '2026-04-21T09:30:45Z'
        archived_at: null
      allOf:
      - $ref: '#/components/schemas/SharedCapabilityPackageSummary'
      - type: object
        required:
        - source_local_package_id
        - package_hash
        - frontmatter
        - body_markdown
        - skill_refs
        - created_at
        properties:
          source_local_package_id:
            type: string
          package_hash:
            type: string
          frontmatter:
            type: object
            additionalProperties: true
          body_markdown:
            type: string
          skill_refs:
            type: array
            items:
              $ref: '#/components/schemas/SharedSkillRef'
          input_contract:
            type: object
            additionalProperties: true
            nullable: true
          output_contract:
            type: object
            additionalProperties: true
            nullable: true
          onboarding_template:
            type: string
            nullable: true
          created_at:
            type: string
            format: date-time
          archived_at:
            type: string
            format: date-time
            nullable: true
    PromotionResult:
      type: object
      required:
      - promotion_id
      - action
      - reason
      - created_at
      properties:
        promotion_id:
          type: string
        action:
          type: string
          enum:
          - ignore
          - create_shared
          - update_shared
        reason:
          type: string
        shared_package_id:
          type: string
          nullable: true
        revision:
          type: integer
          nullable: true
        created_at:
          type: string
          format: date-time
    SourceMessage:
      type: object
      required:
      - role
      - content
      properties:
        role:
          type: string
        content:
          type: string
    RegisterNodeRequest:
      type: object
      required:
      - node_id
      - person_id
      - display_name
      - role_label
      - team_label
      properties:
        node_id:
          type: string
        person_id:
          type: string
        display_name:
          type: string
        role_label:
          type: string
        team_label:
          type: string
        metadata:
          type: object
          additionalProperties: true
          nullable: true
    RegisterNodeResult:
      type: object
      required:
      - node
      - created
      properties:
        node:
          $ref: '#/components/schemas/NodeIdentity'
        created:
          type: boolean
    GetNodeResult:
      type: object
      required:
      - node
      properties:
        node:
          $ref: '#/components/schemas/NodeIdentity'
    UpdateNodeStatusRequest:
      type: object
      required:
      - status
      properties:
        status:
          type: string
          enum:
          - active
          - disabled
          - archived
    UpdateNodeStatusResult:
      type: object
      required:
      - node_id
      - status
      - updated_at
      properties:
        node_id:
          type: string
        status:
          type: string
        updated_at:
          type: string
          format: date-time
    GetSharedMemorySpaceResult:
      type: object
      required:
      - space
      properties:
        space:
          $ref: '#/components/schemas/SharedMemorySpaceSummary'
    PrepareWriteContextRequest:
      type: object
      required:
      - trigger
      - node_identity
      - runtime_context
      - policy
      properties:
        trigger:
          type: string
        node_identity:
          type: object
          required:
          - node_id
          - person_id
          - role_label
          - team_label
          properties:
            node_id:
              type: string
            person_id:
              type: string
            role_label:
              type: string
            team_label:
              type: string
        runtime_context:
          type: object
          properties:
            task_id:
              type: string
              nullable: true
            container_id:
              type: string
              nullable: true
            current_summary:
              type: string
              nullable: true
            source_messages:
              type: array
              items:
                $ref: '#/components/schemas/SourceMessage'
        policy:
          type: object
          required:
          - visibility_default
          properties:
            allow_content_types:
              type: array
              items:
                type: string
            deny_content_types:
              type: array
              items:
                type: string
            visibility_default:
              type: string
              enum:
              - org_internal
    PrepareWriteContextResult:
      type: object
      required:
      - normalized_context
      - existing_candidates
      - recommended_action
      properties:
        normalized_context:
          type: object
          additionalProperties: true
        existing_candidates:
          type: array
          items:
            $ref: '#/components/schemas/SharedMemoryEntrySummary'
        recommended_action:
          type: string
          enum:
          - create
          - update
          - ignore
    CreateSharedMemoryRequest:
      type: object
      required:
      - content
      - content_type
      - source_node_id
      - owner_person_id
      properties:
        content:
          type: string
        content_type:
          type: string
          enum:
          - summary
          - decision
          - risk
          - question
          - handoff_note
          - status_snapshot
          - insight
        summary:
          type: string
          nullable: true
        tags:
          type: array
          items:
            type: string
        source_node_id:
          type: string
        owner_person_id:
          type: string
        source_role_label:
          type: string
          nullable: true
        source_team_label:
          type: string
          nullable: true
        owner_team_label:
          type: string
          nullable: true
        source_task_id:
          type: string
          nullable: true
        source_container_id:
          type: string
          nullable: true
        write_reason:
          type: string
          nullable: true
        source_kind:
          type: string
          nullable: true
    CreateSharedMemoryResult:
      type: object
      required:
      - entry
      - stored_in
      properties:
        entry:
          $ref: '#/components/schemas/SharedMemoryEntry'
        stored_in:
          type: string
          enum:
          - mem9_hosted
    GetSharedMemoryResult:
      type: object
      required:
      - entry
      properties:
        entry:
          $ref: '#/components/schemas/SharedMemoryEntry'
    RecallSharedMemoryRequest:
      type: object
      required:
      - query
      - limit
      - recall_mode
      - include_archived
      properties:
        query:
          type: string
        limit:
          type: integer
          minimum: 1
          maximum: 200
        cursor:
          type: string
          nullable: true
        recall_mode:
          type: string
          enum:
          - hybrid
          - text_only
          - vector_only
        content_types:
          type: array
          items:
            type: string
        source_node_ids:
          type: array
          items:
            type: string
        include_archived:
          type: boolean
        owner_person_ids:
          type: array
          items:
            type: string
        team_labels:
          type: array
          items:
            type: string
    RecallSharedMemoryResult:
      type: object
      required:
      - entries
      - recall_meta
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/SharedMemoryEntry'
        recall_meta:
          type: object
          required:
          - downstream
          - mode_used
          - degraded
          properties:
            downstream:
              type: string
              enum:
              - mem9_hosted
            mode_used:
              type: string
              enum:
              - hybrid
              - text_only
              - vector_only
            degraded:
              type: boolean
    UpdateSharedMemoryRequest:
      type: object
      required:
      - new_content
      - supersede_previous
      properties:
        new_content:
          type: string
        new_summary:
          type: string
          nullable: true
        new_tags:
          type: array
          items:
            type: string
        supersede_previous:
          type: boolean
        update_reason:
          type: string
          nullable: true
    UpdateSharedMemoryResult:
      type: object
      required:
      - entry
      - archived_previous
      properties:
        entry:
          $ref: '#/components/schemas/SharedMemoryEntry'
        previous_entry_id:
          type: string
          nullable: true
        archived_previous:
          type: boolean
    ArchiveSharedMemoryRequest:
      type: object
      required:
      - reason
      properties:
        reason:
          type: string
    ArchiveSharedMemoryResult:
      type: object
      required:
      - entry_id
      - state
      - archived_at
      properties:
        entry_id:
          type: string
        state:
          type: string
          const: archived
        archived_at:
          type: string
          format: date-time
    CreateMemoryImportRequest:
      type: object
      required:
      - source_type
      - source_ref
      properties:
        source_type:
          type: string
          enum:
          - file
          - url
          - text_bundle
        source_ref:
          type: string
        tags:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties: true
          nullable: true
    CreateMemoryImportResult:
      type: object
      required:
      - import_id
      - status
      - downstream
      properties:
        import_id:
          type: string
        status:
          type: string
          enum:
          - pending
          - running
          - completed
          - failed
        downstream:
          type: string
          enum:
          - mem9_hosted
    SessionMessage:
      type: object
      required:
      - id
      - session_id
      - role
      - content
      - content_type
      - tags
      - created_at
      properties:
        id:
          type: string
        session_id:
          type: string
        role:
          type: string
        content:
          type: string
        content_type:
          type: string
        tags:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time
    ListSessionMessagesResult:
      type: object
      required:
      - messages
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/SessionMessage'
    CreateSharedCapabilityRequest:
      type: object
      required:
      - title
      - slug
      - summary
      - frontmatter
      - body_markdown
      - creator_person_id
      - source_node_id
      - source_local_package_id
      - visibility
      properties:
        title:
          type: string
        slug:
          type: string
        summary:
          type: string
        frontmatter:
          type: object
          additionalProperties: true
        body_markdown:
          type: string
        skill_refs:
          type: array
          items:
            $ref: '#/components/schemas/SharedSkillRef'
        input_contract:
          type: object
          additionalProperties: true
          nullable: true
        output_contract:
          type: object
          additionalProperties: true
          nullable: true
        onboarding_template:
          type: string
          nullable: true
        creator_person_id:
          type: string
        source_node_id:
          type: string
        source_local_package_id:
          type: string
        visibility:
          type: string
          enum:
          - org_internal
    CreateSharedCapabilityResult:
      type: object
      required:
      - package
      properties:
        package:
          $ref: '#/components/schemas/SharedCapabilityPackageDetail'
    GetSharedCapabilityResult:
      type: object
      required:
      - package
      properties:
        package:
          $ref: '#/components/schemas/SharedCapabilityPackageDetail'
    UpdateSharedCapabilityRequest:
      type: object
      properties:
        title:
          type: string
          nullable: true
        summary:
          type: string
          nullable: true
        frontmatter:
          type: object
          additionalProperties: true
          nullable: true
        body_markdown:
          type: string
          nullable: true
        skill_refs:
          type: array
          items:
            $ref: '#/components/schemas/SharedSkillRef'
        input_contract:
          type: object
          additionalProperties: true
          nullable: true
        output_contract:
          type: object
          additionalProperties: true
          nullable: true
        onboarding_template:
          type: string
          nullable: true
        update_reason:
          type: string
          nullable: true
    UpdateSharedCapabilityResult:
      type: object
      required:
      - package
      properties:
        package:
          $ref: '#/components/schemas/SharedCapabilityPackageDetail'
        previous_package_id:
          type: string
          nullable: true
    ArchiveSharedCapabilityRequest:
      type: object
      required:
      - reason
      properties:
        reason:
          type: string
    ArchiveSharedCapabilityResult:
      type: object
      required:
      - package_id
      - status
      - archived_at
      properties:
        package_id:
          type: string
        status:
          type: string
          const: archived
        archived_at:
          type: string
          format: date-time
    DiscoverSharedCapabilityRequest:
      type: object
      required:
      - query
      - limit
      - include_archived
      properties:
        query:
          type: string
        limit:
          type: integer
          minimum: 1
          maximum: 200
        cursor:
          type: string
          nullable: true
        include_archived:
          type: boolean
        tags:
          type: array
          items:
            type: string
        task_type:
          type: string
          nullable: true
    DiscoverSharedCapabilityResult:
      type: object
      required:
      - candidates
      properties:
        candidates:
          type: array
          items:
            $ref: '#/components/schemas/SharedCapabilityPackageSummary'
    LocalPackagePayload:
      type: object
      required:
      - package_id
      - title
      - summary
      - frontmatter
      - body_markdown
      - source_node_id
      - creator_person_id
      - package_hash
      properties:
        package_id:
          type: string
        title:
          type: string
        summary:
          type: string
        frontmatter:
          type: object
          additionalProperties: true
        body_markdown:
          type: string
        source_node_id:
          type: string
        creator_person_id:
          type: string
        package_hash:
          type: string
    PromotionStrategy:
      type: object
      required:
      - allow_create
      - allow_update
      properties:
        allow_create:
          type: boolean
        allow_update:
          type: boolean
    PromoteLocalPackageRequest:
      type: object
      required:
      - local_package
      - strategy
      properties:
        local_package:
          $ref: '#/components/schemas/LocalPackagePayload'
        task_capability_summary:
          type: object
          additionalProperties: true
          nullable: true
        strategy:
          $ref: '#/components/schemas/PromotionStrategy'
    PromoteLocalPackageResult:
      type: object
      required:
      - promotion
      properties:
        promotion:
          $ref: '#/components/schemas/PromotionResult'
    SharedSkillRef:
      type: object
      required:
      - ref_id
      - skill_id
      - source_type
      - version
      - required
      - mount_mode
      example: *id002
      properties:
        ref_id:
          type: string
        skill_id:
          type: string
        source_type:
          type: string
          enum:
          - builtin
          - shared_asset
          - external
        version:
          type: string
        required:
          type: boolean
        mount_mode:
          type: string
          enum:
          - reference
          - snapshot
    SharedSkillAsset:
      type: object
      required:
      - asset_id
      - org_id
      - title
      - slug
      - source_type
      - format
      - content_hash
      - version
      - author_node_id
      - status
      - created_at
      - updated_at
      example: *id003
      properties:
        asset_id:
          type: string
        org_id:
          type: string
        title:
          type: string
        slug:
          type: string
        source_type:
          type: string
          enum:
          - builtin_ref
          - uploaded
          - agent_generated
          - imported
        format:
          type: string
          enum:
          - hermes_skill_md
          - markdown
          - yaml
          - json
          - python
          - bundle
        content_text:
          type: string
          nullable: true
        content_json:
          type: object
          additionalProperties: true
          nullable: true
        content_hash:
          type: string
        version:
          type: integer
        author_node_id:
          type: string
        author_person_id:
          type: string
          nullable: true
        status:
          type: string
          enum:
          - active
          - archived
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    GetSharedSkillAssetResult:
      type: object
      required:
      - asset
      properties:
        asset:
          $ref: '#/components/schemas/SharedSkillAsset'
