Skip to content

[Bug]: Mark unread restores a dismissed Woke badge instead of Done #24052

Closed

Description

@Anurag2293

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web (sidebar presentation), with the read-state mutation in apps/server.

Steps to reproduce

  1. Use a thread whose latest run has finished successfully.
  2. Snooze the thread for a short duration, for example Custom → 1 minute.
  3. Let the snooze timer expire. The thread returns with the Woke badge in the sidebar.
  4. Click Dismiss Woke notification. The badge disappears.
  5. From the thread's context menu, choose Mark unread.

No new run or new snooze occurs between steps 4 and 5.

Expected behavior

The thread shows Done, reflecting its unread completion. A wake notification that was already dismissed should stay dismissed until another snooze/wake cycle.

Actual behavior

The old Woke badge reappears instead of Done. Marking the completion unread also makes the previously acknowledged wake look unseen again.

Impact

Minor bug or occasional failure: the sidebar displays a stale wake notification and obscures the intended unread-completion status.

Version or commit

Observed with the official backend release 0.1.2-nightly.20261022.3541, built from 044f07257c9684ae4543bd1e1ebf9c394e9e3830.

Environment

Ubuntu 20.04.6 LTS, Linux x86_64 backend, connected T3 client using the web/desktop sidebar. This appears independent of the model/provider.

Investigation

Source references are pinned to the affected release commit:

  • Dismissing Woke sends a thread visit at wokeAt, acknowledging the notification through lastVisitedAt.
  • Mark unread rewinds lastVisitedAt to one millisecond before the latest run's completion, while the mutation retains the expired snooze fields.
  • The sidebar then sees lastVisitedAt < wokeAt again and prioritizes Woke over Done.

For example: completion at 10:00, snooze expiry and dismissal at 10:05, then Mark unread moves the read timestamp to 09:59:59.999. The same 10:05 wake is classified as unseen again.

Workaround / locally verified fix

A local patch to the same release commit retires an expired snooze when handling thread.mark-unread: clear snoozedUntil and snoozedAt, retaining the expiry timestamp in lastSnoozeWakeAt for auto-settlement. Future snoozes are preserved and updatedAt is unchanged.

The reporter confirmed that the original sidebar sequence works after installing this patched backend.

Regression coverage checks the read timestamp rewind, expired versus future snoozes, the retained wake timestamp, and replaying the mark-unread command after snoozing again. These focused suites passed on the release source: 54 tests.

vp test run \
  apps/server/src/orchestration-v2/Orchestrator.control-reads.test.ts \
  apps/server/src/orchestration-v2/ThreadSettlementService.test.ts \
  packages/client-runtime/src/state/threadSnoozed.test.ts

The compiled executable was also smoke-tested with an isolated data directory. The sidebar confirmation was manual; no automated browser test was run. This is a local workaround, not an upstream fix or a claim about newer releases.

Activity

  1. juliusmarminge commented on Oct 24, 2026

    @juliusmarminge
    Member

    Reproduced on current main eea9895, using the web dev app on Linux with fresh isolated state and a successfully completed Codex run. Custom snooze for 1 minute → timer expires → Dismiss Woke notification removes the badge → context menu Mark unread restores Woke instead of Done. Repeated dismissal and Mark unread gives the same result. Existing fix PR #24080 covers this report.

    Woke restored after Mark unread

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions