Skip to main content
Version: 1.0.0

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​

Terminal
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​

Terminal
touba run program.air.json \
--run-limits-json '{"max_steps":100,"max_tool_calls":20}' \
--output trace

Through the Manifest​

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"run_limits": {
"max_steps": 100,
"max_tool_calls": 20,
"max_agent_invocations": 5,
"max_provider_calls": 4
},
"bindings": {}
}

Then:

Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--output trace

Available Budgets​

BudgetRole
max_run_msmaximum run duration, observed at runtime boundaries
max_stepsmaximum number of consumed runtime nodes
max_tool_callsmaximum number of tool dispatches
max_agent_invocationsmaximum number of agent invocations
max_provider_callsmaximum number of calls to the agentic decision provider
max_runs_per_daytrigger 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
Refused manifest
{
"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:

Trace excerpt
{
"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:

Terminal
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.