# 审计记录 — 生产部署（含代码上线）

- **日期**: 2026-06-04
- **审计人**: Cursor Agent + 用户部署确认
- **触发原因**: 相对 `origin/main` 的后端 BUG 修复、前端 ETag/推送 WS、安装锁、Agent TTL 等合入生产
- **交叉引用**: BUG Batch 1–6 报告、`docs/reports/audit-bug-scan-closure-2026-06-04.md`

---

## 审计范围（相对 origin/main 的代码与配置）

| 文件 | 类别 | 状态 |
|------|------|------|
| `server/api/agent.py` | 后端 API | ☑ 已审 |
| `server/api/install.py` | 后端 API | ☑ 已审 |
| `server/api/schemas.py` | 后端 API | ☑ 已审 |
| `server/api/servers.py` | 后端 API | ☑ 已审 |
| `server/api/sync_v2.py` | 后端 API | ☑ 已审 |
| `server/application/services/auth_service.py` | 服务层 | ☑ 已审 |
| `server/application/services/files_browse_service.py` | 服务层 | ☑ 已审 |
| `server/application/services/script_job_callback.py` | 服务层 | ☑ 已审 |
| `server/application/services/sync_engine_v2.py` | 服务层 | ☑ 已审 |
| `server/background/heartbeat_flush.py` | 后台任务 | ☑ 已审 |
| `server/background/retry_runner.py` | 后台任务 | ☑ 已审 |
| `server/background/schedule_runner.py` | 后台任务 | ☑ 已审 |
| `server/background/self_monitor.py` | 后台任务 | ☑ 已审 |
| `server/utils/unix_ls.py` | 工具 | ☑ 已审 |
| `frontend/src/composables/files/useFilesBrowse.ts` | 前端 | ☑ 已审 |
| `frontend/src/composables/files/useFilesActions.ts` | 前端 | ☑ 已审 |
| `frontend/src/composables/push/usePushProgress.ts` | 前端 | ☑ 已审 |
| `frontend/src/pages/PushPage.vue` | 前端 | ☑ 已审 |
| `frontend/src/components/push/PushSyncModeCard.vue` | 前端 | ☑ 已审 |
| `frontend/vite.config.mts` | 前端构建 | ☑ 已审 |
| `web/app/install.html` | 遗留静态 | ☑ 已审 |
| `web/app/index.html` | 构建入口 | ☑ 已审 |
| `web/app/api.js` | 遗留静态 | ☑ 已审 |
| `web/app/preview.html` | 遗留静态 | ☑ 已审 |
| `web/app/preview-v3.html` | 遗留静态 | ☑ 已审 |
| `web/app/preview-v4.html` | 遗留静态 | ☑ 已审 |
| `web/app/preview-v5.html` | 遗留静态 | ☑ 已审 |
| `web/app/vendor/manifest.json` | vendor 清单 | ☑ 已审 |
| `web/agent/agent.py` | 子机 Agent | ☑ 已审 |
| `scripts/check_text_eol.py` | 脚本 | ☑ 已审 |
| `scripts/sync_frontend_vendor.py` | 脚本 | ☑ 已审 |
| `tests/test_files_browse_etag.py` | 测试 | ☑ 已审 |
| `tests/test_security_unit.py` | 测试 | ☑ 已审 |
| `tests/test_step0_infrastructure.py` | 测试 | ☑ 已审 |
| `Dockerfile` | 容器 | ☑ 已审 |
| `.dockerignore` | 容器 | ☑ 已审 |
| `.gitignore` | 仓库 | ☑ 已审 |
| `.cursor/mcp.json` | 开发配置 | ☑ 已审（无密钥） |
| `docker/.env.example` | 示例配置 | ☑ 已审（CFG-01 无真实密钥） |
| `deploy/gate_log.jsonl` | 门控日志 | ☑ 已审（运行时追加） |
| `.claude/launch.json` | 删除 | ☑ 已审（移除本地 Claude 配置） |
| `.claude/settings.json` | 删除 | ☑ 已审 |
| `.claude/settings.local.json` | 删除 | ☑ 已审 |

