Skip to main content
Version: 1.0.0

Manifest Reference

The manifest connects tools to host handlers and can explicitly activate triggers. It is supplied explicitly to the runtime.

In a Touba project, touba prepare can generate or verify the manifest from AIR. This does not change the runtime contract: execution with a tool still requires --manifest.

The handler is launched without an implicit shell and with a minimal environment. For a JavaScript handler, touba prepare therefore writes the absolute path of the current Node executable into handler.command.

Minimal Shape​

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"bindings": {
"tool:examples.search/SearchDatasets": {
"handler": {
"kind": "process",
"command": "/absolute/path/to/node",
"args": ["handlers/search_datasets.handler.mjs"],
"cwd": "."
},
"grants": ["network"],
"effect_contract": { "kind": "none" },
"sandbox": {
"required": true
},
"timeout_ms": 5000,
"max_payload_bytes": 1048576
}
}
}

Fields​

FieldRole
manifest_versionmanifest version
bindingsexplicit tool -> binding table
triggersexplicit trigger -> activation table
run_limitsautonomy budgets applicable to the run
handler.kindprocess
handler.commandexecutable launched without an implicit shell
handler.argsprocess arguments
handler.cwdoptional working directory
grantsexplicitly granted capabilities
sandboxplatform isolation required for the handler process
secretsgranted secret handles
memoriesgranted memory access
timeout_msprocess timeout
max_payload_bytespayload limit

Explicit effect contract​

touba-manifest-v1 is the only admitted format. Every binding must declare effect_contract: { "kind": "none" } for a non-writing operation, or { "kind": "external_write", "retry_mode": "none" } for an external write without safe retry support. The other retry modes, idempotency_key and reconcile, require real support from the external service.

An external write may also declare compensation: { "entry_ref": "strategy:orders/CancelOrder" }. The inverse must be an eligible strategy in the exact AIR and remains subject to its own authority checks.

The generator leaves effect_contract: null until the developer reviews the handler behavior. This draft is not executable. Unknown fields, missing contracts and retired formats are refused before dispatch. CLI writes require --effect-journal <path.effect-journal.sqlite>; JavaScript runs use the effectJournal option. All handlers use touba-tool-handler-v1, with operation: invoke or operation: compensate.

Secrets​

Secrets are handles. The manifest does not contain values.

touba.manifest.json
"secrets": ["OPENAI_API_KEY"]

Agent Secret Scopes​

touba.manifest.json
{
"agent_secret_scopes": {
"agent:examples/Researcher": ["OPENAI_API_KEY"]
}
}

If the handle is absent from the active agent scope, the runtime refuses before the handler.

Memories​

touba.manifest.json
"memories": [
{ "ref": "memory:examples/ProjectKnowledge", "access": "read" }
]

The runtime crosses AIR, manifest, and active owner before dispatch.

Handler Isolation​

A binding can require platform isolation:

touba.manifest.json
"sandbox": {
"required": true,
"profile": "default"
}

When sandbox.required: true, macOS uses sandbox-exec; Linux x64 combines bubblewrap, seccomp and the native touba-sandbox launcher with Landlock ABI 3 or newer. Out-of-scope data, writes, descendants and network connections are denied by default. Native Linux checks cover Ubuntu 24.04, Node and Python, including termination of descendants on timeout.

On Linux, bubblewrap must be installed and user namespaces available. An Ubuntu host protected by AppArmor may require an administrator profile limited to that binary, without disabling global protections. Each write_paths entry must already exist: use a dedicated output directory to create files. Write access does not grant read access. Exact Unix socket scopes require Landlock ABI 9; an unenforceable policy is refused before launch. The probe runs a command under confinement to check prerequisites.

The Windows backend is still undergoing V1 qualification, including asynchronous Python handlers without network authorization. It is not announced as available in a finalized distribution. An unavailable sandbox or unsupported policy prevents execution, with no direct-execution fallback. Without a required sandbox, handlers remain trusted host code. HandlerSandboxUnsupportedPolicy identifies a policy unsupported by the selected backend.

Paths are relative to the handler's cwd or absolute. Use an absolute interpreter path (the node alias resolves to Touba's Node executable).

FieldRequired grantScope
code_pathshost-selected codeexisting individual library/module files
read_pathsfilesystem_readfiles or subdirectories
write_pathsfilesystem_writefiles or subdirectories
local_socketsnetwork_localexact Unix client socket paths

process permits children that inherit the policy. network permits network access; network_local alone does not permit IP traffic. A permitted service can itself have powerful privileges: do not expose a Docker socket as if it were a restricted database connection.

The technical baseline includes executable code, Node's loaded libraries, system libraries, path metadata and standard OpenSSL configuration. It does not grant blanket access to the project, home directory or temporary files. Review explicitly granted paths; sandboxing does not prove handler safety.

Payload Constraints​

A binding can declare payload constraints applied after the AIR schema and before the handler for input, then before result publication for output.

touba.manifest.json
"payload_constraints": {
"input": {
"request.query": {
"non_empty": true,
"max_length": 120
},
"request.rows": {
"min": 1,
"max": 50
},
"request.mode": {
"allowed_values": ["dry_run", "review", "execute"]
},
"request.recipients": {
"min_items": 1,
"max_items": 5
}
},
"output": {
"$": {
"max_items": 20
}
}
}

Available operators are bounded:

  • non_empty and max_length for Text;
  • min and max for Int or Float;
  • allowed_values for portable JSON scalars;
  • min_items and max_items for List<T>.

A refusal produces ToolPayloadConstraintViolation without displaying the raw payload value.

Run Budgets​

The manifest can restrict autonomy budgets:

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": {}
}

run_limits concerns the Touba run. timeout_ms and max_payload_bytes inside a binding concern the handler process.

The manifest can restrict an AIR limit. It cannot silently broaden it.

Triggers​

A trigger remains inactive until the manifest activates it.

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"triggers": {
"trigger:examples.daily_research/DailyResearchSchedule": {
"enabled": true,
"source": {
"kind": "schedule"
},
"limits": {
"max_runs_per_day": 1,
"timeout_ms": 30000
}
}
}
}

The runtime refuses if the event source does not match or if the manifest attempts to broaden a limit declared in AIR.

Relation with the Supply-Chain Lock​

The manifest remains the runtime authority: it grants the handler, grants, secrets, memories, limits, and triggers.

A supply-chain lock grants no additional right. It only verifies that AIR, manifest, handlers, SDK metadata, and the declared handler_package identity match expected artifacts. With the dependency artifact extension (SC-2), the same lock can also verify handler package files and explicitly declared dependency artifacts. With the provenance and review extension (SC-3), it can also carry declared provenance and review.

Terminal
touba supply-chain validate \
--lock touba.lock.json \
--air program.air.json \
--manifest touba.manifest.json

If the manifest changes after lock creation, validation should report drift. The runtime still applies the manifest supplied at execution.

An approved lock review grants no grant, secret, scope, or trigger. It documents a review discipline.

Manifest Boundaries​

info
  • grants and sandbox are separate controls.
  • a required sandbox depends on the mechanism available on the platform.
  • The manifest is not a complete permission system.
  • No handler is discovered automatically.
  • No secret is read implicitly.
  • A generated manifest remains a reviewable artifact, not invisible authorization.
  • No trigger is activated automatically without an explicit manifest entry.