Native schedules were a bounded subset: one UTC interval of a day or two
seconds, the skip policy, no jitter, at most one run, the default namespace.
They now follow published PHP 2.5.14:
- cron expressions exactly as dragonmantank/cron-expression 3.6.0 evaluates
them, including PHP's DateTime rules around daylight-saving changes,
time zone names as new DateTimeZone() reads them, and computeNextFireAt
over cron expressions and offset intervals;
- creation with PHP's Laravel validation rules, messages and normalization,
any schedule id, jitter, run quota, memo, note and creation paused;
- triggerDetailed and the tick: all six overlap policies, buffering and its
drain, closing the other run, stale and exhausted occurrences, failures,
the recent-actions ring and the next fire time after each fire;
- PHP's description, history snapshot and history page shapes, pause and
resume notes, and namespace-scoped schedules.
scripts/conformance/cron-oracle regenerates the committed corpora of PHP's
own answers from the frozen image; native matches all of them. The new
schedule-policies fixture compares 60 responses with a reviewed copy of
published PHP's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #325.
Native schedules now run PHP's schedule definitions as published Server 2.5.14 runs them. Before this change, native accepted only a narrow subset.
What changes
schedule_cron.rsportsdragonmantank/cron-expression3.6.0: validation, aliases, names, ranges, steps, lists,L,W,#and?, the 1,000-step search limit, and PHPDateTimebehaviour around daylight-saving changes.schedule_zones.rsreads zone names asnew DateTimeZone()does: numeric offsets, PHP's 144 abbreviations, and IANA names in any case.schedule_spec.rscomputes the next fire time across several cron expressions and offset intervals, using PHP'sDateIntervalgrammar.Deliberate differences
schedule_not_paused; PHP returns an unhandled 500.stale_occurrence.Evidence
scripts/conformance/cron-oracleregenerates three corpora byte for byte from the frozen PHP image. Native matches all of them:schedule-policiesfixture sends 60 requests and compares every response with reviewed published-PHP output. It passed locally on published PHP, embedded and this branch's native build; native from main fails it.Next: update, listing (visibility query and page tokens) and backfill; then narrowing the takeover schedule refusal (#568).
🤖 Generated with Claude Code