# RD.4 Calendar-aware dayparts

Date: 2026-07-22

## Existing V1 authority reused

This increment implements the R0.3 `CalendarSource` seam through Oshun's
existing V1 calendar stack. It reuses the authenticated per-user OAuth
connection store, the shared inbound-integration `CalendarTransport`, and the
existing Google OAuth access-token resolver and event transport. It does not
introduce a second calendar credential or provider-event model.

Google is the only provider with a real read transport in the current V1
composition. A user with no connection, missing Google client credentials, or an
Apple/Outlook connection without an injected real transport receives
`calendar_not_configured`; the Rail stays on the persisted manual schedule and
says so. Provider or malformed-source failures return `calendar_unavailable` and
the same visible manual posture. No path fabricates a successful calendar read.

## Privacy-bounded adapter

`V1RailCalendarSource` reads connections only for the authenticated V1 user and
converts provider events into R0.3's bounded interval shape. Only kind, start,
end, and a one-way SHA-256-derived identifier cross the seam. Titles, locations,
attendees, provider event ids, and account identifiers do not.

Confirmed busy events map to `meeting`; Google `focusTime` events map to
`focus-time`. Cancelled, transparent/free, self-declined, out-of-office,
unsupported event types, invalid ranges, and date-only all-day entries do not
create clamps. Reads and returned batches are bounded, and one unreadable
connected provider fails the whole observation closed.

## Daypart authority and presentation

`CalendarAwareDaypartResolver` remains kernel-owned. It first resolves the
persisted timezone-correct schedule, asks the calendar source for the exact
observation instant, validates every returned interval, and gives explicit focus
time precedence when it overlaps a meeting. Any active meeting or focus interval
clamps the effective posture to canonical Deep work: ceiling 1 and no adult-ring
eligibility. The scheduled daypart remains in the response for auditability.

The authenticated BFF endpoint
`GET /v1/rail/dayparts/resolution?timeZone=…&at=…` owns the server-side
composition. The web client validates that the server's scheduled result agrees
with its persisted settings and holds ambient media closed while each calendar
check is pending. Every clamp renders a concise live-status explanation with its
local end time. Missing or unavailable calendars render an explicit manual
schedule notice; an unclamped successful read adds no visual noise.

The status treatment follows the mandatory frontend guidance: it is a slim,
integrated line in the existing near-black Rail hierarchy, uses the established
single signal accent, and avoids adding a generic card or competing action.

## Verification

Focused automated coverage includes:

- kernel fixture calendars for meeting clamps, focus-time precedence,
  non-overlap, malformed results, and the original unconfigured fail-loud seam;
- BFF provider mapping, PII exclusion, absent configuration, provider failure,
  authenticated route composition, manual fallback, and timestamp validation;
- web client validation for automatic and manual responses, including rejection
  when the server disagrees with persisted schedule authority;
- connected React coverage proving that a clamp holds ambient video and that
  automatic and manual explanations are visible; and
- Playwright coverage through the real production Rail surface, plus updated
  calendar responses for every connected-state browser harness.

A Next production build is not run on this 15 GiB host because the repository's
small-host rule requires explicit approval. Targeted TypeScript, Vitest, ESLint,
and Playwright gates cover the affected kernel, service, and web paths.
