> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formation.texturehq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Commitments

> Track durable work, verify outcomes, and manage blocked or unfinished tasks.

A commitment is a task Formation keeps track of until its outcome is verified or the
work is explicitly closed. It can survive the conversation turn that accepted
it, so an agent can continue an investigation, finish a document, or wait for an
external result without relying on someone to send another message.

A successful **run** means one turn finished. A completed **commitment** means
the task's required outcomes have been checked. For recurring reminders and
read-only briefings, use [schedules](/runtime/schedules.md).

## Enable commitments

Commitments require PostgreSQL, an enabled agent, and the Formation run worker
(`MESH_RUN_WORKER_ENABLED=true`). New agents created through the dashboard or
operator API enable commitments automatically when the commitment service and
run worker are available. Existing agents keep their setting. Check the agent's
**Commitments** page; if commitments are off, choose **Enable commitments**.
A failed automatic setup leaves them off without failing agent creation.

Turning commitments from off to on also enables **Capture accepted tasks** and
requester retraction. These settings can be adjusted afterward. Re-enabling
commitments applies those defaults again; review the settings after a pause.

Incoming task capture has three modes:

| Dashboard choice | API value | Behavior |
| - | - | - |
| Off | `off` | No automatic incoming-task classification; existing commitments remain recorded. |
| Evaluate only | `shadow` | Record classifications without accepting tasks or asking clarification questions. |
| Capture accepted tasks | `enforce` | Record confidently classified assignments before work starts; answer other messages as ordinary turns. |

In capture mode, “Can you prepare a deployment checklist?” can create a task;
“What does this setting mean?” can remain an ordinary question. A possible task
or low-confidence classification also reaches the agent as an ordinary turn.
The agent can ask a question when it needs more context; classifier uncertainty
alone does not produce a clarification question.

Classification uses the configured [Decision model](/runtime/decision-models.md),
or the classifier text model when no native Decision route is configured. An
unavailable classifier fails open: the message reaches the agent as an ordinary
turn, and the intake records
`classifier_unavailable` so the outage is visible. A turn interrupted after
classification still leaves its intake pending for bounded recovery.

The agent can also register work explicitly. When commitments are enabled,
workspace actions and external mutations require task ownership even when
automatic capture is off or in shadow mode. Read-only questions remain usable
without a task. Registration defaults to outcome criteria and owns the rest of
the current run, including its settlement and bounded automatic continuation.
With capture enforced, a clear
request ("Great, prepare a PR please") becomes a task before the agent replies,
so the agent does the work without asking first. A follow-up promise found only
in the agent's reply is delivered with an offer after the answer, and only the
person's assent grants autonomous work; one request never authorizes other work
the reply volunteers. An offer from a turn that failed before sending it, or
whose send failed, never reached the person, so it is never resolved and
simply expires. The answer itself is never replaced. Clear accepted
assignments and explicit task registration use their own authorization paths.
Confirming a proposal with “yes” or “all of them” starts eligible work in that
same turn, within the turn's allowance. Work already owned by another run stays
with that owner; Formation reports work that can no longer start.

## What happens after a task is accepted

Formation records the original request, its audience, the required outcomes, a
deadline, and an execution allowance. Foreground turns and background attempts
share one task owner. A compatible follow-up can attach to the existing task;
uncertain matches reach the working model with the saved association decision.
The model reads the request and conversation, then asks a specific question if
it still needs to distinguish existing work from a separate task. Uncertainty
does not pause the task or produce a canned authority-check reply. Replaying
the request during verification or recovery reuses its saved decision rather
than treating the request as an answer to its own clarification. If the model
answers without an association question, that advisory intake is retired. An
unavailable or uncertain question tracker also retires it and preserves the
reply. When the association
classifier is unavailable, the message is answered as an ordinary turn and the
intake records `association_unavailable`. A candidate that changes while the
classifier is deciding, or another request reserving task admission, also
defers matching to the working model without admitting the stale match.

Task intake and association decisions have explicit next steps:

| Decision | Next step |
| - | - |
| Intake says ordinary, possibly a task, or cannot classify | The working model handles the message. |
| Association selects a new task or an available existing task | Persist ownership, then run the working model. |
| The existing task already has an active worker | Durably queue the follow-up for that worker and acknowledge it. |
| Association needs clarification, has low confidence, or its candidate changes | Pass uncertainty to the working model to answer or ask a specific question. |
| A clarification answer identifies new or existing work | Admit that checked task, or queue the follow-up for its active worker. |
| A clarification answer withdraws the request | Acknowledge the withdrawal without starting work. |
| A clarification answer is unrelated, ambiguous, or cannot be classified | Handle it through normal intake or the working model. Repeated ambiguity retires the old association question. |
| Reply tracking confirms an actual association question | Keep the model's question pending for the person's answer. |
| Reply tracking sees an ordinary answer, explicit registration, or an unusable verdict | Retire the advisory intake and preserve the reply. |

