Skip to content

fix(sync): project a create at the calendar's active generation - #2528

Merged
tyler-dane merged 2 commits into
mainfrom
claude/sync-create-generation-stamp
Aug 1, 2026
Merged

fix(sync): project a create at the calendar's active generation#2528
tyler-dane merged 2 commits into
mainfrom
claude/sync-create-generation-stamp

Conversation

@tyler-dane

Copy link
Copy Markdown
Contributor

Problem

Reads serve a calendar's active generation. Provider-linked creates hardcoded their occurrences to generation: 0. On a calendar that a repair had already advanced (active generation 1+), a newly created event was written to the provider successfully and then invisible in Compass — it renders optimistically, the refetch returns server truth without it, and it disappears.

This was a known, documented trade-off: the comment said the next incremental pull would re-read the event and reproject it at the active generation, so the window was small and self-closing. That holds only while pulls are running. When the reconcile sweeps froze on 2026-07-31 (fixed in #2527), the window stayed open for a day, and a user watched events save to Google and vanish from Compass.

Change

Resolve the generation via the existing activeGenerationByCalendar — the same lookup reads use — so the write lands where the read will look. A calendar with no events resource still yields 0, which is what cloud-only calendars want.

This threads a resources repository through ProviderMutationDeps and CloudCommandDeps, which is the dependency the original comment declined to add. It is worth it now: the assumption it was avoiding turned out to be violable for a full day, and the type checker enumerated every construction site.

Cloud-only creates are untouched — they live on calendars with no provider sync resource, so generation 0 is unconditionally correct there and the existing comment says so.

Tests

New regression test: a create onto a calendar whose active generation is 1 is visible to a read at generation 1. It fails on main and passes here.

749/749 sync tests pass; type-check and lint clean.

🤖 Generated with Claude Code

tyler-dane and others added 2 commits July 31, 2026 18:53
A job doc written before requeuedCount existed could not be parsed back out.
Enqueue coalesces onto whatever doc already holds a key and re-parses it, and
the sweep loop had no per-item guard, so a single such doc abandoned the whole
batch. The finders sort deterministically, so the same resource re-won the
front of the ordering every cycle and nothing behind it ever ran again:
calendar sync stopped fleet-wide for 23h.

- requeuedCount defaults to 0 when absent, so a job predating the field is
  read as valid work rather than an error
- the sweep enqueues each resource independently, reporting and skipping one
  that throws, and returns what it actually enqueued rather than what it found
- the self-heal sweep now matches jobs missing the field; Mongo's {$lt: n}
  skips them, so the jobs most likely to be wedged were the only ones it could
  never see

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reads serve a calendar's active generation, but provider-linked creates
hardcoded their occurrences to generation 0. On a calendar a repair had
already advanced, a newly created event saved successfully to the provider
and was then invisible in Compass.

That gap was knowingly left to self-heal on the next incremental pull, which
holds only while pulls are running. When the sweeps froze on 2026-07-31 the
window stayed open for a day and users watched new events vanish.

Resolves the generation via the existing activeGenerationByCalendar, which is
the same lookup reads use, so the write lands where the read will look.
Threads the resource repository through ProviderMutationDeps and
CloudCommandDeps to do it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tyler-dane
tyler-dane merged commit 9555328 into main Aug 1, 2026
20 checks passed
@tyler-dane
tyler-dane deleted the claude/sync-create-generation-stamp branch August 1, 2026 01: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