Separate protocol authority from mutable API contracts
Move API artifacts out of docs/spec, define concrete execution and deletion refinements, and document TLA+ abstraction boundaries so architecture prose cannot become a competing protocol specification.
This commit is contained in:
parent
78be27871c
commit
dfd60cf104
1 changed files with 316 additions and 73 deletions
964
docs/api/openapi.yaml
Normal file
964
docs/api/openapi.yaml
Normal file
|
|
@ -0,0 +1,964 @@
|
|||
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 job projection.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Job'
|
||||
'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}/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/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/events:
|
||||
get:
|
||||
operationId: connectEvents
|
||||
parameters:
|
||||
- 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: Allocated authority or replay of the same claim operation.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClaimResponse'
|
||||
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:
|
||||
'204':
|
||||
description: Existing live coordination lease renewed or duplicate operation accepted; durable authority is unchanged.
|
||||
'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/Job'
|
||||
'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
|
||||
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'
|
||||
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}$'
|
||||
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.
|
||||
HttpSource:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [kind, url]
|
||||
properties:
|
||||
kind:
|
||||
const: http
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
maxLength: 8192
|
||||
credential_ref:
|
||||
type: string
|
||||
maxLength: 512
|
||||
ObjectStoreSource:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [kind, store, bucket, key]
|
||||
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
|
||||
credential_ref:
|
||||
type: string
|
||||
maxLength: 512
|
||||
HuggingFaceSource:
|
||||
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
|
||||
include:
|
||||
type: array
|
||||
maxItems: 1024
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 1024
|
||||
credential_ref:
|
||||
type: string
|
||||
maxLength: 512
|
||||
Source:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/HttpSource'
|
||||
- $ref: '#/components/schemas/ObjectStoreSource'
|
||||
- $ref: '#/components/schemas/HuggingFaceSource'
|
||||
discriminator:
|
||||
propertyName: kind
|
||||
mapping:
|
||||
http: '#/components/schemas/HttpSource'
|
||||
object_store: '#/components/schemas/ObjectStoreSource'
|
||||
hugging_face: '#/components/schemas/HuggingFaceSource'
|
||||
JobSubmission:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [source]
|
||||
properties:
|
||||
source:
|
||||
$ref: '#/components/schemas/Source'
|
||||
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
|
||||
JobPhase:
|
||||
type: string
|
||||
enum: [Queued, Running, RetryWait, Cancelling, 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'
|
||||
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, member_count, total_bytes]
|
||||
properties:
|
||||
kind:
|
||||
const: manifest
|
||||
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]
|
||||
properties:
|
||||
store:
|
||||
type: string
|
||||
bucket:
|
||||
type: string
|
||||
key:
|
||||
type: string
|
||||
version_id:
|
||||
type: string
|
||||
checksum:
|
||||
type: string
|
||||
Job:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, owner, label, revision, phase, lifecycle, source, target, authoritative_attempt, progress, checkpoint, result, failure, created_at, updated_at, event_cursor]
|
||||
properties:
|
||||
id:
|
||||
$ref: '#/components/schemas/OpaqueId'
|
||||
owner:
|
||||
$ref: '#/components/schemas/OpaqueId'
|
||||
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/Source'
|
||||
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
|
||||
JobPage:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [items, next_cursor, event_cursor]
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Job'
|
||||
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]
|
||||
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
|
||||
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, 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/Source'
|
||||
resolved_source_ref:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/OpaqueId'
|
||||
- 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/OpaqueId'
|
||||
- type: 'null'
|
||||
ClaimResponse:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [authority, execution]
|
||||
properties:
|
||||
authority:
|
||||
$ref: '#/components/schemas/AttemptAuthority'
|
||||
execution:
|
||||
$ref: '#/components/schemas/ExecutionEnvelope'
|
||||
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'
|
||||
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'
|
||||
Loading…
Reference in a new issue