- Stale-task auto-archive (close lifecycle: rev 47 detect β rev 48 surface β rev 49 act)Rev 47 detected stale tasks (StaleTasksPanel + GET /api/v1/tasks/stale); rev 48 surfaced them across digest + Slack + outbound + in-line pill; rev 49 closes the lifecycle by letting the desk *act*. New workspace.staleTaskAutoArchiveDays integer column (nullable = off, opt-in by design, valid range 7-90 days). New runStaleTaskAutoArchive() sweep runs at the end of runDailyDigest() β for every onboarded workspace with a configured threshold, calls sweepStaleTaskAutoArchive() which marks non-pinned stale tasks past threshold as status=done with a synthetic blocker note ('Auto-archived after N days idle (threshold: Md). Re-queue if you still need it.') so the audit trail records what happened. Capped at 25 tasks per sweep so a workspace that just enabled the feature with hundreds of stale tasks doesn't see them all archived in one tick. Pinned tasks are deliberately excluded β pinning is the rev-23 affordance for 'keep around regardless of staleness.' Slack push via new buildTaskAutoArchivedSlackPayload() block. New OutboundEvent task.auto_archived + dispatchTaskAutoArchivedWebhook(). Strategic significance: closes the lifecycle that started in rev 47. The full stale-task story is now end-to-end across detect β surface β act, with operator-controlled timing (rev 49 is opt-in) so the desk respects the queue but can self-clean when the operator wants it to.
- Per-recipient stale-task scoping in the daily digest (close named rev-48 follow-up)Rev 48's running state explicitly named 'per-recipient stale-task scoping in digest' as the next-sprint candidate. Rev 49 ships it. getStaleTasks() now accepts an optional assignedToUserId. The daily digest cron (and the rev-36 previewDigestForUser() admin testing path) loads per-recipient stale-task data alongside the rev-48 workspace-shared data, deduplicates against the shared list, and renders a separate 'N of your tasks quiet for 5+ days' section. Solo-operator workspaces continue to see only the workspace-shared section (since their assignee section IS the workspace section). Multi-operator teams now see 'the desk has 8 stale tasks; 3 are yours' without enumerating the dashboard. Strategic significance: closes the per-recipient personalisation symmetry across rev-25 assignee section + rev-31 mentions section + rev-48 stale section + now rev-49 personal stale section. The daily digest is now fully personalised across every load-bearing surface that benefits from per-recipient context.
- Workspace auto-archive config β admin route + integrations panel + v1 mirror + per-user filterNew PATCH /api/workspace/auto-archive-config route (admin-only via requireWorkspaceRole). New GET/PUT /api/v1/workspace/auto-archive-config bearer-auth mirror so MCP hosts inherit the config primitive at parity with the dashboard. New 'Stale-task auto-archive' section in the integrations panel under the rev-20 daily cost cap section so the two queue-hygiene primitives (cost cap + stale archive) read as siblings. The v1 GET /api/v1/tasks/stale endpoint also gained an optional assignedToUserId query param mirroring the rev-49 digest change so MCP hosts on multi-operator desks can answer 'which of my tasks are rotting?' programmatically. Strategic significance: every dashboard primitive shipped this rev has a v1 equivalent shipped in the same rev β the cadence pattern that started in rev 37 (blockers + v1 blockers in lockstep) continues. The rev-49 auto-archive lifecycle has nothing left for the upcoming MCP server to design.
- Countdown-to-auto-archive on the in-line stale pill + dashed-card visual cueThe rev-48 in-line stale pill ('β³ Nd quiet') now also surfaces 'archives in Md' or 'archives today' when the workspace has the rev-49 auto-archive threshold configured AND the task is past the rev-48 staleness threshold. Tasks within 3 days of auto-archival render the pill in red with a 2.4s amberβred pulsing-shadow animation, and the surrounding card border switches to dashed-red β lower-key than rev-23 pinned glow or rev-37 now-ready pulse since the action being signaled is 'consider intervening' not 'this is ready'. Cumulative micro-polish (every rev 22+ has carried one). Strategic significance: rev 48 made staleness in-queue visible; rev 49 makes auto-archive *anticipated*. Operators see the lifecycle countdown without leaving the active-work card β pin the task to keep it (the rev-23 affordance is now load-bearing on the rev-49 lifecycle), re-queue with a cycle to bump updatedAt, or operator-note it to surface intent. The pill row now reads across four orthogonal axes: triage (priority/due/assignee), discussion (comments + mentions), rot (staleness), and lifecycle (auto-archive countdown).