Tighten failure and manifest contracts
This commit is contained in:
parent
5fdb339fe5
commit
a44b687897
3 changed files with 47 additions and 8 deletions
|
|
@ -22,8 +22,9 @@ deletion and cancellation semantics still use this request identity.
|
||||||
|
|
||||||
Internal claim uses job ID plus `operation_id` because no attempt exists yet.
|
Internal claim uses job ID plus `operation_id` because no attempt exists yet.
|
||||||
Renew, progress, and outcome use attempt ID, fencing token, worker incarnation,
|
Renew, progress, and outcome use attempt ID, fencing token, worker incarnation,
|
||||||
and `operation_id`. A replay has the original effect; a different, stale, or
|
and `operation_id`. Each operation identity retains a request fingerprint. An
|
||||||
non-authoritative tuple returns `precondition_failed` without mutation.
|
exact replay has the original effect; a changed worker, fence, payload, stale,
|
||||||
|
or non-authoritative tuple returns `precondition_failed` without mutation.
|
||||||
|
|
||||||
## Authorization and errors
|
## Authorization and errors
|
||||||
|
|
||||||
|
|
@ -55,6 +56,11 @@ unauthorized, absent, and never-committed results are not exposed. The hard
|
||||||
delete endpoint returns the durable deletion resource established by the
|
delete endpoint returns the durable deletion resource established by the
|
||||||
architecture.
|
architecture.
|
||||||
|
|
||||||
|
Worker failure outcomes accept only attempt-reportable runtime classes and do
|
||||||
|
not accept a caller-supplied retryable flag. The service derives the durable
|
||||||
|
disposition from the class mapping in the architecture. Validation,
|
||||||
|
cancellation, and lost-attempt projection use their dedicated boundaries.
|
||||||
|
|
||||||
## WebSocket replay
|
## WebSocket replay
|
||||||
|
|
||||||
An HTTP job or list snapshot carries `event_cursor` at its consistency
|
An HTTP job or list snapshot carries `event_cursor` at its consistency
|
||||||
|
|
|
||||||
|
|
@ -515,15 +515,47 @@ components:
|
||||||
type: integer
|
type: integer
|
||||||
minimum: 0
|
minimum: 0
|
||||||
JobFailure:
|
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
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
required: [class, retryable, message]
|
required: [class, message]
|
||||||
properties:
|
properties:
|
||||||
class:
|
class:
|
||||||
type: string
|
type: string
|
||||||
enum: [validation, authorization, source_not_found, source_changed, transient_source, transient_target, integrity, capacity, internal, cancelled, lost_attempt]
|
enum: [authorization, source_not_found, source_changed, transient_source, transient_target, integrity, capacity, internal]
|
||||||
retryable:
|
|
||||||
type: boolean
|
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 500
|
maxLength: 500
|
||||||
|
|
@ -722,4 +754,4 @@ components:
|
||||||
kind:
|
kind:
|
||||||
const: failure
|
const: failure
|
||||||
failure:
|
failure:
|
||||||
$ref: '#/components/schemas/JobFailure'
|
$ref: '#/components/schemas/AttemptRuntimeFailure'
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ flowchart TD
|
||||||
|
|
||||||
- Every successful job is represented by one immutable `ResultManifest`. A single-object transfer uses a one-member manifest.
|
- Every successful job is represented by one immutable `ResultManifest`. A single-object transfer uses a one-member manifest.
|
||||||
- A manifest is the exact inventory of immutable member identities and carries sufficient integrity metadata to validate the aggregate.
|
- A manifest is the exact inventory of immutable member identities and carries sufficient integrity metadata to validate the aggregate.
|
||||||
|
- Manifest member paths are NFC-normalized relative POSIX segment sequences. Empty segments, dot segments, traversal, leading or trailing separators, and backslashes are invalid rather than normalized into aliases.
|
||||||
- Manifest construction uses memory bounded independently of member count and total result size.
|
- Manifest construction uses memory bounded independently of member count and total result size.
|
||||||
- Remora resolves a result only from its `CommittedResult`; it never derives one by listing a target bucket or prefix.
|
- Remora resolves a result only from its `CommittedResult`; it never derives one by listing a target bucket or prefix.
|
||||||
- An authorized reader may access committed members directly in `TargetStore` using exact manifest identities or time-limited URLs.
|
- An authorized reader may access committed members directly in `TargetStore` using exact manifest identities or time-limited URLs.
|
||||||
|
|
@ -127,7 +128,7 @@ flowchart TD
|
||||||
- Attempt-reported runtime failures carry a durable permanent or retryable disposition into `JobProtocol`. The model is the sole definition of how that disposition affects execution phase and attempt budget.
|
- Attempt-reported runtime failures carry a durable permanent or retryable disposition into `JobProtocol`. The model is the sole definition of how that disposition affects execution phase and attempt budget.
|
||||||
- Authorization, source-not-found, and source-changed runtime failures are permanent. Transient-source, transient-target, integrity, capacity, and internal failures are retryable. Unrecognized runtime errors map to a redacted internal failure.
|
- Authorization, source-not-found, and source-changed runtime failures are permanent. Transient-source, transient-target, integrity, capacity, and internal failures are retryable. Unrecognized runtime errors map to a redacted internal failure.
|
||||||
- Validation normally rejects submission before a job exists. Cancellation and lost attempts follow their dedicated `JobProtocol` behavior rather than a worker-selected failure disposition.
|
- Validation normally rejects submission before a job exists. Cancellation and lost attempts follow their dedicated `JobProtocol` behavior rather than a worker-selected failure disposition.
|
||||||
- All retryable work uses the model-wide attempt bound. Source adapters may vary connect, response-start, no-progress, bounded full-jitter, and bounded server-hint timing without changing that bound.
|
- All retryable work uses the model-wide attempt bound. Source adapters may vary connect, response-start, no-progress, bounded full-jitter, and bounded server-hint timing without changing that bound. Invalid or excessive server hints are ignored or capped; they never change a retryable disposition into a permanent failure.
|
||||||
- Remora has no elapsed wall-clock job deadline. Per-operation timeouts produce a structured runtime failure and remain subject to `JobProtocol`.
|
- Remora has no elapsed wall-clock job deadline. Per-operation timeouts produce a structured runtime failure and remain subject to `JobProtocol`.
|
||||||
- Public failure details are constructed from per-class allowlists. Credentials, upstream bodies, raw URLs, and internal exception text are excluded.
|
- Public failure details are constructed from per-class allowlists. Credentials, upstream bodies, raw URLs, and internal exception text are excluded.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue