- Stale-write rejection telemetry on setDashboardPrefs — closes the named rev-136 next-sprint candidateUntil rev 137 the rev-136 server-side OCC primitive silently dropped older taskCommentFilters writes — the operator on the slow device had no signal that their last filter change didn't land; they just saw the dashboard re-render with somebody else's scope on the next fetch and wondered if they'd misclicked. Rev 137 closes that gap. setDashboardPrefs now collects every per-entry stale-write rejection inside the rev-136 OCC step into a structured `rejected.taskCommentFilters: Array<{taskId, reason: 'stale_write', existingAt, incomingAt}>` and returns it alongside the persisted prefs. The function signature changes from `Promise<DashboardPrefs | null>` to `Promise<{prefs, rejected} | null>` so every existing caller reads one consistent shape across both surfaces — `prefs` carries the canonical post-OCC state operators should re-sync from, `rejected.taskCommentFilters` enumerates what was silently dropped. Empty array means no rejections (the steady-state). Foundation for any future field with its own OCC primitive — the `rejected` shape is per-axis so adding rejections for cap-overflow or future axes doesn't break existing callers.
- Outpaced — reloaded chip on the rev-128 per-thread filter rowTaskComments client-side: every debounced PUT now reads the response. When the response carries a `rejected.taskCommentFilters` entry for THIS taskId, the client (a) surfaces a brand-amber 'Outpaced — reloaded' chip on the rev-128 filter row alongside the rev-134/135 Restored/Synced chips, (b) re-syncs local state (`query`, `authorFilter`, `reactionsOnly`) from the canonical `prefs.taskCommentFilters[taskId]` returned on the same response — no follow-up GET. Auto-fades after 5s; click to dismiss early. Distinct visual vocabulary from the rev-134/135 chips: rev-134 brand-color teal 'Restored' = your scope is loaded from last visit on this browser (passive); rev-135 brand-purple 'Synced' = your scope is loaded from your account state (cross-device informational); rev-137 brand-amber 'Outpaced — reloaded' = something happened, your write was outpaced and your local state was just re-synced (transient confirmation, more attention-grabbing than the passive informational chips). Closes the operator-visibility gap on the rev-136 OCC primitive at the cheapest possible surface — no new round-trip, no polling, no schema; the rejection trail rides the same response the PUT already returned.
- v1 mirror + OpenAPI 3.1 typed coverage on the rev-137 rejection trail — 60th unbroken cadence revCloses the v1 parity gap on the rev-137 dashboard primitive in the same cycle the dashboard primitive ships. Both the dashboard `/api/workspace/dashboard-prefs` PUT and the bearer-auth `/api/v1/workspace/dashboard-prefs` PUT (and DELETE) now return the same `{ prefs, rejected }` response shape so MCP hosts driving the desk programmatically across multiple machines (e.g. a watcher agent on a CRON server + a manual operator on a laptop) see exactly which entries the OCC step rejected — they can avoid double-syncing the same scope or skip a follow-up GET to re-fetch the canonical server state. OpenAPI 3.1 spec types the new `rejected.taskCommentFilters` array with full per-entry shape (taskId, reason enum 'stale_write', existingAt + incomingAt timestamps) plus a description that names the dashboard's matching chip vocabulary so MCP-host code generators reading the spec see exactly how to consume the rejection trail. The rev-78 cadence pattern (every dashboardPrefs primitive gets typed in the OpenAPI spec in the same cycle it ships) reaches its 60th unbroken rev with rev 137.
- Cumulative dashboard polish — brand-amber Outpaced chip + warning-style pulsing dot + 5s fade animationThree complementary visual affordances on the rev-137 chip. (a) New `.ld-task-comment-filter-outpaced` brand-amber palette (`rgba(207, 108, 58, *)`) distinct from the rev-134 brand-color teal Restored chip and the rev-135 brand-purple Synced chip so all three filter-row chips read at three distinct attention levels: passive (Restored teal), passive (Synced purple), transient/attention (Outpaced amber). (b) Slightly more aggressive `@keyframes ld-task-comment-filter-outpaced-pulse` (1.4s vs the rev-134 1.6s, 5px shadow vs 4px) so the chip reads as 'something happened' rather than 'your scope is loaded'. (c) Slightly longer fade window (5s vs the rev-134 4s) because the message carries denser meaning and the operator needs a beat to register that their write was outpaced. New `.ld-task-comment-filter-outpaced-dot` + `:focus-visible` outline ring matches the rev-38 dashboard accessibility pattern. Cumulative micro-polish (every rev 22+ has carried at least one). The rev-137 chip closes the operator-visibility loop on the rev-136 OCC primitive in the rev-22+ design language — the same chip vocabulary that has driven every filter-row affordance since rev 134.