Scheduling

Pinard can spawn agents on a cron schedule — for nightly syncs, periodic checks, or any recurring task. The scheduler runs inside the daemon (every 60s) and reads schedules.yaml.

A single sketched scheduling sequence: a clock dispatches through the daemon to a vendangeur and vigne task, then outcomes notify the conductor. Schedule Daemon Vendangeur Vigne task Outcome event Conductor
The normal dispatch path. The daemon evaluates the schedule, starts a vendangeur in the vigne, and reports the outcome to the conductor. Backfill behavior is described below.
  • 1Normal dispatch — the daemon evaluates the cron entry and spawns a worker.
  • 2Backfill — a missed evaluation is found from the last-run ledger after restart.
  • BBranch — the worker starts from the vigne's configured default branch.
  • !Events — spawned, skipped, and failed outcomes require conductor acknowledgement.

Define a schedule

aoc add schedule nightly-sync \
  --project mnemosyne \
  --cron "0 2 * * *" \
  --prompt "Run the sync task and open an MR if anything changed"

This appends to schedules.yaml:

schedules:
  nightly-sync:
    project: mnemosyne
    cron: "0 2 * * *"
    prompt: "Run the sync task and open an MR if anything changed"
    once: false
FieldMeaning
projectVigne to spawn the agent in
cronStandard 5-field cron expression
promptTask prompt for the spawned agent
onceIf true, the schedule disables itself after its first successful run

Manage schedules

aoc list-schedules            # schedules and their last run times
aoc unschedule --name nightly-sync

You can also edit schedules.yaml directly — the daemon hot-reloads it.

Branch selection

Scheduled spawns base their worktree on the vigne’s default branch (the same rule the issue watcher uses). If a project’s default branch isn’t main, scheduled runs still start from the right place — no extra configuration needed.

Backfill

The scheduler tracks the last run time per schedule in .state/scheduler-runs.yaml. If the daemon was down across a scheduled tick, it evaluates whether the run was missed and backfills rather than silently skipping.

Events

Each evaluation emits a scheduler event to the conductor (schedule_spawned, schedule_skipped, or schedule_failed) as ACK_REQUIRED, so nothing runs unnoticed.