Introduction

OverviewArchitectureAgent Experience

The product

This repository

Structure

Usage

Other

Concepts

Approvals and leasing

How a remote agent takes work without two agents taking the same work, and how a human gate stops a destructive action

Not built yet. There is no Approval table, no lease, and no endpoint to claim against. The Prisma schema still ships the template's stub model. This page describes the intended shape, taken from spec/01-domain-model.md and spec/03-agent-experience.md.

Two problems share one page here because they share one answer: work that leaves the record has to be able to come back. A lease is how work comes back when a machine dies. An approval is how work comes back when a human has to look at it first.

Leasing

A lease is a time-bounded right to work one Task. It is held by one Run, and it expires on its own.

  1. A runner calls tasks_claim with its agent id and a capability filter. The server picks the highest-priority ready task, sets status=in_progress, creates a Run, and returns a lease with a TTL alongside the full working context.
  2. The runner renews the lease by heartbeating while it works.
  3. Heartbeats stop past the TTL. The lease expires, the Run is marked abandoned, the Task returns to todo, and attemptCount increments.
  4. attemptCount past a threshold moves the Task to blocked, with an Event recording why.

A runner that stops heartbeating is assumed dead, not done. That assumption is the whole point: the alternative is a task that looks claimed forever because the workstation it was claimed on went to sleep.

The claim is atomic

Claiming is designed as a single conditional update:

UPDATE tasks
   SET status = 'in_progress', lease_id = $1, lease_expires_at = $2
 WHERE id = $3 AND status = 'todo' AND lease_id IS NULL
RETURNING *;

Two agents claiming at the same moment cannot both win. The one whose update matches no row gets nothing back and asks again. There is no read-then-write window to lose.

Heartbeat cadence

The write-back contract asks for a heartbeat at least every leaseTtl / 3. Three chances to report before the lease is judged dead means one slow network round trip does not cost a runner its work.

A heartbeat carries a progress percentage and a one-line human-readable status, so the lease is also the mechanism by which a human watching the board can see that something is still happening.

What leasing buys

  • Nothing double-runs. One Task, one live lease, one running Run.
  • Nothing is lost. An abandoned attempt requeues rather than disappearing.
  • Failure is visible. attemptCount rising is the signal that a task is not merely slow.

Approvals

An Approval is a human-in-the-loop gate. An agent requests one before a destructive or outward-facing action, and the Task sits in blocked until it resolves.

FieldNotes
questionWhat the agent is asking, in plain language.
options[]The choices offered. A free-text answer is not a decision the state machine can read.
decisionWhich option was chosen.
decidedByUserIdWho chose it. Recorded, like every other write in the system.
expiresAtAn unanswered approval does not hold a lease open forever.

When an approval is required

The workspace carries policy flags, requireApprovalForDestructiveTools among them. Beyond policy, the rule from the agent experience spec is that destructive and outward-facing actions require one, and that the approval is recorded rather than merely respected.

Outward-facing matters as much as destructive. Publishing, sending, deploying and posting are all things that cannot be taken back once done, even though none of them deletes anything.

Why options, not free text

An agent has to be able to act on the answer without interpreting it. options[] plus a decision naming one of them is machine-readable. A paragraph of guidance is a Comment, which is a different mechanism for a different job.

Blocking questions

A Comment posted with blocking: true and left unanswered also moves the Task to blocked. The difference from an Approval is what is being asked for:

  • Approval — permission to do something the agent already knows how to do.
  • Blocking comment — information the agent does not have and cannot obtain.

Both stop the work honestly rather than letting a runner guess and report success. Any feature that makes it easier to report success than to report a blocker is treated as a design defect.

Credentials are never the answer

An agent that needs a secret does not get one from an approval. No table in this model stores a secret value; only secretRef pointers to the real store. The agent receives the reference and resolves it on its own machine, which is the only place the value ever exists.