feat(sync): add Microsoft Graph read adapter

Add strict /me identity, atomic paged calendar discovery, and resumable primary-calendar v1 delta synchronization through the durable provider cache. Keep opaque continuations on trusted Graph URLs and retain credentials only per operation.

Document that stable Graph v1 delta covers only the primary calendar; secondary calendars still require a v1 reconciliation or beta dependency decision.

Verified: 18/18 normal, 18/18 -Werror, and 18/18 ASan/UBSan tests.
This commit is contained in:
2026-07-18 12:34:21 +01:00
parent 3560a7d23d
commit 0582444c61
9 changed files with 1957 additions and 26 deletions

View File

@@ -123,10 +123,11 @@ conflict records are reserved for later write synchronization.
The provider boundary models Microsoft sign-in as a public desktop client
using the system browser, the OAuth authorization-code flow, PKCE with `S256`,
and a loopback redirect. Nocal's application registration must be multitenant,
with the intended organizational/personal Microsoft account audience, and the
first read-only synchronization will request only delegated `Calendars.Read`.
This permission normally supports user consent, but an organization's tenant
policy can still require administrator consent or block user consent. An
with the intended organizational/personal Microsoft account audience. The
read-only adapter requests delegated `User.Read` for `/me` plus
`Calendars.Read` for calendar and event reads. Neither delegated permission
normally requires administrator consent, but an organization's tenant policy
can still require approval or block user consent. An
open-source desktop executable cannot keep a client secret, so none is embedded
or expected.
@@ -160,8 +161,25 @@ cancelled, and storage failures remain distinct errors and never fall back to
another storage channel. Nocal does not mark an account connected until the
complete secret has been stored successfully.
This remains foundation, not working Office 365 integration. There is still no
Microsoft Graph call, account UI, or usable account setup. The next slice is a
Microsoft adapter that calls `/me`, discovers
calendars, and performs read-only delta synchronization with delegated
`Calendars.Read`.
The Microsoft Graph read phase calls `/me` and discovers every calendar through
the complete paged listing, replacing the
cached calendar set atomically only after every page succeeds. Provider/account
identity produces stable deterministic local IDs. Event requests prefer
immutable Graph IDs, parse strictly within fixed bounds, and keep credentials
out of errors. Access tokens are supplied per operation; Secret Service remains
the only persistent token store.
All Graph requests and opaque next/delta links must use HTTPS on
`graph.microsoft.com`. Primary-calendar event windows are half-open UTC ranges.
Each page, its tombstones, and its next or delta cursor commit atomically, so an
interrupted round resumes without advancing past durable data.
Stable Graph v1.0 documents `calendarView` delta only for the primary calendar.
Nocal therefore discovers all calendars but delta-syncs only the primary one;
it deliberately avoids beta and undocumented per-calendar routes. Secondary
calendars require a product decision between v1 full-window reconciliation with
explicit deletion semantics and a beta-specific delta implementation before
Outlook-equivalent coverage can be claimed. There is still no account UI/CLI
orchestration or live Microsoft credential integration, and remote writes
remain out of scope. The next phase is account setup and orchestration plus that
secondary-calendar decision.