dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 自动方案执行插件:四条件触发、方案冻结、任务图与步骤账本、门禁预算、完整度闸门与八部分报告。
DSH(DeepSeek Harness)的自动方案执行宿主插件。
当真实用户提交一份方案时,该插件把当前会话切换到方案执行模式:冻结原方案、建立任务图、 受控连续轮次执行、门禁与预算守卫、独立验收,最后产出一次性完整报告。普通聊天保持原样。
目标宿主:0.2.0-rc.2。包名:dsh-plugin-auto-plan-executor。宿主行 id:auto-plan-executor。
现状(2026-10-19):源码、单元测试、装配验证与双插件共载联调均已完成;插件已装入日常
webprofile——bundles=14、dependencies为link:。本轮新增的步骤账本 / 派生问题 / 边界复核 / OpenViking 实时镜像 / 收尾退出方案模式属于宿主插件代码改动,必须在重启 DSH 后才会生效 (ESM 模块缓存按文件 URL 记,禁用→启用只会重放旧模块)。仍未接线的能力见下文「已知缺口」。
| 能力 | 实现位置 | 运行时是否接线 |
|---|---|---|
| 四条件触发 + 明确否定优先 + 去重 | lib/trigger.js | ✅ 已接线(agent/pre-step) |
| 原方案冻结(哈希、修订、不可变核心) | lib/plan-snapshot.js | ✅ 已接线(激活时冻结一次) |
| 任务图(环检测、缺依赖、同目标并发写) | lib/task-graph.js | ✅ 已接线(auto_plan_task,含 start / list 的就绪判定) |
| 状态机与持久化(原子写、脱敏在 store 边界) | lib/plan-state.js | ✅ 已接线(schema v3:步骤账本字段) |
| 方案步骤清单(原文提取 + 逐字 declare + 受限降级) | lib/plan-steps.js | ✅ 已接线(激活时冻结;需求/交付/验收段也提取) |
| 逐步处置(DONE / OPEN / EXEMPT,收尾重验) | lib/step-coverage.js | ✅ 已接线(收尾时重算,不信持久化 verified;未关闭问题阻塞 DONE) |
| 步骤账本(派生问题 / 生命周期 / 边界复核 / 回退) | lib/step-gate.js | ✅ 已接线(auto_plan_step 的 begin / issue / close_issue / review) |
| OpenViking 实时镜像(写/读/清理,失败不阻塞) | lib/ov-client.js | ✅ 已接线(激活时写清单,每个步骤事件同步一次) |
| 完整度闸门(缺口拒绝收尾 + 缺口任务 + 收敛上限) | lib/completeness.js | ✅ 已接线(auto_plan_finish) |
| 门禁分级 G0–G4 + 决策落盘 | lib/policy.js | ✅ 已接线(auto_plan_gate) |
| 费用守卫(单次/累计 2 元,不可核价即拒绝) | lib/budget.js | ✅ 已接线 |
| 附件读取(白名单、字节/字符/时间上限) | lib/attachment-reader.js | ✅ 已接线 |
Goal 能力发现(按可观测的 goal 工具 + goals 服务) | lib/goal-adapter.js | ✅ 已接线(并如实报告在 auto_plan_status) |
| 独立验收(只认观测证据) | lib/verifier.js | ✅ 已接线(auto_plan_task action="verify") |
Cordis 装配、Prompt 段落、工具、tools.guard | lib/index.js | ✅ 已接线 |
| 与待确认插件的只读观察 | lib/confirmation-adapter.js | ⚠️ 部分:能力发现已接线并在状态里报告;镜像(confirmationMirror)当前没有运行时写入方,所以 confirmations 恒为 []。见下方"已知缺口" |
| 最终统一报告(八部分) | lib/reporter.js | ✅ 已接线(auto_plan_finish 收尾:验收 → 终态 → 报告落盘) |
| Goal 目标文本 | lib/goal-adapter.js | ✅ 已接线并在收尾时产出(auto_plan_finish 返回 goalHandoff) |
优先级例外:同轮出现「不要执行/仅审阅/只是讨论」等明确否定,或本会话仍有未关闭的 待确认事项时,一律不触发。助手输出、工具结果、Goal 合成轮次不会触发。
dsh-confirmation-resolution 的边界register / decide / complete / approve 路径,也不导入其私有 ledger.js;dsh plugin --profile web add C:\Users\a1941\Desktop\DeepSeek\dsh-auto-plan-executor
dsh --profile web --dump-config
--dump-config 需要写入 $DSH_HOME/profiles/web/cordis.yml,因此必须在不被沙箱限制的终端执行。
行配置(cordis.patch.yml 已给出默认值):
| 字段 | 默认 | 含义 |
|---|---|---|
enabled | true | 总开关;false 时完全不介入普通对话 |
sectionName / order | auto-plan:policy / 118 | Prompt 段落名与顺序 |
budgetLimitCny / perOperationCny | 2 / 2 | 累计与单次费用上限(人民币) |
maxConsecutiveFailures | 3 | 同一任务连续失败上限 |
stateDirName | .dsh-auto-plan | 状态目录名 |
workspaceRoot | ""(进程 cwd) | 状态目录根 |
enforceWriteTools | true | 方案激活时,write/edit/ops_replace/apply_patch 等文件改写工具必须落在 RUNNING 任务的 allowed_scope / writes 内;没有 RUNNING 任务直接拒绝。shell/pwsh 无法按路径匹配,仍可能绕过 |
enforceScope | false | 额外开启后,所有带路径参数的工具(含读)都受 allowed_scope 限制;默认关闭以免影响普通任务 |
costArgName | "" | 声明费用数值的工具参数名(供预算守卫) |
maxRounds | 12 | 交给原生 Goal 的轮次上限 |
maxCompletenessRounds | 6 | 完整度闸门允许的补做轮次;同一缺口指纹重复且无进展 → STALLED,按 BLOCKED 如实收尾 |
maxSteps | 400 | 步骤提取上限;超出判 TRUNCATED 并在 extraction 中如实报告(当前不会因此自动拒绝收尾,见已知缺口 9) |
openvikingEnabled | true | 是否把步骤账本实时镜像到 OpenViking;写失败只记录,不阻塞方案 |
openvikingBaseUrl | http://127.0.0.1:1933 | 本机 OpenViking HTTP 端点 |
openvikingHome | viking://~/plans/auto-plan | 镜像根目录(~ 展开为当前用户根;不写进 memories/,避免污染召回) |
openvikingTimeoutMs | 1000 | 单次镜像请求超时;短超时避免拖住回合 |
serialSteps | false | false:保留独立分支并行,只禁止关闭仍被问题阻塞的步骤;true:严格串行,下一步开始前强制复核上一步 |
cleanupOnFinish | true | 通过收尾并退出方案模式后,删除该方案在 OpenViking 的镜像目录;失败如实写进报告 |
它修的是什么:收尾过去只看"模型自己登记的任务图",于是 20 步方案登记 3 步、3 步过了就是 "全部完成并验证"。现在收尾按冻结的方案步骤判。
snapshot.sourceText 确定性提取(编号列表、- [ ]、
步骤N、P0/P1/P2 与标题分段;代码块跳过;需求 / 目标 / 交付 / 验收 / 范围 / 功能 / 任务
段落里的编号、项目符号、表格行与带职责动词的散文句也算步骤;表头含「任务/待办/步骤/交付」
的表格在任意段落都算;「已知问题 / 现状」表格不算工作)。模型只能用 auto_plan_step action="declare"
追加,且每条必须 source_quote 逐字引用原文(只忽略标点差异);已提取步骤不能删除。classify 把某步降为 OPTIONAL,必须引用原文里真实存在的可选措辞
(可选 / 如需 / 视情况 / 可随后 …);P2 段默认可选,出现「必须 / 强制」则重新必需。auto_plan_finish 逐项判定 DONE / OPEN / EXEMPT,DONE 由当场重跑 verifier
决定——持久化的 verified: true 不算数。GAP-PS-xx 缺口任务、记录一轮
完整度、返回续跑指令(下一次 agent/pre-step 注入一次,不新起续轮循环)。USER_AUTHORIZATION 必须引用本方案真实的 DENIED G3/G4 记录;
USER_ACTION 必须写明需要用户提供什么。无证据的豁免判 OPEN:EXEMPTION_UNEVIDENCED。STALLED;轮次用尽 →
ROUNDS_EXHAUSTED;两者都写成 阻塞,绝不写成完成。COMPLETED_VERIFIED(全部完成并验证);
仅剩有证据的用户侧待办 → COMPLETED_USER_PENDING(完成,不含用户侧待办),报告单列「待用户处理」。SEC:<section>:UNCOVERED_SECTION 阻塞收尾;必须用 auto_plan_step action="declare" 补齐,
或用 action="dismiss_uncovered" 提交该段落正文的逐字引用 + 理由,才能放行(报告会列出)。它修的是什么:完整度闸门只保证"清单里的每一步都被覆盖",但执行中派生的问题、以及"某一步 到底算不算完"仍由模型口头决定。现在每一步有独立账本,问题归属该步,未关闭就不能算完成。
viking://~/plans/auto-plan/<plan_id>/ledger.json(机器账本)与 plan.md(人读清单)。
写入失败只记录 lastSync,不阻塞方案(镜像不是权威源)。task-start / task-verified / step-begin / issue-added /
issue-closed / review-* / finish-refused 都会递增 revision,并同时重写 ledger.json
与 plan.md(人读清单不再是激活快照)。auto_plan_step action="issue" 把问题记到 step_id 名下;
该步还有 OPEN 问题 → 步骤状态为 RUNNING,完整度判 ISSUES_OPEN,不能关闭。action="review" 要求为每条未关闭问题给出 resolved 判定——
resolved=true 必须附 evidence_ref,resolved=false 必须写 reason。只要有一条未解决,
复核判 REVIEW_REJECTED,方案回退到该步(rollbacks 留痕),不会推进。serialSteps=false(本轮确认):独立分支可并行开始,只禁止关闭被阻塞的步骤;serialSteps=true:严格串行,开始下一步前必须对上一步提交 APPROVED 复核;
缺复核时 auto_plan_task action="start" 直接拒绝,并返回复核指令。串行模式下
一个任务不得同时覆盖多个必需步骤(否则会跳过上一步复核)。start 开始步骤、提交复核、以及 auto_plan_finish 收尾前都会先读一次
镜像账本,把服务器上本地没有的问题并入本地(本地状态优先;server-only 问题一律按 OPEN
入账,必须本地凭证据关闭),并作废受影响步骤的复核;读不到时按本地账本继续,并标 degraded。cleanupOnFinish)删除该方案镜像目录 → 写报告 →
从会话 runtime 表移除。只有**报告写成功且清理成功(或已跳过)**才退出;报告写失败或清理失败时
保留 runtime,auto_plan_status 仍可见、可重试 auto_plan_finish,不会留下没人管的孤儿。
清理失败会在报告与 SERVER_CLEANUP 里如实写 FAILED,不写成已清理。agent/pre-step 会扫描本地 state.json,
找到同会话、未终态的 plan 后重建 runtime(任务图、步骤、问题、复核、stepBegins、
evidenceByTask、预算记录与已拒绝的 operation key 全部从磁盘恢复),注入一次
「已恢复未完成方案」指令,不要求用户重新提交方案。重启不会把已用预算归零,恢复后的
剩余额度仍受同一 2 元上限约束。
只有服务器镜像、没有本地 state 的方案不会被自动恢复——这是有意的(无法证明它的任务与证据);
可以用 auto_plan_status 的 include_mirrors: true 查看 orphan 镜像,再人工核对/清理。resolved=true 时,evidence_ref 必须精确匹配
本方案已记录的 evidenceRef,或是 file:<工作区相对路径> 且文件存在;随手编一个字符串会被
EVIDENCE_NOT_FOUND 拒绝。它仍然只是"这条引用指向的观测"的声明,不能证明命令真的执行过
(与 verifier 的 evidenceRef 同一局限)。write/edit/ops_replace/apply_patch 等文件改写工具
必须落在当前 RUNNING 任务的 allowed_scope / writes 内;没有 RUNNING 任务时直接拒绝。
这是方案内的轻量门禁,不影响普通会话;shell/pwsh 无法按路径可靠匹配,仍是已知绕过口。镜像不是强制执行器:OpenViking 只是被读写的账本,不会自己驱动 AI。真正的"强制"由插件在
auto_plan_task start/auto_plan_step review/auto_plan_finish三处执行;默认并行模式下 只禁止关闭被阻塞的步骤,需要"第二步前强制复核上一步"时必须显式serialSteps: true。 模型若绕过这些工具直接改文件,只有enforceScope=true的路径门禁能拦住(默认关闭)。 这是已知边界,不是隐性保证。
| 层 | 命令 | 结果 |
|---|---|---|
| 语法 | node --check lib/index.js(含 step-gate / ov-client) | PASS |
| 单元(212 用例) | node --import ./test/host-hooks.mjs --test ...(显式文件清单) | 212 pass / 0 fail |
| 装配(57 项) | node --import ./test/host-hooks.mjs verify/wiring.mjs | 57/57 PASS(含 STEP-REVIEW / 并行模型 / 镜像脱敏 / 收尾清理成功与失败 / 重启恢复+预算 / 未覆盖段落 / 写入工具门禁 / orphan 列表 / 退出方案模式) |
| 双插件共载(21 项) | node --import ./test/host-hooks.mjs verify/dual-plugin.mjs | 21/21 PASS |
| 完整门禁 | 上述三段串行执行(等价 npm run check) | exit 0 |
| 真实 OpenViking 往返 | content/write → content/read → fs/ls → fs DELETE | 200/200/200/200,删后读 404(2026-10-19 实测) |
| 安装到 web profile | plugin_manager install_bundle | 包已装入(bundles=14、link:)+ dsh --profile web --dump-config exit 0 |
| 运行时激活 | Inspector Tool.listTools | auto_plan_status / auto_plan_task / auto_plan_gate 已注册 |
confirmationMirror 没有运行时写入方:lib/confirmation-adapter.js 具备能力发现与只读镜像,
但 index.js 目前没有任何地方调用 mirror.observe()。因此:
auto_plan_status 里的"已观测确认项"恒为空,state.confirmations 恒为 [];C1/C2 文本模式生效,
「本会话仍有未关闭 C 项」那条判据目前不生效。tools/post-execute 观察器;我没有擅自加,因为它会改变
最敏感的触发路径语义(一条被观察为 open 的 C 项会一直阻塞后续触发,直到观察到它关闭)。auto_plan_finish 是唯一的收尾闸门:它先跑完整度检查,缺口未清时拒绝收尾
(不写报告、不推终态),通过后才用同一套 verifier 重新验收、推进终态
(COMPLETED_VERIFIED / COMPLETED_USER_PENDING / BLOCKED / PARTIAL)、写八部分报告,
并返回交给原生 Goal 的目标文本。它不会自己创建 Goal——创建 Goal 是有副作用的主机动作,
所以这里只交文本(方案 §6.1)。
「失败」这一终态不会由本工具推导:任务状态 FAILED 是可重试态,把它映射成"方案失败"
会在还有重试额度时报成失败;失败 只保留给显式中止。snapshot.requiredDeliverables 仍恒为空(激活时按字面量 [] 创建,模型无法自行声明),
因此 validateRequiredCoverage 仍是"空集真空通过";覆盖改由步骤清单承担:
snapshot.planSteps 是新的权威来源,任务用 plan_steps 声明覆盖哪一步。goalObjective 描述的轮次上限(maxRounds)没有被消费,因为没有任何路径创建 Goal。review 的 resolved 是模型基于上下文给出的
判断;插件能强制的是"每条问题必须有判定、resolved 必须带证据、未解决就回退",不能替模型判断
"这段对话是否真的解决了它"。serialSteps=false(默认)下步骤可并行开始,
插件只保证"被问题阻塞的步骤不能关闭"。需要严格"第二步前强制复核上一步"时必须显式
serialSteps: true,否则那个边界不会发生。write/edit/ops_replace/apply_patch 等文件改写工具
在方案激活期间默认受 allowed_scope / writes 约束;但 shell/pwsh 命令无法按路径可靠匹配,
仍可能直接写文件。要硬隔离需要在宿主沙箱/OS 层限制,而不是本插件。cleanupOnFinish 删除的是 viking://~/plans/auto-plan/<plan_id>/;
本地 .dsh-auto-plan/<plan_id>/ 的 state.json 与报告仍保留,作为本地审计痕迹。TRUNCATED 不会自动阻塞收尾:提取超过 maxSteps 时会在 extraction 里如实标记
truncated/ok=false 并给出告警,但当前闸门仍按已提取的前缀判定;需要把未提取部分用
auto_plan_step action="declare" 补齐,插件不会替模型猜剩余步骤。state.json + evidence 文件;
只有服务器镜像、没有本地 state 的方案不会自动恢复,也不会被自动删除(可能是另一台机器/会话的)。
可用 auto_plan_status(include_mirrors: true)查看 orphan 镜像,人工核对后再清理。evidence_ref 已绑定,但仍是声明:现在必须精确匹配本方案已记录的 evidenceRef,或
file:<工作区相对路径> 且文件存在;但一条已记录的 ref 仍只说明"模型声称执行过这个观测",
不能证明命令真的执行了(与 verifier 的 evidenceRef 同一局限)。一条证据只有携带它那个 kind 应有的字段才算"观测",否则只能是"断言":
| kind | 必须携带 | 说明 |
|---|---|---|
command / test | 整数 exitCode + 非空 evidenceRef | 退出码非 0 → 任务判 FAIL(不是 UNVERIFIED) |
diff / probe | 非空 evidenceRef | 指向真实产物 |
manual | 非空 attributedTo | 人工断言必须写明由谁作出,否则不算 |
self-report / model-claim / tool-called / generated-code / planned-command | —— | 永远只能是断言,不能使任务通过 |
为什么:收紧前,{kind:"command", criterion:"<验收原文>", ok:true}(无退出码、无引用)
就能把任务判成 verified=true 并让 COMPLETION: COMPLETE,进而支持"全部完成并验证"的假结论。
现在这种输入一律 UNVERIFIED,并在理由里点名缺了哪些字段。
node_modules/是必需的,不是可选项。lib/用裸说明符 import 宿主包,装进 profile 后由 Node 从本目录向上解析,所以这里必须有指向 DSH 安装的 Junction:node_modules/@deepseek-ai/{cordis,dsh-tools,dsh-llm,schemastery,dsh-attachment}。2026-10-15 实测事故:最初因沙箱拒绝建 Junction 而改成"零
node_modules+ 开发期 resolve 钩子", 结果装进 profile 后failed to import(application: failed / 1 entry did not activate)。 而且首次解析失败会被长驻进程的解析缓存记住——禁用→启用只会重放失败,必须重启 DSH。 判据:同一个包用node -e "import('<包名>')"在新进程里成功、宿主仍报failed to import。
test/host-hooks.mjs保留为兜底(没有 Junction 时也能跑测试),它同样指向 profile 中同一份 宿主包实例,因此不会产生第二份模块身份。该文件不属于发布内容。
dsh-auto-plan-executor/
├── package.json / cordis.patch.yml
├── lib/ 纯逻辑模块 + Cordis 装配
├── test/ 单元测试与开发期 resolve 钩子
├── verify/ 装配验证、双插件共载验证
└── artifacts/ 环境报告、基线、操作手册、回滚、测试矩阵
dsh plugin --profile web remove dsh-plugin-auto-plan-executor
详见 artifacts/rollback.md。