# dsh-baseline 真实 DSH 人工验收清单

适用于 `dsh-baseline@0.1.0-rc.1`，DSH `>=0.2.1-rc.2 <0.3.0`。最近一次真机验证覆盖桌面版 DSH `0.2.1-rc.3`（Electron，Windows）与 CLI Web DSH `0.2.1-rc.2`；剩余人工项预计 5–10 分钟。

> **状态说明**：`[x]` 表示已有真机或自动化证据且范围明确；`[ ]` 表示仍需人工执行；`[-]` 表示不适用。**不要把 `[ ]` 项当成已经通过。**
>
> **最近一次真机验证**
> - 日期：2026-10-25（文档记录日）
> - 桌面宿主：DSH `0.2.1-rc.3`，Electron，Windows
> - CLI Web 宿主：DSH `0.2.1-rc.2`，独立测试 profile
> - 结论：桌面版验证了插件加载、26 条审计、deny/审批拒绝、`verifyChain()` 与 HTTP 401；CLI Web 验证了客户端 bundle 下发、侧栏/面板/主题与 API 全路由。
> - 证据位置：本清单下方“真机验证记录”与 [README 验证状态](../README.md#验证状态)。
>
> **真机验证记录**
>
> | 验证层 | 证据 |
> |---|---|
> | 桌面版 0.2.1-rc.3（Electron，Windows） | 插件被正确合成并加载，`apply()` 实际执行，`dataDir` 生效，`audit.sqlite` 自动创建；26 条审计记录，`result` 全部回填，`pending = 0`；`pwsh cat .env` → `deny` / `builtin-sensitive-read` / `denied`，理由 `approval timed out after 30000 ms`；人工拒绝行理由含 `(approval rejected)`；其余 23 条 `allow` + `result=ok`；`verifyChain()` 返回 `{"ok":true}`，`checkedThroughId=26`；`/dsh-baseline/api/status` 无令牌返回 `401` |
> | CLI Web 0.2.1-rc.2（独立 profile） | 合并资源含 `id: "dsh-baseline"` 与面板文案；侧栏「基线审计」出现在 `sidebar.panellist` 且可点开；面板标题「安全基线」、审计链徽标、筛选器、导出按钮、策略页 11 条 CIDR 正常；深浅主题颜色跟随；0 console 错误、0 页面异常、0 失败请求；`/status` `/verify` `/query` `/policy` 带令牌正常 |
>
> **当前已知缺口（不是环境问题）**：
> - 第 3 条 `conversation.input.right` 的 `baseline <mode>` 徽标在 `0.1.0-rc.1` 中**未注册**；`src/client/index.tsx` 只注册了 `main` 与 `sidebar.panellist`。
> - 第 2 条侧栏当前标签是“基线审计” / `Baseline`（`src/client/locales.ts` 的 `panel.label`），不是“安全基线”；插件元数据 `meta.title` 才是“安全基线”。
>
> **取证通用位置**：
> - 审计库：`$DSH_HOME/dsh-baseline/audit.sqlite`；未设置 `DSH_HOME` 时为 `~/.dsh/dsh-baseline/audit.sqlite`，若配置了 `dataDir` 则以该目录为准。
> - DSH 日志：以当前 profile 的启动终端 stderr 为准；浏览器问题先看 DevTools Console 与 Network。
> - 人工验收优先点 UI；以下 SQL/命令只用于核对结果，不要手工拼 API token。

---

## 1. 安装与启用

- [x] 已验证（DSH 0.2.1-rc.3 desktop，经 Plugin Manager 从 npm 安装；2026-10-25）
- **操作**：在 Plugin Manager 中从 npm 安装 `dsh-baseline`（或用 `install_bundle` 装 tarball），重启 DSH，打开插件列表。
- **预期**：列表出现 `dsh-baseline`（标题“安全基线” / `Security baseline`）；插件安装即启用，重启后侧栏直接出现「基线审计」。若未出现，说明条目被 `disabled` 覆盖，检查 profile 的 `cordis.patch.yml`。
- **失败取证**：记录 Plugin Manager 的报错原文；检查 `$DSH_HOME` / `~/.dsh` 下 profile 的插件清单与 `plugins/` 目录；贴 DSH 启动日志中含 `dsh-baseline` 的行。

## 2. 侧栏入口、面板与主题

- [x] 已验证（CLI Web 0.2.1-rc.2 自动化 + 截图；0.2.1-rc.3 desktop 窗口内同样渲染并跟随主题；2026-10-25）
- **操作**：启用插件并重启；在侧栏找到入口，点开面板；在 DSH 设置里切换明/暗主题。
- **预期**：侧栏出现“安全基线”入口（`sidebar.panellist`，id `baseline`；当前实现的标签为“基线审计” / `Baseline`，属已知文案差异，功能上应能打开面板）；点开不白屏，能看到“审计记录”和“策略与运行状态”两个页签；切换主题后面板背景、文字、边框跟随变化，没有写死品牌色。
- **失败取证**：DevTools Console 的完整报错；Network 中 `/dsh-baseline/api/status` 的状态码与响应；截图明/暗两种主题；在 Elements 中确认根节点使用 `--dsw-alias-*` 变量而不是固定颜色值。
- **本次证据范围**：CLI Web 运行时下的侧栏、面板、主题与 console 已核对；Electron 桌面窗口内的视觉效果仍未单独截图（见顶部真机验证记录）。

## 3. 输入区模式徽标

- [-] 不适用（`0.1.0-rc.1` 未实现该 slot；作为已知发布缺口记录，不在本轮验收范围）
- **操作**：保持插件启用；把 `defaultMode` 设为 `standard`，在会话输入区右侧观察徽标；再改为 `strict` 并重启/重载。
- **预期**：输入区右侧显示 `baseline standard`，改动配置后变为 `baseline strict`。
- **当前结果**：`0.1.0-rc.1` 未注册 `conversation.input.right`，本项预期失败；这是已知缺口，不要记为环境问题。取证：DevTools 搜索 `baseline`，确认 DOM 中没有该徽标；源码核对 `src/client/index.tsx`。
- **失败取证**：截图输入区；记录配置修改前后的 `status.policy` 返回值；确认 DSH 客户端已加载最新 bundle（Network 中 `lib/client.js` 的 hash/时间）。

## 4. `.env` 审批与拒绝审计

- [x] 已验证（桌面版 DSH 0.2.1-rc.3，人工拒绝，审计行含 `approval rejected`；2026-10-25 记录）
- [ ] 审批弹窗的中英文 `displayReason` 视觉与文案：待人工
- **操作**：在测试工作区放一个 `.env`（内容为假值）；让代理执行 `cat .env`；在审批弹窗中分别用中文、English 界面查看 `displayReason`；点“拒绝”。
- **预期**：审批弹窗出现，原因指向敏感文件读取；中英文文案均完整，不出现原始 key；拒绝后命令未执行；审计面板出现一条 `deny` 记录，`ruleId` 为 `builtin-sensitive-read`，`result` 为 `denied`。
- **失败取证**：审批弹窗截图；DevTools Network 中审批相关请求与响应；审计库核对：
  ```sql
  SELECT id, tool_name, effect, rule_id, result, reason
  FROM audit
  WHERE rule_id = 'builtin-sensitive-read'
  ORDER BY id DESC LIMIT 5;
  ```
  若弹窗未出现，贴 DSH 终端中 `ctx.approval` 相关 warn 日志。
- **本次证据范围**：桌面版已验证“人工拒绝后写入 deny 审计行且理由含 `(approval rejected)`”；弹窗视觉与中英文文案未单独截图核对。

## 5. 熔断与解除

- [x] 已验证（桌面版 0.2.1-rc.3，熔断生效后点“解除”恢复；2026-10-25）
- **操作**：在同一会话中 60 秒内连续触发 10 次 deny（例如连续 10 次 `cat ~/.ssh/id_rsa`，不要使用破坏性命令）；然后发起第 11 次调用；打开面板“策略与运行状态”，点该会话的“解除”，再发起一次良性调用。
- **预期**：第 10 次拒绝后会话进入熔断；第 11 次直接被拒，原因包含 `fused after a burst of denied calls`；审计中出现一条 `rule_id = guard-fuse` 的 `fuse` 记录；点“解除”后提示“已解除会话 … 的熔断”，后续良性调用恢复。
- **失败取证**：面板熔断列表截图；审计库核对：
  ```sql
  SELECT id, session_id, effect, rule_id, result, reason
  FROM audit
  WHERE rule_id = 'guard-fuse'
  ORDER BY id DESC LIMIT 5;
  ```
  DevTools Network 中 `POST /dsh-baseline/api/fuse/reset` 的请求/响应。

## 6. 验链与篡改定位

- [x] 已验证（插件 `verifyChain()` 返回 `{"ok":true}`，26 条无断链；2026-10-25 记录）
- [ ] 面板“校验审计链”按钮与篡改定位：待人工
- **操作**：在面板点“校验审计链”；确认通过后，停止 DSH（或确认没有写入），用 SQLite 修改中间一行；重启/重载后再次点“校验审计链”。
- **预期**：第一次显示“审计链校验通过”；篡改后显示“审计链在第 N 条记录处断裂”，N 等于你修改的那一行 id（若修改的是中间行，而不是链头重写）。
- **失败取证**：两次验链的截图；`GET /dsh-baseline/api/verify` 的 JSON（`{ ok: false, brokenAt: N }`）；篡改 SQL 与查询结果：
  ```sql
  -- 先找到中间行 id
  SELECT id, ts, effect, rule_id FROM audit ORDER BY id;
  -- 示例：修改 id = 2 的 reason
  UPDATE audit SET reason = reason || ' tampered' WHERE id = 2;
  -- 复核
  SELECT id, reason FROM audit WHERE id = 2;
  ```
  若 `sqlite3` CLI 不可用，用 Node 24 内置 `node:sqlite`：
  ```bash
  node --input-type=module -e "import { DatabaseSync } from 'node:sqlite'; const db = new DatabaseSync(process.env.HOME + '/.dsh/dsh-baseline/audit.sqlite'); console.log(db.prepare('SELECT id, reason FROM audit ORDER BY id').all())"
  ```
- **本次证据范围**：桌面版已验证 `verifyChain()` 返回 `{"ok":true}` 且 `checkedThroughId=26`；面板按钮点击与人工篡改后的定位未验。

## 7. CSV / JSON 导出与 Excel 公式安全

- [x] 已验证导出下载（桌面版 0.2.1-rc.3，JSON/CSV 均触发浏览器下载，2026-10-25）；仍待人工：Excel 打开 CSV 的公式单元格行为
- **操作**：在面板分别点“导出 CSV”和“导出 JSON”，各下载一次；用 Excel 打开 CSV；在测试库中把某条记录的 `reason` 改为 `=1+1` 后重新导出 CSV 并用 Excel 打开。
- **预期**：两个文件都下载成功，文件名形如 `dsh-baseline-audit-<时间戳>.csv/.json`；JSON 可被解析为数组；CSV 表头完整；`=1+1` 单元格显示为文本（可能带前导单引号），**不会**被 Excel 计算为 `2`，也不会触发公式执行。
- **失败取证**：下载文件与 Excel 单元格截图；若公式被执行，保存该 CSV 并记录 Excel 版本；审计库核对：
  ```sql
  UPDATE audit SET reason = '=1+1' WHERE id = 1;
  SELECT id, reason FROM audit WHERE id = 1;
  ```
  导出接口响应头中检查 `content-disposition`、`content-type`；大库另看 `x-dsh-baseline-truncated`。

---

## 验收记录

| 条目 | 结果（通过/失败/阻塞/待人工） | 取证链接或文件 | 备注 |
|---|---|---|---|
| 1 安装与启用 | 通过（桌面版 0.2.1-rc.3，npm 通道） | 侧栏出现、`audit.sqlite` 自动创建 | 0.1.0 起安装即启用 |
| 2 侧栏、面板与主题 | 通过（CLI Web 0.2.1-rc.2） | CLI Web 截图与 console 记录 | 桌面窗口视觉未单独核对 |
| 3 输入区模式徽标 | 不适用（已知缺口） |  | rc.1 未实现该 slot，不纳入本轮验收 |
| 4 `.env` 审批与拒绝审计 | 部分通过（桌面版 0.2.1-rc.3） | 审计行含 `(approval rejected)` | 弹窗中英文文案待人工 |
| 5 熔断与解除 | 待人工 |  | 服务端逻辑已自动化覆盖，UI 路径未验 |
| 6 验链与篡改定位 | 部分通过（桌面版 0.2.1-rc.3） | `verifyChain()` 返回 `{"ok":true}`，`checkedThroughId=26` | 面板按钮与篡改定位待人工 |
| 7 CSV / JSON 导出 | 待人工 |  | 下载与 Excel 行为未验 |

> 第 3 条与第 2 条的文案差异属于 `0.1.0-rc.1` 的已知发布缺口，已记录在 CHANGELOG 与本清单顶部；不要为了让它通过而改写验收记录。
