Skip to content

Mark newly discovered completed threads unread#4501

Draft
danieliser wants to merge 2 commits into
pingdotgg:mainfrom
danieliser:agent/first-seen-completed-thread-monitoring
Draft

Mark newly discovered completed threads unread#4501
danieliser wants to merge 2 commits into
pingdotgg:mainfrom
danieliser:agent/first-seen-completed-thread-monitoring

Conversation

@danieliser

@danieliser danieliser commented Jul 25, 2026

Copy link
Copy Markdown

What Changed

  • Observe authoritative thread snapshots after each environment has completed its initial bootstrap.
  • Remember the thread keys already seen in each environment.
  • Mark a thread unread when it first appears after bootstrap with an already-completed latest turn.
  • Keep observation history environment-scoped so remote and local snapshots cannot affect one another.

Why

The existing completion indicator is timestamp-based and intentionally treats threads without a visit marker as read. That leaves a narrow gap for a thread created elsewhere that first appears in the current client only after it has already completed.

This draft explores treating that newly discovered completion as unread without lighting up historical threads from the initial snapshot.

Scope

  • This does not change sidebar presentation or manual Mark unread behavior.
  • Initial bootstrap history remains read.
  • This only handles threads first discovered in the completed state; ordinary completion handling remains unchanged.
  • The change is independent and can be evaluated as an optional follow-up.

Attribution

The original implementation is authored by Wout Stiens; that authorship is preserved in the commit history.

Verification

  • 3 focused tests passed:
    • initial snapshot history is seeded without becoming unread
    • a newly discovered completed thread becomes unread
    • unfinished and non-authoritative-environment threads remain unchanged
  • Scoped formatting and lint checks passed.

Note

Mark newly discovered completed threads as unread on first appearance

  • Adds a useMarkFirstSeenCompletedThreadsUnread hook that tracks which threads have been seen per snapshot environment and calls markThreadUnread the first time a completed thread appears after the initial bootstrap.
  • A pure resolveFirstSeenCompletedThreads utility handles the stateless computation, comparing current thread keys against a previously-seen set to find newly completed threads.
  • The hook is mounted in EventRouter in __root.tsx so it runs for the lifetime of the app.
  • Behavioral Change: threads completed while the user is away will be marked unread when they next load the app, but only for snapshot environments.
📊 Macroscope summarized fc354d8. 2 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

StiensWout and others added 2 commits July 24, 2026 22:44
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 65717f03-5a08-4a79-8e71-cc414a0eedb0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 25, 2026
Comment on lines +64 to +68
if (
previousThreadKeys !== undefined &&
!previousThreadKeys.has(threadKey) &&
thread.latestTurn?.state === "completed"
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium hooks/useMarkFirstSeenCompletedThreadsUnread.ts:64

resolveFirstSeenCompletedThreads marks a completed thread as seen and pushes it to newlyUnreadThreads even when latestTurn.completedAt is null. Since markThreadUnread ignores null-timestamp threads, the thread is recorded as seen but never actually marked unread. When the real completedAt arrives in a later snapshot, the thread key is already in the previous-seen set, so it is never retried — the thread stays read forever. Consider deferring the push to newlyUnreadThreads until completedAt is non-null, while still tracking the key as seen.

    if (
      previousThreadKeys !== undefined &&
      !previousThreadKeys.has(threadKey) &&
      thread.latestTurn?.state === "completed" &&
+     thread.latestTurn.completedAt != null
    ) {
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/hooks/useMarkFirstSeenCompletedThreadsUnread.ts around lines 64-68:

`resolveFirstSeenCompletedThreads` marks a completed thread as seen and pushes it to `newlyUnreadThreads` even when `latestTurn.completedAt` is `null`. Since `markThreadUnread` ignores null-timestamp threads, the thread is recorded as seen but never actually marked unread. When the real `completedAt` arrives in a later snapshot, the thread key is already in the previous-seen set, so it is never retried — the thread stays read forever. Consider deferring the push to `newlyUnreadThreads` until `completedAt` is non-null, while still tracking the key as seen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants