Schedules saved in 6.3 are stored on the IR but do not fire. Phase
6.5 (cron scheduler service) is what actually invokes runs. The
Schedule tab surfaces this with a yellow banner so the gap is never
hidden.
The Schedule tab in the Flow Editor UI
edits the optional ir.schedule field. It supports all three kinds the
scheduleSchema accepts.
Kinds
| Kind | Editor surface | IR shape |
|---|
| cron | text input + 6 preset shortcuts + tz dropdown | { kind: "cron", expression: "0 9 * * 1", timezone: "UTC" } |
| interval | minutes input (1–1440 bounded) | { kind: "interval", minutes: 15 } |
| rrule | RRule string + tz dropdown | { kind: "rrule", rrule: "FREQ=DAILY;COUNT=10", timezone: "UTC" } |
Cron presets
Built-in shortcuts in the cron editor:
- Every 15 minutes →
*/15 * * * *
- Every hour →
0 * * * *
- Daily at 09:00 →
0 9 * * *
- Weekdays at 09:00 →
0 9 * * 1-5
- Mondays at 09:00 →
0 9 * * 1
- First of month 09:00 →
0 9 1 * *
”Next 5 fires” preview
Live preview block recomputes on every change. Backed by the
nextFireTimes(schedule, n) helper (lib/flow/schedule/):
- cron uses
cron-parser v5 with timezone support
- rrule uses
rrule v2; honors COUNT and UNTIL
- interval is pure arithmetic from
now
Preview failures (bad cron expression, malformed rrule) surface as a
red error block with the underlying parser message — preserved via
Error.cause.
Saving
Save → POST /api/v1/pipelines/:id/ir with the new IR (mutated
schedule field) → bumps IR version → version pill in the editor topbar
updates → preview re-loads from the new IR.
What’s not in 6.3
- Schedule actually fires → Phase 6.5 (cron scheduler service)
trigger.file_arrival.deadline.{windowMinutes, onMiss} editor →
Phase 6.5 alongside scheduler dispatch
- Visual cron-spec dropdown (“every X minutes between 9-5 on weekdays”
builder) → polish plan after 6.5 lands