Repository Wiki
deepseek-ai/deepseek-harness

安全须知与开发预览约束

本页汇总 DeepSeek Harness 在开发、预览和扩展时必须遵守的安全边界:应用启动入口、profile 与插件隔离、配置覆盖、凭据与环境变量、预稳定持久化格式,以及桌面端开发运行时的隔离方式。

Purpose and Scope

本页面向需要运行、调试或扩展 Harness 的开发者,重点解释“哪些入口受支持”“哪些数据或配置不能被覆盖”“开发预览如何避免污染正常用户状态”,以及这些约束对插件、CLI、Desktop 和持久化数据意味着什么。

本页不替代具体实现参考:CLI 参数和 profile 行为以 apps/cli/README.zh.md 为准;桌面壳、Electron、崩溃恢复和内置运行时以 apps/desktop/README.zh.md 为准;会话格式迁移应继续阅读仓库根部 AGENTS.md。

Overview

Harness 是一个由 Cordis 插件组合而成的 agent harness。安全性不是单独的“安全插件”,而是由启动器约束、配置层顺序、profile 写锁、凭据边界、持久化版本规则和桌面进程隔离共同形成:

  • 只有 dsh profile 启动受支持的 Node 应用;直接调用 package bin、demo 或公开 SDK argv 绕过启动器不受支持。
  • CLI、SDK、ACP 和 Desktop 都通过 profile 表达;SDK 与 ACP 不是独立的公开可执行命令。
  • 配置从空根开始,按组合包、profile patch、home patch、命令行 patch 的顺序叠加;覆盖不是任意的全局修改。
  • API、会话事件和持久化格式处于预稳定状态时,必须同步所有消费者,并以单调递增的 SCHEMA_VERSION 处理 SQLite schema。
  • Desktop 开发状态默认落在 apps/desktop/.desktop-build/development/home,与用户正常 Harness home 分离;开发用一次性项目和 Electron user data 也位于 .desktop-build 下。
  • 真实 API 测试和 demo 使用 DEEPSEEK_API_KEY,凭据不能提交到仓库;没有 key 时 CI e2e 会跳过,而不是伪造成功。

Architecture

Loading diagram...

Source: AGENTS.md

该结构表达的是源代码和仓库规则中的实际边界:dsh 负责选择并加载运行器,profile manifest 决定组合包,patch 层按固定顺序合并;CLI 与 Desktop 可以共享 Harness 的产品数据,但 Desktop 的开发 home、profile 包、插件激活和锁文件不应与普通用户运行时混用。profile write lock 同时保护插件管理和 profile 写入,避免并发包操作破坏 profile 状态。

安全边界与开发约束

1. 只使用受支持的应用启动入口

AGENTS.md 明确规定只有 dsh profile 能启动受支持的 Node 应用。CLI README 进一步说明,dsh 先解析自身 flag,遇到第一个无法识别的 token 后,将剩余参数交给已选择的 profile;因此应用参数不能被误认为 launcher 参数。

sh
1dsh --profile web --port 8080 2dsh --profile tui --resume <id> 3dsh --profile headless "run the tests" 4dsh --profile web --help 5dsh --help

Source: README.zh.md

安全含义是:不要通过 package bin、demo 或 SDK 的 argv 直接启动内部 Node 应用,也不要把 profile 应用的参数提前交给 launcher。无效命令、跨模式选项以及致命配置或启动错误都应以非零状态结束,而不是继续以不明确的配置运行。

2. Profile 是配置和插件的隔离单元

profile 目录包含 package.json、dsh.profile manifest、按顺序排列的 bundles,以及用户 patch 文件。默认情况下,组合层从空根开始,依次应用:

  1. dsh.profile.bundles 中每个 bundle 的 patch;
  2. profile 自身的 cordis.patch.yml;
  3. $DSH_HOME/cordis.patch.yml;
  4. 命令行 --patch 覆盖层。

配置 HMR 启用时,监听 profile manifest、profile patch 和 home patch,并通过统一的串行重载重新组合所有层;没有 HMR 时,编辑要等重启才生效。监听器注册期间的编辑和后续编辑都使用非致命重载错误报告,因此调试配置时应检查诊断,而不是假设每次修改都已生效。

text
1dsh.profile.bundles 2 ↓ 3profile cordis.patch.yml 4 ↓ 5$DSH_HOME/cordis.patch.yml 6 ↓ 7--patch

Source: README.zh.md

3. 插件版本与 profile 写入必须显式协调

安装和 profile 启动会按照声明的 DSH peer 范围检查与 dsh --version 相同的运行时版本。不兼容插件需要用户明确确认精确版本豁免;因此不能通过静默降级或隐式 fallback 绕过兼容性检查。

插件管理与 dsh plugin 共享 profile 写锁。包操作会继承认证环境和终端描述符,但 service 调用会使用清理后的环境并捕获诊断。这个分离限制了包管理操作向长期运行服务泄漏不必要环境的风险,也保证并发修改不会交错写入 profile。

仓库约定还要求:注册都是 effect,注册函数返回 disposer;缺失 referent 的配置要在加载时或最早可解析点明确失败;部署变化的 tunable 必须是可从 cordis.yml 改变并经过校验的 Config 字段,不能隐藏在插件中的硬编码默认值里。

4. 凭据、环境变量和真实 API 测试

真实 API 测试和 demo 使用 DEEPSEEK_API_KEY,可选的 DEEPSEEK_BASE_URL,并读取根目录 .env。这些变量只用于本地或受控测试环境;凭据不能提交到仓库。没有 API key 时,CI e2e 会自我跳过,这与把缺少凭据误报为测试通过不同。

sh
pnpm run test:e2e pnpm dsh --profile headless "task" pnpm run demo:ptc -- "task"

Source: AGENTS.md

在配置中使用 JavaScript 条件时,cordis.yml 允许在 plugin config 和 entry disabled 下使用 !!js,而不是 !js;其他 metadata 保持字面量。需要条件组合时应使用 overlay,而不是让 metadata 变成可执行内容。

核心运行流程

Loading diagram...

启动顺序的关键点是:launcher 先确定 profile,再由 profile 组合配置并激活插件;应用参数在 launcher 解析边界之后由应用插件处理。这样可以把“启动 Harness”与“运行某个 profile 应用”分开,减少跨模式 flag、未初始化 profile 或错误插件版本造成的隐式行为。

配置与开发预览选项

选项类型默认/约束作用
--profile <name>string必须指向可解析 profile;desktop 由 CLI 保留选择要启动的 profile。
--from-default-profile <template>string仅用于尚未使用的非内置名称从随附模板创建自定义 profile 后启动。
--patchpatch 覆盖位于 home patch 之后追加命令行配置覆盖层。
DSH_HOMEpath运行目录之外的产品数据根;开发桌面可显式替换决定 profile、home patch 和持久化产品数据位置。
DEEPSEEK_API_KEYsecret string真实 API 测试需要;不得提交为 e2e、demo 或 headless 运行提供 API 凭据。
DEEPSEEK_BASE_URLURL可选覆盖真实 API 的 base URL。
DSH_DESKTOP_USER_DATA_DIRpathDesktop 开发时可选隔离 Electron 浏览器数据。
DSH_DESKTOP_OPEN_DEVTOOLS0 或默认启用Desktop 开发默认打开 Renderer DevTools设为 0 可保持 Renderer 调试窗口关闭。

上述选项来自根部开发约定、CLI 中文 README 和 Desktop 中文 README;没有在这些源文件中找到更多“安全须知”专用配置项,因此不对未出现的变量推断默认值。

失败模式、边界与并发

  • 无效命令或致命启动错误:CLI 以非零状态退出;调用方不应把部分启动视为成功。
  • 插件版本不兼容:需要用户明确确认精确版本豁免;不应静默安装一个不同版本来绕过检查。
  • 配置 HMR 重载失败:重载错误是非致命诊断,编辑后的配置不应被假定为已激活;必要时修复 patch 或重启。
  • profile 并发写入:插件管理与 profile 写操作共享写锁;不要绕过 dsh plugin 或直接并行改写 profile 文件。
  • Desktop 与普通 CLI 状态污染:Desktop 拥有 $DSH_HOME/profiles/desktop,开发 Harness 默认使用 .desktop-build/development/home;不要用普通 CLI 启动 Desktop profile。
  • 已发布 Session 数据:公共 API 仍是预稳定的,但已提交的 Session generation 不能移动、覆盖或删除;相邻迁移可以增加带版本名的 successor,但不自动意味着 fallback 或 downgrade。
  • SQLite schema:SCHEMA_VERSION 必须单调递增。修改持久化类型时要完成声明式 acknowledgement,并同步所有消费者。
  • 模型可见输入:任何到达模型请求的输入都必须能从 session log 重建;新增模型可见输入必须增加对应 session event。

使用示例:开发桌面预览

Desktop README 规定开发命令先构建当前 Host、客户端 bundle、Web 前端和 Electron 壳,再启动 Electron;开发状态写入隔离的 .desktop-build 路径。

sh
1pnpm run dev:desktop 2pnpm run start:desktop 3pnpm run dev:web 4pnpm run start:web

Source: README.zh.md

在 Desktop 开发中,DSH_DESKTOP_MAIN_INSPECT_PORT、DSH_DESKTOP_RENDERER_DEBUG_PORT 和 DSH_DESKTOP_HOST_INSPECT_PORT 可以分别替换调试端口;默认端口依次为 9229、9222 和 9230。显式 DSH_HOME 只替换开发 Harness home,不改变这一隔离设计的目的。

API / 扩展参考

本页涉及的是运行时约束,不新增公共 API。可安全扩展的方向必须沿现有 capability seam 进行:Service Definition、Service Provider 和 Consumer 三个角色应完整存在;插件行为应通过 documented extension points 注册,而不是直接修改 agent loop。扩展配置应是已校验的 Config 字段,注册和监听必须可 dispose,事件 waterfall listener 必须调用 next() 才能继续链路。

这些规则的设计意图是让插件可组合、可卸载,并让配置、事件和 session log 保持可追踪;直接修改循环、绕过注册 disposer 或引入隐藏默认值,会使启动、重载、持久化和测试之间失去一致性。

Sources

(3 files)
(root)
apps/cli
apps/desktop