Development & Runtime

dsh-confirmation-resolution

bbaz123/dsh-confirmation-resolution · ★ 0

bbaz123

DSH 待确认事项决策 (confirmation_resolution): host-plane plugin that adds the confirmation-item runtime rules to the System Prompt and exposes the confirmation_resolution decision tool…

README body is shown in Chinese.

License
Apache-2.0
Added
2026-10-30
Maintenance
active
Install kind
github
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T09:38:57.264Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add 'github:bbaz123/dsh-confirmation-resolution#4ba6a72967b76fcaf346779876e4485ef447a810'

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: zh · Read Chinese README

Table of contents
  1. 核心特性
  2. 为什么需要它?
  3. 只在待确认阶段生效
  4. 双层触发保护
  5. 状态机
  6. 插件不会直接修改你的项目
  7. 设计目标
  8. V2:上下文感知的多目标综合评判(默认启用,可关闭)
  9. V1 / V2 对照
  10. 默认行为与关闭方式
  11. 五个 outcome 与处理方式
  12. 安全边界(V2 特有)
  13. 兼容与风险说明
  14. 工具调用鲁棒性(2026-10-07)
  15. Quick start
  16. Behavior:状态与 STATUS 契约
  17. 同一会话里编号可以跨轮复用
  18. Architecture
  19. Testing
  20. Compatibility
  21. Uninstall
  22. Roadmap
  23. 变更记录
  24. Contributing
  25. License
  26. 两个物理副本
  27. 依赖模型
  28. 在目标机器上安装
  29. 重新同步分发副本(改完仓库必做)

offline verification License: Apache 2.0 Node.js offline tests

让 DSH 在任务完成后的"待确认事项"阶段,既不机械照做,也不反复询问。

⚠️ 安装前警告 本插件按 npm 全局安装版 DSH 0.2.0-rc.2 + web profile 构建,涉及 DSH 源码修改; 更新 DSH 可能导致插件不兼容,请注意。升级 DSH 后请重跑 npm run check 与 dsh --profile web --dump-config,详见下文「兼容与风险说明」。

当前支持并验证的宿主:DSH 0.2.0-rc.2(@deepseek-ai/dsh;profile 内 dsh-tools / dsh-brand / dsh-util-values 同为 0.2.0-rc.2,peer 声明为 ^0.2.0-rc.2)。 V1 契约保持不变,V2 是默认启用的版本化入口。

dsh-confirmation-resolution 是一个用于 DeepSeek Harness(DSH)的待确认事项决策插件。

当 DSH 完成主任务、留下 C1 / C2 / C3 … 等待确认事项之后,用户的回复不会被简单理解为"照原话修改"。

插件会按照固定顺序判断:

整体质量影响
      ↓
保持现状是否影响用户实际使用
      ↓
用户真实目标
      ↓
最优可行方案

最终决定:

情况 决定
质量不受损 MODIFY
质量会下降,但保持现状不影响实际使用 KEEP_CURRENT
质量会下降,而且保持现状会影响实际使用 MODIFY → 选择用户收益更高、质量损失更小、副作用更少的方案

核心特性

  • 固定决策顺序,不是模型即兴判断:质量影响 → 保持现状是否影响实际使用 → 用户真实目标 → 最优可行方案。
  • 用户提出的做法只是一个候选方案。它必须通过同一组硬性淘汰条件,不会因为用户说了就照做。
  • 代码级硬守卫 + 会话账本:未登记的 C 编号、已关闭的确认项会被拒绝(NOT_APPLICABLE), 而不是被静默当成一次决策。硬守卫不依赖模型是否遵守 Prompt。
  • 三态状态机:register → decide → complete。MODIFY 决策后必须真的执行成功才变 RESOLVED, 执行失败可重试,不会把确认项永久关死。
  • 纯函数决策核心:lib/decide.js 无 I/O、无服务访问、无定时器,可完全离线单测。
  • 调用纪律写进两层:规则段落与工具描述都要求"一次只判定一个确认项、不并发 decide、 候选只写有证据的字段、JSON 只用一个冒号且字符串内引号必须转义"——降低工具参数 JSON 被宿主判为不合法(MALFORMED_RESPONSE)而整轮失败的概率。
  • 零构建、零配置、零运行时依赖:纯 ESM,无编译步骤;只依赖宿主 DSH 提供的 tools 与 systemPrompt 两个服务;安装后规则自动进入每个会话的 System Prompt。

