Skip to content

Wire up the timezone: seed it, honour it in the UI, and stop subordinate_status emitting raw UTC #345

Description

@serge-ivo

Three wiring gaps left by #329

c4394ad made agents speak the user's local time, sourced from users.preferences.timezone (the account blob, reused from #211; no migration; validated by isValidTimeZone from lib/cron-time.ts, so the platform has one timezone vocabulary). It also chose local-zone prose, which means SystemMessage.tsx needs no change — #336's local rendering and the agent's prose agree for free.

Three loose ends remain, each small and each in a lane that was closed at the time.

1. Nothing seeds the timezone, so "unset" is the standing case

preferences.timezone starts empty and there is no prompt to fill it. Until an owner discovers the field, every agent still says UTC — the exact symptom #329 was filed for, just now with a fix that nobody has switched on.

Seed it from Intl.DateTimeFormat().resolvedOptions().timeZone on first load via PUT /v1/preferences. That makes unset a transient state rather than a permanent one.

Seed, do not bind. #329 deliberately rejected the browser value as the source of truth — it changes when you travel, is absent on cron/pump/MCP paths, and cannot be corrected by the owner. Writing it once when empty is the useful half; re-asserting it on every load would reintroduce all three problems.

2. The UI ignores an explicit override

lib/messageStamp.ts's stampTitle uses toLocaleString(undefined, …) — the browser's zone, not the stored one. So an owner who sets a timezone different from their machine sees it honoured in the agent's prose and ignored in the UI, which is a two-clock defect again, one layer down.

Pass preferences.timezone from GET /v1/preferences as the timeZone option.

3. subordinate_status still emits raw UTC

lib/connectors/supervision.ts:254 emits asOf: new Date().toISOString() — this is the actual source of the "22:33:34 UTC" in the incident that prompted #329. formatInZone and utcOffsetLabel are exported from lib/agent-clock.ts for exactly this.

Worth checking the same pattern elsewhere: anywhere a tool payload carries a bare ISO string, a model will read it aloud verbatim.

Why together

All three are "the fix landed but the value never reaches the user". Individually each looks cosmetic; together they are the difference between #329 being done and #329 being available.

Acceptance

  • A new owner gets a correct local time without knowing the setting exists.
  • An owner who overrides their machine's zone sees the override in both prose and UI.
  • No tool payload hands a model a bare UTC timestamp to read out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions