Just-in-time checkpoints
Checkpoints are declarative gates inside activities that halt the workflow until an external condition is met — usually your explicit confirmation. The agent cannot skip past one: the server records the active checkpoint in session state and refuses to advance until it is resolved.
Canonical source: docs/checkpoint_model.md.
Where you stay in control
A checkpoint is a step where the workflow deliberately stops until you decide something: approve a design, pick an option, confirm a commit.
Single-agent flow
Your choice can set workflow variables — picking "skip the audit" or "include migration" changes which activities and steps run afterwards. Some checkpoints define a default option and can auto-advance after a timeout; the server still enforces the timer.
Multi-agent bubble-up
Background workers cannot ask you questions directly, so a checkpoint bubbles up the agent hierarchy to the user-facing agent, and the resolution travels back down.
resume_checkpoint (8) before continuing.Yielding
When a worker reaches a checkpoint step it calls yield_checkpoint. The server records the checkpoint as activeCheckpoint in session.json and mints a one-shot, HMAC-signed checkpoint_handle. The worker emits the handle in a <checkpoint_yield> block in its final output and stops; the orchestrator relays the block upward without interpreting it. A new checkpoint cannot be yielded while one is already active — nested yields are a hard error.
Resolving
The meta orchestrator calls present_checkpoint to fetch the human-readable message, options, and effects, presents the decision through the host UI, then finalizes with respond_checkpoint in exactly one of three modes:
| Mode | Meaning | Server enforcement |
|---|---|---|
option_id | You selected an option | Option validated against the definition; minimum response time (default 3s) blocks instant self-resolution |
auto_advance | Timer elapsed, use the default option | Only for checkpoints with autoAdvanceMs; the full timer must have elapsed since the yield |
condition_not_met | Conditional checkpoint's prerequisite is false | Only valid when the checkpoint defines a condition |
The server clears activeCheckpoint, records the decision and any variable effects (e.g. setVariable: { is_monorepo: true }) in the session state, and returns the effects to the caller.
Resuming
Agents wake in reverse order using the host's resume mechanism, with effects passed down as plain instructions. Before the worker can touch regular tools again it must call resume_checkpoint — a hard gate that verifies the checkpoint really was resolved and hands back the recorded variable updates. In inline (single-agent) execution the wake is a no-op persona switch; the server-side gates are identical.
Shared checkpoint fragments
A checkpoint reused at several sites is declared once as a checkpoint fragment under fragments.checkpoints in the owning workflow's workflow.yaml. Each use site is a kind:checkpoint step carrying only its site-local id and ref: [workflow::]name — plus a condition when the fragment declares none. The loader materializes the fragment body into the step before delivery, so yield, present, respond, and every downstream consumer see an ordinary full checkpoint. The check:fragments guard rejects an inline body that duplicates a declared fragment.
Why this design
- Pause and presentation are separate — the worker records the pause with
yield_checkpointand steps aside; the user-facing agent later presents and responds. Nothing advances past an unresolved checkpoint, wherever it was raised. - Clean UI boundaries — hidden background agents never prompt you directly, so nothing freezes waiting on an invisible question.
- Stateless hand-offs — the signed handle carries the linkage; intermediate agents relay it without parsing or storing checkpoint details.
- Timing enforcement — minimum response times and server-enforced auto-advance timers prevent an agent from "answering" its own checkpoint instantly.
- Effects as data — your choice mutates workflow variables through declared effects, which is what makes deterministic transitions possible.