Autonomy Budgets
Autonomy budgets limit a Touba run. They refuse execution that would exceed a bounded scope: run duration, runtime steps, tool calls, agent invocations, or agentic decision-provider calls.
They bound the Touba runtime contract. Provider billing, token accounting, team quotas, and regulatory compliance are separate accounting and governance layers.
Spending through a host transport can be bounded separately with the SDK monetary ledger.
Usage Syntax
In Touba source
module examples.bounded
limits run
max_run_ms as 30000
max_steps as 100
max_tool_calls as 20
max_agent_invocations as 5
max_provider_calls as 10
A single limits run block, after imports and before declarations, bounds the entire run. Each value is a positive Int literal no greater than 9007199254740991. The compiler retains its source location in AIR; no manual JSON editing is needed.
An authorized capability may be reused while authority and budget allow it. Subagents share the run counters; a human-pause resume preserves prior consumption. Linking takes the minimum across the entry module and modules whose executable declarations are linked. Importing only a type, constant or memory does not transfer its module's run limits.
Through the CLI
touba run program.air.json \
--max-run-ms 30000 \
--max-steps 100 \
--max-tool-calls 20 \
--max-agent-invocations 5 \
--max-provider-calls 4 \
--output trace
Through CLI JSON
touba run program.air.json \
--run-limits-json '{"max_steps":100,"max_tool_calls":20}' \
--output trace
Through the Manifest
{
"manifest_version": "touba-manifest-v1",
"run_limits": {
"max_steps": 100,
"max_tool_calls": 20,
"max_agent_invocations": 5,
"max_provider_calls": 4
},
"bindings": {}
}
Then:
touba run program.air.json \
--manifest touba.manifest.json \
--output trace
Available Budgets
| Budget | Role |
|---|---|
max_run_ms | maximum run duration, observed at runtime boundaries |
max_steps | maximum number of consumed runtime nodes |
max_tool_calls | maximum number of tool dispatches |
max_agent_invocations | maximum number of agent invocations |
max_provider_calls | maximum number of calls to the agentic decision provider |
max_runs_per_day | trigger quota, carried by trigger limits |
Difference from Timeout
--run-timeout-ms is an execution cancellation control. When observed, the run ends as cancelled.
--max-run-ms is an autonomy budget. When exceeded, the run fails with a budget event and final failure status.
Restriction Rule
When several sources declare a limit, the effective limit is the most restrictive one.
The manifest may restrict a limit that comes from AIR. It cannot silently broaden it.
Example:
module examples.restricted
limits run
max_steps as 10
{
"manifest_version": "touba-manifest-v1",
"run_limits": {
"max_steps": 20
},
"bindings": {}
}
The runtime refuses this configuration because 20 broadens the AIR limit 10.
Human pause and resume
A pause does not reset budgets. The checkpoint retains counters, elapsed active
time and effective limits, including host ceilings. Resume takes the minimum of
previous and current limits. Removing or raising a host option does not restore
spent budget. Time waiting for a human decision is excluded from max_run_ms;
the wait has a separate expiration deadline.
Earlier development checkpoints without this complete state are refused unchanged. Keep them; no implicit migration or budget reset is performed.
max_provider_calls counts each decision-provider attempt, including retries
controlled by the runtime. A provider SDK may perform its own HTTP retries:
this counter does not measure actual network requests or guarantee billing.
Read a Refusal
With --output trace, a budget refusal contains events such as:
{
"kind": "dispatch_refused_budget_exceeded",
"payload": {
"budget_kind": "max_tool_calls",
"limit_value": 1,
"consumed_value": 1,
"target_ref": "tool:examples.search/SearchDatasets",
"runtime_error_code": "ToolCallBudgetExceeded"
}
}
Inspect the trace:
touba inspect trace.json
Inspection displays how many budgets were checked, consumed, exceeded, and which budget kinds were involved.
Already Produced Effects
A budget bounds the next runtime-controlled step: a new node, tool dispatch, agent invocation, or provider call. It does not roll back an external effect already completed by a handler.
For example, if an agent writes a note to a memory backend and then exceeds
max_steps while reading confirmation, the write may already be committed in
the host backend. Read the trace as a stop after an effect, not as a
transactional guarantee.
For sensitive workflows, place human approvals, manifest checks, resource bindings, supply-chain locks, and budgets before the effect that must be protected, then make handlers idempotent where the host system supports it.
Runtime Contract
Autonomy budgets are Touba runtime limits. They cover bounded execution inside the runtime contract:
- cooperative run-duration bounds;
- maximum runtime steps;
- maximum tool dispatches;
- maximum agent invocations;
- maximum decision-provider calls;
- trigger run quotas.
Hard process kills, distributed quotas, provider cost accounting, portable token counting, network/filesystem sandboxing, and regulatory compliance are handled by surrounding platform controls.
Shared budgets in parallel groups
All branches and subagents consume the same run counters. Checking and reserving happen atomically before dispatch: two branches cannot consume the same last permit. A transport error does not automatically refund an attempt.
Source max_concurrency and max_items bound one group. Engine parallelLimits,
or CLI --parallel-limits-json, also bound live branches, external transports
and invocation depth across the run, including nested groups. See the
CLI reference. A logical timeout does not release a
still-active transport. These ceilings are neither a bill nor a monetary limit.