Skip to main content
Version: 1.0.0

CLI Reference

Project explorer​

touba explore [project] [--port <number>] [--no-open]

Opens Architecture, Flow and Governance views in your local browser. The current project is the default; --port selects a port and --no-open prints the address without opening a browser. Saved sources refresh the graph. Ctrl+C closes the service. See the explorer guide.

Output and diagnostics​

--output json flushes the complete envelope before exiting, including pipes and file redirection. The SDK consumes that envelope; invalid JSON remains an error, never a success reconstructed from the trace. Exit codes distinguish success (0), failure (1), waiting (3), stop or rejection (4), and cancellation (5).

Entry errors report missing declared fields and the expected type. Unknown fields are counted without exposing their names, which could contain sensitive data. Binding refusals offer reason-specific guidance rather than describing a supplied manifest as missing. touba serve prints its address on startup unless --quiet is supplied.

The commands on this page assume that the touba command is available in the terminal.

The Touba VS Code extension helps with editing, diagnostics, and inspection in the editor. It does not replace the CLI for terminal workflows.

Stopping commands and services​

On POSIX, when delegating a command such as run, serve or trigger serve, the CLI forwards SIGTERM, SIGINT and SIGHUP to its direct child process and waits for it to exit. For both services, sending SIGTERM to the launcher's PID therefore stops the server and releases its port. Ctrl+C remains available in the terminal. The child's exit code is preserved; if it terminates by a signal, the launcher terminates by the same signal.

An operating-system signal is not governed cancellation: it guarantees neither a complete final trace, a checkpoint, nor reversal of a completed effect. Use execution controls for governed interruption. SIGKILL cannot be forwarded; a supervisor forcing termination must manage the entire process group or tree. Forced termination on Windows is not a POSIX signal that the CLI can intercept.

Input and resource admission​

Keys in --inputs-json must match the selected entry's takes parameters exactly. Missing or additional parameters, invalid types and unknown record fields are refused before the first call. Ask responses, human decisions and agent decisions must reference the current program. Responses supplied in advance for declared interactions remain valid.

A resource-bindings document may declare required_resources at its root, alongside resources, for example:

"required_resources": ["memory:app/Records"]

A missing, inactive or unknown required binding is refused before any handler. A logical memory alone does not require an external backend. --require-resource-bindings instead requires every resource in the inventory. Provider identifiers belong to host adapters, not a closed list of databases. An event_source describes trigger wiring; the adapter must still receive, authenticate and normalize events. The bindings document does not activate a trigger in place of the host manifest.

Overview​

CommandRole
touba initInitializes a Touba project directory
touba new moduleCreates a .tb source file using the project convention
touba packageCreate, check, archive, install and remove packages
touba preparePrepares or checks derived project artifacts
touba secretManages the development secret store
touba compileCompiles .tb source to AIR JSON
touba runExecutes AIR JSON
touba serveExposes a Touba project to contract clients
touba deployPlans, publishes, activates, or restores an immutable revision
touba refreshAsks the project server to re-inspect project artifacts
touba trigger runRuns a schedule trigger in a bounded foreground runner
touba trigger serveStarts a webhook service for request triggers
touba inspectInspects source, AIR, trace, or manifest artifacts
touba auditValidates a trace and can produce an audit export
touba supply-chain generateCalculates a lock from actual files; pending review, no overwrite
touba supply-chain validateValidates a supply-chain lock for AIR, manifest, handlers, SDK, handler package, declared provenance, and declared review
touba registry resolveResolves and verifies a package version from a static registry
touba registry checkChecks the catalog, metadata and available files; compares a previous snapshot when supplied
touba mcp importGenerates Touba contracts from an explicit MCP snapshot
touba rest scaffoldGenerates a Touba tool and bounded HTTP handler from an explicit REST/OpenAPI operation
touba manifest generateGenerates a binding manifest from AIR
touba handler stubGenerates handler skeletons for tools
touba versionDisplays the Touba version and build
touba doctorChecks the installation and available public surfaces
touba updateExplains the update policy for the current channel

touba sdk​

touba sdk install javascript
touba sdk install python
touba sdk install python --python python3.12
touba sdk install python --manager uv
touba sdk install python --manager pip
touba sdk path javascript
touba sdk path python

install uses the current directory or --root <project>. Verified archives are copied into vendor/touba-sdk. JavaScript uses npm offline without install scripts; Python creates/reuses .venv, never a global environment. For pnpm/Yarn/Bun projects, use path with that manager instead of creating a second lockfile. path is read-only and prints the verified absolute path. A packaged distribution is required; a source checkout does not build SDKs implicitly. See SDK selection.

touba init​

Terminal
touba init

Initializes the current directory as a Touba project.

The command creates the required local support files without any secret value:

Structure
.touba/
.touba/build/
.touba/state/secrets.local.json
.touba/evidence/
touba.project.json
.env
.gitignore

It adds .touba/ and .env to .gitignore.

touba.project.json is versionable. It contains the host language, the project's Touba SDK, and run profiles:

touba.project.json
{
"project_version": "touba-project-v1",
"language": "javascript",
"sdk": "@touba/sdk",
"artifact_layout": "touba-artifacts-v1",
"run_profiles": {
"pure": {
"require_supply_chain_lock": false
},
"dev": {
"require_supply_chain_lock": false
},
"prod": {
"require_supply_chain_lock": true,
"supply_chain_lock": "touba.lock.json"
}
}
}

Choose the host language when creating the project:

Terminal
touba init --language javascript
# Or, in a different project:
touba init --language python

Then install its SDK with touba sdk install javascript or touba sdk install python. Python generates .py handlers, contract tests and a binding to the interpreter in the local .venv.

The CLI refuses unsupported host languages and reports the available options.

To target another directory:

Terminal
touba init --root my-project

touba new module​

Terminal
touba new module examples.search

Creates a .tb source file using the project convention.

For examples.search, the command creates:

Structure
src/examples/search.tb

with:

source.tb
module examples.search

Useful options:

Terminal
touba new module examples.search --force
touba new module examples.search --root my-project

