UHP lifecycle
The current normative UHP lifecycle from specification version 2026-09-28: how client and server agree on a version, how a client discovers capabilities, the states a task moves through, how sessions continue and delete, how progress streams, how cancellation and retries behave, and how artifacts are handed off.
Page reviewed 4 Oct 2026 Source and review policy
1. Protocol version negotiation
Section titled “1. Protocol version negotiation”A client recovery procedure
Section titled “A client recovery procedure”Track submission, observed response identity and terminal evidence as separate checkpoints. A dropped connection cannot tell you whether the server never received the request or received it and kept running.
| Last reliable observation | Safe next step | Avoid |
|---|---|---|
| No response identity was observed | Review advertised idempotency and operation effects before replay | Assuming a transport timeout means no task started |
Known response is in_progress | Read/follow that response until it becomes terminal | Starting a competing turn in the same session |
incomplete with partial output | Inspect budget cause, then decide whether to continue via the known response | Relabelling budget-limited work as completed |
failed | Preserve output/error and diagnose the cause before retrying | Losing partial evidence while creating a fresh task |
cancelled | Confirm stop evidence; continue the retained session only when appropriate | Assuming cancellation deletes session state |
This procedure applies the versioned lifecycle to client failure handling. It does not add an unspecified universal idempotency key or exactly-once guarantee. The session-recovery guide shows why durable history and active-turn ownership need separate evidence.
UHP versions are dates (YYYY-MM-DD), the day the version was published. A client MAY declare the version it was written against with the UHP-Version request header.
- If the header is absent, the server MUST assume its own default version and MUST state that version in the response header.
- If the header names a supported version, the server MUST honour it for that request.
- If the header names an unsupported version, the server MUST fail with
400andcode: "unsupported_protocol_version", and the errordetailMUST list the versions it supports. It MUST NOT silently serve a different version. - Every response, including errors, MUST carry the version actually used in the
UHP-Versionheader.
A current 2026-09-28 server may advertise older supported versions such as 2026-09-12 and 2026-08-11; a client that explicitly requests the older supported version must receive that version rather than being silently upgraded.
2. Capability discovery
Section titled “2. Capability discovery”GET /v1/uhp is served without requiring a bearer token so a client can confirm it is talking to a UHP server before presenting credentials. The document MUST NOT contain anything principal-specific.
The discovery object reports versions, default_version, conformance_class (core, extended, or full), and a capabilities object of named booleans (for example streaming, sessions, cancellation, files_input, files_output, session_listing, harness_management, session_sharing, idempotency, and plugins).
- A server MUST report
falsefor a capability it does not implement, rather than omitting it, so a client can tell “not supported” from “server is older than this field”. A client MUST treat an absent capability key asfalse. conformance_classMUST be consistent withcapabilities— for example, a server claimingextendedMUST reportfiles_input,files_output, andsession_listingastrue.pluginsis optional at every conformance class. Whenplugins: true, discovery MUST also includeplugin_schemas, identifying the Agent Plugins manifest schemas the server installs; UHP2026-09-12introduced Agent Plugins1.0.0as the package format.environmentsis optional at every conformance class. When false or absent, Environment-specific behavior is unavailable; when true, clients may use the Environments sub-protocol.
Reference-implementation note (not a protocol requirement): the discovery document MAY include a free-form implementation object for debugging. The protocol requires the base discovery fields; plugin_schemas is additionally required only when plugins is true.
3. Task and response lifecycle
Section titled “3. Task and response lifecycle”A task is one unit of work submitted to POST /v1/responses (with Authorization: Bearer <token> and Content-Type: application/json). Key request fields: input, model, metadata.harness_id, metadata.environment, stream, previous_response_id, instructions, store, max_output_tokens, max_step, timeout_seconds, tools, include, background. The server MUST ignore unknown request fields rather than reject the request, and current 2026-09-28 task semantics require ignored request fields to be named in metadata.ignored_fields.
The task state machine is small and well defined:
POST /v1/responses │ ▼ in_progress ──┬──▶ completed (terminal) │ ├──▶ failed (terminal; error explains why) │ ├──▶ incomplete (terminal; a budget stopped the work) └────────┴──▶ cancelled (terminal; client cancelled)| Status | Meaning | Terminal |
|---|---|---|
in_progress | Accepted and running. | no |
completed | The harness finished and produced a result. | yes |
failed | The task could not be completed; error explains why. | yes |
incomplete | The harness stopped at a budget (step or time limit) with partial output. | yes |
cancelled | The client cancelled it; partial output MAY be present. | yes |
Rules:
- A server MUST NOT transition out of a terminal state; later reads of a terminal response return the same terminal status.
incompleteMUST be used when a budget stopped the work, and MUST NOT be used for errors.- A
cancelledtask MUST reportcancelled, notfailed. - Terminal responses MUST retain whatever output was produced before they became terminal.
4. Session creation and continuation
Section titled “4. Session creation and continuation”- A session is created by the server when the first task of a chain runs; its id MUST appear in the response’s
metadata.session_id. - A session MUST preserve, across tasks in the chain: conversational context, the working directory and its files, and the configured harness.
- A task continues a session by sending
previous_response_id. Chaining on the response id names an exact point in the conversation.modelMAY differ between tasks; the server MUST honour a per-task model change. - A session MUST NOT be extended by a task naming a different configured harness. The server MUST fail with
409andcode: "harness_mismatch"rather than silently starting a new session. - Session expiry is server policy. On continuation, an expired session yields
404session_expired; an unknownprevious_response_idyields404response_not_found.
Listing, inspection, and sharing are class-gated: GET /v1/sessions and /turns are Extended; sharing (POST/GET/DELETE /v1/sessions/{id}/share) is Full and MUST be read-only, revocable, and MUST NOT expose credentials or another principal’s data.
Session deletion
Section titled “Session deletion”The current 2026-09-28 sessions chapter retains the Full-class session-delete operation explicitly:
DELETE /v1/sessions/{session_id}Deletion MUST cancel any in-flight task first, remove the session’s stored transcript, trace and working folder, stop that deleted state counting toward enforced storage or memory allowances, answer 2xx, and make a subsequent GET /v1/sessions/{session_id} return 404. Any published share must stop resolving as part of the same lifecycle boundary.
DELETE /v1/traces/{session_id} is the older name for the same operation. A server MAY keep it as a compatibility alias; HarnessRouter does, but clients SHOULD use the protocol-named /v1/sessions/{session_id} path.
5. Streaming behavior
Section titled “5. Streaming behavior”With stream: true, the server responds with Content-Type: text/event-stream and emits Server-Sent Events whose data is one JSON object each.
- Every event MUST carry
typeandsequence_number;sequence_numberMUST start at0and increase by exactly 1 per event. - The stream MUST end with exactly one terminal event:
response.completed,response.incomplete, orresponse.failed. Each carries the complete final response object. - The server MUST NOT buffer the stream to completion; it MUST send events as they happen.
Ordering guarantees: response.created is first; exactly one terminal event is last; for any item, output_item.added precedes every event referring to it and output_item.done follows them all; sequence_number is strictly monotonic with no gaps. A client MUST NOT assume items complete in order, a particular text chunk size, or that optional event types appear.
A dropped connection MUST NOT abort the task; work continues server-side. A client can re-read GET /v1/responses/{response_id}. A server MAY support SSE Last-Event-ID resumption. Non-streaming returns a single response object at the terminal state with identical results to the stream.
6. Cancellation semantics
Section titled “6. Cancellation semantics”Cancellation has two deliberate scopes:
| Endpoint | Scope |
|---|---|
POST /v1/responses/{response_id}/cancel | Stop this task. |
POST /v1/sessions/{session_id}/cancel | Stop whatever is running in this session. |
- Cancellation is a request, not a guarantee of immediacy. A server MUST stop the work as soon as it can and MUST reach a terminal state.
- A cancelled task MUST end with
status: "cancelled", neverfailed. - Output produced before cancellation MUST be retained.
- Cancelling an already-terminal task MUST succeed and change nothing.
- Cancelling MUST NOT delete the session; the conversation remains continuable. A server SHOULD respond to cancel within one second even if the harness takes longer to wind down.
Deletion is the one place cancel and delete are coupled: DELETE /v1/sessions/{session_id} MUST cancel any in-flight task first and then make the session unreadable. The older /v1/traces/{session_id} path is only a compatibility alias where implemented. A bare DELETE /v1/responses/{response_id} deletes stored response history but MUST NOT cancel a running task.
7. Incomplete versus failed work
Section titled “7. Incomplete versus failed work”Both are terminal, but the protocol distinguishes them because a client should treat them differently:
| Status | Trigger | Client guidance |
|---|---|---|
incomplete | A budget (max_step or timeout_seconds) stopped the work, with partial output retained. | Usually worth continuing. |
failed | The harness could not complete the work; error explains why. | Usually not worth retrying unchanged. |
max_step and timeout_seconds are budgets, not precise guarantees. A task that reached failed is reported as a response with status: "failed" and HTTP 200; that is distinct from a non-2xx error envelope, which means the request itself failed.
8. Artifact and file handoff
Section titled “8. Artifact and file handoff”Input files enter a task as inline input_file/input_image items or a file_id from a prior upload. Output artifacts surface as annotations on message content; they are addressed by container_id / file_id and downloaded via GET /v1/containers/{container_id}/files/{file_id}/content, listed via GET /v1/sessions/{session_id}/files, and bulk-fetched via GET /v1/sessions/{session_id}/files/archive.
Because artifacts are attacker-influenced content, normative handling rules live in the security model. The lifecycle concern is that partial output is retained through terminal states and erased when the session is deleted.
9. Retries, continuation, and idempotency
Section titled “9. Retries, continuation, and idempotency”- Continuation — sending
previous_response_idstarts a new task that reuses the session’s context, working directory, and harness. - Retry after failure —
server_erroris retryable with backoff;rate_limitedafterRetry-After;session_busyafter the in-flight task is terminal;invalid_request_errorandauthentication_errorare not. - Idempotency — when the server advertises
idempotency, a repeatedIdempotency-KeyonPOST /v1/responsesMUST return the first result without starting a second execution. Keys SHOULD be retained for at least 24 hours.
Reference-implementation note: a second concurrent task in the same session is rejected with 409 session_busy; the server SHOULD include retry_after_ms when it can estimate it.
10. Adjacent IETF work: Agent Communication Protocols (agentproto)
Section titled “10. Adjacent IETF work: Agent Communication Protocols (agentproto)”The IETF Agent Communication Protocols (agentproto) effort is relevant to the same broad lifecycle problem space, but it is not a UHP specification source. As of 25 August 2026, the IETF Datatracker lists agentproto in BOF state with no charter; its approved IETF 126 BOF request describes the effort as WG forming and proposes framework/protocol-building-block work for cross-vendor agent and tool communication, including long-lived sessions.
An individual Internet-Draft, draft-feng-agentproto-session-requirements-02 (20 Aug 2026), defines requirements rather than a solution for bilateral agent/entity sessions and sessionless interactions. No dependency, adoption, or standardized binding between UHP and agentproto is established.
11. What the specification does not define
Section titled “11. What the specification does not define”2026-09-28 defines no separate queued or pending task state before in_progress; submission is either accepted or rejected with an error envelope. There is no resume-in-place of an interrupted task — recovery is a new task chained via previous_response_id. The protocol does not specify runner-internal states, exact timeout enforcement granularity, or cross-stream sequence_number continuity.
The 2026-09-12 addition of Harness Plugins does not create a second task lifecycle. Plugin installation/composition is a harness-management concern; tasks still use the five response states above.
Related pages
Section titled “Related pages”Read the HTTP API map, Harness Plugins, security and trust boundaries, conformance, architecture, the specification guide, governance and versioning, and the glossary.