#830·rowboat

Home suggestion tray re-shows the same (declined/dismissed) suggestion

Author: GagancreatesCreated Aug 5, 2026Updated Sep 2, 2026
Labelsbughelp wanted

Summary

On the Home to-do surface, a suggestion that was already declined/dismissed (or already accepted) can reappear in the suggestion tray on a later planner run instead of staying permanently filtered out.

Where this lives in code (found on origin/feat/todo-homepage-v2 / origin/fix/todo-home-polish — not on main yet)

  • apps/x/apps/renderer/src/components/todo-view.tsx:1123 — stores suggestions state; :1209-1214 loads them via todo:get; :1334-1352 accept/decline handlers; :1915-1948 renders the suggestion tray.
  • apps/x/apps/main/src/ipc.ts:2656-2686 — exposes todo:get, todo:acceptSuggestion, todo:declineSuggestion; :2796-2805 records dismissal of accepted proposed items.
  • apps/x/packages/core/src/runtime/tools/domains/todo.ts:47-78 — implements the todo-propose tool used by the planner.
  • apps/x/packages/core/src/todo/planner-memory.ts:71-96 — records planner feedback and builds "sticky dismissed" keys; :128-143 dedupes against the current todo/suggestions.md.
  • apps/x/packages/core/src/todo/fileops.ts:35-37 — normalizes suggestion keys (lowercase + whitespace collapse only); :305-314 accepts a suggestion into todo.md.

Root cause hypothesis

  1. Decline/dismiss signals are recorded fire-and-forget in the IPC layer (void recordPlannerSignal(...) at ipc.ts:2684 and :2802). If a planner run happens immediately after a decline, or the app is closed/crashes right after, the write can be missed and the same suggestion gets proposed again.
  2. planner_feedback.json caps stored signals at 200 — older dismissed keys can age out and silently lose their "sticky dismissed" protection.
  3. normalizeKey (fileops.ts:35-37) only lowercases and collapses whitespace. Any trivial rewording or punctuation change from the planner produces a different key, bypassing dedupe even though it's semantically the same suggestion the user already declined.

Repro steps

  1. On the Home to-do surface, trigger a suggestion (click "Suggest" / let the planner run).
  2. Decline one of the suggestions.
  3. Immediately trigger another planner run (click "Suggest" again, or restart the app shortly after declining).
  4. Observe that the same suggestion — or a trivially reworded version of it — reappears in the tray instead of staying filtered out.

Suggested fix directions

  • Await recordPlannerSignal (or otherwise make the dismissal write synchronous/durable) before the IPC call resolves, so a dismiss is guaranteed to be persisted before the next planner run can start.
  • Don't cap dismissed/sticky keys at a fixed count that discards old entries, or otherwise separate "sticky dismissed" storage from the general feedback signal log so it doesn't age out.
  • Make normalizeKey more robust to punctuation/light rewording (e.g. strip punctuation, or use a fuzzy/substring match) so a re-generated suggestion with the same intent still matches a previously dismissed one.

Note: the affected code appears to live on branches feat/todo-homepage-v2 / fix/todo-home-polish, not yet on main.