Trigger
A trigger describes a governed event entry.
It answers the question:
when this event arrives,
run this Touba strategy,
with these limits,
if the manifest explicitly activates it.
A trigger is not an open cron, a direct webhook, or a handler that decides by itself to launch an agent. In Touba, the trigger compiles to AIR, the manifest activates it, the runtime verifies it, and the trace makes acceptance or refusal observable.
Syntax
trigger DailyResearchSchedule
on schedule "every 1s"
runs strategy DailyResearch
limits
max_runs_per_day as 1
timeout_ms as 30000
Touba accepts two V1 families:
trigger Name
on schedule "every 1s"
runs strategy StrategyName
limits
max_runs_per_day as 1
timeout_ms as 30000
trigger WebhookRun
on request POST "/webhook/run"
runs strategy StrategyName
with message as payload.message
limits
max_runs_per_day as 10
timeout_ms as 30000
The schedule runner supports every <n>s, every <n>m, and every <n>h
intervals. The HTTP ingress service routes request triggers by their declared
method and path. Full cron syntax, calendar time zones, distributed queues, and
cloud adapters are separate extensions.
Complete Example
module examples.daily_research
strategy DailyResearch
takes topic as Text
do
show
with message as "Daily research run: " ++ topic
trigger DailyResearchSchedule
on schedule "every 1s"
runs strategy DailyResearch
with topic as "daily review"
limits
max_runs_per_day as 1
timeout_ms as 30000
Manifest
The trigger remains inactive until the manifest activates it.
{
"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 manifest may restrict a limit declared in Touba source. It cannot silently broaden it.
Foreground Runner
touba trigger run daily_research.air.json \
--manifest touba.manifest.json \
--trigger trigger:examples.daily_research/DailyResearchSchedule \
--max-runs 1 \
--state touba.triggers.sqlite
The runner waits for the declared interval, generates a normalized event, then
lets the runtime verify the manifest and limits before executing the strategy.
--max-runs is required. SQLite state defaults to .touba/triggers.sqlite;
--state selects another location. Durable state keeps event_id values,
refusals, and the UTC day key used by max_runs_per_day.
Webhook Service
touba trigger serve webhook.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
The service opens an HTTP endpoint for every request trigger activated by the
manifest. A POST /webhook/run request becomes a normalized
source_kind=request event, is appended to the durable
touba-trigger-queue-v1 queue, then is executed by the runtime. The raw HTTP
payload is not written to the queue, state, or trace; the service stores the
necessary metadata, including body size and SHA-256 digest.
The manifest can declare a payload contract. In that case, the service accepts
only the declared format, content types, and maximum size, then extracts the JSON
fields listed in payload.map. These fields become the only persisted arguments
for the target strategy, and the runtime revalidates them against the Touba
signature before execution.
The x-touba-event-id header lets the caller provide a stable event identity.
If the same event_id is replayed for the same trigger, TD-1 state raises
TriggerReplayRejected before the strategy runs again. Non-loopback interfaces
require --auth-token-env. For webhooks exposed to an external provider,
--signature-secret-env adds HMAC-SHA256 verification through
x-touba-signature: sha256=<hex>. The queue requeues stale processing entries
and can mark repeated failures as dead_lettered.
Trace
A trigger-driven run can produce events such as:
trigger_event_receivedtrigger_event_acceptedtrigger_event_refusedtrigger_execution_startedtrigger_execution_completed
Traces must not contain raw external payloads, secrets, or credentials.
Runtime Contract
- Governed
scheduleandrequestentries compile into AIR. - The manifest explicitly activates each trigger.
- The runtime verifies limits before execution.
- The webhook service persists a
touba-trigger-queue-v1queue. - Incoming JSON payloads are governed by a manifest contract.
- HMAC-SHA256 signatures, bounded retries,
processingrecovery, and dead-letter are available. - Distributed schedulers, distributed queues, cloud adapters, direct agent triggering, manifest auto-discovery, and complete system sandboxing are separate platform layers.