Skip to content

feat: day-aligned sync window in local timezone - #3

Merged
razbahri merged 1 commit into
mainfrom
feat/day-aligned-window
May 9, 2026
Merged

razbahri merged 1 commit into
mainfrom
feat/day-aligned-window

Conversation

@razbahri

@razbahri razbahri commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

Changes the sync window from rolling-relative-to-now to day-aligned in the user's local timezone. Same window_past_days / window_future_days config; new semantics inside the daemon.

Why

Old behavior in cli.py:69-70:

start = now - timedelta(days=window_past_days)
end   = now + timedelta(days=window_future_days)

So a sync at 14:23 saw [yesterday 14:23, +30d 14:23]. Two real bugs:

  1. Boundary churn: events near the past edge slid out of the window throughout the day. The daemon deleted them from Google. User saw events vanish for no apparent reason.
  2. CREATE/DELETE flapping: a noon sync saw event X, a 3pm sync didn't, the next sync re-created it. Especially bad for all-day events whose start time was close to the rolling boundary.

What changed

New helper _compute_sync_window(now, past_days, future_days, tz) returns

[midnight(today − past_days) local, midnight(today + future_days + 1) local)

as UTC-aware datetimes. Exclusive end (idiomatic Python). Window is invariant within a local calendar day — every sync of the same day evaluates the same boundaries.

The sync.start log line now prints the window in local time and uses ) for the exclusive end, e.g.:

2026-05-09T11:23:00Z INFO  ogmac.cli sync.start window=[2026-05-08..2026-06-09)

Tests

5 new tests in tests/unit/test_sync_window.py:

  • test_window_aligns_to_local_midnight
  • test_window_invariant_within_a_local_day
  • test_window_zero_days_is_one_day
  • test_window_returns_utc_datetimes
  • test_window_end_is_exclusive

Use a fixed IDT (UTC+3) timezone so they don't depend on the runner's TZ. 177 tests pass (was 172).

Migration

Behavioral, not schematic. First sync after upgrade may:

  • CREATE events newly in scope
  • DELETE events newly out of scope

After that, the window is stable. No state.db migration, no config schema change.

Test plan

  • pytest tests/ → 177 passed
  • ogmac sync → check ~/Library/Logs/ogmac/sync.log: sync.start window=[YYYY-MM-DD..YYYY-MM-DD) shows day-aligned local dates
  • Run two syncs at different times of the same day and verify the same reconcile create=… counts
  • Run on a Mac with non-UTC local timezone and confirm the window flips at local midnight, not UTC midnight

🤖 Generated with Claude Code

Change the sync window from rolling-relative-to-now to day-aligned
in the user's local timezone. Previously cli.py:69-70 computed:

    start = now - window_past_days
    end   = now + window_future_days

So a sync at 14:23 saw [yesterday 14:23, +30d 14:23]. That caused
two real bugs:

1. Boundary churn: events near the past edge slid out of the window
   mid-day, the daemon deleted them from Google, and the user
   noticed events vanish for no apparent reason.
2. Flapping CREATE/DELETE pairs across consecutive runs: a noon sync
   sees event X, a 3pm sync doesn't, the next sync re-creates it.

New helper _compute_sync_window(now, past_days, future_days, tz)
returns [midnight(today − past_days) local, midnight(today + future_days + 1) local)
as UTC-aware datetimes. The window is invariant within a local
calendar day. All-day events near the edge no longer flicker.

The log line now prints the window in local time and uses ")" for
the exclusive end so the format reflects the semantics.

5 new tests cover the alignment, day-invariance, zero-day edge case,
return-tz contract, and exclusive-end semantics — using a fixed
IDT (UTC+3) timezone so the tests don't depend on the runner's TZ.
177 tests pass (was 172).

Migration: behavioral, not schematic. The first sync after upgrade
may CREATE events newly in scope or DELETE events newly out of scope.
After that the window is stable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@razbahri
razbahri merged commit f192e52 into main May 9, 2026
3 checks passed
@razbahri
razbahri deleted the feat/day-aligned-window branch May 9, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant