Repository navigation
fix(schedule): never schedule a cron run in the past or skip a DST day - #174
Conversation
next_after took the first match from cron's iterator. In a repeated fall-back hour that is the earlier instant, which can be before 'from', so the next run landed in the past. A time inside a spring-forward gap was silently dropped, so a daily job skipped the day the clocks moved. Walk the expression in wall-clock time, resolve each match here, take the first instant strictly after 'from', and run a skipped time at the first valid instant after the gap (cronie's behaviour).
|
Warning Review limit reached
This review includes 2 billable files and costs up to $0.50. Or wait 30 minutes for your next included review. View limit details
Comment |
Tiny Sweeper reviewReviewed head: Findings
Unverified notes — repository context was unavailable; these are not actionable findings Unverified note — critique
Verdict: Changes requested · Priority: high Diagnostics and supporting detailsFull summaryPull request purpose (title): fix(schedule): never schedule a cron run in the past or skip a DST day. Tiny Sweeper completed its review; deterministic results follow. Review snapshot
Completeness: Complete Features
Tests
Before merge
Agent review detailscritique
security
tests
commits
description
Evidence and run details
|
Summary
What was wrong.
ScheduleTimeZone::next_afterreturned the first match fromcron::Schedule::after(..). With cron 0.17 (the latest release), that has two DST bugs:from. With*/15 * * * *in America/New_York andfrom = 2026-11-01T06:10Z(01:10 EST, second pass), the next run came back as05:15Z, 55 minutes in the past.30 2 * * *never ran on 2026-03-08; the next run was2026-03-09T06:30Z.The fix. One helper,
next_wall_clock_run, replaces both arms (named zone and host-local zone). This function is the single choke point for every next-run caller. The helper:from;Spring-forward choice. For a time inside the gap there were two options: keep skipping (the cron crate's default), or run at the first valid instant after the gap. I took the second, which is what cronie does:
30 2 * * *on 2026-03-08 in New York runs at 03:00 EDT. The other choice is a one-line change if maintainers prefer skipping.API Or Behavior Changes
from.Tests
Regression tests (in
schedule_tests.rs,cargo test -p tinyflows-schedule --lib -- <tests>):cron_next_run_in_repeated_fall_back_hour_is_after_from: expects2026-11-01T06:15Z.cron_spring_forward_gap_does_not_skip_the_day: expects2026-03-08T07:00Z(03:00 EDT).Results:
mainsource): 0 passed, 2 failed. The fall-back test got05:15Z; the spring-forward test got2026-03-09T06:30Z.Only those tests were run locally, per our process; CI runs the full matrix.
cargo fmt --check. I ranrustfmton the touched files; CI runs the check.cargo clippy --all-targets -- -D warnings. Left to CI.cargo clippy --all-targets --all-features -- -D warnings. Left to CI.cargo build --all-targets. Left to CI.cargo build --all-targets --all-features. Left to CI.cargo test. Only the targeted tests above were run; CI runs the full suite.cargo test --all-features. Left to CI.Documentation
The new helper's doc comment records the DST rules. No other docs were affected.