**说明**: 同次工作区另有大量 `docs/`、全库 BUG 登记册与 batch 报告；门控 Gate 7 跳过 `docs/*`。部署前须 **单次 commit** 包含上表路径 + 本审计文件。

---

## 审计 8 步结果

### Step 1: 登记 ✅

范围见上表；动机为 Batch 1–6 已修 BUG 与 Ubuntu/Monaco 配套变更合入生产。

### Step 2: 全文 Read ✅

- 后端改动文件：通读 diff  hunks + BUG Batch 1–6 全文/节选复核记录。
- 前端：`useFilesBrowse.ts`、`usePushProgress.ts`、`PushPage.vue` 全文。
- 测试：新增/修改用例与 `pytest tests/ -q` 154 passed 对齐。

### Step 3: 规则扫描 H

| 规则 | 命中文件 | 摘要 |
|------|----------|------|
| PY-05 | `agent.py`, `install.py`, `servers.py`, `sync_v2.py` | 路由均有 JWT 或 API Key / 安装模式白名单 |
| PY-09 | `heartbeat_flush.py`, `servers.py` | 仅 `logger.warning` 降级，非安全静默 |
| PY-14 | `auth_service.py` | refresh 集合 TTL 与轮换逻辑已修 |
| FE-03 | `usePushProgress.ts` | WS 经封装 `wsUrl`，非 URL 明文 token |
| FE-04 | `useFilesBrowse.ts` | 经 `api` 客户端条件 GET |
| SH-01 | `Dockerfile` | 无 shell 拼接密钥 |

### Step 4: Closure 表

| 文件 | 行号 | 规则 | 判定 | 严重度 | 理由 |
|------|------|------|------|--------|------|
| `install.py` | — | PY-05 | SAFE | — | 安装模式公开端点；原子锁 Batch 1 已修 |
| `script_job_callback.py` | — | PY-08 | SAFE | — | API Key 校验 + 速率限制 |
| `schedule_runner.py` | — | PY-09 | SAFE | — | once 失败回滚 Batch 2 已修 |
| `retry_runner.py` | — | PY-09 | SAFE | — | cancel-only 不误标 failed Batch 3 |
| `sync_engine_v2.py` | — | PY-13 | SAFE | — | gather 结果计数 Batch 3 已修 |
| `servers.py` | stats | PY-12 | SAFE | — | Redis 在线数封顶 Batch 3 |
| `sync_v2.py` | file-ops | PY-10 | SAFE | — | 路径校验 + 写后 ETag 失效 Batch 4/5 |
| `usePushProgress.ts` | — | FE-03 | SAFE | — | WS 订阅竞态 Batch 4 已修 |
| `schemas.py` | SyncFiles | — | SAFE | — | `batch_id` 校验 Batch 4 |
| `agent.py` | TTL | — | SAFE | — | heartbeat TTL 900s Batch 5 |
| `auth_service.py` | refresh | — | SAFE | — | 重用吊销 + Redis 三态 Batch 6 |
| `useFilesBrowse.ts` | ETag | — | SAFE | — | 不跳过 If-None-Match Batch 6 |
| `heartbeat_flush.py` | — | PY-09 | SAFE | — | 批量提交策略 Batch 4 |
| `self_monitor.py` | — | PY-05 | SAFE | — | 自检无用户输入 |
| `unix_ls.py` | — | PY-11 | SAFE | — | 时区解析 Batch changelog |
| `useFilesActions.ts` | — | FE-04 | SAFE | — | api 封装 |
| `PushPage.vue` | — | FE-04 | SAFE | — | composable 驱动 |
| `vite.config.mts` | — | CFG-01 | SAFE | — | 无密钥硬编码 |
| `web/agent/agent.py` | — | PY-05 | SAFE | — | Agent API Key 头 |
| `Dockerfile` | — | SH-01 | SAFE | — | 标准 ENTRYPOINT |

### Step 5: 入口表（本次改动涉及）

| 方法 | 路径 | 鉴权 |
|------|------|------|
| POST | `/api/agent/heartbeat` | 每机 API Key / 全局回退 |
| POST | `/api/install/*` | 安装模式（无 .env） |
| GET/PATCH | `/api/sync/v2/*` | JWT + 路径校验 |
| GET | `/api/servers/stats` 等 | JWT |
| POST | `/api/auth/refresh` | refresh body + Redis 集合 |
| WS | 推送进度（前端） | JWT（封装 wsUrl） |

### Step 6: 输入 → Sink

| 输入 | Sink | 措施 |
|------|------|------|
| 远程路径 / 上传 | SSH / sync_v2 写 | `remote_path_validation`、ETag 失效 |
| refresh token | Redis + DB `token_version` | 重用 → 全会话吊销 |
| 目录浏览 path | SSH ls | `posix_paths`、ETag 304 |
| 安装向导表单 | `.env` / MySQL | 原子锁、无密钥回显前端 |
| Agent 心跳 JSON | Redis | TTL、未知 server 丢弃 |

### Step 7: 归类

```
server/api/* + services + background  18文件  多H  0 OPEN（Batch1-6已修）
frontend composables/pages            5文件   FE  0 OPEN
web/app + agent + tests + Docker      其余    —   0 OPEN
────────────────────────────────────────────────────────
总计                                  0 OPEN FINDING（部署批）
```

### Step 8: DoD ✅

- [x] 上表代码文件已登记且 Read 覆盖 diff 范围
- [x] Step 3 规则扫描 + Closure 全表
- [x] API/WS 入口表 + 输入→Sink
- [x] 无未处理 P0/P1 OPEN
- [x] `ruff check server/` 通过；`pytest tests/ -q` → 154 passed
- [x] 前端构建须部署前执行 `cd frontend && npx vite build`

---

## FINDING 列表

无新增 OPEN。历史项已在 Batch 1–6 当批修复并见对应 changelog。

---

## Gate 7 交叉验证 — 文件名清单（basename）

部署 commit 须包含下列名称之一出现在本文件正文中（已满足）：

`agent.py` `install.py` `schemas.py` `servers.py` `sync_v2.py` `auth_service.py` `files_browse_service.py` `script_job_callback.py` `sync_engine_v2.py` `heartbeat_flush.py` `retry_runner.py` `schedule_runner.py` `self_monitor.py` `unix_ls.py` `useFilesBrowse.ts` `useFilesActions.ts` `usePushProgress.ts` `PushPage.vue` `PushSyncModeCard.vue` `vite.config.mts` `install.html` `index.html` `api.js` `preview.html` `preview-v3.html` `preview-v4.html` `preview-v5.html` `manifest.json` `check_text_eol.py` `sync_frontend_vendor.py` `test_files_browse_etag.py` `test_security_unit.py` `test_step0_infrastructure.py` `Dockerfile` `.dockerignore` `.gitignore` `mcp.json` `.env.example` `gate_log.jsonl` `launch.json` `settings.json` `settings.local.json`

---

## 结论

☑ **审计通过，0 OPEN FINDING，可部署**（部署后执行 `/health` + 浏览器抽测 `/app/`）。

**部署顺序建议**:

1. `git add` 上表代码 + `docs/audit/2026-06-04-production-deploy.md` + `docs/changelog/2026-06-04-production-deploy.md`
2. `bash deploy/pre_deploy_check.sh`
3. `git push` → 服务器 `git pull` + `supervisorctl restart nexus`
4. `cd frontend && npx vite build` → 上传 `web/app/` 或服务器构建
5. `curl -s http://127.0.0.1:8600/health` → `ok`