Verification and delivery reuse these saved decisions. Retrying verification of
a settled attempt preserves its answer without reopening the finished workspace.
Classifier uncertainty does not mean task authority was revoked. Cancellation,
source-access revocation, lost execution ownership, and uncertain external
effects still require their own recovery checks before more actions can run.

Repeated identical offers for the same requester, conversation, audience and
completion contract reuse pending or open work. Confirming several matching
offers starts one task, while preserving each request's own source permissions.
Different completion contracts and explicitly closed work remain separate.
Matching text or a retry cannot replace previously accepted completion criteria.
A source that was never accepted cannot attach to completed work.

The background reconciler checks for work that can proceed. New conversational
input takes priority over the next background attempt. Unchanged external waits
do not spend a working-model attempt. Restarts preserve the task record and its
progress, subject to current authorization and execution limits.

Completion depends on the requested outcome. Exact predicates can be checked
against recorded query results. Semantic outcomes use independent verification
of the actual reply or artifact; more complex evidence uses a separate richer
verifier. The agent's own claim that it finished is not sufficient. Changed
criteria, stale evidence, or unread updates prevent an old verdict from closing
the task.

For example, “draft a release note” can finish with a verified draft. “Publish a
release note” needs evidence of publication, within the permission originally
granted. Creating a pull request does not by itself prove a request to merge or
deploy is finished, and a commitment does not grant permission to merge or deploy.

## Waiting and operator actions

The Commitments page shows each task's status, required outcomes, evidence,
activity history, and next steps. Common states include `open`, `in_progress`,
`waiting`, and `completed`; closed work can be `cancelled`, `failed`, or
`closed_incomplete`. Older or stalled tasks can also show `stalled` or `escalated`.

A waiting task records why it cannot proceed: human input, external state,
access, execution allowance, deadline, or an uncertain external write. Human
questions identify the recipient and the answer or action needed. A reply can
unblock work without claiming the whole task is complete.

A final answer does not end an accepted task. A criteria task with unmet or
unconfigured criteria schedules another attempt within its existing allowance,
even when the worker voluntarily returned a partial answer. Its successor gets
the previous artifact, current criterion verdicts, and a next-action instruction.
Foreground answers still reach the person; ordinary background progress stays
quiet. Verification runs once at settlement, and the next attempt uses those
recorded results to repair the work.

A person is needed only for a recorded input, access/permission request, or
explicit attestation criterion. External waits record their condition and wake
when evidence changes. Legacy `operator_ack` contracts retain their explicit
requester-confirmation behavior; missing criteria never creates that contract.
Previously parked legacy waits are not silently reauthorized by an upgrade.

Three consecutive attempts without advancing verified outcomes pause execution
as `escalated` with a recovery reason. Before that pause, successor context asks
for a different approach. Changing the worker's prose or repeating tools does
not count as verified progress. This is a liveness stop, not an invented missing
human input or completion. A substantive new direction or an operator resume
can try again within the remaining grant; cancellation and exhausted grants
remain authoritative.

For a single accepted criteria task, unpublished workspace files are checkpointed
under the task's own lineage before settlement schedules a successor. Capture
failure retains the live tree for that task, bounded by its deadline and a
fourteen-day retention window. Provider-side loss can still destroy a live tree;
the agent must inspect actual files and recorded external effects on resume.
See [Workspace snapshots](/runtime/snapshot-lineage.md) for isolation and retention.

Operators can:

* **Resume bounded work** when an existing allowance and deadline still permit it.
* **Increase allowance or revise deadline** for a nonterminal task with a
  criteria contract, with an attributed reason. Prior usage remains counted.
* **Record a confirmed write result** after checking an external operation whose
  outcome was uncertain. Formation reconciles that result before another write.
* **Close as incomplete** or **Cancel follow-up**, keeping the task's history.
* **Attest completion** only for a task whose evidence contract explicitly allows
  operator acknowledgment.

A tool response can be recorded while its external operation still needs
confirmation. For example, accepting an asynchronous job does not prove that job
finished. The dashboard includes these recorded actions in **Record an external
action’s result** while they still hold a target. Confirm only the exact
operation you verified; this releases its reservation without repeating it or
marking the whole task complete. Other dependencies remain in force.

New tasks default to a seven-day deadline, 12 attempts, and 480 reserved model
iterations. Each background attempt uses the agent's normal turn profile,
iteration setting, and wall clock, capped by the task's remaining allowance and
deadline. For nonterminal tasks with criteria contracts, operators can grant
total limits up to 48 attempts and 5,760 iterations. New and revised deadlines
may be any future date; there is no 30-day lifetime ceiling. Review dates may
also be more than 30 days away. These calendar dates do not raise execution
allowances or individual run limits. An agent can have up to
100 nonterminal commitments.

The agent detail page's **Run limits** controls apply to newly admitted runs:
2–120 model calls and an independent 60–14,400-second wall-time backstop. Blank
uses the profile default (60 work calls or 4 conversation calls; 1,800 seconds).
Tool and token limits scale with the model-call setting. Existing running attempts
keep their admitted limits.

Lifetime accounting reserves the full admitted iteration limit, not just calls
actually used. Thus a new 480-iteration task allows eight full 60-call attempts
or four full 120-call attempts, subject to the separate attempt/deadline limits.
Increasing per-run limits does not increase a task's total grant.

Retry does not renew these limits. Existing tasks keep their previously granted
allowance after an upgrade; an operator must explicitly grant more when needed.
A request to continue work does not itself reset its allowance or expand tool
permissions.

## Open-task limit

An agent holds at most 100 open (non-terminal) tasks, counting every status
other than completed, failed, cancelled, and closed incomplete. Every creation
path enforces the limit inside its write, so a burst of requests cannot
overshoot it. At the limit a new request is answered as an ordinary message
and not recorded: the agent is told the task was not recorded and why, so it
can say so; a captured incoming task is released with failure kind
`capacity_exhausted`; and the Commitments page shows the agent as full, with
the count in the operator API's `capacity`. Nothing is recorded again until
open tasks finish, are closed by an operator, or are cleared (below). Tasks
that are waiting or escalated count against the limit, so a backlog of stalled
follow-ups can fill an agent that is otherwise idle.

## Clearing pending work

Disabling commitments pauses them and preserves open work, unsent notices, and
unanswered proposals. If any are pending when you enable commitments again,
the dashboard offers **Resume existing work** or **Start fresh**.

**Clear pending work** cancels all nonterminal commitments, withdraws unsent
notices, and discards unanswered proposals. Committed task records and activity
history remain available, attributed to the operator who cleared them. Starting
fresh performs this cleanup before enabling the feature. Clearing is also
available while commitments are disabled.

Requester retraction lets a person's stop request cancel their own eligible idle
follow-ups in that conversation. It does not withdraw other people's requests
or undo effects that have already happened.

## External assignment sources

Commitments can discover assigned work through approved, agent-owned MCP
connections. Configure an assignment source on the Commitments page with its
verified account and tenant, read queries, identity mappings, and a real delivery
conversation. Saving or editing a source leaves it disabled. Run a complete
preview before enabling its assignment policy.

A partial scan is not evidence that no work exists. Discovered assignments that
exceed the agent's task capacity remain deferred and are retried when capacity is
available. Source health reports this backlog separately from scan coverage.

Disabling a source withdraws the authority that source granted. Independently
authorized requests remain owned. Re-enabling a source does not silently revive
cancelled or withdrawn tasks. Completed tasks do not become indefinite monitors.

## Privacy and notifications

Each request retains its own audience and permissions. Recognizing the same issue
or artifact in two conversations does not grant either audience access to the
other's instructions or evidence. Shared-memory revocation also prevents reuse
of dependent protected history.

When you start a turn, you receive the agent's answer even if the task is still
unfinished. Delivering that answer does not mark the task complete: completion
still requires its recorded evidence. Cancellation and audience permissions
continue to apply.

Commitment bookkeeping does not take away a person's response. Before a task
starts, an admission or association failure falls back to an ordinary turn;
actions still require their normal task ownership and tool permissions. A
promise that could not be recorded goes out untracked. After the agent has
answered, a bookkeeping failure preserves the answer when current authorization
allows it. A changed task or revoked source stops obsolete execution and gives
the person a safe explanation without repeating work or exposing withheld text.
Background attempts keep their task-owned settlement and notification behavior.

Registration refresh preserves every task already admitted to the turn. If an
earlier task changes or loses authority, refresh refuses instead of dropping its
restrictions. Failed workspace or tool setup leaves the prior task authority and
continuation unchanged. A background run stays background when it registers
another task; task ordering and later ownership changes cannot make it a
person's turn.

Background attempts stay quiet during routine work. They notify you of a
verified result, delivered work awaiting confirmation, a question the task
needs answered, a concrete dependency, or work that has stopped without
finishing. An uncertain external write asks for
its outcome to be checked before another attempt. Retries, backoff, and other
internal bookkeeping stay in the activity history.

Formation delivers verified results independently to each authorized origin. A
failure to notify one recipient does not undo verified work or repeat notices to
recipients already reached. Results and proof that cannot be disclosed to an
origin are withheld.

