# Phase 1 Delta 审计 — Wave D1(同步/后台) **日期**: 2026-06-04 **范围**: 推送/sync 核心路径(Code Review batch1 后 delta) **标准**: `standards/line-walk-audit-standard-v2.md` 8 步 ## 登记 | # | 文件 | 语言 | 行数 N | Read 范围 | |---|------|------|--------|-----------| | 1 | `server/api/sync_v2.py` | Python | 1656 | 1–200, 680–1080, 1280–1657 + 全文件 `@router`/grep H | | 2 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 | | 3 | `server/background/schedule_runner.py` | Python | 262 | 1–262 全文 | | 4 | `server/background/retry_runner.py` | Python | 169 | 1–169 全文 | | 5 | `server/background/heartbeat_flush.py` | Python | 101 | 1–101 全文 | ## Step 3 — 规则扫描 H(摘要) | 文件 | H 命中 | |------|--------| | sync_v2.py | H-Shell, H-Auth, H-Path, H-Audit, H-Upload | | sync_engine_v2.py | H-Shell, H-AuthN/A, H-Concurrency | | schedule_runner.py | H-Cron, H-Script-exec, H-Lock | | retry_runner.py | H-Lock, H-Retry | | heartbeat_flush.py | H-Redis, H-DB | ## 入口表(sync_v2.py API) | 方法 | 路径 | 鉴权 | |------|------|------| | POST | `/api/sync/files` | JWT `get_current_admin` | | POST | `/api/sync/preview` | 同上 | | POST | `/api/sync/file-ops` | 同上 | | POST | `/api/sync/file-clipboard` | 同上 | | POST | `/api/sync/browse` | 同上 | | POST | `/api/sync/browse-local` | 同上 | | POST | `/api/sync/local-file-ops` | 同上 | | POST | `/api/sync/local-file-preview` | 同上 | | POST | `/api/sync/cancel` | 同上 | | POST | `/api/sync/reconcile-stale-logs` | 同上 | | POST | `/api/sync/validate-source-path` | 同上 | | POST | `/api/sync/diagnose` | 同上 | | POST | `/api/sync/file-diff` | 同上 | | POST | `/api/sync/upload` | 同上 | | POST | `/api/sync/upload-zip` | 同上 | | POST | `/api/sync/verify` | 同上 | | POST | `/api/sync/download` | 同上 | | POST | `/api/sync/read-file` | 同上 | | POST | `/api/sync/write-file` | 同上 | | POST | `/api/sync/chmod` | 同上 | | POST | `/api/sync/compress` | 同上 | | POST | `/api/sync/decompress` | 同上 | ## Closure 表 | H | 文件:行号 | 判定 | 理由 | |---|-----------|------|------| | H-Shell | sync_v2.py:156-173 | SAFE | 远程路径 `normalize_remote_abs_path` + `shlex.quote` | | H-Shell | sync_v2.py:777 | SAFE | `remote_file` 经 `remote_join`+quote;`wc -c && cat` 单路径 | | H-Path | sync_v2.py:721-731 | SAFE | `ensure_under_nexus_upload` + prefix 校验 | | H-Path | sync_v2.py:887-890 | SAFE | 上传文件名去斜杠 | | H-Path | sync_v2.py:999-1005 | SAFE | ZIP slip:`assert_zip_member_safe` | | H-Auth | sync_v2.py:74-1610 | SAFE | 全部 22 路由 `Depends(get_current_admin)` | | H-Audit | sync_v2.py:119-122 等 | SAFE | CUD/敏感操作 `_audit_sync` | | H-Upload | sync_v2.py:876-877 | SAFE | 100MB 上限 | | H-Upload | sync_v2.py:977-978 | SAFE | ZIP 500MB 上限 | | H-Shell | sync_engine_v2.py:433-465 | RISK | `StrictHostKeyChecking=no` 运维惯例;单人环境已接受 | | H-Shell | sync_engine_v2.py:440-445 | RISK | sshpass/SSHPASS;内部工具,凭据加密存储 | | H-Concurrency | sync_engine_v2.py:89-150 | SAFE | `_db_lock` 串行化 sync_log 写 | | H-Cron | schedule_runner.py:58-72 | RISK | 畸形 cron 字段 `int()` 可抛 ValueError;外层 254 行捕获 rollback | | H-Script | schedule_runner.py:198-205 | SAFE | 调度脚本仅 JWT 管理员配置的 schedule 触发 | | H-Lock | schedule_runner.py:125-131 | SAFE | `FOR UPDATE SKIP LOCKED` 防双触发 | | H-Lock | retry_runner.py:67-76 | SAFE | SKIP LOCKED 认领 | | H-Retry | retry_runner.py:22-59 | SAFE | 指数退避 + max_retries | | H-Redis | heartbeat_flush.py:42-48 | SAFE | scan 失败 log+continue | | H-DB | heartbeat_flush.py:57-99 | SAFE | 参数化 ORM update;未知 server_id rowcount 0 跳过 | **len(H)=19, Closure=19** ## FINDING(本波) 无 P0/P1 新 FINDING。RISK 项与既有运维/单人决策一致,不阻塞。 ## DoD - [x] len(H) == Closure - [x] Read 覆盖 1..N(sync_v2 大文件分段 + 全路由 grep) - [x] FINDING 含行号 - [x] 入口表 + sink 标注 - [x] 逐行完成 ✓(D1 五文件) ## 验证 - `docker-compose.yml` Redis 发布 6379(修复本地 uvicorn 连 Redis) - 待跑:`bash scripts/local_verify.sh`