外观
01 · 系统总览
System Overview
这是一个挂在 DeepSeek Harness 上的 Cordis 插件:在 Auto 权限预设(machine value auto-approval,host 显示名 Auto approval;sandbox: danger-full-access + approval: ask)下,充当 approval/request 的唯一终结裁决者;判据是 durable raw identity(permissionPresets.permissionState().preset),承诺每个 tuple 一条宿主线 —— 0.2.0-rc.2 与 0.2.1-alpha.1 均完整支持(宿主线跟着用户实际在跑的宿主走,上游进入新 tuple 的 alpha 时再逐条追加),只认 auto-approval(旧机器值 auto 别名已随下限抬升移除)。两面:宿主端(Node 进程,决策与安全)+ 浏览器端(Web GUI,设置与面板交互)。
图例
- 放行 / 常态
- 拒绝 / fail-closed
- LLM / 模型侧
- 数据落盘
四个执行平面
🖥️ 浏览器(client.js)
- 注入 DSH Web GUI:设置卡、会话标题栏统计、审批按钮增强
- 所有通信走 HTTP fetch(
same-origin),无 RPC - 不产决策,只「观察 + 转达 + 显示」
🧠 宿主插件(src/index.ts)
- 约 80% 的裁决逻辑:静态评估、熔断、倒计时、LLM 复审
- 通过
approval/request等事件与 DSH 内核接线 - 定时器唯一作者 —— 超时标记不可伪造
🔌 DSH 内核 + LLM
- 提供
tools/approval/permissionPresets/settings等服务 - 评审可走会话模型(
ctx.llm.stream)或在线端点(OpenAI/Anthropic 兼容) - 官方 ApprovalPanel 是唯一的人工交互面
数据太平面(规范位置 <DSH_HOME>/auto-approval-llm/)
六个运行态文件的规范位置是 DSH_HOME(默认 ~/.dsh)下的 auto-approval-llm/(插件写入前按需创建)——刻意放在插件包目录之外,因为 npm 升级会替换整个包目录,包内的运行态数据每次升级都会被删除。
- 读与写只针对这一个位置:读恒返回规范路径(读写同路径,防「写 A 读 B」脑裂);写前按需创建目录,目录可用性缓存每次解析复检(目录被运行中删除会自愈重建)。
- 目录无法创建或拒绝写入时 fail-closed:写入失败 → 审计闸把全部裁决转拒,并打印进程内一次性告警;不回退、不迁移。旧包根回退链(读回退 / 前搬 / 写回退 / 启动期探针 / 双向对账)已按其退役期限(版本号达 0.0.25)移除——把审计静默搬进 npm 拥有的包目录,方向与「升级会替换包目录」的保护目标相反。
- 重试语义:同路径重试只对「打开目标阶段」失败的错误(
EBUSY/EAGAIN/EINTR瞬时占用 + 拒写类错误码);ENOSPC等写后失败不重试(重放会拼坏记录)。 - 保护更强:规范目录在
DSH_HOME下,guard 对DSH_HOME的写入一律拒绝(不限这六个文件名;常量例外 = 插件自身开发区 ∪ 会话工作区(当它是 DSH_HOME 的 plugins 直接子目录时));读取仍落runtime-state-read观测事件。 - 老安装(≤ 0.0.24 写包根)升级后不会自动迁移:包根旧记录不被读取,升级替换包目录时随之删除;如需保留请在升级前手工放入规范目录。
| 文件 | 语义 | 写入方 |
|---|---|---|
history.jsonl | 审批历史(有界内存窗口 200 条 + 落盘,>1MB 轮转) | 宿主 pushHistory |
audit.jsonl | append-only 审计,清空留 tombstone,>5MB 保尾 5000 行 | 宿主 appendAuditLine |
review-mode.json | 每会话评审模式快照(smart 不落盘,原子 tmp+rename) | 宿主 persistReviewModes |
approval-debug.jsonl | 仅 debug=true 时写入的评审时序,>1MB 保尾 2000 行 | 宿主 debugLog(request/review/follow/resolve) |
llm-latency.jsonl | LLM 评审耗时遥测(环形缓冲 200 条,>1MB 轮转;与审批历史分离) | 宿主 pushLatencySample |
learning.json | 确认制学习条目(SHA-256 键、TTL 30 天/100 条上限,原子 tmp+rename) | 宿主 persistLearning |
以上六个文件同属运行态保护名单(paths.ts:LRUNTIME_STATE_BASENAMES),任何工具调用都改不了它们;规范目录又在 DSH_HOME 之下,guard 对 DSH_HOME 的写入本就一律拒绝,故保护比「按文件名匹配」更宽。
唯一终结者
approval/request 以 {prepend:true, global:true} 注册(index.ts:L"anyCtx.on('approval/request', async")—— 门卫读 durable raw identity(permissionPresets.permissionState().preset ∈ gateNames),对命中本插件档的 ask 就是最终裁决,不会开第二个弹窗、不会双写、不会让审计断裂。