- memoryEntries.archiveWarnedAt column + sweepMemoryArchiveWarnings helper — closes the missing edge of the rev-153/154 lifecycle at the per-entry warning axisCloses the named rev-154 next-sprint candidate ('per-memory retrieval Slack push'). New `memoryEntries.archiveWarnedAt` timestamp column + `sweepMemoryArchiveWarnings()` per-workspace helper that finds non-pinned, importance < 9 memory entries 1-2 days from rev-154 auto-archive (lastRetrievedAt within the warn window of the workspace's staleMemoryAutoArchiveDays threshold) AND haven't been warned yet (`archiveWarnedAt` is null). Mirrors the rev-50 task archive_warning sweep at the per-memory axis exactly. Stamps `archiveWarnedAt` so a second cron tick within the warning window doesn't double-fire. Capped at 25 candidates per sweep so a workspace that just enabled rev-154 auto-archive can't get warning-stormed. Companion `previewMemoryArchiveWarnings()` helper does the same predicate without stamping — used by the rev-36 admin digest preview path so admins iterating on configuration don't pollute the production cron's 'already warned' state. Closes the missing edge of the rev-153/154 lifecycle: workspace-level surface (rev 153 dashboard + per-row chip) + workspace-level closure (rev 154 auto-archive Slack push) + per-entry warning (rev 155).
- memory.archive_warning outbound event + Slack push — workspace-shared, fan-out via runMemoryArchiveWarnings cron sweepNew `OutboundEvent` value `memory.archive_warning` plus matching `dispatchMemoryArchiveWarningWebhook()` dispatcher in `src/lib/outbound.ts`. Mirrors the rev-50 `task.archive_warning` event at the per-memory axis. Workspace-shared — memory entries don't have assignees, so unlike rev-50 task warnings which fire per-task per-assignee, the rev-155 warning lists every imminent entry in one Slack block. Slack post via the new `buildMemoryArchiveWarningSlackPayload()` block with `:alarm_clock: Memory entries about to auto-archive` header + listing each entry with `auto-archives in Nd` + `Nd unused` / `never used` + kind + title + recommendation copy ('Pin entries or raise importance >= 9 to keep'). New `runMemoryArchiveWarnings()` cron sweep added to `runDailyDigest()` IMMEDIATELY BEFORE `runStaleMemoryAutoArchive()` so operators get at least one cron-cycle of heads-up before durable knowledge disappears (same shape rev 50 fires before rev 49). Pure no-op on workspaces without staleMemoryAutoArchive configured. Lets external integrations (knowledge-base mirror, FinOps dashboard, CRM tagging unused brand assets) hear the warning → action push pair (rev 155 warning + rev 154 closure) on the per-memory axis without polling.
- Per-memory archive warning section in the daily digest email + activity-log per-kind glyph + tintingNew `buildMemoryArchiveWarningSection()` digest helper renders up to 6 imminent entries with `⏰ auto-archives in Nd` + kind chip + `Nd unused` / `never used` + recommendation copy in a styled HTML section. Renders alongside the rev-48 stale-tasks section as the per-memory complement of the workspace's two working-set axes (in-flight work + durable knowledge). Closes the email-channel parity gap on the rev-153/154 memory-archive lifecycle so solo founders + email-first operators who don't sit in Slack get the same heads-up Slack-first teams already have. The `runMemoryArchiveWarnings` cron sweep returns a `byWorkspace` Map so the email surface and the Slack/outbound surfaces always agree on which entries fired this cycle (no double-stamping race, no double-query). New `memory_archive_warning` activity-log kind + `KIND_LABEL` + `KIND_GLYPH` (⏰) + `.ld-activity-memory_archive_warning` brand-amber tint mirror the rev-50 task.archive_warning visual vocabulary so operators reading the activity log see warning surfaces for the two working-set axes (in-flight work + durable knowledge) with one consistent affordance.
- Pulse engine clears archiveWarnedAt on retrieval + setMemoryPinned/updateMemoryEntry clear on operator action — warning state stays in lockstep with the operator's decisionPulse engine's `workNextTask()` now also clears `archiveWarnedAt` in the same UPDATE that stamps `lastRetrievedAt` + bumps `retrievalCount` (rev 153) on every memory entry the AI cycle pulled. A re-engaged memory entry leaves the warning state immediately rather than waiting for the next cron tick. `setMemoryPinned()` clears the stamp on pin (pinned entries are exempt from rev-154 auto-archive — the rev-5 'keep forever' veto). `updateMemoryEntry()` clears the stamp when raising importance to >= 9 (also exempt — load-bearing brand-voice / decision context). The OpenAPI 3.1 spec gains a rev-155 changelog block documenting the new outbound event + the warning-state-clearing rules. The cadence pattern from rev 78 onward (every dashboard primitive gets typed in the OpenAPI 3.1 spec in the same cycle it ships) reaches its 77th unbroken rev with rev 155. MCP-host code generators reading the spec see typed contracts for the new event immediately. The MCP server's memory-axis cluster is now nine axes deep (read rev 12 + write rev 12 + bulk-update rev 35 + reactions rev 33 + tags rev 21 + export rev 125 + stale rev 153 + auto-archive rev 154 + archive-warning rev 155) with full v1 parity across every axis.