dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Post-task confirmation decision guard for DeepSeek Harness — balance output quality with real user impact.
让 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、无服务访问、无定时器,可完全离线单测。MALFORMED_RESPONSE)而整轮失败的概率。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 为了保护当前结果 → 忽略真实的用户使用问题
目标是:当修改不会降低质量时满足用户;当修改会降低质量且没有实际使用收益时保持现状; 当真实使用确实受到影响时,解决问题,同时尽可能减少质量损失和副作用。
上面的 confirmation_resolution(V1)以「质量影响」为主轴。V2 是对同一批待确认事项的综合评判:
在满足权限与硬约束的前提下,把 KEEP_CURRENT、用户原话方案与替代方案放在一起比较,给出更贴合用户
目标、风险可控且可解释的裁决。V1 没有被替换——V2 是一个独立版本化入口 confirmation_resolution_v2,
默认注册(enableDecisionV2 默认 true),所以任何挂载本插件的 profile、任何工作区开箱即用,
不需要任何 profile 补丁。
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 | 含义 | 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 |
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)。.docx 规范与代码同步在 02/03 中以 V1/V2 版本标注;两套契约并存期间以代码为准。context、authorization、带证据的 candidates),
载荷比 V1 大。这是「不确定不等于安全」的代价;也正因为载荷更重,才保留了
enableDecisionV2: false 这条一键回到纯 V1 的退路。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 的执行授权混用。触发这条改进的是一次真实事故复盘:同一个会话里连续两个回合都以
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),那是另一个仓库的事。
# 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)。
工具 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。
换句话说,编号只有在真正结束之后才能被复用。
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 必须完成四件事——
user_goal(ACTION = MODIFY 时必填,缺失返回 INSUFFICIENT_CONTEXT +
USER_GOAL_REQUIRED_FOR_MODIFY;KEEP_CURRENT 不需要,因为它不选方案);quality_impact(或给出 quality_dimensions 证据);quality_impact !== NONE 时判断 user_impact_if_unchanged;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 改后」以证明只新增、未改动原有内容。
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、
权限与审批分别验证、伪造审批被拒、陈旧授权被拒)与属性测试(授权单调性、风险单调性、
确定性、不可执行结果不携带许可、鲁棒性)。
@deepseek-ai/cordis);宿主服务 tools、systemPrompt。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 重新生成依赖闭包。dsh plugin --profile web remove dsh-plugin-confirmation-resolution
行随 bundle 层一起消失,System Prompt 段落与工具同时下线(两者都是 fiber 作用域的可逆 effect)。 卸载后 DSH 恢复原行为:不再有确认项决策流程,也不再有这几条 System Prompt 规则。
lib/policies.js 落地——场景策略、维度、阈值与幅度规则都是数据。AGENTS.md)。lib/trace.js 落地——每次 decide 都返回结构化轨迹
(硬门禁结果、帕累托前沿、排序、敏感性、缺口、冲突、审批),仍只返回数据、不写日志。enableDecisionV2 默认 true),
不再需要 profile 补丁。Roadmap 是方向而不是承诺。想推进其中某项,欢迎先开 issue 讨论范围与契约影响。
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)。enableDecisionV2 默认 true),因此任何 profile、任何工作区都不再需要补丁;关闭方式是显式设为
false。这覆盖了方案 §8 PR-3「默认保留 V1」的灰度策略。连带更新:两个把「默认 = 仅 V1」写成断言
的测试改为断言新默认,并新增「显式 false 仍为纯 V1」的覆盖(离线/宿主用例与装配检查各 +1)。欢迎贡献。请先读 CONTRIBUTING.md(怎么改、怎么验)与
AGENTS.md(项目结构、职责边界与硬性约定)。
最快的自检(不需要安装 DSH):
npm run test:offline # 应 130/130
CI 在 Node 22 与 24 上跑这层离线套件,并额外断言"没有 DSH 时 verify 必须以退出码 2 报错"——
防止验证套件在根本跑不起来时静默通过。
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-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