Cron Scheduler Loop
The core of the scheduling system is a background loop withinpalyrad that monitors pending jobs in the JournalStore. The scheduler operates on a tick-based model with an idle sleep of 15 seconds [crates/palyra-daemon/src/cron.rs#42-42](http://crates/palyra-daemon/src/cron.rs#42-42).
Implementation Details
The scheduler identifies “due” jobs by querying thejournal_cron_jobs table for entries where next_run_at_unix_ms is in the past. It processes these in batches of up to 64 [crates/palyra-daemon/src/cron.rs#43-43](http://crates/palyra-daemon/src/cron.rs#43-43).
- Loopback Dispatch: Jobs are dispatched via a loopback call to the
GatewayService. This ensures that cron-initiated runs go through the same message routing, policy evaluation, and sandbox execution pipeline as user-initiated messages[crates/palyra-daemon/src/cron.rs#29-33](http://crates/palyra-daemon/src/cron.rs#29-33). - Identity: System-initiated cron jobs execute under the
system:daemonprincipal[crates/palyra-daemon/src/cron.rs#55-55](http://crates/palyra-daemon/src/cron.rs#55-55)and use a fixed system device ID[crates/palyra-daemon/src/cron.rs#44-44](http://crates/palyra-daemon/src/cron.rs#44-44). - Timezones: The scheduler supports both
UtcandLocaltimezone modes for evaluating cron expressions[crates/palyra-daemon/src/cron.rs#61-65](http://crates/palyra-daemon/src/cron.rs#61-65).
Cron Job Lifecycle
| State | Description |
|---|---|
| Pending | Job is scheduled but the next_run_at_unix_ms has not been reached. |
| Due | Current time is next_run_at_unix_ms. |
| Running | The job has been dispatched to the GatewayService and is currently active. |
| Finalized | The job completed, and the next_run_at_unix_ms was recalculated based on the schedule. |
[crates/palyra-daemon/src/cron.rs#1-105](http://crates/palyra-daemon/src/cron.rs#1-105), [crates/palyra-daemon/src/journal.rs#34-40](http://crates/palyra-daemon/src/journal.rs#34-40)
Routines and Automation
Routines are higher-level abstractions built on top of the cron scheduler. While a cron job is a raw scheduling entry, a Routine includes metadata for delivery, quiet hours, and approval policies.Routine Configuration
Routines are managed via theRoutineMetadataRecord [crates/palyra-daemon/src/routines.rs#188-203](http://crates/palyra-daemon/src/routines.rs#188-203). Key attributes include:
- Trigger Kind: Supports
Schedule,Hook,Webhook,SystemEvent, andManual[crates/palyra-daemon/src/routines.rs#35-41](http://crates/palyra-daemon/src/routines.rs#35-41). - Delivery Mode: Determines where the output is sent:
SameChannel,SpecificChannel,LocalOnly, orLogsOnly[crates/palyra-daemon/src/routines.rs#69-74](http://crates/palyra-daemon/src/routines.rs#69-74). - Quiet Hours: Defines a window (start/end minute of day) during which the routine will not trigger
[crates/palyra-daemon/src/routines.rs#167-172](http://crates/palyra-daemon/src/routines.rs#167-172). - Approval Policy: Can require approval
BeforeEnableorBeforeFirstRun[crates/palyra-daemon/src/routines.rs#125-129](http://crates/palyra-daemon/src/routines.rs#125-129).
Code Entity Mapping: Routine Logic
Title: Routine Entity Relationship Sources:[crates/palyra-daemon/src/routines.rs#1-203](http://crates/palyra-daemon/src/routines.rs#1-203), [crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#53-107](http://crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#53-107)
Misfire and Concurrency Policies
The scheduler handles edge cases where the daemon might have been offline or multiple jobs overlap.Misfire Policies
Defined inCronMisfirePolicy [crates/palyra-daemon/src/journal.rs#35-35](http://crates/palyra-daemon/src/journal.rs#35-35):
- Fire Once: If multiple runs were missed, only trigger one run immediately and then resume the schedule.
- Ignore: Skip all missed runs and wait for the next scheduled time.
Concurrency Policies
Defined inCronConcurrencyPolicy [crates/palyra-daemon/src/journal.rs#35-35](http://crates/palyra-daemon/src/journal.rs#35-35):
- Allow: Multiple instances of the same job can run simultaneously.
- Forbid: If a previous instance is still running, the new trigger is skipped.
- Replace: The running instance is cancelled, and the new one starts.
[crates/palyra-daemon/src/cron.rs#34-40](http://crates/palyra-daemon/src/cron.rs#34-40), [crates/palyra-daemon/src/journal.rs#34-40](http://crates/palyra-daemon/src/journal.rs#34-40)
Background Maintenance Tasks
The scheduler loop is responsible for several internal system health routines that do not appear as user-visible cron jobs.Skill Re-audit Task
To ensure security posture remains current, the daemon periodically re-audits installed WASM skills against the trust store.- Interval: Default is 6 hours
[crates/palyra-daemon/src/cron.rs#54-54](http://crates/palyra-daemon/src/cron.rs#54-54). - Mechanism: Iterates through the
InstalledSkillsIndex[crates/palyra-daemon/src/cron.rs#107-111](http://crates/palyra-daemon/src/cron.rs#107-111)and callsaudit_skill_artifact_security[crates/palyra-daemon/src/cron.rs#18-18](http://crates/palyra-daemon/src/cron.rs#18-18).
Memory Maintenance
The memory system requires periodic background processing to maintain performance and relevance.- Vacuuming: Triggered every 5 minutes (
MEMORY_MAINTENANCE_INTERVAL)[crates/palyra-daemon/src/cron.rs#56-56](http://crates/palyra-daemon/src/cron.rs#56-56). This performs SQLiteVACUUMand cleanups. - Embeddings Backfill: Triggered every 10 minutes
[crates/palyra-daemon/src/cron.rs#57-57](http://crates/palyra-daemon/src/cron.rs#57-57). It processes items missing vector embeddings in batches of 64[crates/palyra-daemon/src/cron.rs#58-58](http://crates/palyra-daemon/src/cron.rs#58-58).
[crates/palyra-daemon/src/cron.rs#42-58](http://crates/palyra-daemon/src/cron.rs#42-58), [crates/palyra-daemon/src/transport/http/handlers/console/system.rs#140-149](http://crates/palyra-daemon/src/transport/http/handlers/console/system.rs#140-149)
HTTP Handlers and CLI Integration
Routines and Cron jobs are managed via the Console API and thepalyra cron CLI command.
Console API Routes
Theroutines handlers in axum manage the persistence of routine definitions:
GET /console/v1/routines: Lists routines with filters fortrigger_kind,enabled, andchannel[crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#154-182](http://crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#154-182).POST /console/v1/routines/upsert: Creates or updates a routine, including its schedule and delivery config[crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#53-107](http://crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#53-107).POST /console/v1/routines/dispatch: Manually triggers a routine execution[crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#125-134](http://crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#125-134).
CLI Commands
The CLI maps these HTTP endpoints to user commands:palyra cron add: Builds aScheduleRoutineConfigand calls the upsert handler[crates/palyra-cli/src/commands/cron.rs#51-89](http://crates/palyra-cli/src/commands/cron.rs#51-89).palyra cron status: Retrieves a summary of scheduled tasks and their next run times[crates/palyra-cli/src/commands/cron.rs#23-34](http://crates/palyra-cli/src/commands/cron.rs#23-34).
[crates/palyra-cli/src/commands/cron.rs#14-173](http://crates/palyra-cli/src/commands/cron.rs#14-173), [crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#1-215](http://crates/palyra-daemon/src/transport/http/handlers/console/routines.rs#1-215)