Verdict: APPROVE for source and preview. No public launch claim. Reviewer model: claude-fable-5-1 (Claude Fable 5.1), read-only, no commands run.
Caveats on scope. The prior refusal at ../reconciliation/review.json is not present on this filesystem, so I could not diff against it. Without git access I reviewed the files the delta names plus the cherry-picked areas, not a machine-generated file list.
Feed export (store_feed_rows.go) is correct on the points that matter:
- One scoped master per series, RRULE and EXDATE verbatim, overrides emitted with RECURRENCE-ID keyed to the original local time. Matches the RFC shape and the export test.
- Overrides are loaded without a
deleted_atfilter, so a soft-deleted override exports as STATUS:CANCELLED and the original occurrence cannot resurrect. This is the right call because deleting an override never writes an EXDATE. - A moved-out override is still exported because its master is a range candidate. A moved-in override whose master finished before the window volunteers the master via its series id. Grant scoping holds through both
Calendarand the joins.
Key sentinel (key_check.go) is sound for consistency, restore and rollback:
- Legacy path verifies against calendar names, which are always non-empty ("Team", "My calendar") and exist whenever a person does. A wrong key cannot install the sentinel on a populated database.
- Runs after migrations, before auth and any store or NextDue work. Rolling the binary back leaves an ignored Meta row. Restoring a pre-sentinel backup re-verifies and installs. No migration needed since
metashipped in 0002.
Non-blocking findings, in priority order:
- Cancelled override carries stale SEQUENCE and DTSTAMP.
DeleteEventon an unbooked override writes onlydeleted_at. A client that dedupes on SEQUENCE may keep the live version. Full-replace subscribers (Apple, Google) are unaffected. Consider bumpingsequenceandupdated_aton override deletion. - Concurrent first boot on a legacy database. Two new processes can both reach the
Create; the loser fails with a duplicate-key error and refuses boot with a non-key message. Treatgorm.ErrDuplicatedKeyas "re-read and verify" to make it idempotent. - No operator documentation of the refusal or its recovery. Nothing in any
.mdnames the sentinel. Add a line to AGENTS.md so nobody "fixes" a wrong-key refusal by deleting the Meta row. - N+1 reads in the feed.
feedEventRowscallsEventper candidate althoughrangeRowsalready returned every column. A busy calendar polled every fifteen minutes will feel it. Perf only. - Nits.
keyCheckPurposesits outside the seal package's purpose block, andkeyCheckMetasits outside the Meta key consts.
Pre-existing, outside this delta: SplitSeries reassigns overrides by their moved start_utc and leaves them carrying the head's UID, so an exported tail override attaches to the head series in a client. Worth a follow-up ticket, not this branch.