Skip to main content

Chains

How far a continuation has run, and whether it is still spending.

Overview​

A continuation chain is the population of generations that descend from one root because each continued the one before it. A chain opens the first time a generation continues another — an approved or expired tool call, a resumed session — so an ordinary one-shot generation is not a chain and gets no record. Gate a tool with guardrails approves a held call and reads the continuation it starts.

The module is read-only. There is nothing for a caller to create, and the size a chain may reach is set on the agent, not here.

This module is a verbatim mirror of the runtime: every field, method, status code and error shape is the runtime's own, re-rooted under the project in the path.

See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Chains.

Data Model​

Chain​

FieldTypeDescription
idstringPublic chain ID (chain_ prefix).
project_idstringThe owning project.
agent_idstring, nullableThe agent whose continuation opened the chain. Its origin, not an owner.
statusstringactive, concluded, expired or budget_exhausted.
generation_countintegerGenerations in the chain, the root included.
last_generation_atstring (date-time), nullableWhen the chain last gained a generation.
created_atstring (date-time)
updated_atstring (date-time)

Key Concepts​

The record describes the chain; it does not bound it​

generation_count and status are observability. The ceiling is enforced by counting the chain's member generations directly at the moment a hop is attempted, so a stale or missing chain record can never let a runaway through.

The ceiling itself is an agent stop condition — {"type": "max_chain_generations", "max_generations": <n>} — and the deployment carries its own limit. The effective ceiling is the smaller of the two, so an agent can be stricter than the platform but never looser. A hop refused by it stops with chain_limit, and the chain reads budget_exhausted afterwards.

concluded is not terminal​

A chain is concluded when a member finished with nothing left pending. That is a description of right now, not an ending: an approval decided months later can spawn another hop and put the same chain back to active. Only budget_exhausted and expired describe a chain that stopped for a reason.

expired means a held approval lapsed and the agent does not react to expiry, so nothing resumed the chain.

A chain can span agents​

agent_id names the agent whose continuation opened the chain, and later hops may run on others. It is held as a plain id rather than a reference the platform maintains, so deleting the agent leaves the chain record intact.

Expanding a chain into its members​

The chain record carries the count, never the generations. To read them, filter GET /v1/projects/{project_id}/generations by chain_id. Every member carries the same chain_id — the continuations and the root they descend from — and it is null on a generation that is not part of a chain. Traces carry it too, so one filter follows a chain through either surface.

Examples​

Find the chains that may still be spending​

naturali list-chains \
--project-id proj_V1StGXR8Z5jdHi6B \
--status active

Read one chain, then its generations​

naturali get-chain \
--project-id proj_V1StGXR8Z5jdHi6B \
--chain-id chain_V1StGXR8Z5jdHi6B

naturali list-generations \
--project-id proj_V1StGXR8Z5jdHi6B \
--chain-id chain_V1StGXR8Z5jdHi6B

Spot a chain a budget stopped​

naturali list-chains \
--project-id proj_V1StGXR8Z5jdHi6B \
--status budget_exhausted