为什么需要它?

例如 DSH 完成一个页面后提出:

C1 — 是否需要进一步强化主操作按钮?

用户回复:

把按钮放大 300%

插件不会因为用户说了"放大 300%"就机械执行。它先区分两件事:

用户提出的方案     按钮放大 300%
用户真正的目标     让关键操作更容易发现

再比较候选方案:

放大 300%
适度增加尺寸
调整视觉层级
改善位置与间距
提高对比度

最后选择能解决真实问题、同时质量损失与副作用更小的方案:

没有本插件(或模型直接照做)
→ 按钮放大 300%,布局被挤压,视觉层级失衡

有本插件
USER_GOAL                 提高关键操作的可发现性        ← 先识别真实目标,而不是执行字面做法
QUALITY_IMPACT            MEDIUM(300% 会显著破坏布局)
USER_IMPACT_IF_UNCHANGED  MEDIUM(用户确实找不到入口)
ACTION                    MODIFY
SELECTED_SOLUTION         把主按钮提高一个视觉层级,并强化局部间距
EXECUTION_SCOPE           主按钮尺寸、层级、局部间距
DO_NOT_CHANGE             页面整体布局、导航结构、其他组件

也就是说:目标达成,质量损失更小,边界写死。 如果用户的做法本来就是最优解,它会照采用; 如果保持现状根本不影响实际使用(纯审美偏好),它会返回 KEEP_CURRENT,而不是为了讨好用户 牺牲质量。

只在待确认阶段生效

这个插件不是全局修改规则。只有同时满足以下条件时,才进入确认决策流程:

主任务已经完成
+
DSH 已经主动输出待确认事项
+
用户当前正在回复其中某个待确认事项

普通新任务、普通修改、新需求和无关 follow-up 继续使用 DSH 原有行为。

双层触发保护

层 位置 作用
软规则 System Prompt 段落 + 工具描述 告诉模型什么时候应该调用、什么时候不该调用
硬守卫 execute() + 会话账本(Session Ledger) 代码级校验:这个 C 编号是否真的由当前会话发布过、是否仍处于未关闭状态

未登记的确认项、已经完成的确认项会被拒绝(返回 NOT_APPLICABLE),而不是进入决策流程: 没有任何隐式登记后门,也不会被静默当成一次"决策"处理。 硬守卫不依赖模型是否遵守 Prompt——这正是本插件与"只靠提示词约束"的区别所在。

状态机

每个确认事项都经过明确的生命周期:

DSH 输出 C1
      ↓
register(C1)  → 登记本轮发布的编号      STATUS = REGISTERED,状态 PENDING
      ↓
用户回复 C1
      ↓
decide(C1)    → 账本校验 → 固定决策
      │
      ├─ KEEP_CURRENT → 决策即完成 ───────────────────→ RESOLVED
      │
      └─ MODIFY       → STATUS = READY_TO_EXECUTE
                        (账本状态 AWAITING_EXECUTION:等待执行)
                              ↓
                        DSH 实际执行
                              ↓
                        complete(C1)  → STATUS = REGISTERED,状态 RESOLVED

MODIFY 决策不等于执行。 只有 DSH 真的执行成功、并调用 complete(C1) 之后,该项才变成 RESOLVED;如果修改执行失败,就不要调用 complete,确认项保持等待执行,可以重新决策、 重试执行,不会被误判成"已经完成"。KEEP_CURRENT 是自完成的——不修改本身在决策那一刻就已完成。

每一次新的决策都会先废除上一份尚未执行的授权。 重试 decide 时,旧的 MODIFY 授权在重新计算 之前就被撤销;因此如果这次的结果是 INSUFFICIENT_CONTEXT,该项回到 PENDING, complete 再也无法拿旧授权把它关掉。不存在"最新判断是信息不足、旧 MODIFY 却仍可完成"这种状态。

插件不会直接修改你的项目

confirmation_resolution 只负责:

判断质量影响
判断用户实际使用影响
识别决策条件
淘汰不合理方案
比较候选方案
返回 MODIFY / KEEP_CURRENT
限制允许修改的范围

它不会直接修改你的页面、代码、文件、设计稿或项目结构,也不自动执行任何东西。 实际修改仍由 DSH 完成。

设计目标

这个插件试图避免两个极端:

极端 1    用户说怎么改 → 不判断影响,直接照做
极端 2    为了保护当前结果 → 忽略真实的用户使用问题

目标是:当修改不会降低质量时满足用户;当修改会降低质量且没有实际使用收益时保持现状; 当真实使用确实受到影响时,解决问题,同时尽可能减少质量损失和副作用。


V2:上下文感知的多目标综合评判(默认启用,可关闭)

上面的 confirmation_resolution(V1)以「质量影响」为主轴。V2 是对同一批待确认事项的综合评判: 在满足权限与硬约束的前提下,把 KEEP_CURRENT、用户原话方案与替代方案放在一起比较,给出更贴合用户 目标、风险可控且可解释的裁决。V1 没有被替换——V2 是一个独立版本化入口 confirmation_resolution_v2, 默认注册(enableDecisionV2 默认 true),所以任何挂载本插件的 profile、任何工作区开箱即用, 不需要任何 profile 补丁。

V1 / V2 对照

V1 confirmation_resolution V2 confirmation_resolution_v2
决策主轴 质量影响 → 保持现状的实际使用影响 → 目标 → 最优方案 硬门禁 → 证据可信性 → 场景化多维比较 → 必要审批
「不改」的地位 质量不受损就不进入比较 是显式候选基线,修改方案必须胜过它
缺证据 乐观默认(缺 violates_constraints ≈ 未违反) UNKNOWN,拦住自动执行
结果枚举 MODIFY / KEEP_CURRENT 另加 REQUEST_APPROVAL / REJECT,并区分 INSUFFICIENT_CONTEXT
场景权重 固定优先级 ui_preference / accessibility / code_change / external_action / urgent_fix / generic 各自一套
幅度规则 200% 为普适硬淘汰 仅界面场景的异常信号,且可由 scale_verified 覆盖
授权令牌 状态即授权 每次 decide 递增 decision_revision,complete 必须带对版本
审批 无 AWAITING_APPROVAL 状态;不接受模型自填的 approved: true

默认行为与关闭方式

V2 默认启用:不加任何配置时,该行会注册两个工具(confirmation_resolution 与 confirmation_resolution_v2)和两条规则段落(confirmation:policy 与 confirmation:policy.v2)。 这是刻意的——本插件是全局部署,作者要求"无论在哪个 profile、哪个工作区都默认 V2", 所以不依赖任何 profile 补丁。

要回到「只有 V1」,显式关闭即可。注意:删掉该配置并不会关闭 V2,因为默认值就是 true:

# profiles/<name>/cordis.patch.yml 中该行的 config
- id: confirmation-resolution
  config:
    enableDecisionV2: false            # 唯一可靠的关闭方式
    # 可选:V2 开启时只对特定会话生效;留空表示所有会话都可用
    decisionV2Sessions:
      - <session id>

decisionV2Sessions 只在 V2 开启时有意义:列了会话 id 就只对它们注册 V2,其余会话仍是纯 V1。 V2 的两样贡献(独立工具 + 独立规则段落)都随该行一起卸载,ctx.effect 是可逆的。

五个 outcome 与处理方式

outcome 含义 DSH 应当怎么做
MODIFY 已选定可行方案 按 selected_solution + execution_scope 执行,成功后用同一 decision_revision 调 complete
KEEP_CURRENT 现状综合更优 不修改;该项已 RESOLVED
REQUEST_APPROVAL 候选合法,但有必须由用户拍板的重大权衡 不是执行授权:把 approval_question 转达用户,用户答复后再发起新的 decide
INSUFFICIENT_CONTEXT 关键目标、权限、风险或证据不足 按 missing_information 补齐后重判;不得回落用户原方案
REJECT 请求触犯不可突破的约束 不执行;解释被挡住的硬门禁。REJECT 不是 KEEP_CURRENT

安全边界(V2 特有)

  • UNKNOWN ≠ PASS:门禁证据缺失一律按 UNKNOWN 处理并拦住自动执行,绝不乐观默认。
  • 权限与审批分别验证:authorization.verification 决定许可性;审批不能赋予原本没有的权限。
  • 不实现自动审批跃迁:当前宿主没有可供工具核验的用户确认事件,因此 approve 动作一律返回 NOT_APPLICABLE(NO_VERIFIABLE_APPROVAL_SOURCE),只返回审批建议。模型自己填写的 approved: true 永远不被采信;只有 source=USER_REPLY 且 user_decision=APPROVED 的显式记录才会被当作「调用方申明的用户同意」,并在决策轨迹里标记为 attested 而非 verified。
  • 陈旧授权无法复活:每次 decide 都递增 decision_revision 并清空旧审批与旧执行许可; complete 必须带上本次的 decision_revision,否则拒绝(STALE_DECISION_REVISION)。
  • 两套契约互不驱动:同一个 C 编号由 V1 还是 V2 登记,就只能由那一版继续驱动 (ITEM_VERSION_MISMATCH)。

兼容与风险说明

  • V2 的 .docx 规范与代码同步在 02/03 中以 V1/V2 版本标注;两套契约并存期间以代码为准。
  • V2 增加了调用方需要准备的输入(context、authorization、带证据的 candidates), 载荷比 V1 大。这是「不确定不等于安全」的代价;也正因为载荷更重,才保留了 enableDecisionV2: false 这条一键回到纯 V1 的退路。
  • 当前支持并验证的宿主:npm 全局安装版 DSH 0.2.0-rc.2,package.json 的 peer 声明同步为 @deepseek-ai/dsh-tools: ^0.2.0-rc.2。本插件按该版本与对应 web profile 构建,涉及宿主内部模块 (dsh-tools 等)。更新 DSH 可能导致插件不兼容,升级后请重跑 npm run check 与 dsh --profile web --dump-config。
  • 回滚:把 enableDecisionV2 显式设为 false 即回到纯 V1(删掉该配置不会关闭,因为默认是 true);已产生的 V2 会话账本随进程重启清空, 不会与 V1 的执行授权混用。

工具调用鲁棒性(2026-10-07)

触发这条改进的是一次真实事故复盘:同一个会话里连续两个回合都以

DeepSeek Messages stream: tool input is invalid JSON   (code: MALFORMED_RESPONSE)

终止,坏点全部落在 confirmation_resolution 的工具参数 JSON 上——一处是 "user_impact_if_unchanged"::(键值之间多写了一个冒号),一处是字符串值里 嵌了未转义的英文双引号;同一回合里还出现过同一组 side_effects 键被重复输出三次。

已核实的两端事实:

端 事实
宿主 适配器发现任一工具块参数不是合法 JSON 就抛 MALFORMED_RESPONSE 终止整轮;宿主默认重试策略只覆盖 EMPTY_RESPONSE / RATE_LIMIT / SERVER / TIMEOUT / TRANSPORT,不含它,所以这类失败没有自动恢复路径。
插件 工具参数由模型生成,插件无法替模型修复 JSON;能做的只有"要求它少产出、产出得更简单"。

因此本插件在软规则两层同时加了调用纪律(lib/rules.js 的「决策调用纪律」段落 + 工具描述):一次只调用一个确认项、不并发 decide;候选方案只写有证据的字段、不复述原题; JSON 只用一个冒号、字符串内部引号必须转义、不输出重复键组;被宿主判为 JSON 不合法时 (此时工具一次都没执行、账本状态未变)直接重发或拆成单项。

配套机械断言见 test/mandatory-scenarios.test.mjs 与 test/ledger-guard.test.mjs, 改动文案时纪律不会被悄悄删掉。这不是把失败消灭——真正的自动重试属于宿主的 retryPolicy(把 MALFORMED_RESPONSE 加进 retryableCodes),那是另一个仓库的事。

Quick start

# 1. 安装进你的 profile(会同时写入 dsh.profile.bundles)
dsh plugin --profile web add <本仓库路径>

# 2. 重启 DSH(bundle 层在启动时组合,不会热加载)

# 3. 验证:退出码 0 且输出含 id: confirmation-resolution
dsh --profile web --dump-config

dsh 启动时会执行 assertEntriesActivated:任何一条行无法解析或无法激活都会让整个 profile 启动失败。 因此 --dump-config 退出码 0 等价于「该行已成功解析并激活」。

不需要任何配置项。规则会自动出现在每个会话的 System Prompt 中(段落名 confirmation:policy)。

Behavior:状态与 STATUS 契约

工具 confirmation_resolution 有三个动作,DSH 按序使用;账本状态的唯一写入者是这个工具本身:

register → 登记本轮发布的 C 编号        → STATUS = REGISTERED,状态 PENDING
decide   → 账本校验 → 决策              → MODIFY:READY_TO_EXECUTE,状态 AWAITING_EXECUTION
                                          KEEP_CURRENT:决策即完成 → RESOLVED
complete → DSH 实际执行成功后调用        → STATUS = REGISTERED,状态 RESOLVED

四种 STATUS:

STATUS 含义 DSH 应当怎么做
REGISTERED 账本写入成功(register 登记,或 complete 关闭) 这不是拒绝,按 notes 继续
READY_TO_EXECUTE 决策完成,等待执行 按 SELECTED_SOLUTION 执行;成功后调用 complete
INSUFFICIENT_CONTEXT 信息不足,未做决策 补齐 MISSING_INFORMATION 后重新 decide;该项保持 PENDING
NOT_APPLICABLE 守卫拒绝,属于非法调用 不重试、不执行,改走正常 DSH 流程

complete 只在状态为 AWAITING_EXECUTION 时被接受,因此 register 之后直接 complete 会被拒绝(ITEM_NOT_AWAITING_EXECUTION)。也就是说"必须经过 decide"是代码强制的, 不是 Prompt 要求。

NOT_APPLICABLE 的触发条件:编号在本会话从未 register 过、已 RESOLVED 且未被用新文本重新发布、 或 complete 时没有待执行的 MODIFY 裁决。

同一会话里编号可以跨轮复用

一个长会话里完成第一个任务后开始第二个任务时,DSH 很自然又会从 C1 开始编号,用户仍然只看到 C1。 接受与拒绝的界线是明确的:

该编号的当前状态 register 的结果
不存在 登记成功(第 1 轮)
PENDING(等用户回复) 拒绝 CONFIRMATION_ID_STILL_OPEN——不覆盖正在处理中的项
AWAITING_EXECUTION(等执行) 拒绝 CONFIRMATION_ID_STILL_OPEN——连新文本也不行
RESOLVED + 相同文本 拒绝 ITEM_ALREADY_RESOLVED——重复登记,不复活已结束项
RESOLVED + 新文本 开启新一轮:回到 PENDING,轮次 +1,上一轮裁决被清空

新一轮必须重新 decide:上一轮的裁决不会授权新一轮的 complete。 换句话说,编号只有在真正结束之后才能被复用。

Architecture

lib/
├── rules.js        01 触发/执行规则文本(V1)+ V2 规则文本 → 注册为 System Prompt 段落
├── decide.js       02 V1 固定决策算法:纯函数、无 I/O、不做自然语言推断
├── evidence.js     V2 证据模型:PASS/FAIL/UNKNOWN、保守合并、冲突诊断、缺口
├── policies.js     V2 场景策略:维度、优先级、阈值、幅度规则、帕累托与排序
├── trace.js        V2 结构化决策轨迹(只返回数据,不写日志)
├── decision-v2.js  V2 纯决策核心 decideV2():构造基线 → 硬门禁 → 比较 → 审批 → 结果
├── ledger.js       会话级确认项账本:纯状态容器,按 exec.agent.id 隔离,含版本化决策令牌
└── index.js        Cordis 装配 + 代码级守卫 + 状态机(V1 与版本化 V2 两个工具)

V2 的分层是刻意的:decision-v2.js 保持纯函数(无 I/O、无账本、无宿主调用), 版本分发、会话白名单与状态迁移都留在 index.js,因此整套判断仍可离线复现。

职责边界:本插件是方案评审器,不是方案生成器。调用前 DSH 必须完成四件事——

  1. 识别 user_goal(ACTION = MODIFY 时必填,缺失返回 INSUFFICIENT_CONTEXT + USER_GOAL_REQUIRED_FOR_MODIFY;KEEP_CURRENT 不需要,因为它不选方案);
  2. 判断 quality_impact(或给出 quality_dimensions 证据);
  3. quality_impact !== NONE 时判断 user_impact_if_unchanged;
  4. 生成 2–3 个 candidate_solutions 供淘汰与排序。

第 4 项缺失时返回 INSUFFICIENT_CONTEXT 而不是自行编造方案——这正是决策核心能保持纯函数、 测试稳定的原因。候选方案的排序优先级(02 §8):解决真实问题 → 用户收益 → 质量损失更小 → 副作用更少 → 系统一致性 → 稳定性 → 实现复杂度。

仓库根目录另附三份规范 .docx 源文件,与代码的对应关系:

规范文件 负责 落地位置
01_DSH_System_Prompt_待确认事项触发规则 触发与执行层(V1) lib/rules.js → RULES 段落
02_Confirmation_Resolution_Plugin_执行规则 决策层(V1) lib/decide.js + lib/index.js
03_DSH_待确认事项决策规范 规范、校验与测试(V1) test/(不注入运行时)

三份 .docx 的正文描述的都是 V1 契约(该契约未变),文末各带一段 「2026-10-15 版本补充:V1 / V2 双契约」,标注 V2 的边界并指向 lib/rules.js 的 RULES_V2、 V2 的四个纯函数模块与对应测试——不把 V2 算法抄进规范,避免形成双重事实来源。 补充段落由 tools/docx-v2-addendum.ps1 追加,tools/docx-addendum-verify.ps1 逐段比对 「改前 vs 改后」以证明只新增、未改动原有内容。

Testing

npm run test:offline   # 130 个用例:V1/V2 纯决策算法 + 证据模型 + 场景策略 + 账本,任何机器都能跑,不需要 DSH
npm test               # 187 个用例:上面 + 端到端生命周期 + V1/V2 真实注册工具的守卫与状态机用例(需要 DSH)
npm run verify         # 32 项:真实 Cordis 上下文 + 真实 defineTool 的装配验证,含双版本共存(需要 DSH)
npm run check          # 语法 + 全部测试 + 装配验证(需要 DSH)

沙箱环境下 npm run test:offline 可能因 spawn EPERM 失败(子进程管道被沙箱拦截),这不是用例 失败。等价且可用的跑法是 node --test --experimental-test-isolation=none <files>。

test/e2e-lifecycle.test.mjs 是端到端叙事测试:走完一个会话的完整生命周期 (发布 → 登记 → 决策 → 执行失败可重试 → 执行成功关闭 → 新轮复用编号 → 非法调用被拒), 每一步都断言下一步所依赖的状态,因此流程一旦偏离文档化的状态机就会在偏离处失败。 它驱动真实注册的工具,所以与 ledger-guard.test.mjs 一样需要 DSH。

测试能分层的依据是精确的:lib/decide.js、lib/ledger.js、lib/rules.js、lib/evidence.js、 lib/policies.js、lib/trace.js、lib/decision-v2.js 不 import 任何外部包, 所以只覆盖它们的用例可以完全离线运行;而任何 import 到 lib/index.js 的用例都会拉入宿主的 @deepseek-ai/dsh-tools(它自己又依赖 dsh-scope/dsh-llm/dsh-session 等宿主内部模块), 因此必须在已安装 DSH 的环境里跑。npm run verify 用 DSH_HOME 与 DSH_PROFILE 定位 profile, 没有硬编码路径;找不到 DSH 时以退出码 2 明确报错,不会把"没能执行"当成通过。

覆盖重点:决策矩阵的三种结果、硬性淘汰门、跨字段矛盾输入、信息不足不回落原方案、 状态机的 register → decide → complete、无隐式登记、会话隔离;以及 V2 的方案 §9 场景矩阵 (T01–T16:纯偏好不归零、质量为 NONE 不自动改、300% 与精确尺寸的区别、UNKNOWN ≠ PASS、 权限与审批分别验证、伪造审批被拒、陈旧授权被拒)与属性测试(授权单调性、风险单调性、 确定性、不可执行结果不携带许可、鲁棒性)。

