revka cron
Schedule recurring, one-shot, interval, and delayed tasks from the command line.
revka cron schedules tasks that the Revka runtime runs for you automatically — recurring on a cron expression, repeating on a fixed interval, or firing once at a future moment. Each job runs as either a shell command or an agent prompt, and the whole subsystem is backed by a SQLite database that the daemon’s scheduler polls.
This page is the CLI reference for creating and managing jobs: the four ways to schedule (add, add-every, add-at, once), how to list, update, pause, resume, and remove them, the timezone semantics of --tz, and the agent-only flags --agent and --allowed-tool. For the conceptual model and the expression syntax in depth, see Cron overview & expressions and Agent jobs & delivery.
Schedule types at a glance
Section titled “Schedule types at a glance”Every job uses exactly one of three schedule shapes. The CLI exposes each through a dedicated subcommand:
| Subcommand | Schedule shape | Repeats? | Timezone-aware? |
|---|---|---|---|
revka cron add <expr> <cmd> | cron expression | Yes | Yes (--tz) |
revka cron add-every <ms> <cmd> | every N milliseconds | Yes | No |
revka cron add-at <rfc3339> <cmd> | once at an absolute UTC time | No | No (always UTC) |
revka cron once <delay> <cmd> | once after a relative delay | No | No |
Only cron-expression jobs honor --tz. Interval and one-shot schedules are timezone-agnostic — add-at and add-every ignore wall-clock zones entirely.
Add a recurring job
Section titled “Add a recurring job”revka cron add takes a cron expression and a command:
# Shell job: every five minutesrevka cron add '*/5 * * * *' 'echo ok'
# Shell job: weekdays at 09:00 in a specific timezonerevka cron add '0 9 * * 1-5' --tz Asia/Seoul 'python3 /opt/report.py'Key flags:
| Flag | Applies to | Meaning |
|---|---|---|
--tz <IANA_TZ> | cron jobs only | IANA timezone name (e.g. America/Los_Angeles). Default: UTC |
--agent | all add variants | Treat the trailing argument as an agent prompt, not a shell command |
--allowed-tool <NAME> | agent jobs only (repeatable) | Restrict which tools the agent may use |
On success the CLI prints the generated job id, the resolved expression, and the next fire time:
✅ Added cron job 7b3f1c20-...-9a Expr: 0 0 9 * * 2-6 Next: 2026-06-19T00:00:00+00:00 Cmd : python3 /opt/report.pyNote the Expr shown is the normalized 6-field form — see Expression normalization for why 1-5 became 2-6.
Add an interval job
Section titled “Add an interval job”revka cron add-every repeats every N milliseconds:
# Shell job every hour (3,600,000 ms)revka cron add-every 3600000 'echo hourly'
# Agent job every 15 minutesrevka cron add-every 900000 --agent 'Check disk space and summarize'The interval must be a positive integer. Interval jobs are not affected by --tz.
Add a one-shot job
Section titled “Add a one-shot job”There are two ways to fire a job exactly once.
After a relative delay
Section titled “After a relative delay”revka cron once accepts a human-readable delay:
revka cron once 1h 'backup create'revka cron once 30m --agent 'Check the build and post the result'The delay is a number followed by a unit:
| Unit | Meaning |
|---|---|
s | seconds |
m | minutes |
h | hours |
d | days |
At an absolute timestamp
Section titled “At an absolute timestamp”revka cron add-at takes an RFC 3339 (ISO 8601) UTC timestamp. The offset is required, and the time must be in the future at the moment of creation:
revka cron add-at 2026-12-31T23:59:00Z 'echo new year'revka cron add-at 2026-07-01T08:00:00Z --agent 'Send the monthly reminder'Agent jobs
Section titled “Agent jobs”Pass --agent to any add variant to schedule an agent prompt instead of a shell command. The trailing positional argument becomes the prompt that the Revka agent runs at fire time:
revka cron add '0 9 * * 1-5' --agent 'Summarize overnight alerts'revka cron add-every 3600000 --agent 'Check server health'revka cron once 30m --agent 'Follow up on the open incident'Agent jobs run in an isolated, fresh session by default and inject relevant memory context before the prompt. They are blocked when the agent is in read-only mode. To control session sharing, model overrides, and output delivery to a chat channel, use the cron_add agent tool or declarative config — those surfaces are covered in Agent jobs & delivery.
Restricting tools with --allowed-tool
Section titled “Restricting tools with --allowed-tool”For agent jobs you can whitelist exactly which tools the agent may call during that job. Repeat --allowed-tool once per tool:
revka cron add '*/15 * * * *' --agent \ --allowed-tool file_read \ --allowed-tool web_search \ 'Check the changelog feed and note anything new'When set, only the listed tools are available to that job. When omitted, all tools remain available.
List jobs
Section titled “List jobs”revka cron list prints every registered job with its id, schedule, next and last run times, and last status:
revka cron list🕒 Scheduled jobs (2):- 7b3f1c20-...-9a | Cron { expr: "0 0 9 * * 2-6", tz: Some("Asia/Seoul") } | next=2026-06-19T00:00:00+00:00 | last=never (n/a) cmd: python3 /opt/report.py- 9d40f6a1-...-c2 | At { at: 2026-07-01T08:00:00Z } | next=2026-07-01T08:00:00+00:00 | last=never (n/a) prompt: Send the monthly reminderShell jobs show a cmd: line; agent jobs show a prompt: line. The schedule is printed in its internal debug form, so you can see the normalized expression and the stored timezone. If there are no jobs yet, the command prints a short usage hint instead.
Update a job
Section titled “Update a job”revka cron update <id> edits an existing job in place without re-creating it. At least one flag is required:
# Change the schedule and timezonerevka cron update 7b3f1c20 --expression '0 10 * * *' --tz Europe/Berlin
# Change just the timezone, keeping the existing expressionrevka cron update 7b3f1c20 --tz Europe/London
# Change the command and labelrevka cron update 7b3f1c20 --command 'echo updated' --name 'Morning report'| Flag | Meaning |
|---|---|
--expression <EXPR> | New cron expression (preserves the existing --tz if you don’t also pass one) |
--tz <IANA_TZ> | New timezone (preserves the existing expression if used alone) |
--command <CMD> | New shell command (or, for agent jobs, the new prompt) |
--name <NAME> | New human-readable label |
--allowed-tool <NAME> | Replace the agent tool allowlist (repeatable; agent jobs only) |
Pause, resume, and remove
Section titled “Pause, resume, and remove”revka cron pause 7b3f1c20 # disable without deletingrevka cron resume 7b3f1c20 # re-enablerevka cron remove 7b3f1c20 # permanently delete (cannot be undone)A paused job stays in the database with its schedule intact; its next run does not advance while paused. remove deletes the job and its run history (the cron_runs rows cascade). There is no undo.
Timezone semantics
Section titled “Timezone semantics”--tz localizes a cron expression to any IANA timezone. The scheduler computes the next fire time in that zone — correctly across daylight-saving transitions — then stores it as UTC. So '0 9 * * *' --tz America/Los_Angeles fires at 09:00 Los Angeles time year-round, not at a fixed UTC offset.
The timezone name is validated by chrono-tz at creation time; an unknown name is rejected.
Expression normalization
Section titled “Expression normalization”You write standard 5-field crontab expressions (min hour day month weekday). Revka normalizes them to its internal 6-field format before storing, which is why the Expr line in add output and list looks different from what you typed.
Two transformations happen for 5-field input:
- A seconds field is prepended.
0 9 * * *becomes0 0 9 * * *(fire at second 0). - The weekday column is renumbered. Standard crontab uses
0/7= Sunday,1= Monday …6= Saturday. Revka’s internal cron engine uses1= Sunday,2= Monday …7= Saturday. So a weekday of1-5(Mon–Fri) is stored as2-6.
You always write the familiar vixie-cron numbering (1 = Monday); the renumbering is internal. Wildcards (*, ?), named days (MON, MON-FRI), ranges (1-5), lists (0,6), and steps (*/2, 1-5/2) are all supported, and named days pass through without renumbering.
6- and 7-field expressions (which already include a seconds field, and optionally a year) are passed through unchanged — they are assumed to be in the internal format already.
A few examples of what you write and what they mean:
| You write | Meaning |
|---|---|
*/5 * * * * | Every 5 minutes |
0 9 * * * | Every day at 09:00 |
0 9 * * 1-5 | Weekdays at 09:00 |
0 9 * * MON-FRI | Weekdays at 09:00 (named days) |
0 0,12 * * * | Midnight and noon every day |
0 */2 * * * | Every 2 hours, on the hour |
0 2 * * 0 | Sundays at 02:00 |
How CLI jobs relate to other surfaces
Section titled “How CLI jobs relate to other surfaces”Jobs you create here are stored alongside jobs created by the agent tools, the gateway API, and declarative config — they all share the same database and appear together in revka cron list.