Task Runs and Leases
How agents claim work, renew leases, finish runs, and release session-bound ownership safely.
- Audience
- Operators running durable agent work
- Focus
- Autonomy guidance shaped for scanability, day-two clarity, and operator context.
Task runs are the durable execution records for tasks. A run becomes claimable only after publish, start, approval, UI start, automation approval, or an equivalent API enqueues it. The task service is the only authority for run ownership and terminal state.
Claiming the next run
A managed agent session claims work either through the dedicated autonomy tool family or the parallel CLI. Both routes call the same task service writers and obey the same session-bound contract.
Tool path:
agh__task_run_claim_next { "wait": true, "lease_seconds": 300 }CLI path:
agh task next --wait --lease-seconds 300 -o jsonThe claim is atomic. AGH selects one eligible queued run, binds it to the current managed session, sets a lease deadline, and returns a synchronous claim response that includes:
- task summary
- run summary
- safe lease summary
claim_token_hashfor observability- coordination channel metadata when the run has a bound channel
The raw bearer lease token is internal to AGH. Public CLI, HTTP, UDS, native-tool, web, stream,
log, channel, and memory payloads use the calling session plus run_id and expose at most
claim_token_hash. Tools belonging to the agh__autonomy toolset reject any input or response
field that would carry a raw claim token.
Lease rules
The MVP lease contract is intentionally narrow:
| Rule | Behavior |
|---|---|
| One owner | Exactly one managed session may own a non-terminal run lease. |
| One active lease per session | A managed session may hold at most one active task-run lease in the MVP. |
| Session fencing | Heartbeat, complete, fail, and release resolve the internal lease from the caller session and run_id. |
| Bounded renewal | --lease-seconds must be zero or positive and is capped by the task service. Omitted or zero uses the service default. |
| Expiry recovery | Expired leases are recovered by boot recovery or scheduler sweeps through the task service. |
| Stale holders fail | A stale heartbeat or late complete after recovery fails explicitly; it does not extend or overwrite a newer claim. |
Heartbeat
Use heartbeat when work is still active and the session still owns the run.
Tool path:
agh__task_run_heartbeat { "run_id": "run-123", "lease_seconds": 300 }CLI path:
agh task heartbeat run-123 --lease-seconds 300Heartbeats are task-service operations. Do not mirror routine heartbeats into coordination channel messages unless a human-readable update is useful.
Completing a run
Use complete for successful terminal state.
Tool path:
agh__task_run_complete { "run_id": "run-123", "result": { "summary": "tests passed" } }CLI path:
agh task complete run-123 \
--result '{"summary":"tests passed"}'The optional result JSON must not contain raw lease credentials.
Failing a run
Use fail when the current claim cannot complete successfully.
Tool path:
agh__task_run_fail { "run_id": "run-123", "error": "tests failed", "metadata": { "command": "make test" } }CLI path:
agh task fail run-123 \
--error "tests failed" \
--metadata '{"command":"make test"}'Failure metadata must not contain raw lease credentials.
Releasing a run
Use release when the session should give up ownership without making the run terminal.
Tool path:
agh__task_run_release { "run_id": "run-123", "reason": "handoff" }CLI path:
agh task release run-123 --reason handoffRelease is also used by daemon-owned cleanup. For example, if a spawned child reaches TTL or its
parent stops, AGH releases active child leases with structured reasons such as ttl_expired or
parent_stopped before stopping the child session.
Deterministic autonomy errors
Lease writers and the autonomy tool bridge return the same deterministic reason codes:
| Code | When it fires |
|---|---|
AUTONOMY_SESSION_REQUIRED | The caller had no session scope; tool/CLI/HTTP/UDS reject the call before lease lookup. |
AUTONOMY_NO_ACTIVE_LEASE | The session does not currently own a run lease; nothing to extend or finalize. |
AUTONOMY_FOREIGN_RUN | The supplied run_id does not match the session's active lease. |
AUTONOMY_LEASE_EXPIRED | The lookup found a stale or expired lease and refused to mutate it. |
AUTONOMY_LEASE_ALREADY_HELD | claim_next was called while the session already owns an active lease. |
Lease credentials and channels
Never send raw lease credentials through agh ch send, agh ch reply, agh__network_send,
network envelopes, logs, or memory. If another participant needs to know progress, send a
coordination message. If a session needs to prove ownership, it calls one of the agh__autonomy
tools or the matching agh task command for the owned run_id; AGH resolves the internal lease
server-side.
Related pages
- Coordination Channels explains channel metadata and message kinds.
- Task CLI Reference lists exact command flags for the parallel CLI surface.
- Tool CLI Reference lists the operator commands for inspecting the registry, including the
agh__autonomyfamily. - Hooks lists task-run hook events.