- Loop interval admin control — closes a long-outstanding configuration gapThe `workspace.loopIntervalMinutes` column has been settable in the schema since rev 1 (default 5) but had no UI or API surface — operators wanting to slow the desk down on a quiet workspace, or speed it up after upgrading to Pro/Team, had no path. Rev 140 closes that gap. New `setWorkspaceLoopInterval()` helper + admin-only `PATCH /api/workspace/loop-interval` route + `LoopIntervalControl` client component mounted directly under DeskLoopControl. Plan-tier-aware: server-side floor (free=15, pro=5, team=1) is layered on top of the requested value so a free workspace can't sneak below 15 minutes. Returns both the requested + effective values so the dashboard UI can surface the floor when it lifts the value. Six presets (1/5/15/30/60/240 min) — presets below the operator's plan floor render with a dashed border + amber `↑Nm` mark + tooltip naming the floor so the upgrade path is visible on every plan. Activity log records every change. Closes the third axis of operator-driven cadence control alongside the rev-1 desk-state primitive (loopState on/paused/off) + rev-21 scheduled-pause primitive.
- OCC primitive extended to the three remaining single-scalar dashboardPrefs fields — closes the named rev-139 next-sprint candidateUntil rev 140 the rev-83 activeWorkSort + rev-79 digestPersonalSections + rev-80 digestQuietWeekends scalars on the rev-78 dashboardPrefs JSONB were last-write-wins. Even though the rev-139 running state correctly noted that 'the surface for it is smaller since these aren't typically toggled rapid-fire from multiple devices', closing the OCC symmetry across every multi-device-synced primitive on the dashboardPrefs JSONB makes the conflict-resolution semantics uniform — every scalar on the JSONB now has the same OCC story. Three new optional `*UpdatedAt` companion fields on the prefs payload + three new OCC steps inside `setDashboardPrefs` mirroring the rev-139 density OCC step exactly: when the patch carries `{field}UpdatedAt` older than the existing server-side stamp, the server keeps the newer field value and surfaces the rejection on the rev-137 telemetry trail at `rejected.{field}: { reason: 'stale_write', existingAt, incomingAt } | null`. Equal timestamps fall through to the upsert path. Each rejection is independent (a stale activeWorkSort doesn't affect the digestPersonalSections decision) so the response can carry up to three rejections per PUT. The per-field check runs only when the patch actually carries the field, so a no-op PUT that doesn't touch the field can't accidentally accept an old timestamp from a stale companion field.
- v1 mirror + OpenAPI 3.1 typed coverage on every new field — 62nd unbroken cadence revBearer-auth `/api/v1/workspace/loop-interval` PATCH mirrors the dashboard endpoint exactly so MCP hosts driving the desk programmatically can tune the cadence without dashboard sessions — pairs with `/workspace/loop` (rev 82 desk-state) + `/workspace/pause-until` (rev 82 scheduled pause) as the third axis of programmatic cadence control. Bearer-auth `/api/v1/workspace/dashboard-prefs` PUT accepts the three new `*UpdatedAt` fields via the same Zod schema as the dashboard route, returns the same `{ prefs, rejected }` response shape extended with `rejected.activeWorkSort` + `rejected.digestPersonalSections` + `rejected.digestQuietWeekends`. The OpenAPI 3.1 spec types the new loop-interval endpoint with full request/response schemas (request: loopIntervalMinutes integer 1-1440; response: ok, loopIntervalMinutes, effectiveLoopIntervalMinutes, planTier enum) + types the three new `*UpdatedAt` integer fields on the PUT request body + the three new `rejected.*` nullable objects on the PUT response with full per-field shape (reason enum 'stale_write', existingAt + incomingAt timestamps). The cadence pattern from rev 78 onward (every dashboardPrefs primitive gets typed in the OpenAPI spec in the same cycle it ships) reaches its 62nd unbroken rev with rev 140.
- Cumulative dashboard polish — loop-interval popover with brand-color hover lift + plan-floor visual treatmentNew `.ld-loop-interval` + child classes — visual treatment matches the rev-23 keyboard FAB + rev-39 density toggle + rev-21 scheduled-pause popover so the four power-user controls on the dashboard read with one consistent visual vocabulary. 1px hover lift + 160ms transitions match the rev-22+ tactile click affordance vocabulary. New `:focus-visible` outline ring matches the rev-38 dashboard accessibility pattern so keyboard-only operators land cleanly. Plan-floor visual treatment: presets below the operator's plan floor render with a dashed border + amber `↑Nm` mark + tooltip naming the floor — pairs with the rev-21 cost-cap warning + rev-32 cost-spike alarm as the third floor-aware affordance on the dashboard, all wearing the same brand-amber palette so the operator pattern-matches 'this is your plan floor talking' across all three surfaces. New `@keyframes ld-loop-interval-fade` (200ms) for the popover entrance animation matches the rev-21 scheduled-pause popover entrance animation. Cumulative micro-polish (every rev 22+ has carried at least one) — rev 140's polish anchors the new control in the rev-22+ design language thread and makes the plan-tier upgrade story visible on the most operator-loaded surface (the desk-state panel).