canvasSlice.tsfix(pipeline,inbox): filters that survive a refresh, and a lost deal that leaves the board Three reported bugs, two of them the same mechanism seen from different ends. A rejected viewConfig save was invisible. Every filter control fires `void saveCanvasViewConfig(id)`, so a rejection had no observer at all: no toast, no retry, and a local config the user believed was stored. `dirtyCanvasIds` kept the edit on screen — but that Set was never persisted while `canvasesById` was, so a reload came back with the change still in localStorage and nothing marking it unsaved. The server's pre-save row then won rehydration, which is why this read as "my pipeline filters don't survive a refresh" rather than as a write that failed. The save now reports failure and resolves false instead of rejecting, so all ~20 `void` call sites are covered without touching them; the dirty set persists, so the guard already in upsertCanvas holds across the reload it was being thrown away by; and CanvasHeader stops flashing "Saved" over a failure. Saves are also chained per canvas. Working through a filter popover fired several updateCanvas mutations at one row concurrently, so the last RESPONSE to land, not the last edit made, decided what the server kept. Closed Lost deals stayed in the pipeline because status is filtered SERVER-side: a page's membership is fixed when it is fetched, and marking a deal Closed Lost writes to the store, never to that page. The status/priority change now invalidates listConversations — it was the only successful-update path that never did — and the fetched rows are re-checked against the optimistic value, so the row leaves in the same frame as the click and the refetch merely agrees. That check is one shared predicate now; the kanban had its own copy, which is why two views of one pipeline disagreed about what a stage filter admits. Escape clears the inbox filters, in a second stage. Selection first, filters only once nothing is selected — a single stage would throw a filter set away on every ordinary deselect. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 29, 2026, 4:06 PM