Ctrl K
ComunidadGuías…

openapi/openapi.yaml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
openapi: 3.1.0
info:
  title: Ferryman API
  version: 0.1.0
servers: [{url: http://127.0.0.1:8787}]
components:
  securitySchemes:
    ProjectBearer:
      type: http
      scheme: bearer
      description: Project-scoped operator token.
    ActorBearer:
      type: http
      scheme: bearer
      description: Eight-hour communications actor token returned once by the actor token endpoint.
  schemas:
    Error: {type: object, required: [code, message], properties: {code: {type: string}, message: {type: string}}}
    Job: {type: object, required: [id, project_id, status, input], properties: {id: {type: string}, project_id: {type: string}, status: {type: string, enum: [pending_approval, queued, leased, succeeded, failed, cancelled]}, input: {type: object}, policy: {type: object}}}
    Artifact: {type: object, required: [id, job_id, sha256, content_type, byte_len], properties: {id: {type: string}, job_id: {type: string}, sha256: {type: string}, content_type: {type: string}, byte_len: {type: integer}}}
    CommunicationParticipant:
      type: object
      additionalProperties: false
      required: [name, role, capabilities]
      properties:
        name: {type: string, pattern: '^[A-Za-z0-9._-]+$', maxLength: 128}
        role: {type: string, pattern: '^[A-Za-z0-9._-]+$', maxLength: 128}
        capabilities:
          type: array
          maxItems: 128
          items: {type: string, minLength: 1, maxLength: 128}
    CommunicationMessage:
      type: object
      required: [format, id, project_id, idempotency_key, sender, recipient, created_at, acknowledgement_deadline, payload_reference, payload, reply_required]
      properties:
        format: {type: string, const: ferryman-message/v1}
        id: {type: string, format: uuid}
        project_id: {type: string}
        idempotency_key: {type: string, maxLength: 256}
        sender: {type: string, maxLength: 128}
        recipient: {type: string, maxLength: 128}
        created_at: {type: string, format: date-time}
        acknowledgement_deadline: {type: string, format: date-time}
        payload_reference: {type: string, maxLength: 2048}
        payload:
          description: JSON limited to 256 KiB after serialization; credential-bearing keys are rejected recursively.
        reply_required: {type: boolean}
    CommunicationStatus:
      type: object
      required: [project_id, external_probes_performed, local_health, shared_health, git_health, git_live, git_inbound_active, preferred_successes, outbox_depth, acknowledgement_outbox_depth, quarantine_files, git_backoff_attempt, updated_at]
      properties:
        project_id: {type: string}
        external_probes_performed: {type: boolean}
        local_health: {type: string, enum: [healthy, unavailable, rate_limited]}
        shared_health: {type: string, enum: [healthy, unavailable, rate_limited]}
        git_health: {type: string, enum: [healthy, unavailable, rate_limited]}
        git_live: {type: boolean}
        git_inbound_active: {type: boolean}
        preferred_successes: {type: integer, minimum: 0}
        outbox_depth: {type: integer, minimum: 0}
        acknowledgement_outbox_depth: {type: integer, minimum: 0}
        oldest_outbox_age_seconds: {type: [integer, 'null'], minimum: 0}
        quarantine_files: {type: integer, minimum: 0}
        git_backoff_attempt: {type: integer, minimum: 0}
        git_retry_after_unix_ms: {type: [integer, 'null'], minimum: 0}
        updated_at: {type: string, format: date-time}
    CommunicationActorRegistration:
      type: object
      required: [project_id, actor, actor_token, expires_at]
      properties:
        project_id: {type: string}
        actor: {type: string}
        actor_token: {type: string, writeOnly: true}
        expires_at: {type: string, format: date-time}
paths:
  /healthz: {get: {responses: {'200': {description: health}}}}
  /v1/projects:
    post: {summary: Create a project (local setup endpoint), requestBody: {required: true, content: {application/json: {schema: {type: object, required: [id,name,token]}}}}, responses: {'201': {description: created}, '400': {description: invalid, content: {application/json: {schema: {$ref: '#/components/schemas/Error'}}}}}}
  /v1/projects/{project_id}/communications:
    parameters: [{name: project_id, in: path, required: true, schema: {type: string}}]
    post: {security: [{ProjectBearer: []}], summary: Configure the outer-local and inner-portable project communications mapping, responses: {'200': {description: project route}, '400': {description: unsafe or mismatched route}}}
    get: {security: [{ProjectBearer: []}], summary: Read the project communications mapping, responses: {'200': {description: project route}, '404': {description: no mapping}}}
    delete:
      security: [{ProjectBearer: []}]
      summary: Unregister the hub mapping and revoke actor tokens without deleting files
      responses:
        '204': {description: mapping removed; attachment files remain}
        '409': {description: refused because durable outbox items remain}
  /v1/projects/{project_id}/communications/messages:
    parameters: [{name: project_id, in: path, required: true, schema: {type: string}}]
    post:
      security: [{ProjectBearer: []}]
      summary: Durably enqueue and deliver a project-scoped message
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [sender, recipient]
              properties:
                sender: {type: string, maxLength: 128}
                recipient: {type: string, maxLength: 128}
                payload_reference: {type: string, default: inline, maxLength: 2048}
                payload: {default: null}
                reply_required: {type: boolean, default: false}
                idempotency_key: {type: [string, 'null'], maxLength: 256}
                acknowledgement_timeout_seconds: {type: integer, minimum: 5, maximum: 3600, default: 30}
      responses:
        '201': {description: stable message and delivery receipt}
        '400': {description: invalid route, payload, or idempotency conflict}
    get: {security: [{ProjectBearer: []}], summary: List portable project messages, responses: {'200': {description: messages}}}
  /v1/projects/{project_id}/communications/messages/{message_id}/claim:
    parameters:
      - {name: project_id, in: path, required: true, schema: {type: string}}
      - {name: message_id, in: path, required: true, schema: {type: string, format: uuid}}
    post:
      security: [{ActorBearer: []}]
      summary: Atomically claim a message idempotency key before execution
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [recipient]
              properties: {recipient: {type: string}}
      responses:
        '200': {description: claim result; claimed false means do not execute}
        '401': {description: missing, expired, or wrong actor token}
  /v1/projects/{project_id}/communications/messages/{message_id}/acknowledge:
    parameters:
      - {name: project_id, in: path, required: true, schema: {type: string}}
      - {name: message_id, in: path, required: true, schema: {type: string, format: uuid}}
    post:
      security: [{ActorBearer: []}]
      summary: Record a separate acknowledgement and retire the outbox item
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [recipient]
              properties: {recipient: {type: string}}
      responses:
        '200': {description: acknowledgement, idempotent record result, and durable delivery receipt}
        '401': {description: missing, expired, or wrong actor token}
  /v1/projects/{project_id}/communications/actors/{actor}/token:
    parameters:
      - {name: project_id, in: path, required: true, schema: {type: string}}
      - {name: actor, in: path, required: true, schema: {type: string, pattern: '^[A-Za-z0-9._-]+$'}}
    post:
      security: [{ProjectBearer: []}]
      summary: Mint an eight-hour token for one registered communications actor
      responses:
        '201':
          description: actor token returned once
          content:
            application/json:
              schema: {$ref: '#/components/schemas/CommunicationActorRegistration'}
  /v1/projects/{project_id}/communications/actors/{actor}/messages:
    parameters:
      - {name: project_id, in: path, required: true, schema: {type: string}}
      - {name: actor, in: path, required: true, schema: {type: string, pattern: '^[A-Za-z0-9._-]+$'}}
    get:
      security: [{ActorBearer: []}]
      summary: List only messages addressed to this actor name or registered role
      parameters:
        - {name: synchronize, in: query, schema: {type: boolean, default: true}, description: Pull inbound private-Git state when shared delivery is unavailable or Git inbound mode is active.}
      responses:
        '200':
          description: actor-scoped inbox
          content:
            application/json:
              schema:
                type: object
                required: [items, synchronized_via]
                properties:
                  items:
                    type: array
                    items: {$ref: '#/components/schemas/CommunicationMessage'}
                  synchronized_via: {type: [string, 'null'], enum: [local_filesystem, shared_folder, private_git, null]}
        '401': {description: missing, expired, or wrong actor token}
  /v1/projects/{project_id}/communications/reconcile:
    parameters: [{name: project_id, in: path, required: true, schema: {type: string}}]
    post: {security: [{ProjectBearer: []}], summary: Reconcile the durable outbox and transport failover state immediately, responses: {'200': {description: delivery receipts}}}
  /v1/projects/{project_id}/communications/status:
    parameters: [{name: project_id, in: path, required: true, schema: {type: string}}]
    get:
      security: [{ProjectBearer: []}]
      summary: Inspect transport health, failover state, queue age, and quarantine
      parameters:
        - {name: probe_external, in: query, schema: {type: boolean, default: true}, description: Set false for a strictly local snapshot without Syncthing or private-Git health probes.}
      responses:
        '200':
          description: current communications status
          content:
            application/json:
              schema: {$ref: '#/components/schemas/CommunicationStatus'}
  /v1/projects/{project_id}/jobs:
    parameters: [{name: project_id, in: path, required: true, schema: {type: string}}]
    post: {security: [{ProjectBearer: []}], summary: Submit an idempotent job, responses: {'202': {description: accepted, content: {application/json: {schema: {$ref: '#/components/schemas/Job'}}}}}}
    get: {security: [{ProjectBearer: []}], summary: List jobs, parameters: [{name: limit, in: query, schema: {type: integer}}, {name: cursor, in: query, schema: {type: string}}, {name: status, in: query, schema: {type: string}}], responses: {'200': {description: jobs}}}
  /v1/projects/{project_id}/agents:
    post: {security: [{ProjectBearer: []}], summary: Create a project-role-derived agent and its Markdown profile, requestBody: {required: true, content: {application/json: {schema: {type: object, required: [role,description,persistence], properties: {role: {type: string}, description: {type: string}, persistence: {type: string, enum: [temporal, permanent]}}}}}}, responses: {'201': {description: agent created}}}
    get: {security: [{ProjectBearer: []}], summary: List project agents and profile paths, responses: {'200': {description: agents}}}
  /v1/projects/{project_id}/memory:
    post: {security: [{ProjectBearer: []}], summary: Append bridge-owned project recovery memory, requestBody: {required: true, content: {application/json: {schema: {type: object, required: [category,content], properties: {category: {type: string}, content: {type: string}, source: {type: string}}}}}}, responses: {'201': {description: entry created}}}
    get: {security: [{ProjectBearer: []}], summary: Read project recovery memory, parameters: [{name: limit, in: query, schema: {type: integer}}], responses: {'200': {description: entries}}}
  /v1/projects/{project_id}/continuity-packs:
    post: {security: [{ProjectBearer: []}], summary: Create an authenticated encrypted local continuity pack, responses: {'201': {description: pack created}, '500': {description: recovery key unavailable or integrity failure}}}
  /v1/projects/{project_id}/continuity-packs/{pack_hash}/recover:
    post: {security: [{ProjectBearer: []}], summary: Verify and reconstruct a read-only recovery workspace without dispatching work, parameters: [{name: pack_hash, in: path, required: true, schema: {type: string}}], responses: {'200': {description: resume briefing}, '500': {description: corrupt or unauthenticated pack}}}
  /v1/projects/{project_id}/continuity-packs/{pack_hash}/delivery-consents:
    post: {security: [{ProjectBearer: []}], summary: Create the exact consent required to send an encrypted pack to configured private Git, responses: {'201': {description: pending recovery-upload consent}}}
  /v1/projects/{project_id}/continuity-packs/{pack_hash}/deliver:
    post: {security: [{ProjectBearer: []}], summary: Send an approved encrypted pack and manifest to the configured private Git recovery branch, responses: {'200': {description: verified remote receipt}}}
  /v1/projects/{project_id}/recovery-drill:
    post: {security: [{ProjectBearer: []}], summary: Create, verify, and recover a test continuity pack without dispatching work, responses: {'200': {description: drill result}}}
  /v1/projects/{project_id}/timeline:
    get: {security: [{ProjectBearer: []}], summary: Cursor-paginated append-only decision timeline, parameters: [{name: after, in: query, schema: {type: integer}}, {name: category, in: query, schema: {type: string}}, {name: job_id, in: query, schema: {type: string}}], responses: {'200': {description: ordered events}}}
  /v1/projects/{project_id}/policy/simulate:
    post: {security: [{ProjectBearer: []}], summary: Non-mutating capability, consent, quota, and retention-policy simulation, responses: {'200': {description: simulation result}}}
  /v1/projects/{project_id}/outbound-submissions:
    post: {security: [{ProjectBearer: []}], summary: Create an immutable pending-consent outbound manifest; performs no delivery, responses: {'201': {description: pending submission manifest}}}
  /v1/projects/{project_id}/improvement-proposals:
    post: {security: [{ProjectBearer: []}], summary: Create a reviewable improvement proposal and pending consent; never modifies source, responses: {'201': {description: proposal only}}}
  /v1/projects/{project_id}/jobs/{job_id}/events:
    get: {security: [{ProjectBearer: []}], summary: Stream job events with Server-Sent Events, responses: {'200': {description: event stream, content: {text/event-stream: {schema: {type: string}}}}}}
  /v1/projects/{project_id}/jobs/{job_id}:
    get: {security: [{ProjectBearer: []}], summary: Inspect one job, responses: {'200': {description: job, content: {application/json: {schema: {$ref: '#/components/schemas/Job'}}}}, '404': {description: missing}}}
  /v1/projects/{project_id}/jobs/{job_id}/approve:
    post: {security: [{ProjectBearer: []}], summary: Approve a pending job, responses: {'200': {description: approved job}, '404': {description: job is not awaiting approval}}}
  /v1/projects/{project_id}/jobs/{job_id}/cancel:
    post: {security: [{ProjectBearer: []}], summary: Cancel a queued or leased job, responses: {'200': {description: cancelled job}, '404': {description: job cannot be cancelled}}}
  /v1/projects/{project_id}/jobs/{job_id}/artifacts:
    post: {security: [{ProjectBearer: []}], summary: Store an artifact body, requestBody: {required: true, content: {application/octet-stream: {schema: {type: string, format: binary}}}}, responses: {'201': {description: stored artifact, content: {application/json: {schema: {$ref: '#/components/schemas/Artifact'}}}}}}
    get: {security: [{ProjectBearer: []}], summary: List a job's artifact metadata, responses: {'200': {description: artifacts}}}
  /v1/projects/{project_id}/artifacts/{artifact_id}:
    get: {security: [{ProjectBearer: []}], summary: Inspect artifact metadata, responses: {'200': {description: artifact, content: {application/json: {schema: {$ref: '#/components/schemas/Artifact'}}}}}}
  /v1/projects/{project_id}/artifacts/{artifact_id}/content:
    get: {security: [{ProjectBearer: []}], summary: Download artifact bytes, responses: {'200': {description: artifact content, content: {application/octet-stream: {schema: {type: string, format: binary}}}}}}
  /v1/metrics:
    get: {summary: Local queue, acknowledgement queue, quarantine, and worker-health metrics, responses: {'200': {description: metrics}}}
  /v1/projects/{project_id}/workers/{worker_id}/lease:
    post: {security: [{ProjectBearer: []}], summary: Atomically lease one ready job, responses: {'200': {description: lease}, '204': {description: no job}}}