pub async fn worker_degradation(
__arg0: State<AppState>,
headers: HeaderMap,
__arg2: Json<DegradationBody>,
) -> Result<StatusCode, ApiError>Expand description
POST /v1/worker/degradation (GH #32). Bearer = same short-handle /
full-CapToken forms as worker_submit. Body = JSON, not raw bytes —
this endpoint carries structured data, unlike its raw-bytes siblings.
Independent channel: appends a DegradationEntry to
RunRecord.degradations via RunStore::append_degradation directly.
Never touches OutputStore / the fold path (Crux invariant 2 — a
degradation must not surface as step OUTPUT / $.step.parts).
Behavior:
task_idis auto-looked-up server-side from the token/handle, same asworker_submit/worker_artifact.- GH #37 terminal-run guard applies first — a degradation addressed at
an already-terminal Run is rejected with
410 Gone([reject_if_run_terminal]), same as a submit/artifact would be. step_ref/attempt/atare server-injected —step_refis the fetching agent’s resolved name (AgentContextView.agent, the best proxy forStep.refavailable at this layer),attemptis the task’s current attempt,atis now (Unix epoch seconds). The client body never supplies any of the three.- No Run linkage in
agent_ctx(a pre-run-tracking dispatch), an unparseablerun_id, or anappend_degradationcall against a Run the store doesn’t actually hold (RunStoreError::NotFound— the same condition [reject_if_run_terminal] itself fails open on) all take the same silent204 No Contentpath, logged viatracing::warn!— this is a legitimate no-tracking codepath, not a client error. Any otherRunStorefailure propagates asApiError::engine.