openapi: 3.2.0 $self: https://remora.invalid/api/openapi.yaml jsonSchemaDialect: https://spec.openapis.org/oas/3.2/dialect/2025-09-17 info: title: Remora API version: 1.0.0 description: Mutable implementation contract for public job management and service-authenticated worker operations. servers: - url: /api security: - oidc: [] paths: /v1/jobs: post: operationId: submitJob parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/JobSubmission' responses: '202': description: Accepted, or the original accepted response for the same key and fingerprint. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/Job' '409': $ref: '#/components/responses/IdempotencyConflict' default: $ref: '#/components/responses/Error' get: operationId: listJobs parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Limit' - name: include_deleted in: query schema: type: boolean default: false responses: '200': description: Authorized keyset page bound to one snapshot and filter. content: application/json: schema: $ref: '#/components/schemas/JobPage' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}: parameters: - $ref: '#/components/parameters/JobId' get: operationId: getJob responses: '200': description: Current authorized full job or minimal hard-deletion tombstone projection. content: application/json: schema: $ref: '#/components/schemas/JobResource' '404': $ref: '#/components/responses/NotFound' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/result: parameters: - $ref: '#/components/parameters/JobId' get: operationId: getJobResult responses: '200': description: Visible committed manifest-rooted result. content: application/json: schema: $ref: '#/components/schemas/ResultDescriptor' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/result/members: parameters: - $ref: '#/components/parameters/JobId' get: operationId: listJobResultMembers description: Enumerates members only from the visible committed result. parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Limit' responses: '200': description: Authorized page of committed result members ordered by normalized path. content: application/json: schema: $ref: '#/components/schemas/ResultMemberPage' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/result/members/{member_id}/content: parameters: - $ref: '#/components/parameters/JobId' - name: member_id in: path required: true schema: $ref: '#/components/schemas/OpaqueId' get: operationId: accessJobResultMember description: Revalidates current authorization and redirects to a time-limited URL for the exact committed member identity. responses: '307': description: Temporary redirect to the exact committed member. The URL is sensitive and must not be logged or cached. headers: Location: description: Time-limited member URL. required: true schema: type: string format: uri Cache-Control: description: Prevents caching of the credential-bearing redirect response. required: true schema: const: no-store '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/cancel: parameters: - $ref: '#/components/parameters/JobId' post: operationId: cancelJob parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '202': description: Cancellation intent accepted or prior response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/Job' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/soft-delete: parameters: - $ref: '#/components/parameters/JobId' post: operationId: softDeleteJob parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '200': description: Job hidden, or prior response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/Job' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/restore: parameters: - $ref: '#/components/parameters/JobId' post: operationId: restoreJob parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '200': description: Soft-deleted job restored, or prior response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/Job' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/hard-delete: parameters: - $ref: '#/components/parameters/JobId' post: operationId: hardDeleteJob parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '202': description: Durable deletion operation created or replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/DeletionOperation' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/revoke: parameters: - $ref: '#/components/parameters/JobId' post: operationId: revokeJobExecutionGrant description: Administrator-only revocation of an accepted execution grant. parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '202': description: Durable cancellation intent recorded or prior response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/Job' default: $ref: '#/components/responses/Error' /v1/jobs/{job_id}/attempts: parameters: - $ref: '#/components/parameters/JobId' get: operationId: listJobAttempts parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Limit' responses: '200': description: Durable attempt history ordered by fencing token. content: application/json: schema: $ref: '#/components/schemas/AttemptPage' '404': $ref: '#/components/responses/NotFound' default: $ref: '#/components/responses/Error' /v1/source-credentials: post: operationId: createSourceCredential parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SourceCredentialCreate' responses: '201': description: Credential metadata and first immutable version created, or the original response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/SourceCredential' '409': $ref: '#/components/responses/IdempotencyConflict' default: $ref: '#/components/responses/Error' get: operationId: listSourceCredentials parameters: - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Limit' responses: '200': description: Authorized credential metadata page without secret material. content: application/json: schema: $ref: '#/components/schemas/SourceCredentialPage' default: $ref: '#/components/responses/Error' /v1/source-credentials/{credential_id}: parameters: - $ref: '#/components/parameters/CredentialId' get: operationId: getSourceCredential responses: '200': description: Authorized credential metadata without secret material. content: application/json: schema: $ref: '#/components/schemas/SourceCredential' '404': $ref: '#/components/responses/NotFound' default: $ref: '#/components/responses/Error' /v1/source-credentials/{credential_id}/versions: parameters: - $ref: '#/components/parameters/CredentialId' post: operationId: rotateSourceCredential parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SourceCredentialRotate' responses: '201': description: New immutable version created and selected for future grants, or the original response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/SourceCredential' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/IdempotencyConflict' default: $ref: '#/components/responses/Error' /v1/source-credentials/{credential_id}/revoke: parameters: - $ref: '#/components/parameters/CredentialId' post: operationId: revokeSourceCredential parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '200': description: Credential revoked for future grants, or the original response replayed. headers: Idempotency-Expires-At: $ref: '#/components/headers/IdempotencyExpiresAt' content: application/json: schema: $ref: '#/components/schemas/SourceCredential' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/IdempotencyConflict' default: $ref: '#/components/responses/Error' /v1/deletions/{operation_id}: parameters: - name: operation_id in: path required: true schema: $ref: '#/components/schemas/OpaqueId' get: operationId: getDeletionOperation responses: '200': description: Current deletion operation. content: application/json: schema: $ref: '#/components/schemas/DeletionOperation' '404': $ref: '#/components/responses/NotFound' default: $ref: '#/components/responses/Error' /v1/event-tickets: post: operationId: createEventTicket description: >- Creates an independent short-lived, single-use browser WebSocket credential bound to the authenticated principal and request origin. This ephemeral authentication exchange does not enter the public domain mutation idempotency ledger. responses: '201': description: Event ticket created. The response is not cacheable. content: application/json: schema: $ref: '#/components/schemas/EventTicket' default: $ref: '#/components/responses/Error' /v1/events: get: operationId: connectEvents security: - oidc: [] - eventTicket: [] parameters: - name: ticket in: query description: Short-lived single-use browser credential created by createEventTicket. Native clients may use OIDC bearer authentication instead. schema: $ref: '#/components/schemas/OpaqueId' - name: cursor in: query description: Opaque authorization-bound replay cursor from an HTTP snapshot or prior frame. schema: type: string minLength: 16 maxLength: 2048 responses: '101': description: WebSocket frames conform to events.schema.json. An absent, invalid, expired, or unauthorized cursor yields resync_required. default: $ref: '#/components/responses/Error' /internal/v1/jobs/{job_id}/claim: parameters: - $ref: '#/components/parameters/JobId' post: operationId: claimJob security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClaimRequest' responses: '200': description: Reserved and durably authorized attempt, or replay of the same claim operation. The authority is non-executable until activateAttempt succeeds. content: application/json: schema: $ref: '#/components/schemas/ClaimResponse' '409': $ref: '#/components/responses/IdempotencyConflict' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/renew: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: renewAttempt security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptRenewRequest' responses: '200': description: Existing exact live coordination lease renewed or prior response replayed; durable authority is unchanged. content: application/json: schema: $ref: '#/components/schemas/LeaseProjection' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/activate: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: activateAttempt security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptActivateRequest' responses: '200': description: Exact authority activated, or a prior successful activation replayed while its lease and durable executing tuple still agree. content: application/json: schema: $ref: '#/components/schemas/ActivationResponse' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/stop: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: stopAttempt security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptStopRequest' responses: '204': description: The exact attempt has cooperatively stopped, or no further stop action is required. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/staging/write-intent: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: registerAttemptStagingWriteIntent security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptStagingWriteIntentRequest' responses: '204': description: Exact staging key intent durably registered before target I/O. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/staging/object: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: registerAttemptStagingObject security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptStagingObjectRequest' responses: '204': description: Exact completed staging object identity durably registered. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/staging/multipart: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: registerAttemptStagingMultipart security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptStagingMultipartRequest' responses: '204': description: Exact staging multipart identity durably registered. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/resolved-source: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: pinAttemptResolvedSource security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptResolvedSourceRequest' responses: '204': description: Resolved source pinned once, or the exact operation replayed. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/checkpoint: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: persistAttemptCheckpoint security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptCheckpointRequest' responses: '204': description: Validated checkpoint persisted, or the exact operation replayed. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/progress: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: reportAttemptProgress security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptProgressRequest' responses: '204': description: Current progress accepted or duplicate ignored. '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' /internal/v1/attempts/{attempt_id}/outcome: parameters: - $ref: '#/components/parameters/AttemptId' post: operationId: reportAttemptOutcome security: - serviceAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AttemptOutcomeRequest' responses: '200': description: Durable outcome projection or replay of the same operation. content: application/json: schema: $ref: '#/components/schemas/JobPhaseProjection' '409': $ref: '#/components/responses/PreconditionFailed' default: $ref: '#/components/responses/Error' components: securitySchemes: oidc: type: openIdConnect openIdConnectUrl: https://identity.invalid/.well-known/openid-configuration serviceAuth: type: mutualTLS eventTicket: type: apiKey in: query name: ticket parameters: IdempotencyKey: name: Idempotency-Key in: header required: true description: Subject- and operation-scoped key retained for at least 24 hours. schema: type: string pattern: '^[A-Za-z0-9._~-]{16,128}$' Cursor: name: cursor in: query schema: type: string minLength: 16 maxLength: 2048 Limit: name: limit in: query schema: type: integer minimum: 1 maximum: 200 default: 50 JobId: name: job_id in: path required: true schema: $ref: '#/components/schemas/OpaqueId' AttemptId: name: attempt_id in: path required: true schema: $ref: '#/components/schemas/OpaqueId' CredentialId: name: credential_id in: path required: true schema: $ref: '#/components/schemas/CredentialId' headers: IdempotencyExpiresAt: description: Earliest time at which the server may forget this key. schema: type: string format: date-time responses: Error: description: Structured error with user-safe detail only. content: application/problem+json: schema: $ref: '#/components/schemas/ApiError' NotFound: description: Missing or unauthorized resource; the response does not distinguish them. content: application/problem+json: schema: $ref: '#/components/schemas/ApiError' IdempotencyConflict: description: The key exists with a different canonical request fingerprint. content: application/problem+json: schema: $ref: '#/components/schemas/ApiError' PreconditionFailed: description: Durable authority, fence, phase, or lifecycle precondition failed. content: application/problem+json: schema: $ref: '#/components/schemas/ApiError' schemas: OpaqueId: type: string pattern: '^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$' PrincipalId: description: Internal stable principal identifier mapped to one exact OIDC issuer and subject pair. allOf: - $ref: '#/components/schemas/OpaqueId' CredentialId: description: Owner-authorized source credential registry identifier. allOf: - $ref: '#/components/schemas/OpaqueId' CredentialVersionId: description: Immutable application credential-version identifier; backend secret-store coordinates are never exposed. allOf: - $ref: '#/components/schemas/OpaqueId' Target: type: object additionalProperties: false required: [store, bucket, prefix] properties: store: type: string minLength: 1 maxLength: 128 bucket: type: string pattern: '^(?!.*\.\.)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$' prefix: type: string maxLength: 1024 description: NFC-normalized target segments; semantic validation follows architecture.md. TargetOverride: type: object additionalProperties: false minProperties: 1 properties: bucket: type: string pattern: '^(?!.*\.\.)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$' prefix: type: string maxLength: 1024 description: NFC-normalized target segments; semantic validation follows architecture.md. StagingTarget: type: object additionalProperties: false required: [store, bucket, prefix] properties: store: type: string minLength: 1 maxLength: 128 bucket: type: string pattern: '^(?!.*\.\.)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$' prefix: type: string minLength: 1 maxLength: 1024 description: Exact attempt-scoped internal prefix selected by the service. ResultPath: type: string minLength: 1 maxLength: 4096 description: NFC-normalized relative POSIX path validated under architecture.md. HttpSourceSubmission: type: object additionalProperties: false required: [kind, url, result_path] properties: kind: const: http url: type: string format: uri maxLength: 8192 writeOnly: true description: Sensitive execution input. Public projections expose only display_url. result_path: $ref: '#/components/schemas/ResultPath' credential_id: $ref: '#/components/schemas/CredentialId' ObjectStoreSourceSubmission: type: object additionalProperties: false required: [kind, store, bucket, key, result_path] properties: kind: const: object_store store: type: string minLength: 1 maxLength: 128 bucket: type: string minLength: 3 maxLength: 63 key: type: string minLength: 1 maxLength: 4096 version_id: type: string maxLength: 1024 result_path: $ref: '#/components/schemas/ResultPath' credential_id: $ref: '#/components/schemas/CredentialId' HuggingFaceSelection: type: object additionalProperties: false minProperties: 1 anyOf: - required: [paths] - required: [prefixes] properties: paths: type: array minItems: 1 maxItems: 1024 uniqueItems: true items: $ref: '#/components/schemas/ResultPath' prefixes: type: array minItems: 1 maxItems: 1024 uniqueItems: true items: $ref: '#/components/schemas/ResultPath' HuggingFaceSourceSubmission: type: object additionalProperties: false required: [kind, repository_type, repository_id, revision] properties: kind: const: hugging_face repository_type: type: string enum: [model, dataset, space] repository_id: type: string pattern: '^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$' revision: type: string minLength: 1 maxLength: 256 selection: $ref: '#/components/schemas/HuggingFaceSelection' credential_id: $ref: '#/components/schemas/CredentialId' SourceSubmission: oneOf: - $ref: '#/components/schemas/HttpSourceSubmission' - $ref: '#/components/schemas/ObjectStoreSourceSubmission' - $ref: '#/components/schemas/HuggingFaceSourceSubmission' discriminator: propertyName: kind mapping: http: '#/components/schemas/HttpSourceSubmission' object_store: '#/components/schemas/ObjectStoreSourceSubmission' hugging_face: '#/components/schemas/HuggingFaceSourceSubmission' HttpSourceProjection: type: object additionalProperties: false required: [kind, display_url, result_path] properties: kind: const: http display_url: type: string format: uri maxLength: 8192 description: Sanitized URL without userinfo, sensitive query values, or fragments. result_path: $ref: '#/components/schemas/ResultPath' credential_id: $ref: '#/components/schemas/CredentialId' ObjectStoreSourceProjection: type: object additionalProperties: false required: [kind, store, bucket, key, result_path] properties: kind: const: object_store store: type: string minLength: 1 maxLength: 128 bucket: type: string minLength: 3 maxLength: 63 key: type: string minLength: 1 maxLength: 4096 version_id: type: string maxLength: 1024 result_path: $ref: '#/components/schemas/ResultPath' credential_id: $ref: '#/components/schemas/CredentialId' HuggingFaceSourceProjection: type: object additionalProperties: false required: [kind, repository_type, repository_id, revision] properties: kind: const: hugging_face repository_type: type: string enum: [model, dataset, space] repository_id: type: string pattern: '^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$' revision: type: string minLength: 1 maxLength: 256 selection: $ref: '#/components/schemas/HuggingFaceSelection' credential_id: $ref: '#/components/schemas/CredentialId' SourceProjection: oneOf: - $ref: '#/components/schemas/HttpSourceProjection' - $ref: '#/components/schemas/ObjectStoreSourceProjection' - $ref: '#/components/schemas/HuggingFaceSourceProjection' discriminator: propertyName: kind mapping: http: '#/components/schemas/HttpSourceProjection' object_store: '#/components/schemas/ObjectStoreSourceProjection' hugging_face: '#/components/schemas/HuggingFaceSourceProjection' JobSubmission: type: object additionalProperties: false required: [source] properties: source: $ref: '#/components/schemas/SourceSubmission' target: description: Fields omitted here are taken from the configured default target before authorization. $ref: '#/components/schemas/TargetOverride' label: type: string minLength: 1 maxLength: 200 SourceCredentialKind: type: string enum: [basic_auth, bearer_token, http_headers, object_store, hugging_face] BasicAuthMaterial: type: object additionalProperties: false required: [username, password] properties: username: type: string minLength: 1 maxLength: 1024 password: type: string minLength: 1 maxLength: 16384 writeOnly: true TokenMaterial: type: object additionalProperties: false required: [token] properties: token: type: string minLength: 1 maxLength: 16384 writeOnly: true HttpHeadersMaterial: type: object additionalProperties: false required: [headers] properties: headers: type: object minProperties: 1 maxProperties: 64 propertyNames: allOf: - pattern: '^[a-z0-9!#$%&''*+.^_`|~-]+$' - not: enum: [authorization, connection, content-length, cookie, host, keep-alive, proxy-authenticate, proxy-authorization, te, trailer, transfer-encoding, upgrade] additionalProperties: type: string minLength: 1 maxLength: 16384 description: Canonical lowercase end-to-end headers. Connection-nominated and routing, framing, cookie, proxy, and authentication headers are rejected. writeOnly: true ObjectStoreCredentialMaterial: type: object additionalProperties: false required: [access_key_id, secret_access_key] properties: access_key_id: type: string minLength: 1 maxLength: 1024 secret_access_key: type: string minLength: 1 maxLength: 16384 session_token: type: string minLength: 1 maxLength: 16384 writeOnly: true CredentialMaterial: oneOf: - $ref: '#/components/schemas/BasicAuthMaterial' - $ref: '#/components/schemas/TokenMaterial' - $ref: '#/components/schemas/HttpHeadersMaterial' - $ref: '#/components/schemas/ObjectStoreCredentialMaterial' writeOnly: true description: Write-only material whose closed shape must match the credential kind. Values are never returned or logged. SourceCredentialCreate: oneOf: - $ref: '#/components/schemas/BasicAuthCredentialCreate' - $ref: '#/components/schemas/BearerTokenCredentialCreate' - $ref: '#/components/schemas/HttpHeadersCredentialCreate' - $ref: '#/components/schemas/ObjectStoreCredentialCreate' - $ref: '#/components/schemas/HuggingFaceCredentialCreate' discriminator: propertyName: kind mapping: basic_auth: '#/components/schemas/BasicAuthCredentialCreate' bearer_token: '#/components/schemas/BearerTokenCredentialCreate' http_headers: '#/components/schemas/HttpHeadersCredentialCreate' object_store: '#/components/schemas/ObjectStoreCredentialCreate' hugging_face: '#/components/schemas/HuggingFaceCredentialCreate' BasicAuthCredentialCreate: type: object additionalProperties: false required: [label, kind, material] properties: label: type: string minLength: 1 maxLength: 200 kind: const: basic_auth material: $ref: '#/components/schemas/BasicAuthMaterial' BearerTokenCredentialCreate: type: object additionalProperties: false required: [label, kind, material] properties: label: type: string minLength: 1 maxLength: 200 kind: const: bearer_token material: $ref: '#/components/schemas/TokenMaterial' HttpHeadersCredentialCreate: type: object additionalProperties: false required: [label, kind, material] properties: label: type: string minLength: 1 maxLength: 200 kind: const: http_headers material: $ref: '#/components/schemas/HttpHeadersMaterial' ObjectStoreCredentialCreate: type: object additionalProperties: false required: [label, kind, material] properties: label: type: string minLength: 1 maxLength: 200 kind: const: object_store material: $ref: '#/components/schemas/ObjectStoreCredentialMaterial' HuggingFaceCredentialCreate: type: object additionalProperties: false required: [label, kind, material] properties: label: type: string minLength: 1 maxLength: 200 kind: const: hugging_face material: $ref: '#/components/schemas/TokenMaterial' SourceCredentialRotate: type: object additionalProperties: false required: [material] description: The material shape must match the stored credential kind; rotation never changes kind. properties: material: $ref: '#/components/schemas/CredentialMaterial' SourceCredentialVersion: type: object additionalProperties: false required: [id, created_at] properties: id: $ref: '#/components/schemas/CredentialVersionId' created_at: type: string format: date-time CredentialGrantVersion: type: object additionalProperties: false required: [credential_id, version_id] properties: credential_id: $ref: '#/components/schemas/CredentialId' version_id: $ref: '#/components/schemas/CredentialVersionId' SourceCredential: type: object additionalProperties: false required: [id, owner, label, kind, status, active_version, created_at, updated_at] properties: id: $ref: '#/components/schemas/CredentialId' owner: $ref: '#/components/schemas/PrincipalId' label: type: string minLength: 1 maxLength: 200 kind: $ref: '#/components/schemas/SourceCredentialKind' status: type: string enum: [active, revoked] active_version: oneOf: - $ref: '#/components/schemas/SourceCredentialVersion' - type: 'null' created_at: type: string format: date-time updated_at: type: string format: date-time SourceCredentialPage: type: object additionalProperties: false required: [items, next_cursor] properties: items: type: array items: $ref: '#/components/schemas/SourceCredential' next_cursor: type: [string, 'null'] JobPhase: type: string enum: [Queued, Running, RetryWait, Cancelling, Succeeded, Failed, Cancelled] JobPhaseProjection: type: object additionalProperties: false required: [phase] properties: phase: $ref: '#/components/schemas/JobPhase' TerminalJobPhase: type: string enum: [Succeeded, Failed, Cancelled] JobLifecycle: type: string enum: [visible, soft_deleted, hard_deleting, hard_deleted] AttemptAuthority: type: object additionalProperties: false required: [attempt_id, fence, worker_incarnation] properties: attempt_id: $ref: '#/components/schemas/OpaqueId' fence: type: integer minimum: 1 worker_incarnation: $ref: '#/components/schemas/OpaqueId' LeaseProjection: type: object additionalProperties: false required: [expires_at, renew_after] properties: expires_at: type: string format: date-time description: Expiry of the exact coordination lease established for this authority. renew_after: type: string format: date-time description: Earliest recommended renewal time, strictly before expires_at. Progress: type: object additionalProperties: false required: [attempt_id, fence, completed_bytes, completed_members, observed_at] properties: attempt_id: $ref: '#/components/schemas/OpaqueId' fence: type: integer minimum: 1 completed_bytes: type: integer minimum: 0 total_bytes: type: [integer, 'null'] minimum: 0 completed_members: type: integer minimum: 0 total_members: type: [integer, 'null'] minimum: 0 observed_at: type: string format: date-time ProgressValue: type: object additionalProperties: false required: [completed_bytes, completed_members] properties: completed_bytes: type: integer minimum: 0 total_bytes: type: [integer, 'null'] minimum: 0 completed_members: type: integer minimum: 0 total_members: type: [integer, 'null'] minimum: 0 CheckpointProjection: type: object additionalProperties: false required: [reusable, validated_bytes, validated_members] properties: reusable: type: boolean validated_bytes: type: integer minimum: 0 validated_members: type: integer minimum: 0 JobFailure: oneOf: - type: object additionalProperties: false required: [class, retryable, message] properties: class: type: string enum: [validation, authorization, source_not_found, source_changed, cancelled] retryable: const: false message: type: string maxLength: 500 safe_details: type: object additionalProperties: type: [string, integer, boolean, 'null'] - type: object additionalProperties: false required: [class, retryable, message] properties: class: type: string enum: [transient_source, transient_target, integrity, capacity, internal, lost_attempt] retryable: const: true message: type: string maxLength: 500 safe_details: type: object additionalProperties: type: [string, integer, boolean, 'null'] AttemptRuntimeFailure: type: object additionalProperties: false required: [class, message] properties: class: type: string enum: [authorization, source_not_found, source_changed, transient_source, transient_target, integrity, capacity, internal] message: type: string maxLength: 500 safe_details: type: object additionalProperties: type: [string, integer, boolean, 'null'] ResultDescriptor: type: object additionalProperties: false required: [kind, manifest_id, schema_version, manifest, member_count, total_bytes] properties: kind: const: manifest manifest_id: $ref: '#/components/schemas/OpaqueId' schema_version: type: integer minimum: 1 manifest: $ref: '#/components/schemas/ObjectIdentity' member_count: type: integer minimum: 1 total_bytes: type: integer minimum: 0 ObjectIdentity: type: object additionalProperties: false required: [store, bucket, key, checksum, size] properties: store: type: string bucket: type: string key: type: string version_id: type: string checksum: $ref: '#/components/schemas/Sha256Digest' size: type: integer minimum: 0 Sha256Digest: type: string pattern: '^sha256:[a-f0-9]{64}$' DurableDescriptorRef: type: object additionalProperties: false required: [id, kind, schema_version, byte_length, checksum] properties: id: $ref: '#/components/schemas/OpaqueId' kind: type: string enum: [resolved_source, checkpoint] schema_version: type: integer minimum: 1 byte_length: type: integer minimum: 0 item_count: type: integer minimum: 0 checksum: $ref: '#/components/schemas/Sha256Digest' ResultMember: type: object additionalProperties: false required: [id, path, size, object] properties: id: $ref: '#/components/schemas/OpaqueId' path: type: string minLength: 1 maxLength: 4096 description: NFC-normalized relative POSIX path validated under architecture.md. size: type: integer minimum: 0 object: $ref: '#/components/schemas/ObjectIdentity' ResultMemberPage: type: object additionalProperties: false required: [items, next_cursor] properties: items: type: array items: $ref: '#/components/schemas/ResultMember' next_cursor: type: [string, 'null'] Job: type: object additionalProperties: false required: [resource_kind, id, owner, label, revision, phase, lifecycle, source, target, authoritative_attempt, progress, checkpoint, result, failure, created_at, updated_at, event_cursor] properties: resource_kind: const: job id: $ref: '#/components/schemas/OpaqueId' owner: $ref: '#/components/schemas/PrincipalId' label: type: [string, 'null'] minLength: 1 maxLength: 200 revision: type: integer minimum: 1 phase: $ref: '#/components/schemas/JobPhase' lifecycle: $ref: '#/components/schemas/JobLifecycle' source: $ref: '#/components/schemas/SourceProjection' target: $ref: '#/components/schemas/Target' authoritative_attempt: oneOf: - $ref: '#/components/schemas/AttemptAuthority' - type: 'null' progress: oneOf: - $ref: '#/components/schemas/Progress' - type: 'null' checkpoint: oneOf: - $ref: '#/components/schemas/CheckpointProjection' - type: 'null' result: oneOf: - $ref: '#/components/schemas/ResultDescriptor' - type: 'null' failure: oneOf: - $ref: '#/components/schemas/JobFailure' - type: 'null' created_at: type: string format: date-time updated_at: type: string format: date-time event_cursor: type: string minLength: 16 JobTombstone: type: object additionalProperties: false required: [resource_kind, id, owner, target, terminal_phase, deletion_operation_id, created_at, hard_delete_started_at, updated_at, event_cursor] properties: resource_kind: const: tombstone id: $ref: '#/components/schemas/OpaqueId' owner: $ref: '#/components/schemas/PrincipalId' target: $ref: '#/components/schemas/Target' terminal_phase: $ref: '#/components/schemas/TerminalJobPhase' deletion_operation_id: $ref: '#/components/schemas/OpaqueId' created_at: type: string format: date-time hard_delete_started_at: type: string format: date-time updated_at: type: string format: date-time event_cursor: type: string minLength: 16 JobResource: oneOf: - $ref: '#/components/schemas/Job' - $ref: '#/components/schemas/JobTombstone' discriminator: propertyName: resource_kind mapping: job: '#/components/schemas/Job' tombstone: '#/components/schemas/JobTombstone' JobPage: type: object additionalProperties: false required: [items, next_cursor, event_cursor] properties: items: type: array items: $ref: '#/components/schemas/JobResource' next_cursor: type: [string, 'null'] event_cursor: type: string minLength: 16 AttemptRecord: type: object additionalProperties: false required: [id, fence, worker_incarnation, state, progress, result, failure, created_at, updated_at] allOf: - if: required: [state] properties: state: const: AttemptCommitted then: properties: result: $ref: '#/components/schemas/ResultDescriptor' else: properties: result: type: 'null' properties: id: $ref: '#/components/schemas/OpaqueId' fence: type: integer minimum: 1 worker_incarnation: $ref: '#/components/schemas/OpaqueId' state: type: string enum: [AttemptAuthorized, AttemptExecuting, AttemptStopped, AttemptCommitted] progress: oneOf: - $ref: '#/components/schemas/Progress' - type: 'null' result: oneOf: - $ref: '#/components/schemas/ResultDescriptor' - type: 'null' failure: oneOf: - $ref: '#/components/schemas/JobFailure' - type: 'null' created_at: type: string format: date-time updated_at: type: string format: date-time AttemptPage: type: object additionalProperties: false required: [items, next_cursor] properties: items: type: array items: $ref: '#/components/schemas/AttemptRecord' next_cursor: type: [string, 'null'] DeletionProblem: type: object additionalProperties: false required: [class, message] properties: class: type: string enum: [authorization, target_unavailable, configuration, internal] message: type: string maxLength: 500 DeletionOperation: type: object additionalProperties: false required: [id, job_id, state, problem, created_at, updated_at] properties: id: $ref: '#/components/schemas/OpaqueId' job_id: $ref: '#/components/schemas/OpaqueId' state: type: string enum: [queued, running, retry_wait, blocked, completed] problem: oneOf: - $ref: '#/components/schemas/DeletionProblem' - type: 'null' created_at: type: string format: date-time updated_at: type: string format: date-time EventTicket: type: object additionalProperties: false required: [ticket, expires_at] properties: ticket: $ref: '#/components/schemas/OpaqueId' expires_at: type: string format: date-time ApiError: type: object additionalProperties: false required: [code, message, request_id] properties: code: type: string enum: [invalid_request, unauthenticated, forbidden, not_found, idempotency_conflict, precondition_failed, cursor_invalid, cursor_expired, rate_limited, unavailable, internal] message: type: string maxLength: 500 request_id: $ref: '#/components/schemas/OpaqueId' fields: type: array maxItems: 100 items: type: object additionalProperties: false required: [pointer, code] properties: pointer: type: string maxLength: 500 code: type: string maxLength: 100 ClaimRequest: type: object additionalProperties: false required: [operation_id, worker_incarnation] properties: operation_id: $ref: '#/components/schemas/OpaqueId' worker_incarnation: $ref: '#/components/schemas/OpaqueId' ExecutionEnvelope: type: object additionalProperties: false required: [id, job_id, attempt_id, fence, worker_incarnation, source, sensitive_source_ref, credential_version, resolved_source_ref, target, staging_target, execution_grant_ref, checkpoint_ref] properties: id: $ref: '#/components/schemas/OpaqueId' job_id: $ref: '#/components/schemas/OpaqueId' attempt_id: $ref: '#/components/schemas/OpaqueId' fence: type: integer minimum: 1 worker_incarnation: $ref: '#/components/schemas/OpaqueId' source: $ref: '#/components/schemas/SourceProjection' sensitive_source_ref: description: Opaque grant-bound reference to the complete accepted source input; credential_version identifies any pinned credential separately. $ref: '#/components/schemas/OpaqueId' credential_version: oneOf: - $ref: '#/components/schemas/CredentialGrantVersion' - type: 'null' resolved_source_ref: oneOf: - $ref: '#/components/schemas/DurableDescriptorRef' - type: 'null' target: $ref: '#/components/schemas/Target' staging_target: $ref: '#/components/schemas/StagingTarget' execution_grant_ref: $ref: '#/components/schemas/OpaqueId' checkpoint_ref: oneOf: - $ref: '#/components/schemas/DurableDescriptorRef' - type: 'null' ClaimResponse: type: object additionalProperties: false required: [authority, execution] properties: authority: $ref: '#/components/schemas/AttemptAuthority' execution: $ref: '#/components/schemas/ExecutionEnvelope' ActivationResponse: type: object additionalProperties: false required: [authority, execution, lease] properties: authority: $ref: '#/components/schemas/AttemptAuthority' execution: $ref: '#/components/schemas/ExecutionEnvelope' lease: $ref: '#/components/schemas/LeaseProjection' AttemptMutation: type: object required: [operation_id, fence, worker_incarnation] properties: operation_id: $ref: '#/components/schemas/OpaqueId' fence: type: integer minimum: 1 worker_incarnation: $ref: '#/components/schemas/OpaqueId' AttemptRenewRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' AttemptActivateRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' AttemptStopRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' StagingObjectIdentity: type: object additionalProperties: false required: [store, bucket, key] properties: store: type: string minLength: 1 bucket: type: string minLength: 1 key: type: string minLength: 1 version_id: type: string minLength: 1 StagingWriteIntent: type: object additionalProperties: false required: [store, bucket, key] properties: store: type: string minLength: 1 bucket: type: string minLength: 1 key: type: string minLength: 1 StagingMultipartIdentity: type: object additionalProperties: false required: [store, bucket, key, upload_id] properties: store: type: string minLength: 1 bucket: type: string minLength: 1 key: type: string minLength: 1 upload_id: type: string minLength: 1 AttemptStagingObjectRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [object] properties: object: $ref: '#/components/schemas/StagingObjectIdentity' completed_upload_id: type: string minLength: 1 AttemptStagingWriteIntentRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [intent] properties: intent: $ref: '#/components/schemas/StagingWriteIntent' AttemptStagingMultipartRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [multipart] properties: multipart: $ref: '#/components/schemas/StagingMultipartIdentity' AttemptResolvedSourceRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [resolved_source_ref] properties: resolved_source_ref: allOf: - $ref: '#/components/schemas/DurableDescriptorRef' - type: object properties: kind: const: resolved_source AttemptCheckpointRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [checkpoint_ref, resolved_source_id, validated_bytes, validated_members] properties: checkpoint_ref: allOf: - $ref: '#/components/schemas/DurableDescriptorRef' - type: object properties: kind: const: checkpoint resolved_source_id: $ref: '#/components/schemas/OpaqueId' validated_bytes: type: integer minimum: 0 validated_members: type: integer minimum: 0 staging_multipart: $ref: '#/components/schemas/StagingMultipartIdentity' AttemptProgressRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [progress] properties: progress: $ref: '#/components/schemas/ProgressValue' AttemptOutcomeRequest: unevaluatedProperties: false allOf: - $ref: '#/components/schemas/AttemptMutation' - type: object required: [outcome] properties: outcome: oneOf: - type: object additionalProperties: false required: [kind, result] properties: kind: const: success result: $ref: '#/components/schemas/ResultDescriptor' - type: object additionalProperties: false required: [kind, failure] properties: kind: const: failure failure: $ref: '#/components/schemas/AttemptRuntimeFailure'