# Upgrade Guide — v0.12.10

## What Changed

This release eliminates notification spam caused by restart loops and state loss:

1. **AutoUpdater dedup state persistence**: `notifiedVersionMismatch` and `lastNotifiedRestartVersion` are now saved to the state file. Previously these were in-memory only, so every server restart reset the dedup counters, causing repeated "Just updated to vX.Y.Z" messages.

2. **Lifeline rate limit persistence**: `lastServerDownNotifyAt` and `suppressedServerDownCount` are now written to `state/lifeline-rate-limit.json`. Previously, every restart reset the 5-minute rate limit, causing floods of "Server went down: Health check failed" messages.

3. **Supervisor restart loop detection**: `ServerSupervisor.checkRestartRequest()` now tracks how many times it has restarted for a given target version via `state/restart-version-count.json`. After 2 restarts for the same version, it stops and logs "restart loop detected" instead of continuing the cycle.

4. **Dashboard edit-in-place**: `TelegramAdapter.broadcastDashboardUrl()` now tries to edit the existing pinned message via `editMessageText` before falling back to send+pin. This eliminates unread badges on the Dashboard topic during server restarts. The message ID is persisted in `state/dashboard-message.json`.

## What to Tell Your User

- **No more notification spam**: "The firehose of repeated update and health check messages is fixed. The server now remembers what it already told you, even across restarts."
- **Dashboard stays clean**: "The Dashboard topic won't show unread badges anymore. The link updates silently in place."

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| Persistent notification dedup | Automatic — no configuration needed |
| Restart loop detection | Automatic — stops after 2 restarts for the same version |
| Dashboard edit-in-place | Automatic — edits existing pinned message instead of posting new ones |
