Trace Reference
Choose pure-function trace detail
--trace-pure-functions full keeps all detail and is the default.
With calls, internal pure-function branches, loops, bindings and successful
scopes are omitted. Calls, returns, errors, budgets and governance events
remain recorded. The entry function's scope is retained.
touba run --project . --trace-pure-functions calls --trace-out trace.json
The trace records run.pure_function_detail: "calls". Filtering happens before
numbering, observers and persistence, so they receive the same trace.
The serve command and both SDKs also expose this setting.
Store execution traces
touba run program.air.json --trace-store .touba/traces.sqlite --trace-out trace.json
SQLite stores traces in the project's .touba/traces.sqlite by default.
Without a parent touba.project.json, the CLI uses the directory of the supplied AIR document or run plan.
--trace-store selects another private journal. Events are stored progressively;
pure computation details are grouped into small batches, committed before
calls and checkpoints. A storage failure stops progression before the next
effect. Each execution or resume creates a separate segment.
--trace-out exports the touba-trace-v1 document. The --output trace, json
and all modes read the journal progressively and wait for output capacity.
The exported file is replaced only after the new content is complete.
The --output run-summary summary and --evidence-out evidence also read the
journal progressively. Summary collections have a 16 MiB limit; if it is
reached, export the full trace with --trace-out.
The journal allows 512 MiB of serialized data and 1 MiB per event by default.
It is retained until the host archives it; automatic purging is not enabled.
Use a private, backed-up directory. SDK options are traceStore (JavaScript)
and trace_store (Python). Full SDK results retain the 32 MiB transport limit.
Archive a journal
touba trace archive --store .touba/traces.sqlite
mkdir -m 700 archives
touba trace archive --store .touba/traces.sqlite --destination archives/traces.sqlite --apply
The first command previews reclaimable content. Applying creates and verifies
an archive before removing successful runs from the source. Paused, failed and
interrupted runs remain available. Select the archive with --store to read
the same references. The destination must be new; existing files are not replaced.
For a project server, archive the complete state with the server stopped so that
traces, checkpoints and effects stay together. Server previews contain the last
200 events and the full count. GET /runs/{run_id}/trace?index=true lists segments;
/runs/{run_id}/trace/segments/0?limit=100 reads a page with project authorization.
Without index, the route streams the complete export.
Read a trace in pages
--output json-reference returns the business result and a trace_reference.
The default journal is sufficient; --trace-store selects a different path.
Events are read separately, in pages.
To read a page, pass the complete JSON reference to:
touba trace read --store .touba/traces.sqlite --reference-json '<JSON reference>' --limit 100
The response contains header, events, next and done. Pass next as
--after for the following page, until done: true. The initial read without
a cursor also verifies the complete segment digest in bounded memory.
Later pages check their events and order. Reading runs no program and makes
no changes to the journal.
A page contains at most 1,000 events and 1 MiB of event content, plus the reference and header. The JavaScript and Python SDK guides show the full loop. A reference identifies a completed segment, including pauses and failures. An admission refusal keeps its small trace in the error result.
Provenance and decisions
New AIR documents produced by the CLI use source identities relative to a common root of compiled files, without storing that root's absolute path in AIR. Traces inherit these identities. The technical --json compiler envelope separately supplies source_root to the editor; local diagnostics retain navigable file paths. Review application data and metadata before sharing: this is not a general anonymizer.
The editor resolves relative sources from the workspace folder or asks for the project root. Moving a project preserves AIR identity when sources and relative paths are unchanged. Existing AIR and traces are not rewritten: recompile and review locks again when migrating their provenance.
An authorized repeated invocation remains executable. Observations and timelines expose repeated_from_step and identical_invocation_number, without one-use permissions. A native selection may supply no reason: that absence is neither available hidden reasoning nor an error; no explanation is invented. Unchanged skill-pack metadata is traced once per agent invocation; authority and budget checks are still evaluated for every request.
Traces make execution observable. They are engineering evidence, not proof of sandboxing, strong permission, or scientific verification.
The current contract is touba-trace-v1 with the
touba-trace-capabilities-v1 profile. Execution traces require run.air_digest,
the canonical SHA-256 AIR digest computed before execution. Older traces without
this commitment are not V1 evidence and are not repaired while reading.
An admission refusal has run.admission: "refused", null AIR identity fields
and exactly one admission_refused event. It attests no program execution.
Events have unique identifiers and a contiguous sequence, with consistent run
and module references. Completed traces require exactly one terminal event.
Renderers reject broken ordering, unknown profiles, or forbidden sensitive
payloads; they do not silently repair the artifact.
Envelope
A trace contains:
trace_protocol_versiontrace_capability_profilerunevents
Each event carries a kind and a payload.
Main Events
| Event | Meaning |
|---|---|
call_started | Entered an AIR call |
call_completed | Exited an AIR call |
binding_created | Local bind value created without exposing the value |
tool_binding_authorized | Tool authorized before handler dispatch |
secret_handle_authorized | Secret handle authorized before handler dispatch |
secret_handle_refused | Secret handle refused before handler dispatch |
memory_access_authorized | Logical memory access authorized |
memory_provenance_observed | Memory provenance metadata observed |
memory_integrity_observed | Memory integrity evidence observed |
memory_metadata_refused | Memory metadata refused |
memory_integrity_refused | Memory integrity evidence refused |
agent_invocation_authorized | Agent entry authorized |
agent_invocation_refused | Agent entry refused |
agent_capabilities_listed | Capabilities declared in uses for the active agent |
agent_capability_descriptions_diagnosed | Quality of capability descriptions exposed to the decision provider |
agent_decision_requested | Structured request sent to the decision provider, with request_digest and model-input mode without raw payload |
agent_decision_provider_call_attempted | Decision provider call attempted with attempt, timeout, and non-secret metadata |
agent_decision_catalog_requested | Full catalog requested by the provider |
agent_decision_provider_retry_scheduled | Bounded retry scheduled after eligible provider failure |
agent_decision_provider_returned | Structured provider response |
provider_cost_recorded | Host cost reservation or settlement, correlated with the agent invocation; unknown usage retains its bound |
agent_decision_recorded | Agent decision received by the runtime |
agent_direct_answer_returned | Direct answer returned without catalog presentation |
skill_pack_discovery_listed | Available skill packs listed as short hints without raw content |
skill_pack_activated | Skill pack explicitly activated as bounded context |
skill_pack_activation_refused | Activation or model input refused by budget |
skill_pack_resource_loaded | Declared resource loaded as context, without content in trace |
skill_pack_resource_refused | Skill pack resource or execution link refused |
agent_capability_selected | Authorized capability selected |
agent_capability_result_returned | Capability result made available as observation for the next decision |
agent_capability_refused | Capability refused as outside declared scope |
agent_human_review_requested | Human review requested by agent in catalog mode |
agent_step_limit_exceeded | Agentic step limit exceeded |
trigger_event_received | Normalized trigger event received |
trigger_event_accepted | Trigger accepted before target execution |
trigger_event_refused | Trigger refused before target execution |
trigger_rate_limited | Trigger run limit reached |
trigger_execution_started | Target execution triggered |
trigger_execution_completed | Target execution completed |
trigger_execution_failed | Target execution failed |
run_cancel_requested | Cancellation requested by host, timeout, or kill switch |
run_cancelled | Cooperative cancellation completed |
run_timeout_exceeded | Global run timeout observed |
kill_switch_enabled | Kill switch enabled by host |
kill_switch_disabled | Kill switch disabled by host |
dispatch_refused_cancelled | New dispatch refused after cancel request |
budget_limit_checked | Effective autonomy budget established |
budget_consumed | Autonomy budget counter consumed |
budget_limit_exceeded | Autonomy budget exceeded or configuration refused |
dispatch_refused_budget_exceeded | New dispatch refused by autonomy budget |
human_approval_requested | Human validation requested |
human_approval_paused | Execution suspended |
human_approval_pause_refused | Human pause refused because durable resume would be required after external effect |
human_approval_decided | Human decision supplied |
user_interaction_shown | show executed |
user_interaction_paused | Execution suspended for missing input |
user_interaction_answered | Input supplied by host |
failure_detected | Observable runtime failure |
fallback_selected | Recovery branch matching the observed failure family |
run_completed | Run completed |
Read a Trace
touba inspect trace.json
The inspector displays existing events. It does not re-read handlers, secrets, or backends.
OpenTelemetry Export
Touba keeps touba-trace-v1 as its native trace readable by Touba commands. For external observability, touba inspect can produce a JSON projection compatible with OpenTelemetry span models:
touba inspect trace.json --otel-out trace.otel.json
This export bridges to observability stacks. It does not replace the native trace, sign events, or prove compliance. Touba events become GenAI spans when the mapping is established: invoke_workflow, invoke_agent, or execute_tool. The export preserves AIR references, run_id, sequence, refusal codes, and non-sensitive counters.
The OpenTelemetry export does not write full prompts, raw messages, user answers, tool results, raw observations, secret values, or local paths. The Touba trace remains the native audit artifact.
For memory provenance and integrity (PI-1), traces can contain memory provenance references, a digest, and integrity_evidence. These fields describe available evidence; they do not prove that content is true, safe, or verified end to end.
For skill packs, traces expose refs, counters, activation reasons, budgets, and refusal codes. They do not contain full pack content, script content, raw payload, full prompt, or secret value.
Audit a Trace
touba audit \
--trace trace.json \
--air program.air.json \
--source source.tb \
--manifest touba.manifest.json \
--export trace-audit.export.json
Trace audit (TA-1) produces a validation report and can write a trace-audit-export-v1-local export.
It verifies only explicitly supplied artifacts: trace, AIR, source, runtime manifest, or audit manifest. It computes sha256 digests, checks structural coherence, and refuses obvious leaks according to the selected redaction policy.
Cryptographic signatures, legal timestamping, immutable storage, and compliance guarantees are separate evidence layers.
Sensitive Data
- AIR references
- Secret handle names
- Secret-handle authorizations or refusals
- Capabilities
- Schema paths
- Expected or observed types
- Secret values
- Raw values sent to the decision provider
- Full prompt or complete model input
- Raw runtime observations returned to the decision provider
- Raw external trigger payload
- Exact values of local bindings
- Exact
askanswers inuser_interaction_answered - Hard-kill system signal
- Distributed control-plane state
- Distributed quota
- Complete sensitive payloads
- Raw memory content
- Memory trust score
VerifiedorUnverifiedstatus
Parallel causality
Events are parallel_group_admitted, parallel_group_refused,
parallel_branch_started, parallel_branch_completed,
parallel_branch_suspended, parallel_join_completed,
parallel_join_failed and parallel_group_resumed.
Descendant events carry group_id, branch_id and parent_branch_id,
stable on resume. Local event order is not a total order of external systems.
Results and private continuation journals are not public trace payloads.
Branch show messages are published in input order.
Observation time
Each new native event carries observed_at in UTC
YYYY-MM-DDTHH:mm:ss.sssZ format. Trace and checkpoint digests cover this
timestamp. Resume preserves recorded events and timestamps new events when
they execute. sequence_index determines causal order; time comes from the host.
OpenTelemetry export uses those instants. For an older trace without timestamps, it explicitly identifies its synthetic time projection.