fix(server): stop stale settlement notifications - #9081
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — The PR makes a small, tested correction to use terminal work timestamps rather than later thread metadata when publishing completed or failed awareness states. Its production impact is limited to preventing stale settlement notifications and preserving existing behavior for active states. You can add or adjust custom eligibility rules. Learn more. |
Server-side auto-settlement stamped settledAt with the sweep time, so old threads looked newly settled on every startup and sorted wrong in the Settled shelf. The reactor now carries the thread's last user/turn activity through the internal auto-settle command and the decider persists it as settledAt, while updatedAt stays the command time. Migration 046 repairs projection_threads.settled_at for identifiable past sweeps without touching the event log. Web and mobile sort and label settled rows through a shared client-runtime resolver. Refs #9057. Pairs with #9081. Made with GPT-5.6 Sol in T3 Code through the Codex harness; follow-up and merge by Claude Fable 5 in Claude Code. Co-authored-by: eimexdev <eimexdev@users.noreply.github.com>
|
Maintainer verification: the timestamp precedence reads correctly — completed/failed awareness pins terminalSessionAt, then latestTurn.completedAt, then session.updatedAt, so post-finish metadata edits no longer re-fire notifications or tombstone the lock-screen card, while live phases still track thread.updatedAt. Tests pin TERMINAL_AT against a later NOW. One ask: no Check/Test CI appears in this PR's rollup, so it needs a rebase and a CI re-run before merge. |
Automatic thread settlement refreshes a thread's general update time. Existing completed or failed agent-awareness state then looks fresh enough to queue another mobile notification.
Terminal awareness now keeps the actual turn or provider-session terminal time. Running and waiting states still use the thread update time, so live activity freshness is unchanged. Focused coverage includes settlement cleanup, ready sessions without a materialized turn, and failed sessions.
Validation
git diff --checkpassedCloses #9057
Made with GPT-5.6 Sol in T3 Code through the Codex harness.
Note
Low Risk
Narrow change to awareness
updatedAtselection for terminal phases only; active-state freshness is unchanged and behavior is covered by focused tests.Overview
Fixes duplicate or stale mobile notifications when automatic thread settlement bumps
thread.updatedAtafter work has already finished.For completed and failed awareness phases,
projectThreadAwarenessno longer always exposesthread.updatedAt. It now prefers the provider session’s terminalupdatedAt(ready/idle for success, error for failure), thenlatestTurn.completedAt, with fallbacks to session and thread times. Running and waiting phases still usethread.updatedAtso live activity stays current.Tests separate a later settlement time (
NOW) from terminal work time (TERMINAL_AT) and assertupdatedAton interrupted-but-completed turns, ready sessions without a turn row, and failed sessions.Reviewed by Cursor Bugbot for commit 2f9b1f9. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix stale settlement
updatedAtinprojectThreadAwarenessThe
updatedAtfield of the returnedAgentAwarenessStateno longer always usesthread.updatedAt. Forcompletedandfailedphases, it now prefers the session's terminal transition time or the latest turn'scompletedAt.terminalSessionAtfromsession.updatedAtwhen a completed/failed phase has the matching terminal session status.updatedAtfalls back throughterminalSessionAt,latestTurn.completedAt,session.updatedAt, thenthread.updatedAt.TERMINAL_ATconstant and assert the newupdatedAtbehavior.state.updatedAtalways matchingthread.updatedAtfor terminal phases will see a different value.Macroscope summarized 2f9b1f9.