**Findings — proof audit pass 1**

1. **Evidence is incomplete.** The strings in [#32371](https://git.cafe/pingdotgg/t3code/pull/32371) describe runs but do not show the warmed formatter, live zone switch, rerender, or absence of a reload. All seven capture rows below are missing. This is a proof verdict, not a finding that the implementation is wrong.
2. **Revision qualification.** Audited local head [6b77ac7a](https://git.cafe/pingdotgg/t3code/commit/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0), against merge-base [047d492736](https://git.cafe/pingdotgg/t3code/commit/047d492736ef7ad6c46250b52afafbd0b731f32f). The worktree is clean. The head is a merge whose parents are the published PR revision and the specified base. GitCafe currently reports published head [982a6a5a](https://git.cafe/pingdotgg/t3code/commit/982a6a5add9b74509441ba3c5e1ae5717c1e7b5d), with 42 successful checks and a conflict against the newer base. Those checks and existing reviews do not establish verification of the audited merge head. Do not silently retarget the captures to the published parent.
3. **Acceptance is next-render correctness.** [#32355](https://git.cafe/pingdotgg/t3code/issues/32355) and the PR discussion require a newly rendered label to use the viewer's current zone. Automatic invalidation of already visible rows was explicitly deferred. Every recording must deliberately rerender existing rows as well as render a new message; merely changing the zone and waiting is not a failure test for this PR.
4. **Native evidence is separate.** Web uses current `Date.getTimezoneOffset()` with UTC formatters; mobile reads the zone from a fresh `Intl.DateTimeFormat`, rebuilds its cache, and uses that zone for both time and calendar comparisons. Node/browser output cannot establish Hermes behavior. Android can exercise the actual device change; iOS host-zone mutation is prohibited in this task, so its proposed fallback is explicitly a harness with an OS-integration limitation.

**Render-path inventory and collapse**

The diff contains two formatting modules and their two test files; it changes no component layout, transport contract, provider adapter, or navigation. The following are all production callers found at the audited head. Component names below link to that head. “Covered by” means a representative fixture exercises the shared formatting branch, not that each listed wrapper has been visually tested.

| Changed export / production render path | Branches and layout inputs relevant to the timestamp | Covered by |
|---|---|---|
| Web day-aware + tooltip: [TimelineUserMessageRow](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineUserMessageRow.tsx), direct user actions and expanded automation via `TimelineRowTimestamp` | `createdAt`; ordinary/grouped user bubble; agent/automation folded versus expanded; coarse pointer versus hover/focus actions; action wrapping; automation timestamp exists only when expanded. Attachments, copy/revert/link actions change surrounding space, not formatting. | W1, W2 |
| Web day-aware + tooltip: [TimelineAssistantRows](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineAssistantRows.tsx), inline metadata and standalone `AssistantMetaTimelineRow` | Uses `updatedAt`, not `createdAt`; inline metadata needs `showAssistantMeta`; timestamp hidden while streaming; standalone metadata always visible, inline revealed by hover/focus/coarse pointer; optional status/copy/fork/checkpoint siblings. Empty completed response still has metadata when enabled. | W1, W2 |
| Web day-aware + tooltip: [TimelineRowParts](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineRowParts.tsx), called by [TimelineWorkEntryRow](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineWorkEntryRow.tsx) and [TimelineWorkGroupRows](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineWorkGroupRows.tsx) | Work-entry/group `createdAt`; hidden until row hover/focus unless `alwaysVisible` (error row); group expanded/collapsed; pending approval replaces the normal work row. Counts/tool kinds/statuses change surrounding labels, not the formatter. | W1, W2 |
| Web short time: [Sidebar.snooze](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/Sidebar.snooze.ts) → thread snooze choices; [SnoozePresetsSettings](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/settings/SnoozePresetsSettings.tsx) → preview and menu order | Snooze wake instant; duration preset or local clock preset; weekday prefix composed outside helper. Passed/duplicate/same-wake options omit a formatted timestamp. Settings add/remove/reorder/edit and menu opening can rerender. | W3; W1 can additionally open the live snooze menu |
| Web short time: [DiffPanel](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/DiffPanel.tsx) → Turn submenu | One entry per checkpoint summary, `completedAt`; zero summaries means no time entries. Menu opening is needed to expose time. No count-dependent formatting. | W3 |
| Web short time: [V2LifecycleRow](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/V2LifecycleRow.tsx) → `SubagentNotificationLink` event | `createdAt`; no matching subagent uses fallback; resumed subagent omits the historical notification event; event exists for non-resumed outcome. Result/status/remote child affect other text. | W3 |
| Web upcoming: [ComposerUsageLimits](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/ComposerUsageLimits.tsx) → fallback reset description and `LimitWindows` | Optional `resetsAt` adds reset suffix; missing means no time. Single/multiple account reports, notices, credits and compact bars affect surrounding content. | W3 |
| Web upcoming: [UsageLimitRecoveryBanner](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/UsageLimitRecoveryBanner.tsx) | Reset versus later snooze deadline; `Resets` versus `Resumes`; null → unavailable text; workspace-specific notice replaces the reset description; settled/pending/auto-resume control actions. | W3 |
| Web upcoming: [ThreadDetailsUsage](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/ThreadDetailsUsage.tsx), [UsageLimits](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/usage/UsageLimits.tsx), [UsageLimitsPooled](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/usage/UsageLimitsPooled.tsx) | Details tooltip requires future reset; usage bar tooltip allows reset when supplied; pooled account detail has optional reset row; report `now` can be fixed to report time, not wall clock. Empty/loading/error/no-reset states contain no affected formatted value. Account counts/pool segments/credit availability do not select a different time formatter. | W3 |
| Web upcoming with explicit zone: [TimelineWorkEntryRow](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/chat/TimelineWorkEntryRow.tsx) error/reset label | Failure/reset optional; fresh viewer zone passed explicitly and printed in parentheses. That explicit-zone branch must preserve instant formatting; a fixed explicit zone must remain fixed even when the system changes. | W3 control |
| Web clock preference: [UsagePage](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/usage/UsagePage.tsx) → `resolveHour12` | `locale`, `12-hour`, `24-hour`; now uses UTC-backed formatter but hour-cycle result should remain the preference. `weekStartsOn` → [CustomSnoozeDialog](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/web/src/components/CustomSnoozeDialog.tsx) is unchanged. | W1 preference cycle; W3 control |
| Mobile [messageTimestamp](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/mobile/src/features/threads/messageTimestamp.ts) → [ThreadFeed](https://git.cafe/pingdotgg/t3code/blob/6b77ac7a55d07fec24bddc5df93d14ddfb54ead0/apps/mobile/src/features/threads/ThreadFeed.tsx) | User `createdAt`, assistant `updatedAt`. User pending/unacknowledged shows `Pending`; acknowledged shows time. Automation passes label to its folded row. Workflow opening and compaction messages replace the message row. Assistant time requires terminal message, no unsettled matching run, not streaming, and nonempty text or attachments. User attribution/folding, media, wide markdown, duo columns, widths and platform alter surrounding layout. Both iOS and Android use this helper and system locale clock preference, not web's setting. | A1, A2, I1 |

Helper branches: web invalid → empty; `formatDayAwareTimestamp`: today/future → time only, yesterday → `yesterday at`, older same-year → numeric month/day + time, older prior-year → numeric date/year + time. Tooltip is time + English ordinal day/month/year, independently of numeric-date locale. Upcoming: past → day-aware fallback; today → time only; tomorrow → `tomorrow at`; later → numeric date with conditional year. Both default/current and explicit zones exist. Mobile invalid → empty; same calendar date → time only; any other date (including future) → numeric date + time, with year only when different. Mobile must re-use cache while zone unchanged and rebuild when zone changes or changes back.

Theme, viewport, number of messages, attachment counts, empty/loading/error shells, expanded tool output and provider choice do not add formatter branches. One desktop viewport/theme plus native portrait/theme is enough; no Cartesian caller × theme suite. The maximum date/year text is represented in W2/A2. Hover/focus, menu opening, thread switching, streaming completion and every live-zone/time scenario require **recording**; stills alone cannot prove any required row.

**Fixture data and capture rules**

Use synthetic content only. Live rows: start the lead's isolated server with `T3CODE_DEV_SEED=0 vp run dev` and an empty task-owned home; never refresh it from real data. Create a synthetic project and two threads through the app/RPC, select the free Replay (dev) provider and complete one replay. Actual route is `/$environmentId/$threadId`; useful routes are `/settings/general` (Time format), `/settings/threads` (Snooze), and `/usage`. Keep provider/model pickers and credentials out of evidence. Capture actual client content, with a separate nonsecret sidecar recording zone, UTC instant, expected string and revision. Do not overlay replacement timestamp text onto the app.

In each live recording, warm labels in source zone, retain the same page/process, change zone, send another replay message, navigate to the second thread and back, then hover/focus completed timestamps. Record a stable page/session marker to establish no reload. Compare each label against a newly constructed formatter using the **explicit target zone**, the same locale/hour preference and the exact source instant. Stale labels before the deliberate rerender are allowed. Restore the initial zone to exercise the reverse transition.

Boundary fixture clock `N = 2026-11-07T04:45:43.877Z`. Source `America/New_York`, target `Asia/Bangkok`. Messages: `T=N`; `Y=2026-11-06T08:45:00Z` (today in source, yesterday in target); `O=2026-11-04T20:00:00Z` (older numeric date); `J=2025-12-31T20:00:00Z` (prior-year in source, same-year in target); `B=2026-10-31T20:00:00Z` (tooltip crosses October → November); `F=2026-11-07T06:45:00Z` (tomorrow in source, today in target); `L=2026-11-09T20:00:00Z` (later numeric date); `K=2026-12-31T20:00:00Z` (upcoming numeric year changes). Controls: empty input, `not-a-date`, fixed explicit zone `America/New_York`.

Examples under en-US/12-hour: T is `11:45 PM` → `11:45 AM`; O is `11/4 3:00 PM` → `11/5 3:00 AM`; B tooltip is `4:00 PM, 31st October 2026` → `3:00 AM, 1st November 2026`. Expectations for other locales must come from explicit-zone formatters, not these literal strings.

Exact historical message dates cannot be seeded through normal message RPC: the current `message.dispatch` schema has no `createdAt` and the client turn operation does not forward its legacy input time. Do not claim otherwise or write SQLite. For W2/W3/A2, use a clearly labelled scratch diagnostic harness that imports the audited production formatter, supplies the listed inputs and `nowMs=N`, and displays actual outputs plus independent explicit-zone expectations. This is helper evidence, not an app screenshot. The live rows independently prove integration. A future harness driver must write to a new timestamped directory, not overwrite earlier evidence.

| Row / named fixture | Diff affected? / visually distinct data | Real app seed or labelled harness | Minimum viewport × theme × row; evidence type | Required observation | Pass-1 status |
|---|---|---|---|---|---|
| **W1 — web live messages** | Yes: user time, completed assistant time, work-row time and hover tooltip; 12-hour / 24-hour / locale preference | Real app, synthetic replay and second thread as above. Warm each preference through `/settings/general` before switching. Open thread snooze menu if convenient; no separate snooze capture required. | 1365×900 × dark × W1; **recording**, base/head pair | New and revisited rows use current viewer zone without reload. New York → Bangkok, then London → Kolkata (fractional offset), with reverse leg; completed assistant time appears only after completion. Hover/focus shows matching tooltip. | **MISSING recording**; existing PR strings are not captures |
| **W2 — web calendar boundaries** | Yes: time-only, yesterday, numeric date, conditional year, month-boundary tooltip | **LABELLED WEB HELPER HARNESS**; N and T/Y/O/J/B, `12-hour`; also show one `24-hour` output of J for longest numeric form. Normal RPC cannot backdate these messages. | 1365×900 × dark × W2; **recording**, base/head pair | Warm in New York, change to Bangkok, rerender same inputs; date/year prefixes and tooltip month move together. Include invalid/empty control outputs as labelled empty values. | **MISSING harness recording** |
| **W3 — auxiliary short/upcoming and explicit-zone control** | Yes default-zone short/upcoming; explicit-zone/hour-cycle controls unchanged | **LABELLED WEB HELPER HARNESS**, same imported module and N. Short time B; upcoming O/T/F/L/K; fixed-zone counterparts. Synthetic usage/reset wrappers may be added but are not required separately. Show default and explicit results side-by-side; no paid or real account limits. | 1365×900 × dark × W3; **recording**, base/head pair | Default outputs follow changed zone for short, past fallback, today/tomorrow, later date/year. Fixed explicit-zone outputs stay fixed. `resolveHour12` preserves each preference. Null-reset wrappers are inventory exclusions, not fabricated empty helper inputs. | **MISSING harness recording** |
| **D1 — Electron renderer** | Yes: same web helper, desktop system-locale bridge | Real desktop client connected to the same isolated server, synthetic two-thread replay. Use CDP renderer zone override; do not mutate host zone. Record host locale and obtain target-zone expectations using that locale. | 1365×900 content area × dark × D1; **recording**, base/head pair | One warmed completed timestamp and tooltip follow a zone change after thread revisit, without window reload. This proves renderer handling; label CDP override explicitly and do not claim an actual OS-setting test. | **MISSING desktop recording** |
| **A1 — Android live Hermes** | Yes: user createdAt / terminal assistant updatedAt | Real native app connected to isolated synthetic server; same replay thread. Lease device, install checkout client if needed, then change emulator zone with supported `adb shell cmd alarm set-timezone <zone>` or `adb shell service call alarm 3 s16 <zone>` and verify actual zone. No app restart. | 412×915 dp portrait (or report actual leased device size) × dark × A1; **recording**, base/head pair | Warm before change; force real thread unmount/remount by navigating away/back, and send a new message. Both acknowledged user and completed terminal assistant labels use new zone. Report fresh Intl zone and Date offset separately; stale Date offset is not the oracle. Reverse zone and rerender again. | **MISSING device recording** |
| **A2 — Android calendar branches** | Yes: numeric date/year selection uses Intl zone instead of Date calendar methods | **LABELLED NATIVE HERMES HELPER HARNESS** with N and T/Y/O/J/F, invalid/empty; imported production mobile helper. Change actual leased emulator zone as A1. Fixed historical values cannot be entered through normal RPC. | Same portrait size × dark × A2; **recording**, base/head pair | T time only; Y/O/F use numeric date when not today (mobile has no “yesterday at”/“tomorrow at” wording); J year prefix disappears after crossing into target-zone year. Correct even if Date's local offset remains stale. | **MISSING native harness recording** |
| **I1 — iOS native cache/formatting fallback** | Yes: same mobile helper, separate platform Intl implementation | **LABELLED iOS HERMES HARNESS** using A2 data and real explicit-zone Intl formatting; a narrowly scoped zone-reporting seam supplies New York → Bangkok → New York to the module's fresh default-zone resolver. Restore seam afterward. This is not a real system-zone change; simulator follows host and host-zone mutation is prohibited. | 393×852 pt portrait (or report actual device size) × dark × I1; **recording**, base/head pair | Rebuild and reverse-cache behavior, current-zone calendar branches and native formatting agree with independent explicit-zone Intl. Actual iOS OS-zone notification/integration remains **UNVERIFIED**; do not substitute Node or silently present harness as app evidence. | **MISSING labelled native harness recording**; real OS-zone leg unavailable under task constraints |

Minimum: **seven logical fixture recordings**, each showing source/target/rerender/reverse in one continuous session per revision; baseline/head can be paired clips. W2/W3 and A2 can share a recording file with explicit chapters. No extra theme, provider, hoverless still, loading, empty-list, account-count or connection-mode captures are required. Remote/relay/tunnel transport cannot select the formatter zone: retain UTC input instants and vary the viewer zone. D1 may connect remotely to exercise the original report's arrangement without a new fixture family.

The two existing focused test files cover selected Node cases and explicit-zone calendar behavior; they were inspected, not rerun in this pass. They do not replace native/device recordings. No servers, emulators, leases, browser tabs, or paid turns were started; no tracked files, forge comments, refs or PR state were changed.

AI-assisted; verified with the tests and tools listed above.

FRICTION:
forge | GitCafe still names the pre-merge published head while this audit is pinned to a local merge revision; CI/reviews refer to the published head | Publish and link evidence to the exact audited revision before treating checks as current.
VERDICT: INSUFFICIENT W1 W2 W3 D1 A1 A2 I1
