Cron Triggers

Cron triggers run workflows on a schedule, create an ephemeral agent for each run, and record scheduled workflow history.

What cron triggers do

A cron trigger starts a workflow from time instead of an issue tracker event. Use cron workflows for recurring repository maintenance, dependency updates, nightly checks, reports, audits, or other bounded work that should run without a person clicking a button.

Each scheduled fire creates a workflow run, provisions a new agent, injects cron context into the run, and terminates the agent when the workflow reaches a terminal stage.

Basic workflow

yaml
schema_version: v1
name: dependency-maintenance
enabled: true

trigger:
  cron:
    schedule: "0 9 * * 1"
    timezone: "America/Chicago"
    overlap_policy: skip
    timeout: 2h

provider: daytona
tags: ["cron", "dependencies"]
color: cyan

stages:
  - id: working
    label: Working
    entry: true
    on_enter:
      inject: |
        This is a scheduled dependency maintenance run.

        Inspect go.mod, package.json, and lockfiles.
        Apply safe patch and minor updates.
        Run tests.
        Open one grouped PR if changes are ready.
        Say [DONE] when the PR is open or no updates are needed.

  - id: complete
    label: Complete
    triggers:
      - message_contains: "[DONE]"
    terminal: true
Cron workflows are still normal workflows. Stages, gates, run actions, labels, PR watchers, and terminal stages work the same way as issue-triggered workflows.

Cron fields

schedule - Required cron expression, such as 0 9 * * 1. Descriptors such as@daily are also supported.

timezone - Optional IANA timezone. If omitted, the schedule uses UTC.

overlap_policy - Optional. Controls what happens when the next scheduled time arrives while a previous run is still active.

timeout - Optional Go-style duration such as 30m, 2h, or1h30m.

Overlap policy

Cron workflows should usually avoid overlapping runs. The default policy is skip.

skip - If a previous run is active, record the new run as skipped and do not create another agent.

queue - Reserved for queued follow-up runs. In the current implementation, queued runs are skipped when another run is active.

parallel - Allow multiple active runs for the same workflow.

yaml
trigger:
  cron:
    schedule: "0 */6 * * *"
    timezone: "UTC"
    overlap_policy: skip

Run context

Scheduled runs receive generated context so the agent can distinguish a cron run from a manual or issue-triggered run.

json
{
  "run_id": "5f35f8f6-7a2a-4f32-bb50-6e0cbd53c6ef",
  "scheduled_at": "2026-06-15T14:00:00Z",
  "workflow_name": "dependency-maintenance",
  "workspace_name": "engineering",
  "trigger_type": "cron"
}

Manual runs

Cron workflows can be triggered manually from the CLI when the cron scheduler is available. Manual runs use the same workflow definition and run history as scheduled runs.

bash
elasticclaw workflow trigger dependency-maintenance --workspace engineering --cron
Disabled workflows cannot be triggered by cron. Set enabled: false to pause a scheduled workflow.

Run history

ElasticClaw records cron workflow runs with status, result, claw ID, timestamps, and run context.

bash
elasticclaw workflow runs dependency-maintenance --workspace engineering --limit 20
elasticclaw workflow logs dependency-maintenance <run-id> --workspace engineering

Run statuses include pending, running,completed, failed, skipped,timed_out, and canceled.

Cron triggers in v2 workflows

v2 workflows declare cron triggers under a top-level trigger block. The syntax is similar to v1, but the workflow must be enabled: true and uses v2 states and transitions instead of stages.

yaml
schema_version: 2
name: dependency-maintenance
enabled: true
initial_state: update_dependencies

trigger:
  cron:
    schedule: "0 9 * * 1"
    timezone: "America/Chicago"
    overlap_policy: skip
    timeout: 2h

states:
  update_dependencies:
    description: Inspect manifests, apply safe updates, and open a grouped PR if needed.
    phase: build
    on_enter:
      effects:
        - dependency.update:
            ecosystems: [go, npm]
            include_major: false
        - agent.task:
            prompt: |
              If dependency.update produced changes, commit them, run tests,
              and open one grouped PR. If no updates were needed, finish
              without opening a PR.
  pr_open:
    description: Grouped dependency update PR is open.
    phase: pr
    terminal: true
  no_updates:
    description: No dependency updates were necessary.
    phase: done
    terminal: true

transitions:
  dependency_pr_opened:
    from: update_dependencies
    on: pull_request.verified_open
    when:
      pull_request:
        state: open
    to: pr_open

commands:
  skip:
    from: [update_dependencies]
    to: no_updates
    require_reason: false

overlap_policy supports skip (default) and parallel. v1 queue is converted to skip with a warning. In v2, state descriptions are metadata; the real work starts via on_enter.effects. The example above can complete via a verified PR or the skip command when no updates are needed. Invoke the command from the CLI:

bash
# Trigger a cron workflow manually
elasticclaw workflow trigger dependency-maintenance --workspace engineering --cron

# Invoke the skip command while the run is in update_dependencies
elasticclaw workflow command dependency-maintenance skip --workspace engineering

# View cron run history (including skipped ticks)
elasticclaw workflow runs dependency-maintenance --workspace engineering --cron

Recommended patterns

Use overlap_policy: skip for maintenance workflows. This prevents daily or hourly schedules from piling up when a run takes longer than expected.

Keep the entry message explicit. Tell the agent whether to open a PR, skip when no work is needed, and what completion signal to use.

Add deterministic run and gate stages for tests or scanners when a workflow should only proceed after a tool reports a clean result.

Use one grouped PR per scheduled run for dependency maintenance unless major, security, or runtime updates need separate handling.