# BUG 专项逐行走读 — Batch 3（2026-06-04）

**标准**: `docs/project/line-walk-audit-standard.md` · 八类仅列 **BUG**

## 范围（5 文件，全文 Read）

| 文件 | N | Read |
|------|---|------|
| `server/background/retry_runner.py` | 148 | 1–148 |
| `server/application/services/files_browse_service.py` | 150 | 1–150 |
| `server/api/servers.py` | stats 225–282 | |
| `frontend/src/pages/DashboardPage.vue` | 411 | stats/summary/WS |
| `server/application/services/sync_engine_v2.py` | `sync_files` 60–287 | gather 计数 |

---

## Step 3 规则扫描（BUG 相关）

| 文件 | 命中 |
|------|------|
| retry_runner.py | 成功判定、cancel 分支、backoff |
| files_browse_service.py | 路径 `..`、SSH 命令引用 |
| servers.py | `offline = total - online`、Redis 脏 key |
| DashboardPage.vue | 是否混用 stats / 列表在线 |
| sync_engine_v2.py | `gather(return_exceptions=True)` |

---

## Closure 表（BUG）

| 文件 | 行号 | 判定 | 严重度 | 理由 |
|------|------|------|--------|------|
| retry_runner.py | 85-100 | **FINDING** | P2 | 仅 `failed==0 && completed>0` 成功；全 cancel 时 job 永久 pending |
| sync_engine_v2.py | 241-242 | **FINDING** | P2 | 任务异常时 `results` 缺项，`failed+completed` 可小于 `total` |
| servers.py | 276-279 | **FINDING** | P2 | Redis heartbeat 数可大于 DB `total`，在线率 >100% |
| files_browse_service.py | 33-46, 98-101 | SAFE | — | `normalize_remote_abs_path` + `shlex.quote` |
| DashboardPage.vue | 302-320 | SAFE | — | 卡片用 `/servers/stats`；列表分页独立 |
| DashboardPage.vue | 345-376 | RISK | P3 | `loadSummary` 仅前 200 台算 CPU/Agent 均值（已知限制） |

---

## FINDING 列表

### BUG-06-04-05 · P2 · retry_runner.py

**现象**：重试任务在 `cancelled>0` 且 `completed=failed=0` 时不进入成功/耗尽分支，每 5 分钟无限重试。

**修复**：`apply_push_retry_outcome()` — cancel-only 标 `failed`；统一 backoff。

### BUG-06-04-06 · P2 · sync_engine_v2.py:241-242

**现象**：`_sync_one` 未捕获异常时 gather 吞掉，`failed` 统计偏小。

**修复**：记录 `BaseException`；`unaccounted = total - len(results)` 并入 `failed`。

### BUG-06-04-07 · P2 · servers.py:276-279

**现象**：过期 `heartbeat:*` 使 `online > total`，仪表盘在线率失真。

**修复**：`online = min(online, total)`（有 DB 行时）。

---

## Step 7 统计

```
retry_runner.py           1 FINDING（已修）
sync_engine_v2.py         1 FINDING（已修）
servers.py                1 FINDING（已修）
files_browse_service.py   0
DashboardPage.vue         0
```

## Step 8 DoD

- [x] 5 文件覆盖
- [x] Closure 全表
- [x] 3 项 P2 已修 + pytest

## 验证

```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 --tb=no
```

Changelog: `docs/changelog/2026-06-04-bug-batch3-retry-sync-stats.md`

## 下一批（BUG）

- `server/api/files.py`（上传/删除 mutation + ETag 失效）
- `server/background/heartbeat_flush.py`
- `frontend` 推送页与 WS 进度一致性