A task's recorded sources — the earlier messages, memories and tool results
the agent had in view when it accepted the request — are re-checked against
the task's own conversation and audience before every attempt and notice. When
that check refuses, the refusal is final for that row, and it is reported
rather than retried: at admission the request is not recorded and the agent
answers as an ordinary turn (its own `commit_to_task` gets the reason back and
can say so); an already recorded task stops as `failed` with a reason naming
the kinds and counts of refused sources ("2 earlier messages, 1 memory"), and
a finished task owed a notice keeps its status with the notice withheld. The
dashboard detail view shows the same reason. Contents are never named: the
refused text is exactly what must not reach that audience.

External writes still depend on tool authorization and recorded outcomes. Formation
cannot guarantee exactly-once arbitrary shell commands or remote operations;
an unknown write result requires reconciliation before retry.

## Reconciler watchdog

The deployment needs a worker that runs between HTTP requests. Inspect the
Commitments page for due work and heartbeat health. An independent monitor can
use `GET /api/commitments/health` or the repository's
`scripts/check-commitments.sh` with a read-only API token. The endpoint returns
503 if the enabled reconciler has no heartbeat within two minutes or dispatch is
over five minutes overdue.

It also returns 503 when any agent has left a message without a reply, whether
or not commitments are on. `unanswered` counts messages from the last day that
started a turn, or whose admitted work failed, went stale, or could not be
routed to its agent before a turn started, are more
than ten minutes old, and whose turn delivered no reply. A failure notice is
not an answer, and an unrelated later message does not count; `oldest_unanswered_seconds` is the oldest one's
age. A turn still working, a turn the person stopped (their "stop" is
recorded against it; any other cancellation does not count), a turn the model
deliberately left silent, a disabled agent, and an install-wide stop are not
counted. The agent's Commitments page shows the same
count, so an agent that stops answering is caught in minutes rather than hours.

See the [operator API](/operator-api.md#durable-commitments) for settings, task
actions, source previews, and health responses. Maintainers can read the
[completion runtime reference](https://github.com/TextureHQ/formation/blob/main/docs/runtime/commitment-completion.md)
and [ownership reference](https://github.com/TextureHQ/formation/blob/main/docs/runtime/commitment-ownership.md)
for execution and verification contracts.

Commitment tool input refusals, including date validation performed against the
transaction clock, are returned to the model as recoverable tool observations.
The agent can correct the input or explain it and still reply to the person.
This applies to registration, criteria configuration, resource binding, and wait
controls. Database failures, cancelled tasks, and lost execution leases retain
their existing failure/fencing semantics; an input refusal is not permission to
continue a cancelled execution or ignore an uncertain external write.

### Agent-driven backlog cleanup

A person can ask an agent to investigate and clean up its commitments instead
of reviewing each dashboard row manually. `review_commitments` pages through
active work using a stable `next_after` cursor, including work from other
conversations only when every retained source permits disclosure into the
current audience. A specific commitment ID returns its immutable completion
criteria and linked resources. Empty pages can still have a continuation cursor;
continue until the cursor is absent. Closing rows does not skip later pages.

`resolve_commitments` applies up to 20 individual, versioned decisions and returns
a result for each. A stale, unavailable, or unverifiable task does not stop the
rest of the sweep. Both tools work at the task capacity limit without registering
another commitment. They derive the person from the executing run's authenticated
inbound message; the model cannot supply an operator identity or another agent ID.
Background attempts, scheduled occurrences, and notice/question runs cannot borrow
a historical requester to invoke these tools. Foreground accepted tasks retain
the tools when a person is actually waiting for that cleanup turn.

* `verify` imports fresh, successful query receipts from the current run and
  independently checks the existing rubric against every accepted request. The
  runtime finds receipts matching each declared tool and its exact arguments;
  the model need not supply database IDs. Explicit receipt IDs are optional. It
  cannot rewrite criteria, count a claim as external evidence, ignore an unknown
  write, or take over an active execution. A merged PR proves only the requested
  outcomes it actually satisfies. Human-attestation requirements remain human
  requirements. Missing/unconfigured evidence leaves work open and reports why.
* `cancel` ends obsolete work under the person's cleanup instruction.
* `close_incomplete` records an explicit decision to end unfinished work.

Cancellation and unfinished closure require the requesting person to control
**every live origin**, not merely be able to see the objective. Each transition
retains the originating message, actor and individual reason. Linked external
issues/PRs are inspected through the agent's existing authorized tools; these
management verbs do not themselves close issues, merge PRs, raise execution
allowances, or send an extra notice for every cleaned-up row. They preserve
history and the unknown-write journal. A partially successful batch is safe to
inspect and retry: completed transitions have new versions and cannot be applied
again against the old snapshot.

Daily workload reviews at every workload size, an additional immediate review
on first reaching 20 active tasks, a per-agent destination picker from existing
DMs and channels, guided issue-tracker selection, mandatory issue creation/linking,
and selective dashboard bulk cleanup remain follow-up work; these management
tools alone do not schedule a standup.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.