Metadata
| Status | done |
|---|---|
| Assigned | agent-1376 |
| Agent identity | f51439356729d112a6c404803d88015d5b44832c6c584c62b96732b63c2b0c7e |
| Created | 2026-05-01T16:35:04.200991180+00:00 |
| Started | 2026-05-01T16:35:32.676286040+00:00 |
| Completed | 2026-05-01T17:45:21.344369598+00:00 |
| Tags | fix,bug,tui,ux,chat,sorting, eval-scheduled |
| Eval score | 0.70 |
| └ blocking impact | 0.72 |
| └ completeness | 0.65 |
| └ constraint fidelity | 0.70 |
| └ coordination overhead | 0.72 |
| └ correctness | 0.72 |
| └ downstream usability | 0.68 |
| └ efficiency | 0.72 |
| └ intent fidelity | 0.70 |
| └ style adherence | 0.76 |
Description
Description
The chat the user is currently working in (e.g., the persistent chat handling this session) should render prominently in the TUI's graph view — high up, easy to find. Instead, it's buried among older tasks, sorted by some criterion that doesn't reflect recent activity.
User report 2026-05-01: 'The chat we're working in now, why isn't it rendering high up in the TUI, like relative to every message I've sent it?'
User mental model: a chat with frequent recent message activity is what the user is currently focused on; the TUI should reflect that focus. Sorting purely by creation time means the actively-used chat sinks below newer non-chat tasks; sorting purely by status means chats lump together and the user can't tell which is the active one.
Spec
Sort criterion for chat tasks
Within the in-progress chat-task group, sort by last activity timestamp (last message sent OR received, whichever is more recent). The chat with the most recent activity bubbles to the top.
Sort criterion for the broader task list
- Status grouping stays as-is (in-progress before open before done, etc.) — chats don't ALWAYS leapfrog non-chat work
- Within each status group, recent-activity sort applies
- Chat tasks: 'last activity' = last message timestamp
- Non-chat tasks: 'last activity' = last state change (started_at, last log entry, etc.)
What 'activity' means concretely
- Chat task:
max(last_user_message_at, last_agent_message_at)from chat history - Non-chat task:
max(updated_at, last_log_entry_at)— the freshest signal of work happening
Visual treatment (optional polish)
Consider a subtle visual indicator that this is the 'active' chat — e.g., bolder weight, a small dot/marker, or a highlight on the row. Users with multiple chats benefit from this differentiation.
Validation
- Failing test or repro: in TUI with multiple chat tasks of varying activity, the most-recently-messaged chat appears at the top of the chat-task group
- Live smoke: send a message to chat-A; observe chat-A bubble to top. Switch to chat-B; send message; chat-B bubbles to top.
- No regression: status grouping still works (in-progress before done, etc.)
- Chat tab order in the chat tab bar is consistent with graph view ordering (or document the divergence if intentional)
- cargo build + cargo test pass
- cargo install --path . was run before claiming done
Coordinate with adjacent tasks
- diagnose-tui-viewport (in-flight): viewport behavior — different concern (where the view is anchored), but if this fix changes the order of rows, the viewport's 'top of graph' calculation may shift accordingly. Verify they don't fight.
- implement-tui-viewport (done): viewport stability policy. The user's prior preference 'top of view at top of graph' implies the most-recently-active task is what should be anchored at top — which is exactly what THIS fix implements via sort.
Depends on
Required by
- (none)
Log
- 2026-05-01T16:35:04.179200674+00:00 Task paused
- 2026-05-01T16:35:09.172237586+00:00 Task published
- 2026-05-01T16:35:29.988319592+00:00 Lightweight assignment: agent=Careful Programmer (f5143935), exec_mode=full, context_scope=task, reason=Careful Programmer is well-suited for TUI sorting implementation; high score (0.80) on similar code tasks; Careful tradeoff matches detailed validation spec with regressions and live smoke testing.
- 2026-05-01T16:35:32.676290319+00:00 Spawned by coordinator --executor claude --model opus
- 2026-05-01T16:35:41.416825235+00:00 USER REFRAMING 2026-05-01: this isn't a chat-specific 'fix' — it's a missing generic primitive. User direct quote: 'well... fixing lol... there should be a generic mechanism to track the interaction time etc.' The right architecture is the same shape as design-exponential-failure: introduce a GENERIC primitive that tasks expose, then consume it for sort/render/etc. across all surfaces. REVISED SCOPE: ### Step 1: define the primitive Add a `last_interaction_at` field to every task in the graph. Updated by ANY event that constitutes interaction with that task: - State change (open → in-progress, etc.) - New log entry (`wg log`) - New message (`wg msg send` or `wg msg read`) - Chat history append (for chat tasks: user typed, agent replied) - Worker agent activity / heartbeat for in-progress tasks - TUI user actions: clicked the row, viewed details, switched into the chat - Edits via `wg edit` Every event handler that touches a task ALSO bumps `last_interaction_at`. One central place: a helper that wraps mutation + timestamp-bump. ### Step 2: consume it - TUI sort: within each status group, sort by `last_interaction_at DESC`. Chats with recent messages bubble; tasks with stale activity sink. Generic, not chat-specific. - HTML sort: same primitive consumed by wg html for its task list ordering - TUI 'active task' visual cue: row whose last_interaction_at is within the last ~30s gets bold/highlight (subtle indicator) - wg list / wg ready / wg show output: include 'last interaction' field if useful (or default-hide it; show only with --verbose) - agency stats / cost reporting: 'tasks not touched in N days' becomes trivial query ### Step 3: schema migration Per skip-back-compat-ceremony memory: hard add the field. Existing tasks without the field default to created_at OR last entry from operations log. No deprecation window. ### Updated validation - [ ] Failing test: spawn a worker on task A, send a wg msg to task B. last_interaction_at on both is updated to event time. - [ ] Failing test: edit task C's description. last_interaction_at on C is updated. - [ ] Failing test: a chat receives a message. last_interaction_at on the chat task is updated. - [ ] TUI: sort by last_interaction_at within status groups; recent-activity tasks/chats bubble to top - [ ] HTML: same sort applied - [ ] No regression of any other ordering / display - [ ] cargo build + cargo test pass - [ ] Permanent smoke scenario: simulate sequence of events on tasks A, B, C; assert sort order matches event recency - [ ] cargo install --path . was run before claiming done This is a richer task than the original chat-specific 'fix.' Worth doing right because it unblocks several future features (recently-touched filter, stale-task detection, audit windows, etc.).
- 2026-05-01T16:35:42.415434543+00:00 Starting investigation: locating TUI graph view sorting code
- 2026-05-01T16:48:06.932893167+00:00 Implemented activity-based sort within status groups; new helper task_last_activity_secs reads chat inbox/outbox mtime for chat tasks, last log entry / lifecycle stamps for non-chat. Default sort changed from Chronological to StatusGrouped. Chat tab bar deliberately stays in chat-id order — documented divergence in code comment for keyboard nav stability.
- 2026-05-01T17:44:45.882196887+00:00 Validated: 4 new unit tests pass (activity_sort_tests). 3342 lib tests pass overall. integration_chat failures are pre-existing on main (wg init now requires -m / --route).
- 2026-05-01T17:44:47.108910741+00:00 Ran cargo install --path . — global wg binary updated.
- 2026-05-01T17:45:08.553524185+00:00 Committed: 73f2f5c11 — pushed to remote
- 2026-05-01T17:45:21.344377704+00:00 Task pending eval (agent reported done; awaiting `.evaluate-*` to score)
- 2026-05-01T17:48:28.238610989+00:00 PendingEval → Done (evaluator passed; downstream unblocks)