Skip to content

fix(crush): read session timestamps as Unix seconds, not milliseconds - #357

Open
LarsArtmann wants to merge 1 commit into
janekbaraniewski:mainfrom
LarsArtmann:fix/timestamps-unix-seconds
Open

fix(crush): read session timestamps as Unix seconds, not milliseconds#357
LarsArtmann wants to merge 1 commit into
janekbaraniewski:mainfrom
LarsArtmann:fix/timestamps-unix-seconds

Conversation

@LarsArtmann

@LarsArtmann LarsArtmann commented Sep 8, 2026

Copy link
Copy Markdown

What

millisToTime read sessions.created_at / updated_at as Unix milliseconds. The columns actually store Unix seconds, so every Crush session landed in January 1970 — day buckets, statusline windows, and any time-based filtering were silently wrong.

Evidence

Real crush.db row from a live machine:

sessions.created_at = 1784269138
  • as seconds → 2026-07-17 06:18:58 UTC ✅ (matches when the session actually ran)
  • as milliseconds → 1970-01-21 15:37:49 UTC ❌ (what the crush provider produced)

The root cause is Crush's own initial migration comment, which claims created_at stores milliseconds. It does not:

Changes

  • time.UnixMilli(v)time.Unix(v, 0), and millisToTime renamed to unixSecondsToTime so the name and comment stop propagating the wrong unit
  • new TestQuerySessions_TimestampsAreUnixSeconds: builds a fixture Crush DB and asserts the end-to-end querySessions result — fails on current main (produces 1970-01-21), passes with this fix

Testing

  • go test ./internal/providers/crush/ — green
  • full go test ./... — only pre-existing, unrelated failures (internal/daemon change-detection test, hermes/zed missing-DB tests; each verified failing on pristine main before this change)

Beyond this fix

For context (not a dependency suggestion): I maintain go-crush-data (MIT), a typed read-only Go library for the Crush on-disk format — capability probing against schema drift, tolerant parts decoding, census-verified todos shape, tested against crush v0.92.0 and real production DBs. This bug is a good example of why that probing exists. I've since opened the upstream Discussion with charmbracelet/crush about stable read access for ecosystem tools — this PR and its sibling (mnemo#22) are the motivating receipts: charmbracelet/crush#3740

Crush's initial migration comment claims created_at/updated_at are
milliseconds, but the stored values are Unix seconds: the
update_sessions_updated_at trigger writes strftime('%s','now') and the
Crush CLI renders time.Unix(CreatedAt, 0). Verified against real Crush
DBs: a session row with created_at = 1784269138 is 2026-07-17 (UTC) as
seconds, but 1970-01-21 when misread as milliseconds — every session
was silently bucketed into January 1970.

Rename millisToTime -> unixSecondsToTime so the name and comment stop
propagating the wrong unit, and pin the behavior with an end-to-end
test backed by a fixture Crush DB (fails on main, passes with the fix).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant