Skip to content

fix: notifications dashboard fails to display some notifications it should#783

Merged
dlvhdr merged 4 commits intodlvhdr:mainfrom
sideshowbarker:fix/done-store-timestamps
Mar 4, 2026
Merged

fix: notifications dashboard fails to display some notifications it should#783
dlvhdr merged 4 commits intodlvhdr:mainfrom
sideshowbarker:fix/done-store-timestamps

Conversation

@sideshowbarker
Copy link
Contributor

@sideshowbarker sideshowbarker commented Feb 17, 2026

Summary

Bug: The Notifications dashboard had been failing to show particular new notifications that it should be showing: Namely, new notifications in threads which include an older notification that a user marked Done.

Cause: GitHub notification thread IDs are per-subject (per issue/PR), not per-event. When a user marks a notification Done in gh-dash, the thread ID is stored in done.json. If new activity later arrives on that same thread, GitHub creates a new unread notification with the same thread ID. And because we had IsDone() only checking whether the ID existed in the store, some new notifications will unexpectedly never get shown — because they have a thread ID we had already marked as Done.

Fix: This PR replaces the current ID-only Done store with a timestamp-aware Done store that records when each notification was marked Done (using its updated_at). On subsequent fetches, IsDone compares the stored timestamp against the notification's current updated_at. If the notification has been updated since it was marked Done, it resurfaces.

Additionally, the Done store now prunes stale entries on load: entries older than 14 days and legacy zero-time entries are removed, keeping the file from growing indefinitely. GitHub only retains Done-marked notifications for about 1 week, so entries beyond 14 days are dead weight.

⚠️ Important: Breaking change for existing users

On first run after a dash upgrade with this change included, dash will re-show users all of the notifications they have previously marked as Done. The old format (done.json as a plain JSON array of IDs) stored no timestamps — so there's unfortunately no way to determine which stored notification-thread IDs have new activity vs. which are genuinely stale.

But that resurfacing of all Done notifications is a one-time thing. Now, once a user marks any notification as Done, a proper timestamp is stored for it — and then only any genuinely-new notification in its thread will ever be shown.

How it works

Scenario Old behavior New behavior
Mark notification Done ❌ Store only thread ID Change: Store thread ID + updated_at timestamp
No new notification w/ same thread ID ✅ Dash never again shows Done-marked notification ✅ Same: Dash never again shows Done-marked notification
New notification w/ same thread ID ❌ Bug: Dash does not show new notification Fixed: Dash shows new notification
Legacy done.json on upgrade N/A ⚠️ One time: Dash (re)shows all existing Done-marked notifications from the Done store — as if they were new — and user needs to re-mark all those as Done ☹️
Stale entries (>14 days old) ❌ Accumulate forever New: Pruned on startup
Legacy zero-time entries ❌ Persist forever New: Pruned on startup (functionally equivalent — IsDone returns false either way)

@sideshowbarker sideshowbarker marked this pull request as ready for review February 17, 2026 13:13
@sideshowbarker sideshowbarker force-pushed the fix/done-store-timestamps branch from 7ea30f5 to 6e288d4 Compare February 17, 2026 13:15
@sideshowbarker sideshowbarker changed the title fix: done store no longer permanently hides notifications with new activity fix: done store no longer permanently unexpectedly hides notifications that it shouldn’t Feb 17, 2026
@sideshowbarker sideshowbarker changed the title fix: done store no longer permanently unexpectedly hides notifications that it shouldn’t fix: notifications dashboard no longer fails to display some notifications that it should Feb 17, 2026
@sideshowbarker sideshowbarker changed the title fix: notifications dashboard no longer fails to display some notifications that it should fix: notifications dashboard fails to display some notifications that it should Feb 19, 2026
@sideshowbarker sideshowbarker changed the title fix: notifications dashboard fails to display some notifications that it should fix: notifications dashboard fails to display some notifications it should Feb 19, 2026
Copy link
Owner

@dlvhdr dlvhdr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had a question on your plans for the done store long term

@sideshowbarker sideshowbarker force-pushed the fix/done-store-timestamps branch from 6e288d4 to 3afe37b Compare March 1, 2026 01:02
…tivity

GitHub notification thread IDs are per-subject, not per-event. When new
activity arrives on a thread that was previously marked "done," the API
reuses the same thread ID. The old done store only tracked IDs, so these
notifications were permanently hidden.

Replace the ID-only store with a timestamp-aware DoneStore that records
*when* each notification was marked done (using its updated_at). On
subsequent fetches, IsDone compares the stored timestamp against the
notification's current updated_at — if the notification has been updated
since it was marked done, it resurfaces.

BREAKING: on first run after upgrade, all previously-done notifications
will reappear. The old format stored only IDs without timestamps, so
there is no way to tell which notifications have new activity. This is a
one-time resurfacing — once dismissed again, proper timestamps are stored
and only genuinely new activity will resurface them going forward.
GitHub only retains Done-marked notifications for about 1 week. So,
entries older than that in our Done store are dead weight — because the
API won’t be return those any longer anyway. So this change causes Dash
to prune the Done store on load, with a 14-day cutoff (1 week + 1 week
safety margin) — to keep the Done store from growing unbounded. Zero-time
(legacy) entries are also pruned; removing those from the Done store has
the same effect as keeping them, since IsDone returns false either way.
@sideshowbarker sideshowbarker force-pushed the fix/done-store-timestamps branch from 3afe37b to d9f687a Compare March 1, 2026 01:04
Document the new timestamp-based DoneStore (separate from
NotificationIDStore), the IsDone timestamp comparison logic,
14-day pruning on load, sessionMarkedDone tracking, and legacy
format backward compatibility.
@dlvhdr dlvhdr merged commit 629a692 into dlvhdr:main Mar 4, 2026
3 checks passed
@sideshowbarker sideshowbarker deleted the fix/done-store-timestamps branch March 4, 2026 23:31
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.

2 participants