Agent Task Contract
Any consumer that runs a bounded agent task on runGovernedAgentLoop (a hosted executor, a
third-party builder, a self-hosted project) gets the same run contract from the Agent Runtime Pack.
Hosting (HTTP routes, webhooks, storage) stays with the host.
createAgentTaskRun() returns the loop hooks and a guarded runtime:
Step records
Section titled “Step records”AgentTaskStepRecordSchema (zod) validates every step: step_id, index, kind
(model_call or tool_call), intent_text, action_summary, status
(completed, failed, denied, expired), evidence_refs, cost_usd (null when the price or
usage is unknown) and started_at/ended_at. run.steps() returns them in start order.
Budgets
Section titled “Budgets”AgentTaskLimits has max_steps, max_cost_usd and max_duration_s. They are checked before
each model call. A hit stops the loop with the reason code budget_exhausted, names the limit and
hands the host a resumable AgentTaskCheckpoint (steps, receipts, spend, elapsed time, history).
A cost cap with an unknown cost stops too, never a silent continue. Cost comes from the trusted
per-model prices in agent_runtime.models through usageCostUsd. To resume, create a run with
resume: checkpoint and start the loop with run.resumeMessages().
request_user gate
Section titled “request_user gate”createRequestUserGate() raises an approval bound to {task_id, step_id, action_hash, tenant_subject, actor_ref, expires_at}. A guarded tool call whose manifest declares an
approval_class holds the loop until a decision arrives. gate.resolve() refuses a different
action_hash (ACTION_HASH_MISMATCH), a different tenant_subject (TENANT_SUBJECT_MISMATCH), a
second resolve (ALREADY_RESOLVED) and a late one (APPROVAL_EXPIRED). An approval that expires
denies, and the tool does not run.
Approval classes
Section titled “Approval classes”Classes are read from agent_runtime.approval_classes (see
Configuration). Narrower policies
(per tenant or tool) can ask, deny or shorten expiry; none can auto-approve a class whose
auto_approve_allowed is false.
Resume without repeating effects
Section titled “Resume without repeating effects”A completed side-effecting step is stored as a hash-chained receipt keyed by call id and action hash. A resumed run that sees the same call returns the stored output and records a replayed step; the effect does not run again. A checkpoint whose receipt chain does not verify is refused.