Skip to content

Make app schedules timezone-durable via IANA identity - #314

Closed
miljanm wants to merge 1 commit into
mobius-os:mainfrom
miljanm:fix/schedules-timezone-durable
Closed

Make app schedules timezone-durable via IANA identity#314
miljanm wants to merge 1 commit into
mobius-os:mainfrom
miljanm:fix/schedules-timezone-durable

Conversation

@miljanm

@miljanm miljanm commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #290, redesigned per its review: the offset-snapshot fields (tz_name/tz_offset_minutes) are gone. The durable schedule identity is now an IANA timezone plus a zone-local daily cron, and the scheduler owns it end to end.

Design

  • POST /api/apps/{id}/schedule accepts an optional timezone (IANA). The identity is declared as SCHEDULE_TZ/SCHEDULE_SOURCE lines in the app's init-cron.sh (parsed, never executed — same contract as ENTRY), written by the platform after the scaffold runs; the scaffold's own interface is unchanged.
  • The crontab entry is that identity's server-local materialization (app/cron_tz.py), recomputed by the existing boot reconciliation and by an hourly in-process pass — so a DST transition in either zone explicitly reschedules the entry instead of drifting its wall time. The periodic pass only runs while a zone declaration exists.
  • GET /api/apps/schedules exposes the durable identity (timezone, zone_cron) plus server_timezone, the server clock's own IANA name (TZ env, /etc/localtime, else UTC) — no abbreviations, no offsets.
  • Only plain daily expressions (m h * * *) may carry a zone: shifting across an offset can cross a day boundary, which is well-defined daily and ambiguous for date-pinned expressions. Anything else is rejected with a 400.

Tests cover both 2026 European DST boundaries in both directions of ownership (zone-owned schedule on a UTC server; UTC-owned schedule on a DST-observing server), day-boundary wrap (UTC+5:45), declaration parsing incl. malformed halves, endpoint validation, and reconciliation re-materializing a stale entry from its declaration.

The companion app-memory PR feeds this from the schedule settings UI and degrades to server-local against an older backend.

🤖 Generated with Claude Code

Co-authored-by: Möbius Agent <mobius-agent@users.noreply.github.com>
@miljanm miljanm added area: backend Server and API behavior enhancement New feature or request labels Jul 28, 2026
@miljanm
miljanm requested a review from hamzamerzic July 28, 2026 12:11
@hamzamerzic

Copy link
Copy Markdown
Collaborator

I found two correctness blockers while reviewing this PR and prepared a focused follow-up directly on its current head (b126a85cf):

  • a static UTC-offset snapshot cannot preserve an IANA wall-clock schedule across DST gaps/folds;
  • the live crontab was changed before the durable timezone declaration was appended, so a later write failure could return an error after behavior had already changed.

The follow-up uses a supervised wall-clock gate with explicit gap/fold policy and an atomic per-app/date claim, and installs the complete durable declaration before any live crontab change. It also removes the obsolete hourly rematerializer.

Reviewed commit: https://github.com/hamzamerzic/mobius-1/commit/f31100d58f17f1e80e0346c7671c7ee67cfda72b

Verification: 231 relevant tests passed (3 skipped), 46 focused regressions passed, Python compilation, shell syntax, and diff checks passed. The tradeoff is one lightweight gate process per timezone-owned app per minute; 1,439 ordinary non-due ticks exit before token minting or job authority.

@hamzamerzic

Copy link
Copy Markdown
Collaborator

Superseded by #339, which has now merged. The replacement preserves durable IANA timezone identity while fixing the unsafe partial-application order, evaluating daylight-saving transitions from the zone rules rather than a captured offset, failing invalid declarations closed, and claiming at most one run per local civil date. Closing this original version rather than merging its known failure paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: backend Server and API behavior enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants