Scheduled triggers
Use cron-schedule event triggers to run periodic work — daily summaries, stale-task reminders, trust decay audits — without external schedulers.
What they are
Event triggers in Syncropel are stored as LEARN records on
th_engine_config with body.topic = "event_trigger". They come in
two flavors:
- Record-matching — fire when a record matching a CEL expression is ingested (documented in Routing rules)
- Schedule-based (this guide) — fire when a cron schedule elapses
This guide is about the schedule flavor — the "give me a daily summary at 9am" pattern. No external scheduler needed; the kernel's CRON loop evaluates schedules on every tick.
Prerequisites
- Running
spl servedaemon - An actor DID to dispatch to (typically
did:sync:agent:<role>) - The actor must have a registered adapter (see Actors and adapters)
Quickstart — daily summary
Dispatch your dev agent every morning at 9am to summarize yesterday's work:
spl config add-trigger \
--name "daily-summary" \
--schedule "0 9 * * *" \
--target "did:sync:agent:dev" \
--goal "Summarize yesterday's commits + open tasks, post as KNOW on th_daily_summary" \
--cooldown 300 \
--budget 0.5 \
--timeout 600Cron format is standard: minute hour day month weekday. The above
reads "at 9am UTC every day". The daemon evaluates each cron on every
tick_interval_ms (default 1s), so firing resolution is ~1s.
Verify the trigger
spl config list-triggersLook for your new entry. Confirm it's enabled: true and the schedule
matches. To see past firings:
spl config trigger-history --limit 10Each row shows the trigger name, firing time, thread id produced, and cost.
Common patterns
Stale-task reminder
Fire every 4 hours, poke any tasks that have been in_progress >48h:
spl config add-trigger \
--name "stale-task-check" \
--schedule "0 */4 * * *" \
--target "did:sync:agent:ops" \
--goal "For each task where status == in_progress and age > 48h, emit KNOW with reminder" \
--budget 0.2 \
--timeout 300Trust decay audit
Weekly Wilson-LB-dropped actors get surfaced for operator review:
spl config add-trigger \
--name "weekly-trust-audit" \
--schedule "0 10 * * MON" \
--target "did:sync:agent:auditor" \
--goal "List actors whose trust.code.effective dropped >0.1 in the past 7 days" \
--budget 0.3Fleet heartbeat verification
Every 15 minutes, fail-fast if any fleet peer hasn't posted health:
spl config add-trigger \
--name "fleet-peer-liveness" \
--schedule "*/15 * * * *" \
--target "did:sync:agent:ops" \
--goal "Alert if any fleet peer has not heartbeat in 5 minutes" \
--budget 0.1 \
--timeout 180Cron expression cheatsheet
| Spec | Fires |
|---|---|
0 9 * * * | 9:00am every day (UTC) |
*/15 * * * * | Every 15 minutes |
0 */4 * * * | Every 4 hours on the hour |
0 10 * * MON | 10:00am every Monday |
0 0 1 * * | Midnight on the 1st of every month |
30 8 * * MON-FRI | 8:30am on weekdays |
Schedules are UTC. If you want a local-time firing, offset accordingly.
Rate limiting
--cooldown <secs> throttles a trigger's firings. Useful if the CEL
schedule somehow produces double fires, or if you want a defensive
minimum gap.
Turn a trigger off
# Remove by name
spl config remove-trigger --name daily-summary
# Or disable without removing (preserves history)
spl config update-trigger --name daily-summary --enabled falsePairs with
- Routing rules — record-matching triggers with actions
- CEL expressions — the expression language for record-matching trigger conditions
- Actors and adapters — how dispatched actors actually run
Routing Rules
Control how records are routed to actors — match patterns, set targets, and let the system learn.
CEL Expressions
Write rules, gates, and predicates using Syncropel's canonical expression language — one syntax for triggers, routing, preconditions, fold rules, health checks, AITL, permissions, and fan-out join predicates.