- Per-task discussion filter persistence โ closes the named rev-133 next-sprint candidateUntil rev 134 the rev-128 keyword + rev-129 author + rev-130 reactions-only filter scope on a task's discussion thread reset to default the moment an operator left the dashboard. An operator narrowing deeply to 'Steve's comments matching concern with reactions' on a long-running task had to re-type the scope every time they returned. Rev 134 closes that gap. New `taskCommentFilter(taskId)` namespace key in the rev-116 shared draft-storage helper. New `readPersistedFilter` / `writePersistedFilter` helpers with type-guards on every field (a tampered localStorage entry can't render the surface in an inconsistent state) + a 30-day TTL (stale scopes don't accumulate on tasks the operator hasn't touched in months). Lazy state initializer reads on mount; a useEffect persists every change. URL hash deep-links (rev-31 / rev-133 share-permalink format) still win over the persisted filter โ a shared link is the strongest possible signal of intent and explicitly clears the persisted scope on arrival. Pairs with rev-78 multi-device sync at the per-thread axis: drafts + composer state stay localStorage-only because they're per-device by design (an in-flight filter on Machine A shouldn't follow you to Machine B mid-triage), but the persisted scope means an operator who narrowed deeply doesn't lose their lens between sessions on the same browser.
- Visible Clear-filters chip + Restored-filter affordance for mouse-first operatorsTwo complementary visual affordances on the per-thread filter row. (a) New `.ld-task-comment-clear-all` chip surfaces beside the rev-128 copy-thread chip whenever any filter axis is active โ mirrors the rev-129 Esc-to-clear shortcut for mouse-first operators who don't keep the keyboard primitive in muscle memory. Hidden when no axis is active so the chip cluster never reads as bloat. Hover lift (1px) + soft red treatment so the affordance reads as a 'reset' action distinct from the rev-128 brand-teal copy chip. (b) New `.ld-task-comment-filter-restored` chip flags that the operator's last filter scope on this task was loaded from localStorage. Brand-color dashed-border + pulsing dot + 4s auto-fade animation so the affordance reads as 'your scope is loaded' without persisting as chrome that competes with the rev-131 match counter or the rev-128 copy-thread chip. Tap-to-dismiss on the chip itself; explicit operator interaction (typing, tapping author chips, toggling reactions-only, Esc, or empty-state Clear) also dismisses immediately so the chip never reads stale.
- since=ISO recency axis on /api/v1/tasks/{id}/comments โ closes the recency axis on the per-task comment surfaceUntil rev 134 the per-task comments cluster on the v1 surface carried scope-by-content (rev 129 keyword), scope-by-attribution (rev 129 author), and scope-by-engagement (rev 130 reactions-only on the dashboard) but no scope-by-time on the protocol-bound side. MCP hosts polling for 'what's new on this task in the last hour' had to enumerate every comment and filter client-side. Rev 134 closes that with an optional `since=ISO` query param. Composes with q + authorId via intersection: a recipient that sets all three gets only comments posted since the instant AND matching the keyword AND from the named author. Bounded to a 1-year max lookback to keep the in-memory filter cost predictable; an unparseable timestamp falls back to no since filter. The response echoes the resolved instant so callers can verify the filter was applied + reuse the same value as the next poll's `since` param, walking the timeline forward without losing or duplicating comments. The dashboard `/api/tasks/{id}/comments` mirror gains the same param + echo field in lockstep so any direct caller of either surface (the v1 bearer-auth endpoint or the dashboard session-auth endpoint) reads one consistent contract โ the same parity discipline that's been running since rev 132.
- OpenAPI 3.1 typed coverage on the rev-134 since param + cumulative cadence โ 57th unbroken revCloses the typed-contract gap on the rev-134 v1 enhancement in the same cycle it ships. The OpenAPI spec's `/tasks/{taskId}/comments` GET endpoint gains a typed `since` query parameter (date-time format) + a typed `since` field on the response shape (nullable string, format date-time). The rev-78 cadence pattern (every v1 enhancement gets typed in the OpenAPI spec in the same cycle it ships) reaches its 57th unbroken rev with rev 134. MCP-host code generators reading the spec see a typed contract for the recency axis immediately. The OpenAPI spec changelog header gains a rev-134 block explaining the recency axis closure + the polling pattern (echo the resolved `since` instant, reuse on the next poll). The `/api/v1` self-describing endpoint index updates the comments endpoint signature to include `since=ISO` inline so MCP-host integrators reading the index discover the recency axis without opening the spec.