Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2.7 KiB
| id | type | title | status | decided | deciders | related | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| RMGR-ADR-002 | architecture-decision-record | Canonical UTC timestamps; local time only at I/O boundaries | accepted | 2026-08-21 |
|
|
ADR-002: Canonical UTC timestamps; local time only at I/O boundaries
Status
Accepted (2026-08-21).
Context
Repo Manager emits timestamps into repository records, indexes, mutation meters, events, evidence, and compatibility contracts. Host-local clocks and implicit calendar conversion make identical events serialize differently, create daylight-saving ambiguity, and make deterministic reconciliation harder.
Users and external systems still need local calendars, wall-clock times, and locale-specific formatting. Those are presentation and ingestion concerns, not stored identity.
Decision
- Every value representing an instant is created, stored, compared, and exchanged in UTC.
- New textual timestamps use RFC 3339/ISO 8601 with the canonical
Zsuffix. Readers may accept legacy explicit offsets and normalize them to UTC before comparison or re-emission. Naive datetimes are rejected at boundaries. - Database timestamp columns use timezone-aware types and UTC values. Epoch values, where a foreign contract requires them, denote UTC instants.
- Conversion to or from a local timezone, locale, calendar, or wall-clock representation occurs only in UI and I/O adapters. The converted value never replaces the canonical instant.
- Inputs that omit a timezone are invalid unless the specific I/O contract also supplies an explicit timezone. DST gaps and folds must be resolved at that boundary before producing UTC.
- A genuine date-only domain value—for example a contractual due date—is not a timestamp and keeps its declared calendar semantics. A date derived from the current instant for repository metadata uses the UTC calendar date.
- Tests, fixtures, logs, filenames, events, and idempotency material follow the same rule; test convenience is not an exception.
Enforcement
- Repo Manager timestamp creation goes through
repo_manager.time. - Ruff
DTZandUPrules remain explicitly selected so naive datetime use and non-canonical UTC APIs fail lint even if Ruff defaults change. - Contract tests require UTC-aware values and canonical
Zserialization.
Consequences
Stored and exchanged instants are byte-stable across hosts. Ordering and reconciliation no longer depend on operator locale or daylight-saving rules. Presentation clients must retain the canonical value and treat local rendering as a reversible view. Legacy offset-bearing timestamps remain readable but are normalized when rewritten.