# Changelog — BUG Batch 3：重试分类 / 推送计数 / 仪表盘在线（2026-06-04）

## 摘要

修复推送重试任务在「仅取消」场景下无限 pending、批量推送异常时成功/失败计数偏少、以及 Dashboard `online` 可能大于 `total` 的三处 P2 逻辑问题。

## 动机

- `retry_runner` 成功条件过窄，cancel-only 的 `sync_files` 结果永不结案。
- `sync_engine_v2` 使用 `gather(return_exceptions=True)` 但未对缺失 `results` 的服务器补计失败。
- Redis 残留 `heartbeat:*` 在服务器已删后仍计数，导致在线率超过 100%。

## 变更

| 文件 | 说明 |
|------|------|
| `server/background/retry_runner.py` | `apply_push_retry_outcome()`、`_backoff_seconds()` |
| `server/application/services/sync_engine_v2.py` | gather 异常日志 + `unaccounted` 并入 `failed` |
| `server/api/servers.py` | `online` 封顶为 `total` |
| `tests/test_retry_runner_outcome.py` | 重试结果分类单测 |
| `docs/reports/audit-bug-line-walk-2026-06-04-batch3.md` | BUG Batch 3 报告 |

## 迁移 / 重启

- 需重启 `nexus` Supervisor 进程。
- 无 schema 变更。

## 验证

```bash
ruff check server/background/retry_runner.py server/application/services/sync_engine_v2.py server/api/servers.py
pytest tests/test_retry_runner_outcome.py tests/ -q
```

## 关联

- Batch 2：`docs/changelog/2026-06-04-schedule-once-rollback.md`
- Batch 1：`docs/changelog/2026-06-04-install-lock-atomic.md`