--force replaces the file when it already exists.

touba package​

new [name] [--org <organization>] [--context] [--yes] creates the author project in its short-name directory. With no arguments, a questionnaire confirms the organization.name identity before creation. check [directory] [--publishing] validates sources, files and requirements without executing author code. test [directory] [--env NAME] runs only declared Node tests. version [patch|minor|major|version] updates the canonical version, without Git. pack [directory] [--output <archive.tar.gz>] defaults to dist/<name>-<version>.tar.gz, without overwriting. add <name|directory|archive.tar.gz> verifies, installs and locks content. add org.name@1.0.0 --registry <directory|HTTPS-URL> selects an indexed archive. list validates and lists dependencies; remove <name> removes a dependency not required by another. With no target in an application, check checks dependencies; in an author project, it checks the package itself.

checkout <id> --registry <URL> [--root <parent>] retrieves a private draft into a new author folder. submit [directory] [--registry <URL>] [--draft <id>] checks and submits an archive to a private draft. The registry may come from the local link created by checkout or an earlier submission. Both operations accept --no-browser and authenticate the terminal; publishing remains a separate action.

submit [directory] --ci <authorization> --registry <URL> prepares a new draft from an authorized GitHub Actions job. It uses temporary OIDC identity, id-token: write, and an exact repository/workflow/branch/environment binding. An authorized member publishes through the interface. The --draft and --no-browser options are incompatible with this mode.

All accept --json and --root. The root is found from subdirectories. packages/ is reserved for installed copies. Installation, check and pack never execute tests or hooks and never grant authority. See the guide and reference.

touba registry check --registry <source> [--source-root <directory>] checks index, metadata and optionally archives. --previous <trusted-snapshot> also checks continuity of previously published identities and versions.

touba prepare​

--host-decisions host-decisions.json reads a local JSON file (maximum 64 KiB, relative to --root). Alternatively, --host-decisions-json '<object>' accepts the same document inline. Choose one form. The document selects manifest grants, handles, effects and limits. plan shows the diff, check refuses unapplied changes, and write applies decisions idempotently. See the project guide.

Terminal
touba prepare --mode plan
touba prepare --mode write
touba prepare --mode check

Prepares derived artifacts for a Touba project.

Modes:

ModeRole
planshows what would be produced without writing
writewrites missing artifacts
checkchecks consistency without writing

A project without an executable tool produces AIR, but no manifest or handler.

A module with pure imports produces prepared AIR where imports of type, non-sensitive define, and pure function are represented and resolved by project assembly.

A project with effectful imports can also assemble tool, skill, strategy, agent, and memory across modules from the same project. References remain canonical, inter-module callable_by and memory scopes are checked, and tools produce explicit execution artifacts:

Structure
.touba/build/<profile>/air/...
.touba/build/<profile>/touba.manifest.json
.touba/build/<profile>/touba.run-plan.json
.touba/build/<profile>/touba.effective-project.json
handlers/...
touba.secrets.dev.json
touba.secrets.prod.json

A project can also load an explicit package when that package is provided in touba.project.json or through --package. The package makes its exports available for imports, but it grants no handler, grant, secret, memory scope, agent caller, or active trigger.

Common options:

Terminal
touba prepare --source src/examples/search.tb --mode write
touba prepare --air program.air.json --mode check
touba prepare --package authors/research/touba.package.json --mode write
touba prepare --binding-fragment bindings/search.json --mode write
touba prepare --resource-bindings touba.resources.json --require-resource-bindings --mode check
touba prepare --run-plan touba.run-plan.json --entry strategy:examples.search/Run --mode write
touba prepare --run-plan touba.run-plan.json --mode check
touba prepare --ownership touba.ownership.json --profile prod --mode check
touba prepare --handler-root handlers --handler-command /absolute/path/to/node --mode write

prepare does not start the runtime and does not execute handlers.

The touba-effective-project-v1 projection explains the resolved source, AIR, entry, handlers, grants, secret handles, scopes, callers, budgets, sandbox, lock, triggers, and evidence with their provenance. It is derived and never becomes runtime authority.

--package does not perform global name lookup and does not download anything. The path points to a local touba-package-v1 manifest.

--binding-fragment reads an explicit touba-binding-fragment-v1 fragment and composes it into the project manifest. The fragment can propose handler, grants, secrets, limits, and payload constraints, but it is never consumed directly by touba run. The assembled manifest remains the runtime authority.

--resource-bindings validates an explicit touba-resource-bindings-v1 artifact against prepared AIR. Resource bindings cover families attachable to the current AIR: memory_backend, event_source, and decision_provider. The CLI checks known resources, supported family, grants, required secret handles, memory scopes, and absence of raw payload. During touba run, the runtime then passes to the handler only the bindings associated with resources used by the called tool. The CLI does not select an official backend.

--require-resource-bindings refuses when a logical resource required by AIR has no active binding.

--run-plan asks prepare to produce or verify an explicit touba-run-plan-v1 execution plan. The plan points to prepared AIR, the manifest when a tool is used, the secret profile when a secret is required, and the supply-chain lock when the profile requires it. It contains no business inputs, raw prompt, or secret value.

If the entry cannot be inferred unambiguously, specify it:

Terminal
touba prepare --run-plan touba.run-plan.json \
--entry strategy:examples.search/Run \
--mode write

--ownership asks prepare to validate a touba-ownership-v1 artifact against prepared AIR and the current profile. Validation covers teams, owners, review gates, and reviews. It refuses missing reviews, missing owners for sensitive targets, and fields that attempt to grant runtime authority such as grants, secrets, handler, provider, callable_by, or automatic-compliance fields.

Terminal
touba prepare \
--ownership touba.ownership.json \
--profile prod \
--mode check

--require-ownership refuses when no ownership artifact is provided. touba.ownership.json never modifies the manifest, resource bindings, run plan, locks, secrets, handlers, or memory scopes.

Canonical project layout​

Projects declare artifact_layout: "touba-artifacts-v1". There is one layout: .touba/build/<profile> for prepared artifacts and .touba/state for runtime state. Older layouts are refused without rewriting user files. Prepare and project runs default to dev. A unique entry is inferred; otherwise set entry in the project configuration or pass --entry to prepare.

touba secret​

Terminal
touba secret set OPENAI_API_KEY --value-stdin
touba secret list
touba secret check OPENAI_API_KEY
touba secret remove OPENAI_API_KEY

Manages a development secret store.

The command displays handles, not values.

Example:

Terminal
printf '%s' "$OPENAI_API_KEY" | touba secret set OPENAI_API_KEY --value-stdin
touba secret check OPENAI_API_KEY

To target a project:

Terminal
touba secret list --root my-project

The runtime reads this store only when an explicit secrets file requests it with a touba_store source.

touba compile​

Terminal
touba compile source.tb --out program.air.json

Compiles .tb source to AIR JSON.

Inside a project, the command finds the project root from the source file and resolves installed-package imports after checking their integrity, even when the terminal is open elsewhere. touba prepare also prepares manifests, bindings and execution plans for the whole project.

--out is the recommended mode: Touba verifies that the target ends with .air.json and that compiler output is an AIR JSON document before writing the file.

Shell redirection remains possible for advanced uses:

Terminal
touba compile source.tb --stdout > program.air.json

In this case, --stdout makes the pipeline explicit. The shell still creates the file to the right of >; Touba cannot validate its extension. Without --out or --stdout, touba compile refuses execution.

The Touba runtime executes AIR, not the .tb file directly.

touba run​

For local diagnostics, --handler-diagnostics <new-file> requires a POSIX dev run plan without hardened profile or required lock. See the private handler channel.

Terminal
touba run program.air.json

Executes AIR JSON.

Traces are stored in the project's .touba/traces.sqlite by default. --trace-store <database.sqlite> selects another private SQLite journal. --trace-out <trace.json> exports the JSON document. See trace storage.

--output json-reference returns the result with a journal reference. touba trace read --store <database.sqlite> --reference-json <json> --limit 100 then reads events in pages. See paged reads.

touba trace archive --store <database.sqlite> previews retention. Add --destination <new-archive.sqlite> --apply to archive successful runs and remove them from the source after verifying the copy. For a project server, archive its complete state with the server stopped.

--trace-pure-functions full|calls selects pure-function trace detail. full is the default; calls keeps calls, results and failures, together with all governance events. The option is also available with touba serve. See trace detail.

With an explicit run plan:

Terminal
touba run --run-plan touba.run-plan.json

From an explicit project entry:

Terminal
touba run --project . --entry strategy:examples.search/Run --profile dev

The facade resolves .touba/build/dev/touba.run-plan.json, verifies the entry, and passes that explicit plan to the low-level runner. The runtime does not discover authority artifacts by filename.

The run plan replaces repeated artifact options, not business inputs. It can point to:

touba.run-plan.json
{
"run_plan_schema_version": "touba-run-plan-v1",
"entry_ref": "strategy:examples.search/Run",
"air": "air/examples/search.air.json",
"manifest": "touba.manifest.json",
"secrets_profile": "touba.secrets.dev.json",
"profile": "dev",
"outputs": {
"mode": "show"
}
}

The runtime refuses before execution when AIR is missing, entry_ref does not exist, AIR requires a manifest or secret profile that is missing, a strict profile requires a missing lock, the supply-chain lock has drifted, or the run plan contains sensitive fields such as inputs, payload, prompt, secret, or secrets.

If --manifest points to a touba-binding-fragment-v1 fragment instead of an assembled touba-manifest-v1 manifest, the runtime refuses with BindingFragmentNotAssembled.

Inputs remain supplied separately:

Terminal
touba run --run-plan touba.run-plan.json \
--inputs-json '{"request":{"topic":"demo"}}'

Explicit resource bindings:

Terminal
touba run program.air.json \
--resource-bindings touba.resources.json \
--require-resource-bindings

The runner validates the artifact before dispatch, but it does not create a PostgreSQL, HTTP, queue, Vault, or control-surface connection.

With explicit inputs:

Terminal
touba run program.air.json \
--inputs-json '{"request":{"topic":"demo"}}'

With manifest:

Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--inputs-json '{"request":{"topic":"demo"}}'

With secrets:

Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--secrets touba.secrets.dev.json

With a supply-chain lock:

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

--supply-chain-lock asks touba run to validate the lock before dispatch. --require-supply-chain-lock makes this gate strict: missing lock, supply-chain error, or supply-chain warning refuses execution before a handler starts.

Without --require-supply-chain-lock, a supply-chain warning remains non-blocking. The lock grants no authority, reads no secrets, and does not prove that the handler is safe. The manifest remains the runtime authority for handlers, grants, secrets, memories, limits, and triggers.

With a project profile:

Terminal
touba run program.air.json \
--profile prod \
--manifest touba.manifest.json

--profile prod reads touba.project.json in the current directory and applies the prod profile. By default, this profile requires touba.lock.json and enables the strict supply-chain gate before dispatch. --profile dev keeps the current behavior without a mandatory lock.

With ask inputs supplied by file:

Terminal
touba run program.air.json \
--user-inputs user-inputs.json

With explicit terminal input for a manual trial:

Terminal
touba run program.air.json \
--interactive-user-inputs

--interactive-user-inputs cannot be combined with --user-inputs or --user-inputs-json.

With human decisions supplied at startup:

Terminal
touba run program.air.json \
--human-decisions human-decisions.json

To suspend a run at a human decision and resume without replaying effects that already occurred:

Terminal
touba run program.air.json \
--human-checkpoint-out human.checkpoint.json \
--output trace

touba run program.air.json \
--human-resume-checkpoint human.checkpoint.json \
--human-decisions-json '{"approval:example":"approved"}' \
--output trace

The checkpoint covers human_approval nodes and request_human_review requests attached to the execution graph. Ambiguous resume attempts are refused. For asynchronous client interactions, touba serve stores the checkpoint and resumes the run from the authenticated decision.

With explicit autonomy budgets:

Terminal
touba run program.air.json \
--max-run-ms 30000 \
--max-steps 100 \
--max-tool-calls 20 \
--max-agent-invocations 5 \
--output trace

With JSON autonomy budgets:

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

--run-timeout-ms produces a cancelled outcome. --max-run-ms produces a budget refusal with failure status.

With an explicit trigger event:

Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--trigger-event-json '{"trigger_ref":"trigger:examples.daily/DailyRun","event_id":"evt-001","source_kind":"schedule"}' \
--output trace

The manifest must enable the trigger. The runtime refuses before execution if the trigger does not exist in AIR, the manifest entry is missing or inactive, the event source does not match, or the manifest attempts to widen limits declared in AIR.

With an event file:

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

With dry run:

Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--trigger-event trigger-event.json \
--trigger-dry-run

Dry run displays checks without starting the trigger target. It validates the alignment between AIR, manifest, event source, and limits.

With the foreground runner:

Terminal
touba trigger run program.air.json \
--manifest touba.manifest.json \
--trigger trigger:examples.daily/DailyRun \
--max-runs 1 \
--state touba.triggers.sqlite \
--trace-out trace.json

The runner waits for a real interval declared in source with one of these formats:

every <n>s
every <n>m
every <n>h

It then generates a normalized trigger event without raw payload and calls the same runtime as --trigger-event-json. --max-runs and --state are required for the foreground runner.

--state <touba.triggers.sqlite> activates durable trigger state touba-trigger-state-v1. The runner stores consumed event_id values, acceptances, refusals, and the UTC day key used to apply max_runs_per_day. A previously consumed event_id for the same trigger_ref is refused with TriggerReplayRejected before the strategy is started again. An acceptance recorded on a previous day does not block the first event of the current day. This file contains no raw payload and grants no runtime authority. The path passed to --state must end with .triggers.sqlite.

With the webhook service:

Terminal
touba trigger serve program.air.json \
--manifest touba.manifest.json \
--state touba.triggers.sqlite \
--queue touba.trigger-queue.sqlite \
--host 127.0.0.1 \
--port 8787 \
--trace-dir traces \
--max-attempts 3 \
--signature-secret-env TOUBA_TRIGGER_SIGNATURE_SECRET

The service routes request triggers activated by the manifest. Each accepted request is appended to the touba-trigger-queue-v1 queue, then passed to the same runtime as --trigger-event-json. The queue stores event identity, method, path, payload size, and SHA-256 digest; it does not store the raw body. When the manifest declares payload, only JSON fields referenced by payload.map become persisted strategy arguments. The runtime revalidates those arguments against the target signature. --state and --queue must point to paths ending in .triggers.sqlite and .trigger-queue.sqlite.

Main options:

OptionRole
--trigger <trigger_ref>restricts the service to one request trigger
--trace-dir <dir>writes one JSON trace per processed entry
--max-events <n>stops the service after n processed entries
--max-attempts <n>bounds retries for non-structural failures
--processing-timeout-ms <n>requeues a stale processing entry
--auth-token-env <NAME>requires a bearer token or x-touba-trigger-token
--signature-secret-env <NAME>requires x-touba-signature: sha256=<hex>
--secrets <path>resolves declared secret handles for triggered runs

Source and manifest for a typed webhook:

webhook.tb
module examples.webhook

strategy RunWebhook
takes message as Text
gives Text
do
give message

trigger WebhookRun
on request POST "/webhook/run"
runs strategy RunWebhook
with message as payload.message
limits
max_runs_per_day as 100
timeout_ms as 30000
touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"bindings": {},
"triggers": {
"trigger:examples.webhook/WebhookRun": {
"enabled": true,
"source": { "kind": "request" },
"payload": {
"format": "json",
"content_types": ["application/json"],
"max_bytes": 4096,
"map": {
"message": "$.message"
}
},
"limits": {
"max_runs_per_day": 100,
"timeout_ms": 30000
}
}
}
}

Touba provides an explicit daemon for request -> strategy. Distributed schedulers, distributed queues, cloud adapters, system supervision, and complete durable multi-process recovery remain separate layers.

With run controls:

Terminal
touba run program.air.json \
--cancel-before-dispatch \
--output trace
Terminal
touba run program.air.json \
--cancel-on-pause \
--output trace
Terminal
touba run program.air.json \
--run-timeout-ms 5000 \
--output trace
Terminal
touba run program.air.json \
--manifest touba.manifest.json \
--trigger-event-json '{"trigger_ref":"trigger:examples.daily/DailyRun","event_id":"evt-001","source_kind":"schedule"}' \
--kill-switch-enabled \
--output trace

These options produce cancel, timeout, or kill-switch traces. They do not provide a system hard kill or distributed control plane.

With an explicit AIR entry:

Terminal
touba run program.air.json \
--entry skill:examples.project/RunGreeting

--entry expects an AIR reference that exists in the compiled program. Without --entry, the runtime chooses the default entry of the current AIR.

With an explicit agent decision:

Terminal
touba run program.air.json \
--agent-decisions-json '{"agent:examples.research/Researcher":{"target_ref":"skill:examples.research/BuildBrief","reason":"brief requested"}}'

The decision must select a capability declared in uses for that agent. If the requested reference is not authorized, the runtime refuses before entering the capability.

With an agentic decision provider:

Terminal
touba run program.air.json \
--agent-decision-provider providers/researcher.provider.mjs \
--agent-decision-provider-content-mode opaque_refs \
--agent-decision-provider-initial-mode capabilities \
--agent-decision-provider-timeout-ms 30000 \
--agent-decision-provider-max-retries 1 \
--max-agent-steps 8 \
--max-provider-calls 4

The provider module exports decideAgentCapability, decide, or a default function. The runtime calls it with the touba-agent-decision-v1 protocol. The request also contains model_input.protocol = "touba-agent-model-input-v1": a structured model input that separates agent responsibility, instructions, user data, external content, and progressive capability disclosure.

--agent-decision-provider-content-mode accepts inline or opaque_refs. The default mode is inline. In opaque_refs mode, external observations and runtime inputs that are not explicit user intent are replaced with opaque references and metadata; their raw payload is not included in the provider request.

--agent-decision-provider-initial-mode accepts summary or capabilities. The default mode is summary. capabilities presents the authorized catalog in the first provider request; it is recommended when the host already knows that the agent must choose among declared capabilities and wants fewer model roundtrips. In both modes, the runtime still verifies uses, callable_by, arguments, budgets, and manifest constraints before execution. Every capability exposed to a decision provider through agent.uses must declare an explicit source description; otherwise the runtime refuses before the provider call with AgentCapabilityDescriptionRequired.

The module can export non-secret metadata. These metadata are included in traces to identify the provider, model, or prompt template without exposing raw payload.

researcher.provider.mjs
export const provider_metadata = {
provider_kind: "sdk_ai",
provider_name: "researcher-provider",
provider_version: "1.0.0",
model_family: "openai",
prompt_template_id: "researcher-v1",
decision_schema_version: "touba-agent-decision-v1",
};

The provider can answer directly or ask for the full catalog:

researcher.provider.mjs
import { isDeepStrictEqual } from "node:util";

export function decideAgentCapability(request) {
const target = "skill:examples.research/BuildBrief";
const input = request.inputs.request;
const completed = request.observations?.findLast((item) =>
item.target_ref === target
&& isDeepStrictEqual(item.arguments, { request: input })
&& typeof item.value?.summary === "string");
if (completed) return {
action: "answer_directly", source: "custom_provider",
reason: "The requested dataset brief is available in the matching observation.",
result: completed.value.summary,
};
if (request.mode === "finalization") return {
action: "cannot_complete", source: "custom_provider",
reason: "No matching brief is available within the execution budget.",
};
if (request.mode === "summary") {
if (input?.query === "hello") return {
action: "answer_directly", source: "custom_provider",
reason: "A greeting needs no dataset operation.", result: "Hello.",
};
return { action: "request_capabilities", source: "custom_provider",
reason: "The requested brief still requires execution." };
}
if (!request.capability_refs.includes(target)) throw new Error("Brief capability unavailable");
return { target_ref: target, source: "custom_provider",
reason: "The authorized skill produces the requested dataset brief.",
arguments: { request: input } };
}

In catalog mode, it can also request governed human review:

researcher.provider.mjs
return {
action: "request_human_review",
target_ref: "human_review",
source: "custom_provider",
reason: "The result must be confirmed before continuing",
review_prompt: "Validate this intermediate result.",
};

The runtime then verifies target_ref against uses, maps arguments to the capability signature, and refuses before execution when the target or arguments are invalid.

--max-agent-steps bounds the sequential loop of a provider-driven agent. --max-provider-calls bounds the number of provider calls. When a limit is exceeded, the run fails with an observable refusal instead of continuing indefinitely.

A provider can call an external model. In JavaScript, @touba/sdk provides createAiSdkDecisionProvider and createOpenAiDecisionProvider. No LLM vendor becomes the official authority of Touba: the provider is configured explicitly, then the runtime revalidates.

touba run Outputs​

Terminal
touba run program.air.json --output show
touba run program.air.json --output result
touba run program.air.json --output trace
touba run program.air.json --output all
touba run program.air.json --output run-summary

Integration output contract​

Use touba run program.air.json --output json: the touba-run-result-v1 envelope contains status, reason, result, messages, and trace. Pending questions appear in pending_interactions, an array of {interaction_ref, prompt} objects. For user_input_pending, pending_interaction also points to the first question. The array may also appear in a mixed human-approval pause. Branches that have not started are not listed. Answer by occurrence reference, then resume with the saved checkpoint. Business messages remain separate from traces; private checkpoints are excluded. Do not parse human-readable output.

Exit codeMeaning
0Success
1Admission or execution failure
2Invalid CLI options
3Waiting for human approval or user input
4Explicit stop, rejected or expired approval
5Cancellation, including timeout or human cancellation

reason distinguishes completed, explicit_stop, human_approval_pending, user_input_pending, human_approval_rejected, human_approval_expired, human_approval_cancelled, cancelled, timeout, and kill_switch. Runtime failures expose their machine error code. Scripts must handle exit 3 as waiting, not success.

touba inspect trace.json shows a compact chronology and observed limits; --json retains the complete chronology. A supplied explanation appears as reported_reason; the inspector never invents model intent.

Modes:

ModeRole
showdisplays only show messages; default mode
resultdisplays the returned value
tracedisplays the complete JSON trace
alldisplays show, result, and trace sections
run-summarydisplays touba-run-summary-v1, a stable JSON summary for integrations and observation scripts

To keep a trace in a file while preserving user output:

Terminal
touba run program.air.json \
--trace-out trace.json

touba serve​

The project server API guide covers interaction routes, decision identity, approval context, resume and providers.

Terminal
touba serve --project-root my-project --port 8791

Starts the Touba project server. This command provides a real-time surface for clients that consume Touba public contracts. It exposes the inspected project state, the authority graph, product identity, run summaries, human approvals, server events, and reviewable change proposals.

The server refuses ambiguous startup configurations: invalid ports, missing contract roots, inconsistent decision-store paths, or network exposure without an explicit token. By default, it listens on 127.0.0.1.

Terminal
TOUBA_PROJECT_TOKEN=replace-with-a-strong-token \
TOUBA_IDENTITY_SERVICE_TOKEN=replace-with-a-strong-service-token \
touba serve \
--project-root my-project \
--host 127.0.0.1 \
--port 8791 \
--auth-token-env TOUBA_PROJECT_TOKEN \
--identity-control-plane-url https://identity.example.com \
--identity-service-token-env TOUBA_IDENTITY_SERVICE_TOKEN

When --auth-token-env is configured, clients send Authorization: Bearer <token> on HTTP requests and on the /events stream. With the control plane, clients also send X-Touba-Identity-Token; the server verifies the active session and required permission for each route.

The public routes are governed by the product-surfaces schemas:

RouteContract
GET /statelive project, run, trigger, and decision state
GET /eventstouba-project-event-stream-v1, carrying touba-project-event-v1 envelopes
GET /authority/graphtouba-authority-graph-v1, covering agents, skills, tools, strategies, human gates, and grants
GET /identitytouba-product-identity-v1, covering users, teams, devices, sessions, assignments, and escalation policies
POST /project/refreshtouba-project-refresh-request-v1 to touba-project-refresh-v1
POST /runs/sandboxgoverned execution of a declared entry point
POST /triggers/firemanual manifest-governed trigger
POST /elements/proposesemantic creation of a Touba primitive
POST /governance/relations/proposesemantic authority-relation change
POST /changes/proposetouba-project-change-proposal-v1 to touba-project-change-proposed-v1
POST /changes/applytouba-project-change-apply-v1 to touba-project-change-result-v1
GET /deploymentsrevisions and current activation
POST /deployments/plandeployment checks and plan
POST /deployments/publishimmutable revision publication
POST /deployments/activateverified revision activation
POST /deployments/rollbackrestore the preceding revision

Each event contains an event_id, a monotonic sequence for the current server process, a type, source, emitted_at, and a versioned payload. Clients can display or replay observable changes without parsing free-form text.

The authority graph is derived from Touba artifacts. An inconsistent reference is exposed as a diagnostic, never converted into implicit authority. Product identity identifies the humans and devices used by a client; it does not replace Touba Engine runtime checks.

A change proposal does not write to the project directly. The server validates paths, JSON contracts and .tb compilation, then returns a proposal that can be applied or refused. An accepted application writes the complete change as one transaction; an error restores the initial state.

By default, touba serve loads touba.secrets.dev.json when that file exists at the project root. --secrets <file> selects another profile. Resolved values remain inside the server and runtime; clients never receive them.

The complete flow is described in the project server API guide.

touba deploy​

Terminal
touba deploy plan --root . --profile prod --target https://deploy.example.com

The plan creates a deterministic bundle and checks sources, manifests, digests, the supply-chain lock, handlers and source-revision state.

Terminal
export TOUBA_DEPLOY_TOKEN='replace-with-a-strong-token'

touba deploy publish \
--root . \
--profile prod \
--target https://deploy.example.com \
--auth-token-env TOUBA_DEPLOY_TOKEN

Publication adds an immutable revision. Activation remains explicit:

Terminal
touba deploy list \
--target https://deploy.example.com \
--auth-token-env TOUBA_DEPLOY_TOKEN

touba deploy activate \
--target https://deploy.example.com \
--auth-token-env TOUBA_DEPLOY_TOKEN \
--revision sha256:...

touba deploy rollback \
--target https://deploy.example.com \
--auth-token-env TOUBA_DEPLOY_TOKEN

Start a target:

Terminal
touba deploy target serve \
--storage /srv/touba/revisions \
--auth-token-env TOUBA_DEPLOY_TOKEN \
--host 127.0.0.1 \
--port 8792

A non-loopback target requires --tls-cert and --tls-key. Tokens stay in the CLI or project server and never enter contracts sent to clients.

touba refresh​

Terminal
touba refresh --url http://127.0.0.1:8791

Asks an already running project server to re-inspect Touba artifacts. The response reports observed files, changes detected since the server's previous snapshot, and project readiness diagnostics. A client uses the same route to stay synchronized with changes made from an editor or through the CLI.

touba inspect​

Terminal
touba inspect program.air.json
touba inspect trace.json
touba inspect touba.manifest.json
touba inspect touba.package.json
touba inspect touba.resources.json
touba inspect touba.run-plan.json
touba inspect .touba/build/dev/touba.effective-project.json
touba inspect .touba/build/dev/touba.effective-project.json --json
touba inspect touba.ownership.json
touba trigger state touba.triggers.sqlite --trigger trigger:examples.daily_research/DailyResearchSchedule
touba inspect trace-audit.export.json
touba inspect --supply-chain touba.lock.json
touba inspect --supply-chain supply-chain.report.json
touba inspect program.air.json --report-out program.inspect.txt
touba inspect trace.json --otel-out trace.otel.json

Inspects a Touba artifact without inventing missing data.

Depending on the file provided, the command can display:

  • AIR declarations;
  • execution graphs;
  • traces;
  • memory provenance and integrity counters observed in traces;
  • manifest bindings;
  • local packages, binding fragments, resource bindings, and run plans provided explicitly;
  • Availability graph, showing modules, imports, declarations, and available exports;
  • Authority graph, showing AIR requirements, manifest, resource bindings, run plan, and supplied lock;
  • Ownership and Responsibility graph, showing teams, owners, review gates, and reviews without runtime authority;
  • durable trigger states, including acceptances, refusals, and consumed event_id values;
  • audit manifests, reports, and exports;
  • supply-chain locks and reports;
  • useful missing data.

touba inspect does not read handlers, memory backends, .env files, secret files, or local stores. It does not scan the workspace to discover a neighboring package or manifest.

For touba-effective-project-v1, text output and --json use the same deterministic document. The absent, non_applicable, derived, declared, and effective states are preserved. The projection contains no secret value, business payload, prompt, result, or memory content.

With --report-out <report.inspect.txt>, the command writes the same text report to a file with an explicit .inspect.txt suffix and keeps standard terminal output.

With --otel-out <trace.otel.json>, the command writes an OpenTelemetry JSON projection of a native trace. The option requires either a single trace file or --trace <trace.json> in a multi-artifact inspection.

The projection maps events to GenAI spans such as invoke_workflow, invoke_agent, or execute_tool when possible, and exports only references, counters, codes, and non-sensitive metadata.

Explicit multi-artifact inspection:

Terminal
touba inspect \
--air build/touba/project.air.json \
--manifest build/touba/touba.manifest.json \
--package authors/research/touba.package.json \
--resource-bindings touba.resources.json \
--run-plan touba.run-plan.json \
--ownership touba.ownership.json

The touba-binding-fragment-v1 fragment can also be inspected with --binding-fragment, but it is displayed as non-authoritative for runtime. Only the assembled manifest is an execution authority.

With --source, inspection compares artifact references to the supplied file. On Windows, D:\project\main.tb and d:\project\main.tb name the same drive. The comparison preserves folder and filename case, as well as the original references; it does not modify the artifacts.

touba audit​

Terminal
touba audit --trace trace.json

Validates a Touba trace and produces a trace-audit-validation-v1 report.

With more context:

Terminal
touba audit \
--trace trace.json \
--air program.air.json \
--source source.tb \
--manifest touba.manifest.json

With export:

Terminal
touba audit \
--trace trace.json \
--air program.air.json \
--source source.tb \
--manifest touba.manifest.json \
--retention-class project_audit \
--redaction-policy no_secrets_no_raw_prompts_no_memory_content \
--export trace-audit.export.json \
--report-out trace-audit.trace-audit-report.json

Options:

OptionRole
--tracetrace to validate, required
--airassociated AIR, optional
--sourceexplicit .tb source; repeat for imported modules
--manifestassociated runtime manifest, optional
--audit-manifestexisting audit manifest to verify
--retention-classdeclarative retention class
--redaction-policyexpected redaction policy
--exportexport file, written only when the report is ok
--report-outtrace-audit-validation-v1 report file written with .trace-audit-report.json suffix
--output text|jsonreport format

touba audit does not sign artifacts, create a legal timestamp, or declare regulatory compliance.

touba supply-chain generate​

Calculates a pending-review lock without overwriting an existing lock or executing handlers. Static local JavaScript and Python imports are inventoried alongside package.json or pyproject.toml identity.

touba supply-chain generate --air program.air.json \
--manifest touba.manifest.json --out touba.lock.json

Additional options: repeatable --air, --package-root, repeatable --file, --entrypoint-arg <index|command>, --sdk-metadata-json, --python <trusted-interpreter> (isolated Python 3.11+ analysis). Declared dependencies require their manager's lockfile. Artifact bytes are checked, not dependency resolution or the installed environment. See the supply-chain guide.

touba supply-chain validate​

Terminal
touba supply-chain validate \
--lock touba.lock.json \
--air program.air.json \
--manifest touba.manifest.json \
--require-review \
--report-out project.supply-chain-report.json

Validates a supply-chain lock against explicitly supplied artifacts.

Validation covers:

  • sha256 digest of AIR;
  • sha256 digest of the manifest;
  • sha256 digest of listed handlers;
  • handler command, cwd, and args;
  • declarative SDK metadata, including name, version, and expected handler protocol;
  • declared handler_package identity for handlers;
  • handler package files and declared dependency artifacts under handler_package;
  • declared lock provenance;
  • declared lock review and associated evidence;
  • anti-leak diagnostics on authority fields.

Options:

OptionRole
--locktouba-lock-v1 lock, required
--airAIR expected by the lock, required
--manifestmanifest expected by the lock, required when the lock declares one
--report-outtouba-supply-chain-validation-v1 report file written with .supply-chain-report.json suffix
--output text|jsonreport format
--strictalso fails on warnings
--require-reviewrequires a consistent approved review in the lock

JSON example:

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

Example with mandatory review:

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

touba supply-chain validate does not execute handlers, scan the workspace, read secrets, sign artifacts, verify a registry, or perform vulnerability auditing. handler_package is a declared identity and declared artifact root, not a trust source. An approved review is a declared discipline, not a signature, compliance proof, or Verified / Unverified status.

touba registry resolve​

This inspection command selects an exact entry from an explicitly chosen local or HTTPS registry. It checks index and metadata digests, version, protocol compatibility and review status. With --source-root it also checks local artifact digests. The package reference uses pkg:<qualified.name>.

Command form
touba registry resolve --registry ./registry --package pkg:acme.review \
--version 0.1.0 --source-root ./registry --json

This assumes that your registry contains that package. There is no default registry or preinstalled example package. Use --out <file.json> only when you want to save the inspection record (touba-static-registry-lock-v1).

Draft and deprecated records require --allow-draft and --allow-deprecated respectively; yanked entries are refused. registry check can audit all metadata, including yanked entries. Neither command grants runtime authority.

For installation use touba package add, which also checks the archive, source contracts, compatibility and exact dependency closure, then records the installation lock. The optional registry inspection record does not replace it.

touba mcp import​

Terminal
touba mcp import mcp.demo.json \
--module integrations.mcp.demo \
--out integrations/demo \
--mode write

Generates reviewable Touba artifacts from an explicit MCP tools snapshot: .tb source, manifest fragment, MCP bridge config, bridge handlers, secrets template, import report, and local README.

The input file uses touba-mcp-import-config-v1:

mcp.demo.json
{
"mcp_import_config_version": "touba-mcp-import-config-v1",
"server": {
"name": "demo",
"transport": "snapshot",
"secret_handles": ["DEMO_MCP_TOKEN"],
"timeout_ms": 5000,
"max_payload_bytes": 65536
},
"tools": [
{
"name": "search",
"description": "Search a governed MCP source",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
},
"outputSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" }
},
"required": ["summary"]
}
}
]
}

Common options:

OptionRole
--module <module.name>Touba module that receives the generated types and tools
--out <dir>output directory under the project root
--mode plan|write|checkpreviews, writes, or checks generated files
--select <tool>imports only one named MCP tool, repeatable
--forceallows overwriting a generated file that differs
--jsonprints the import report as JSON

The generated mcp.bridge.config.json configures the approved MCP stdio server that will execute tools/call:

mcp.bridge.config.json
{
"mcp_bridge_config_version": "touba-mcp-bridge-config-v1",
"server": {
"transport": "stdio",
"command": "/path/to/mcp-server",
"args": [],
"timeout_ms": 5000,
"max_payload_bytes": 65536,
"max_text_content_length": 65536,
"env": {
"SERVICE_TOKEN": {
"from_secret_handle": "DEMO_MCP_TOKEN"
}
}
}
}

env maps variables expected by the MCP server to secret handles already granted to the tool. The file remains versionable because it contains no secret value.

The report separates imported tools from refused tools. Refusals cover unmappable schemas, missing selections, invalid secret handles, and drift detected by --mode check.

The generated bridge handler initializes an MCP stdio session, calls tools/call, normalizes structuredContent or bounded text content, and returns controlled errors through the Touba handler protocol. Effective authority remains in the manifest, secrets, approvals, and Touba runtime policies.

touba rest scaffold​

Terminal
touba rest scaffold rest.search.json \
--module integrations.rest.search \
--out integrations/search \
--mode write

Generates integration artifacts for an explicit HTTP operation: .tb source, manifest fragment, REST handler configuration, minimal HTTP handler, secrets template, generation report, and local README.

The input file uses touba-rest-scaffold-config-v1:

rest.search.json
{
"rest_scaffold_config_version": "touba-rest-scaffold-config-v1",
"service": {
"name": "search",
"base_url": "https://api.example.test",
"secret_handles": ["SEARCH_API_KEY"],
"timeout_ms": 5000,
"max_payload_bytes": 65536
},
"operation": {
"name": "search_web",
"method": "GET",
"path": "/v1/search",
"description": "Search a governed API",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" },
"max_results": { "type": "integer" }
},
"required": ["query"]
},
"outputSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"source_count": { "type": "integer" }
},
"required": ["summary"]
}
}
}

The same format can target a simple OpenAPI specification with openapi and operation_id. The scaffold extracts the named operation, its parameters, its JSON body, and its response schema.

Common options:

OptionRole
--module <module.name>Touba module that receives the generated types and tool
--out <dir>output directory under the project root
--mode plan|write|checkpreviews, writes, or checks generated files
--forceallows overwriting a generated file that differs
--jsonprints the generation report as JSON

The generated rest.handler.config.json describes the base URL, operation, timeouts, payload limits, and secret mapping. The manifest fragment declares network and secret_read when handles are requested, but it does not grant silent authority to the project.

The report separates generated operations from refusals. Refusals cover JSON schemas that cannot be mapped to Touba types, missing OpenAPI operations, and drift detected by --mode check.

touba manifest generate​

Terminal
touba manifest generate program.air.json --out touba.manifest.json

Generates a binding manifest from tools declared in AIR.

Common options:

Terminal
touba manifest generate program.air.json \
--out touba.manifest.json \
--handler-command /absolute/path/to/node \
--handler-root handlers

The generated manifest is a starting point. It must be reviewed before running a program with tools.

The manifest can also carry payload constraints, for example:

touba.manifest.json
{
"bindings": {
"tool:examples.fetch_source/FetchSource": {
"payload_constraints": {
"input": {
"request.query": {
"non_empty": true,
"max_length": 120
},
"request.mode": {
"allowed_values": ["dry_run", "review", "execute"]
},
"request.recipients": {
"min_items": 1,
"max_items": 5
}
}
}
}
}
}

These constraints are evaluated by touba run after the AIR schema and before the handler. A refusal produces ToolPayloadConstraintViolation without displaying the refused raw value.

Base constraints cover non_empty, max_length, min, and max. The allowed-values extension adds allowed_values to bound a field to an explicit list of scalar JSON values (Text, Boolean, Int, Float). Touba does not treat these constraints as expressions, regexes, or a policy language. List cardinality constraints add min_items and max_items on values already validated as List<T> by AIR.

touba handler stub​

Terminal
touba handler stub program.air.json

Generates handler skeletons for tools declared in AIR.

Common options:

Terminal
touba handler stub program.air.json \
--handler-root handlers

To generate only one tool:

Terminal
touba handler stub program.air.json \
--tool-ref tool:examples.search/SearchDatasets \
--handler-root handlers

The generated stub does not implement the external effect. It lays down the handler contract to complete.

touba version​

Terminal
touba version

Displays two lines: touba <version> and build <short identifier>. The identifier is the first 12 characters of the assembled toolchain payload's SHA-256 fingerprint. It distinguishes development builds without introducing another version number.

Use touba doctor to check the installation.

An unpackaged source checkout reports source-local. An installation without a recognized assembly identity reports unknown: rebuild and reinstall the toolchain to obtain this identity. The identifier depends on neither the installation directory nor environment variables. It identifies the content at assembly time; it is neither a signature nor a fresh integrity check on each invocation.

touba doctor​

Terminal
touba doctor

Checks the active installation: Node version, Touba component versions, presence of public commands, and project profiles available in the current directory. The report identifies warnings and errors without reading secret values.

touba update​

Terminal
touba update
touba update --json

Explains the update policy for the current channel.

The command reports the installed version, channel, platform, Touba Hub URL, expected archive and reinstall commands. --json returns the same contract in a machine-readable form.

Updates use explicit reinstallation from a new archive or from the package manager channel that installed Touba.

Parallel runs​

touba run accepts --parallel-checkpoint-out <path>, --parallel-resume-checkpoint <path> and --parallel-limits-json <object>. Private checkpoints are atomically written with mode 0600 before dispatch, after results and before join. Supply --human-decisions-json for the exact pending occurrence's approval_ref; one decision cannot release a sibling.

Host ceilings are maxBranches (1024), maxExternalCalls (16), maxDepth (64), maxConcurrency and maxItems (1024 each), maxJournalEntries (100000) and maxCheckpointBytes (16777216). Host ceilings may tighten source limits. Resume cannot enlarge saved ceilings. Keep the effect journal alongside checkpoints for writing tools. An uncertain external outcome without journal evidence is refused, never blindly repeated. The checkpoint covers the group before join, not arbitrary workflow execution after that join. See the tutorial.

Trusted human approval adapter​

touba run and touba serve accept --human-approval-host <host.mjs|host.py|pkg:organization.name/host-id>. Python hosts export attest_human_approval and optionally initiator_ref. The selected package is checked before loading. --human-approval-authority-timeout-ms sets the technical attestation timeout from 1 to 60,000 ms (default: 5,000). A timeout refuses the decision and leaves the program's business deadline unchanged. The module exports attestHumanApproval and optionally initiatorRef. Constrained decisions include an opaque evidence_ref, not client-supplied roles. See the executable tutorial. An expired source deadline can be resumed without a decision; use a separate --human-checkpoint-out path to retain a new escalation wait.