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

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

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

| 文件 | N | Read |
|------|---|------|
| `server/api/agent.py` | 360 | Redis TTL + heartbeat |
| `server/background/heartbeat_flush.py` | 102 | flush 循环 |
| `server/api/sync_v2.py` | write/chmod/compress/decompress | 1374–1665 |
| `server/background/self_monitor.py` | 108 | 1–108 |
| `server/application/services/files_browse_service.py` | invalidate 辅助 | 65–85 |

---

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

| 文件 | 命中 |
|------|------|
| agent.py | `REDIS_KEY_EXPIRE` vs `FLUSH_INTERVAL` |
| heartbeat_flush.py | 与 agent TTL 常量重复/不一致 |
| sync_v2.py | 写/chmod/压缩/解压后 ETag |
| self_monitor.py | 仅监控 alert WS |
| files_browse_service.py | 父目录批量失效 |

---

## Closure 表（BUG）

| 文件 | 行号 | 判定 | 严重度 | 理由 |
|------|------|------|--------|------|
| agent.py | 34, 226-227 | **FINDING** | P2 | 注释写 TTL=1.5×flush，实际 600=600，停 Agent 后 key 可能在 flush 前过期 |
| sync_v2.py | 1474-1650 | **FINDING** | P2 | write/chmod/compress/decompress 未失效 browse ETag（Batch4 已覆盖 ops/upload） |
| heartbeat_flush.py | 18-20 | SAFE | — | 常量与 agent 对齐后由 agent 单一来源 |
| self_monitor.py | 102-107 | RISK | P3 | 原仅记录 alert WS；已补 sync WS 计数到 debug 日志 |
| files_browse_service.py | 65+ | SAFE | — | 新增 `invalidate_browse_parents` |

---

## FINDING 列表

### BUG-06-04-11 · P2 · agent.py REDIS_KEY_EXPIRE

**现象**：`REDIS_KEY_EXPIRE=600` 与 `FLUSH_INTERVAL=600` 相同，末次心跳可能在 10min flush 前从 Redis 消失，MySQL 历史落后。

**修复**：`REDIS_KEY_EXPIRE = int(FLUSH_INTERVAL * 1.5)` → 900s。

### BUG-06-04-12 · P2 · sync_v2 远程写路径

**现象**：`/write-file`、`/chmod`、`/compress`、`/decompress` 成功后 browse 304 仍可能返回旧目录。

**修复**：`invalidate_browse_parents(server_id, *paths)`。

---

## Step 7 统计

```
agent.py                  1 FINDING（已修）
sync_v2.py                1 FINDING（已修）
heartbeat_flush.py        0
self_monitor.py           0（P3 观测增强）
files_browse_service.py   0（辅助函数）
```

## Step 8 DoD

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

## 验证

```bash
ruff check server/api/agent.py server/api/sync_v2.py server/background/self_monitor.py
pytest tests/test_agent_heartbeat_ttl.py tests/test_files_browse_etag.py tests/ -q --tb=no
```

Changelog: `docs/changelog/2026-06-04-bug-batch5-agent-etag.md`

## 下一批（BUG）

- `server/api/auth_jwt.py` / refresh 重用检测边界
- `server/background/script_execution_flush.py`
- 前端 `FilesPage` 与 ETag/If-None-Match 联调
