# Upgrade Guide — v0.21.1

<!-- bump: patch -->

## What Changed

### Server Robustness — Five Self-Healing Improvements

This release addresses a class of failure modes where agents become permanently unrecoverable after a server crash, particularly during auto-updates combined with Node.js version changes.

**1. `/restart` intercepted by lifeline when server is down**

Previously, typing `/restart` in Telegram when the server was down would queue the message — creating a dead man's switch where the recovery command required the thing that was broken. Now the lifeline intercepts `/restart` when the server is unhealthy and routes it to the supervisor's restart logic directly, bypassing the server entirely.

**2. Planned-exit marker TTL (10 minutes)**

Auto-updates write a `planned-exit-marker.json` so the supervisor suppresses false "server down" alerts during expected restarts. Previously this marker persisted forever. If the restart failed, the marker caused the supervisor to keep entering maintenance mode on every retry attempt. The marker now expires after 10 minutes and is auto-cleaned.

**3. Slow retry mode — agents never truly give up**

After the circuit breaker exhausts its fast retries (3x at 30-minute intervals), it previously gave up permanently — requiring manual intervention. Now it enters a slow-retry mode that attempts a restart every 2 hours indefinitely. Transient issues (Node version changes, disk full, port conflicts) often resolve themselves. `/lifeline reset` still provides immediate retry.

**4. Plist self-healing at lifeline startup**

On every lifeline startup (macOS), the system now validates that the launchd plist uses the boot wrapper pattern (`instar-boot.sh`) instead of a hardcoded Node.js binary path. If an old-style plist is detected, it auto-regenerates both the boot wrapper script and the plist via the standard `installAutoStart()` path. This prevents the failure mode where Node.js version changes (via asdf, nvm, etc.) break the launchd auto-start.

**5. Cross-agent restart API**

New endpoint: `POST /agents/:name/restart`. Any agent can now restart any other agent on the same machine via the agent registry. The endpoint:
- Is auth-gated (requires Bearer token)
- Looks up the target agent by name in the registry
- Prevents self-restart (returns 400)
- Validates the shadow install exists before execution
- Uses `execFile` with argument arrays (no shell injection)
- Runs the standard `server start` command via the target's shadow install

## What to Tell Your User

- **Recovery from Telegram**: "If your agent's server goes down, typing /restart in any Telegram topic now works even when the server is down. The lifeline catches it and restarts the server directly — no need to remember /lifeline restart."

- **Agents never give up**: "Your agents will now keep trying to recover indefinitely after a crash. Previously they could permanently give up after too many failures. Now they retry every 2 hours even in the worst case. If something was temporarily broken — like a Node update or a full disk — the agent will eventually come back on its own."

- **Self-healing auto-start**: "If you switch Node.js versions, your agents' auto-start configuration now repairs itself automatically. This was the root cause of the SageMind outage — that failure mode is now structurally prevented."

- **Cross-agent recovery**: "Your agents can now restart each other. If one agent goes down, you can ask any other running agent to bring it back. No need to open a terminal."

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| /restart works when server is down | Automatic — lifeline intercepts when server is unhealthy |
| Planned-exit marker TTL | Automatic — markers expire after 10 minutes |
| Slow retry mode | Automatic — retries every 2 hours after circuit breaker exhaustion |
| Plist self-healing | Automatic — old-style plists upgraded on lifeline startup |
| Cross-agent restart | `POST /agents/:name/restart` |