Compatibility

  • Node.js ≥ 22.19.0;纯 ESM,无构建步骤。
  • Cordis 4(@deepseek-ai/cordis);宿主服务 tools、systemPrompt。
  • 支持并验证的宿主:npm 全局安装版 DSH 0.2.0-rc.2;package.json 的 peer 声明为 @deepseek-ai/dsh-tools: ^0.2.0-rc.2。
  • 分发包内携带的依赖闭包(已按当前宿主重新生成):dsh-tools / dsh-brand / dsh-util-values 0.2.0-rc.2、cordis 4.0.4、schemastery 3.18.4、cosmokit 1.8.5、 @standard-schema/spec 1.1.0。宿主版本差异较大时,按下方说明用 tools/materialize-deps.mjs 重新生成依赖闭包。

Uninstall

dsh plugin --profile web remove dsh-plugin-confirmation-resolution

行随 bundle 层一起消失,System Prompt 段落与工具同时下线(两者都是 fiber 作用域的可逆 effect)。 卸载后 DSH 恢复原行为:不再有确认项决策流程,也不再有这几条 System Prompt 规则。

Roadmap

  • 可配置的决策边界:已由 V2 的 lib/policies.js 落地——场景策略、维度、阈值与幅度规则都是数据。
  • 账本可选持久化:目前账本按会话隔离且不持久化(DSH 重启即空)。是否需要跨重启保留, 属于契约变更,需先讨论(见 AGENTS.md)。
  • 决策轨迹可观测:已由 V2 的 lib/trace.js 落地——每次 decide 都返回结构化轨迹 (硬门禁结果、帕累托前沿、排序、敏感性、缺口、冲突、审批),仍只返回数据、不写日志。
  • 把 V2 变成默认策略:已完成——按部署要求,V2 已是插件默认(enableDecisionV2 默认 true), 不再需要 profile 补丁。
  • 更小载荷的判定形态(讨论中):目前候选可带十余个字段,模型容易被诱导长篇填充; 若要把载荷进一步压小,需要连着 V2 的排序依据一起改,属于决策层契约变更,需先讨论。
  • 跟随宿主演进:持续跟踪 DSH 宿主内部模块的版本变化,验证装配兼容性。

Roadmap 是方向而不是承诺。想推进其中某项,欢迎先开 issue 讨论范围与契约影响。

变更记录

  • 1.1.0(2026-10-15) — 引入 V2 决策引擎:新增 confirmation_resolution_v2 工具与 独立规则段落 confirmation:policy.v2,新增 lib/evidence.js(三值证据)、lib/policies.js(6 套场景策略)、 lib/trace.js(决策轨迹)、lib/decision-v2.js(decideV2()),账本增加 AWAITING_APPROVAL 与 decision_revision 版本令牌。V1 契约未变。peer 声明收窄为 DSH ^0.2.0-rc.2, 分发包依赖闭包同步重新生成(V2 代码见提交 5f71319)。
  • 1.1.0 后续调整(未发布) — 按部署要求,V2 由「显式启用」改为插件默认启用 (enableDecisionV2 默认 true),因此任何 profile、任何工作区都不再需要补丁;关闭方式是显式设为 false。这覆盖了方案 §8 PR-3「默认保留 V1」的灰度策略。连带更新:两个把「默认 = 仅 V1」写成断言 的测试改为断言新默认,并新增「显式 false 仍为纯 V1」的覆盖(离线/宿主用例与装配检查各 +1)。
  • 1.0.x — V1 固定决策矩阵(质量影响 → 保持现状的实际使用影响 → 用户目标 → 最优方案)、 会话账本硬守卫(无隐式登记、编号跨轮复用规则)、三态状态机与三层测试基线。

Contributing

欢迎贡献。请先读 CONTRIBUTING.md(怎么改、怎么验)与 AGENTS.md(项目结构、职责边界与硬性约定)。

最快的自检(不需要安装 DSH):

npm run test:offline   # 应 130/130

CI 在 Node 22 与 24 上跑这层离线套件,并额外断言"没有 DSH 时 verify 必须以退出码 2 报错"—— 防止验证套件在根本跑不起来时静默通过。

License

Apache License 2.0 © 2026 bbaz123


两个物理副本

路径 说明
源仓库 本仓库 唯一开发位置
分发副本 同名目录 + 同名 .zip 自包含离线包,用于备份或搬到另一台机器

副本不会自动跟随仓库更新。 曾经出现过"仓库已修好、分发副本仍是旧版,于是按副本评审时看到旧代码" 的事故。凡改动 lib/、test/、verify/、tools/ 或根目录元数据,都必须重新同步并复验。

依赖模型

  • 随包携带:lib/、test/、verify/、tools/、cordis.patch.yml、package.json、README.md、 AGENTS.md、LICENSE、CONTRIBUTING.md、三份规范 .docx,以及 node_modules 中的直接依赖闭包 —— @deepseek-ai/dsh-tools、 @deepseek-ai/schemastery、@deepseek-ai/cordis 及三者的运行期依赖 (@deepseek-ai/cosmokit、@deepseek-ai/dsh-brand、@deepseek-ai/dsh-util-values、 @standard-schema/spec,共 7 个包)。依赖是真实目录副本而非目录链接,移动或解压后仍可用。
  • 不随包携带:目标 DSH 自身提供的 peer 包(dsh-agent、dsh-llm、dsh-scope、dsh-session、 dsh-invariants、dsh-system-prompt、dsh-ptc-runtime、dsh-sandbox、dsh-sandbox-policy、 dsh-user-approval、cordis-plugin-loader、cordis-plugin-include 等)。这是刻意的:这些是宿主内部模块, 自带副本会造成模块身份冲突。目标机器上必须已安装 DSH。
  • 依赖闭包由 tools/materialize-deps.mjs 生成,可重复执行:
node tools/materialize-deps.mjs <bundleDir> "$env:USERPROFILE\.dsh\profiles\node_modules"

因此:在未安装到 profile 的独立副本目录里跑 npm test 会因宿主 peer 无法解析而失败, 这是依赖模型的预期结果,不是缺陷。副本里请用 npm run test:offline(应 130/130 通过); 装进 profile 后再跑 npm test(应 187/187)与 npm run verify(应 32/32)。

在目标机器上安装

dsh plugin --profile <profile> add <解压目录>
# 然后重启 DSH 使宿主组合重新加载

安装验证:dsh --profile <profile> --dump-config 退出码 0 且输出包含 id: confirmation-resolution。

重新同步分发副本(改完仓库必做)

$src  = '<仓库路径>'
$pack = '<分发副本路径>'
foreach ($d in 'lib','test','verify','tools') {
  Remove-Item (Join-Path $pack $d) -Recurse -Force
  Copy-Item (Join-Path $src $d) $pack -Recurse -Force
}
foreach ($f in 'README.md','AGENTS.md','package.json','cordis.patch.yml','.gitignore',
               'LICENSE','CONTRIBUTING.md',
               '01_DSH_System_Prompt_待确认事项触发规则.docx',
               '02_Confirmation_Resolution_Plugin_执行规则.docx',
               '03_DSH_待确认事项决策规范_维护与测试基准.docx') {
  Copy-Item (Join-Path $src $f) $pack -Force
}
# 副本目录里宿主 peer 不可解析,因此跑离线层(不要跑 npm test)
cd $pack; npm run test:offline

复验判据(缺一不可):副本内 lib/ledger.js 存在、lib/index.js 含 ledger.guard 与 action === 'complete'、lib/decide.js 含 USER_GOAL_REQUIRED_FOR_MODIFY、 V2 的四个纯函数模块 lib/evidence.js、lib/policies.js、lib/trace.js、lib/decision-v2.js 存在、lib/index.js 含 confirmation_resolution_v2、lib/ledger.js 含 STALE_DECISION_REVISION 与 AWAITING_APPROVAL,以及 npm run test:offline 全绿。 复验命令(在副本目录里跑,不需要 DSH):

node --test --experimental-test-isolation=none `
  test/decide.test.mjs test/ledger.test.mjs test/mandatory-scenarios.test.mjs `
  test/v1-baseline.test.mjs test/evidence.test.mjs test/policies.test.mjs `
  test/decision-v2.test.mjs test/ledger-v2.test.mjs   # 应 130/130