Skip to content

Releases

v2.1.3 — 规划器超时可配置

Choose a tag to compare

@abbaababa abbaababa released this 06 Nov 09:06

v2.1.3 — 规划器超时可配置(修复超时复发根因)

一句话说明

修复自动任务分解「稳定超时被误报成意外中断」的问题:把规划器的思考时间上限从写死的常量改成可配置项。

问题是什么

插件在接到一个复杂任务时,会先花一段时间自动把它「拆分」成几个子任务,再分派给各部门去执行。这一步是有时间上限的:

  1. 之前的上限只有 2 分钟(120 秒)。当任务描述特别长、要求特别多时,拆分还没做完,就被定时器强制打断了;
  2. 2.1.1 把上限提到 5 分钟(300 秒),但只是推迟了超时,没解决「单次 LLM 调用被固定超时卡死」的结构性问题。复杂任务仍会在 5 分钟处稳定触发超时。

改了什么

新增 DSH_WORKPLAN_PLANNER_TIMEOUT_MS 环境变量(毫秒,>0),未配置时回落到默认值 300000。复杂任务可按需放宽时限,无需重新编译发布。

安装

npm install dsh-workplan@2.1.3

v2.1.2 — 修复规划器超时被误报为偶发中断

Choose a tag to compare

@abbaababa abbaababa released this 06 Nov 08:46

dsh-workplan 2.1.2 发布说明(Release Notes)

发布日期:2026-11-06 | 版本号:2.1.2 | 升级类型:patch(bug 修复)


一句话说明

修复自动任务拆分「稳定超时被误报成意外中断」的问题:把规划器的思考时间上限从 2 分钟放宽到 5 分钟,并让真正超时时报出明确原因。

一、问题是什么(通俗版)

插件在接到一个复杂任务时,会先花一段时间自动把它「拆分」成几个子任务,再分派给各部门去执行。这一步是有时间上限的:

  1. 之前的上限只有 2 分钟(120 秒)。当任务描述特别长、要求特别多时,拆分还没做完,就被定时器强制打断了;
  2. 更糟的是,底层的大模型接口把「超时被打断」这件事,误报成了「请求意外中断」(DeepSeek Messages request aborted),看起来像网络偶发故障,根本看不出真正原因是「时间到了」。

结果就是:复杂任务每次都会稳定失败,但日志却让人以为是「偶发中断」,排查方向被带偏。

二、改了什么(只有这两处)

  1. 把拆分的时间上限从 2 分钟(120 秒)放宽到 5 分钟(300 秒),给复杂任务留足拆分时间。
  2. 当确实是「超时」被打断时,不再被误报成「意外中断」,而是明确抛出「规划器超时:任务分解未在时限内完成」的清晰报错。

改动只涉及 lib/runtime.js 与 src/runtime.ts 两个文件(+14/−2),没有改其它任何功能。

三、安装

npm install dsh-workplan@2.1.2

(版本号 2.1.2 为 patch 升级,属 bug 修复级别。)


四、版本号与内容一致性核对清单

# 核对项 结果 证据
C1 发布说明标题与正文版本号均为 2.1.2,与 T2 目标版本号一致 ✅ 一致 本文档标题与正文、CHANGELOG.md 顶部 ## 2.1.2 — 2026-11-06;T2 结论 2.1.2(patch,远端 404 未占用)
C2 只陈述已验证的两处修正(120000→300000、新增 PLANNER_TIMEOUT 明确报错),无虚构事实 ✅ 一致 git diff:lib/runtime.js 与 src/runtime.ts 各 +7/−1(共 +14/−2);PLANNER_TIMEOUT_MS 两文件均为 300000;新增 throw new PlanError('规划器超时…','PLANNER_TIMEOUT')
C3 改动范围陈述准确(仅 2 文件、+14/−2) ✅ 一致 git diff --stat:lib/runtime.js 与 src/runtime.ts 各 8 行改动(+7/−1)→ 合计 14 insertions / 2 deletions
C4 对外语句通俗易懂、无内部术语堆砌 ✅ 通过 全文用「拆分」「时间上限」「意外中断」等白话表述,无 runPlanner/abortError/PlanError 等内部标识符直接出现在正文(仅作为代码引用保留必要的字段名说明)

v2.1.1 — 退回通知送达修复与文档一致性

Choose a tag to compare

@abbaababa abbaababa released this 06 Nov 04:59

2.1.1 — 2026-11-06

修复 2.1.0 的三处「说到了但没做到」:格式退回通知在续跑时送不到部门人员、中文 README 的安装命令仍指旧版本、安全文档里有一句「当前 1.12.0」的错误陈述。

一、退回通知为什么没送到(根因与修复)

2.1.0 把退回原因写进了状态行,但续跑顺序错了:再次派发时 dispatchPlan 先调用 resetBlockedStatuses,把受阻行连同 blockedKind / error 一起清成待跑;executeSubtask 随后才去读「上次是不是格式退回」,信息已被清掉。实测两次激活的提示词长度完全相同(4374 字符),子 Agent 只能把同样的格式错误再交一遍。

修复 src/runtime.ts:

  1. dispatchPlan 在 resetBlockedStatuses 之前扫出 blockedKind === 'comm-format' 的行,把退回原因抄进本轮的 record.commFormatRejections;
  2. executeSubtask 在行内信息已被清掉时改读这份记录,作为 COMM_FORMAT_REJECTED 的上次失败原因带进子提示词;
  3. 消费一次即删,不会被后续无关重试重复带上。

修复后实测:第 2 次激活的提示词多出「上一次尝试失败」段,含失败类型与逐条不合规项(4374 → 4584 字符)。

二、另外两处修正

  • README.zh.md:72 安装命令仍是 dsh-workplan@1.12.3(同文件徽章已是新版本)→ 改为 2.1.1。
  • docs/cc/AGD-OPS-SECURE-OPERATION.md 安装校验步骤里的「当前 1.12.0」→ 改为版本中立表述,并在文首补一条带日期的版本说明(其余 1.12.0 是那次评估的历史快照,不改写历史)。

三、验证

  • 新增 tests/workplan-comm-format-e2e.test.ts(2 条):真实运行时 + 假子会话跑完整链路,并断言第 2 次激活提示词带「上一次尝试失败」段、COMM_FORMAT_REJECTED 与逐条不合规项。
  • npm run check 退出码 0。
  • npm test:580 / 580 通过。

四、制品校验

  • sha256 9db23eed0c22a8f38b7a2aeef892f1d8277d1469605cf5518577e634f3071d03
  • sha1(与 npm registry 一致)c9a8a627648477a28837583ca388a4f6f673fba4

v2.1.0 — 沟通交流格式契约(下发—自检—核验—退回闭环)

Choose a tag to compare

@abbaababa abbaababa released this 06 Nov 04:42

2.1.0 — 2026-11-06

建立主 Agent 与部门人员之间的统一沟通交流格式契约:派活时随任务附带同一份格式要求,部门人员提交前照此自查,主 Agent 收件后照同一份格式核验,不合规立刻退回并附逐条问题,通知其重新检查格式后全盘重交。

一、这次要解决的问题(说人话版)

以前主 Agent 给部门人员派活,只讲「要做什么」,没讲「结果按什么格式交」。于是同一种误会反复发生:活干完了,但交上来的回执缺证据、缺复盘、少验收条目,主 Agent 只能打回,来回折腾。

2.1.0 把「交付格式」本身变成双方共同遵守的契约:

  • 派活时,格式要求跟着任务一起发下去(不是事后才说)。
  • 部门人员交结果前,先自己照着这份格式逐条检查,全合规了才交。
  • 主 Agent 收到后用同一份格式逐条核验;只要有一条不合规,立即退回,并写清是哪几条、为什么不合规。
  • 部门人员重交时,会看到具体的退回原因,只补缺口,不用把整件事重做。

二、九条格式要求(F1–F9)

编号 要求 为什么需要
F1 结果块用规定的起止标记包起来 主 Agent 才能准确切出结果正文,不会把说明文字当成结果
F2 状态只能是 done / blocked / partial 防止自造状态,导致机器无法判断
F3 三阶段(规划、执行、验证)都要写 证明是「想过、做过、验过」,不是只有结论
F4 说「通过」的验收项必须附证据 没有证据的「通过」不算通过
F5 验收条目数不少于计划里要求的条数 防止漏答要求
F6 产物条目格式合法(类型为文件/网址/备注,内容非空) 让「产物在哪」可被机器核对
F7 复盘四项(问题、弯路、解决、防再犯)各至少一条 经验能沉淀,下次少踩坑
F8 报「受阻」必须写清卡在哪 主 Agent 才能给出有效指示,而不是干等
F9 不得编造 诚信底线;由三阶段门禁与人工复核兜底

三、落地位置(可核对)

环节 代码位置 行为
下发 src/comm-format.ts#renderCommFormatSpec → src/plan.ts#buildChildPrompt 末尾 每个子任务提示都附带九条规范与「提交前自查(强制)」指令
自检 同上(提示词内强制指令) 部门人员提交前逐条对照
核验 src/comm-format.ts#checkCommFormatCompliance → src/plan.ts#adjudicateResult 主 Agent 用同一份规范逐条核验 F1–F8
退回 adjudicateResult 返回 blockedKind:'comm-format' 不合规即判受阻,退回通知写明逐条不合规项
重交 src/runtime.ts#executeSubtask 的 lastFailure 注入 退回原因随下次激活回到子提示词,只补缺口不重做

四、验证

  • npm run check(tsc --noEmit)退出码 0。
  • npm test:578 条用例,pass 578 / fail 0。
  • 新增 tests/workplan-comm-format.test.ts:F1–F8 逐条拒收、合规放行、退回通知文案、requirePhases:false 兼容边界。
  • 既有 1 条用例按新契约前移:tests/workplan-evidence-contract.test.ts 的 C-19 由「空证据 pass 降级 unverified 仍算完成」改为「按 F4 退回 blocked/comm-format」。
  • 同时保留 2.0.5 草案的规划器 JSON 结构修复(括号/逗号/截断恢复),规划入口不再因一个字符的结构瑕疵整体降级。

五、发布渠道

  • npm:dsh-workplan@2.1.0
  • GitHub Release:v2.1.0,附 dsh-workplan-2.1.0.tgz
  • 制品校验:
    • sha256 0f015202575999b4be428bd55f2349f676a88ad48c605727cbd6e8494c9ac261
    • sha1(与 npm registry 一致)afc59da063e210f03eb0424b00da6e594f8536eb

六、边界(不夸大)

  • 只拦「即将判完成」的路径。解析失败、验收缺口、三阶段缺失已被更早的门禁拦下,保留原有更具针对性的诊断。
  • requirePhases:false(历史回放 / 明确关闭新契约)不追溯否决旧日志里按当时规则合法的完成记录。
  • F6 只校验产物声明是否合法,是否必须交付文件由各子任务的验收标准决定,避免把写作类任务误判为不合规。
  • F9 不做自动判定:编造检测需要语义理解而非结构校验,写成提示词级诚信约束,由三阶段门禁与人工复核承担。

dsh-workplan 2.0.4 — 回执判定四缺陷修复 + 交互式收尾留痕

Choose a tag to compare

@abbaababa abbaababa released this 05 Nov 13:43

2.0.4 — 2026-11-05

修复「子 Agent 干完活却交不了差」的四条判定缺陷,并给交互式会话收尾加上「放行但留痕」。

一、问题与证据链

用户 2026-11-05 报告:计划里 5 个子 Agent 的产物都已在磁盘上,结果却被判「结果块无法解析」「未提供结构化证据块」,交付门禁反复重开;同一会话里还出现「子任务没完成就先给结论」。

逐条核对子会话原始回执后确认,这不是模型没干活,而是四处判定把「格式瑕疵」当成了「没有证据」:

# 事实 证据
1 3 份回执结尾各少一个 },补一个括号后 JSON.parse 立即通过 逐字符括号扫描;补后解析成功
2 2 份回执 JSON 合法,只是漏写 WORKPLAN_EVIDENCE 标记(放在代码块里) 旧实现判「未提供证据块」,与事实相反
3 旧验收只做 实际文本.includes(声明原文),同义改写一律判「没回应」 acceptanceCoverage()
4 reported 状态没有 done 出边,复核已回报的行必撞「非法闭环迁移」 状态迁移表
5 交互式会话 steer 上限 2 次,用尽后静默放行,用户看不到「这次是没做完就收尾」 onTurnStopping

二、改了什么

  • 回执解析有界修复:新增 closeOpenJson / lastSafeCut / repairEvidenceJson,只在结构层补括号与截断,不补内容;修不好的仍如实报错,并给出「只保留 status/summary/acceptance/artifacts/needs 后重发」的下一步。
  • 无标记回执可认领:新增 rescueEvidenceFromFence(),仅在缺规定标记时,从代码块中认领「有 status 且至少带一个证据字段」的对象;计划载荷、配置片段这类普通 JSON 不会被误认。
  • 验收匹配放宽到语义层:新增字符二元组 Dice 相似度与否定词一致性校验——同义改写、语序调整算同一条;删掉「不得」这类否定词,或只抄前半句,仍然判不覆盖。
  • 状态机补齐:已回报的行再次交付时保持 reported,不再强写 done,也不再报非法迁移。
  • 交互式收尾「放行但留痕」(方案 B):steer 用尽时不再沉默 return,而是把 releasedIncomplete(轮次、进度、未完成项)记入计划状态、向会话追加一条 notice、并写一条 warn 日志;三处使用同一组数字。headless 场景维持原有 WORKPLAN_INCOMPLETE 硬失败语义。
  • 错误文案分档:截断、少闭合符、缺标记三种情况给出各自的修复指令,不再统一说「无法解析」。

三、验证

  • 新增 tests/workplan-user-logic-204.test.ts:13 条用例覆盖同义改写、部分回应、删否定词、只抄前半句、缺括号、缺标记、误认普通 JSON、已回报复核。其中「删否定词」「只抄前半句」两类假阳性由独立复核子 Agent 用 18 条真实差异对复现后补入。
  • npm test:562 条用例全过,0 失败。
  • npm run build 重新生成 lib/、dist/、client.js,与 src/ 同步。
  • npm pack --dry-run 文件清单核对:不含 .backups、node_modules、测试临时文件与任何凭证。

四、范围说明(重要)

本版本不含官方 @deepseek-ai/dsh-client-ui-chat 的界面文案改动。那条改动(「已完成,用时 」→「本轮过程已完成,用时 」)落在第三方包内部文件,属官方 DSH 安装目录,不随本包分发;需要的话请按仓库文档中的说明自行替换,或等待上游修复。

五、发布

  • npm:dsh-workplan@2.0.4
  • GitHub Release:v2.0.4,附 dsh-workplan-2.0.4.tgz 制品与 SHA256
  • 索引源(dsh-plugin-catalog 链路):条目 tarball 指向 v2.0.4 Release,由上游 CI 生成 catalog

安装

dsh plugin --profile web add dsh-workplan@2.0.4

制品校验

  • dsh-workplan-2.0.4.tgz
  • SHA256 0060d7401e90e6c2a39f68e436577dd4c147594466545ebe5be8082ca95e894a

v2.0.3 — /goal 自动分解修复

Choose a tag to compare

@abbaababa abbaababa released this 05 Nov 10:58

2.0.3 — 2026-11-05

修复「官方 /goal 目标指令会让 dsh-workplan 自动分解永远不触发」的真实缺陷:goal 第一轮现在作为合法任务入口参与自动分解;已有进行中计划时 goal 轮次绝不抢跑。

一、问题与证据链

用户 2026-11-05 报告:使用官方 DeepSeek Harness 的「目标 goal」指令后,dsh-workplan 的自动任务分解似乎不会触发。核查代码后确认这不是猜测,而是一条可复现的契约缺口:

# 事实 证据位置
1 /goal <objective> 命令只写 goal 领域状态,不产生 user/message @deepseek-ai/dsh-command-goal 的 create 分支
2 goal 的自动续跑轮次由 round driver 以 source.kind = "goal" 的 user 消息送达,文本形如 <goal_round>Objective: "…"</goal_round> @deepseek-ai/dsh-goal-round-driver/lib/index.js 的 renderGoalRoundPrompt 与 createUserMessage
3 2.0.2 的 humanMessages() 只接受 source.kind === 'user' 或未标记的消息 src/runtime.ts#humanMessages
4 maybePlan() 在 human.length === 0 时直接返回,不进入规划 src/runtime.ts#maybePlan

1+2+3+4 合并后的结论:如果任务是通过 /goal 设置的,整条 goal 生命周期内都不存在「人类消息」,插件永远不会自动分解该任务。人工消息路径(普通输入框任务)不受影响。

二、改了什么

  • 新增 goalRoundPlanningTask(ctx, payload, existing):只接受 source.kind === 'goal' 且 round === 1 的消息作为自动分解入口。
  • maybePlan() 在没有任何人工消息时改走该入口;任务文本优先级为:goals 领域服务的结构化 objective → 从官方 <goal_round> 信封解析 JSON objective → 整条消息原文。
  • 防抢跑:会话里存在进行中计划(executing / paused / pending / verification 等)时,goal 轮次直接放行不建计划;done / ended / cancelled / superseded / degraded / clarify 属于历史记录,不拦新任务。
  • 人工消息路径、humanMessages() 的既有语义、执行中变更(changeRequest)与 replan 规则全部保持不变。

三、验证

  • 新增 tests/goal-round-planning.test.ts:7 条断言覆盖 round 1/round 2、goals 服务优先、信封解析、无 objective 兜底、进行中计划防抢跑、历史终态放行。
  • npm test:553 条用例全过;npm run check(tsc --noEmit)退出码 0。
  • npm run build 重新生成 lib/、dist/、client.js,与 src/ 同步。

四、发布

  • npm:dsh-workplan@2.0.3
  • GitHub Release:v2.0.3,附 dsh-workplan-2.0.3.tgz 制品
  • 索引源(dsh-plugin-catalog 链路):条目 tarball 指向 v2.0.3 Release,等待上游 CI 生成 catalog

v2.0.2 — 更正「第一、二阶段禁用插件」的适用范围

Choose a tag to compare

@abbaababa abbaababa released this 05 Nov 06:02

dsh-workplan 2.0.2 — 更正「第一、二阶段禁用插件」的适用范围

发布日期:2026-11-05(Asia/Shanghai)

一句话

2.0.2 只做一件事:把「第一、二阶段禁用 dsh-workplan 插件」更正为仅适用于 2026-11-05 本次优化会话,不再作为所有后续会话的永久产品规则。三阶段工作法、阶段三核验与自我学习复盘全部保持不变。

安装 / 升级

dsh plugin --profile web add dsh-workplan@2.0.2

装完重启一次 DSH Web(或重新载入页面)。

从 2.0.1 升级时不需要迁移数据:phases 证据格式、phases.verification.retrospective、教训记忆文件 ~/.dsh/workplan/lessons.jsonl 都没有变化。

为什么要出 2.0.2

用户在 2.0.1 发布后澄清:原要求 4「第一、二阶段禁用 dsh-workplan 插件」是本次会话内对优化过程的约束,不是要求插件对所有未来会话禁用。1.13.0 起该条被写成了产品级规则(子 Agent 提示词、dsh_workplan_verify 描述、运行时报错、README 与协作文档),属于对需求范围的误读,2.0.2 全面更正。

改了什么

位置 2.0.1 及以前 2.0.2
子 Agent 提示词 「阶段一、二:dsh-workplan 插件禁用。不得调用任何 dsh_workplan_* 工具」 「阶段一、二先把问题、思路与执行记录写全;调用 verify 会因缺少前两阶段证据返回 PHASE_GATE(证据门禁,不是禁用插件)」
dsh_workplan_verify 描述 「阶段一、二禁用本插件」 「缺少 planning / execution 证据时返回 PHASE_GATE 与待补项」
运行时报错 「插件在阶段一、二禁用」 「阶段三核验缺少前两阶段证据」
README(中/英) 声明永久禁用 声明仅本次会话约束;主 Agent 任何阶段都可用计划、派发、查询与改判工具
协作文档与安全文档 表格写「禁用」 写「证据门禁」并加 2.0.2 更正说明

没有变的部分

  • 三阶段「规划 → 执行 → 验证」仍是产品功能;完成判定仍要求 phases 齐全。
  • dsh_workplan_verify 仍只接受三阶段齐全的证据;缺 planning/execution 仍返回 PHASE_GATE——这是证据门禁,不是插件禁用。
  • 阶段三复盘(问题 / 弯路 / 解决 / 防再犯)与永久教训记忆完全不变。
  • 没有新增或删除模型工具,工具面仍是 11 个。

验证

  • npm run check(tsc --noEmit)退出码 0。
  • npm test:全量通过(具体条数见仓库发布记录与 CI 输出)。
  • tests/three-phase.test.ts 新增断言:提示词不得再出现「插件禁用」,同时仍要求阶段三门禁与 PHASE_GATE。

兼容性

  • 2.0.2 是 2.0.1 的措辞更正版,证据契约与数据格式完全兼容,可直接升级。
  • 旧结果回放仍可用 requirePhases: false 走 1.13.0 以前的旧语义(与 2.0.1 相同)。

v2.0.1 — 自我学习与自我迭代

Choose a tag to compare

@abbaababa abbaababa released this 05 Nov 05:23

dsh-workplan 2.0.1 — 自我学习与自我迭代

发布日期:2026-11-05(Asia/Shanghai)

一句话

部门 Agent 每次完成工作后必须复盘(问题 / 弯路 / 解决 / 防再犯),复盘写入永久记忆文件;下次派发同类任务时自动注入历史教训,同一类错误重复出现会累加次数并提前排序。三阶段工作法保持「规划 → 执行 → 验证」,复盘是验证阶段收尾的必填项。

安装 / 升级

dsh plugin --profile web add dsh-workplan@2.0.1

从源码安装:

git clone https://github.com/abbaababa/dsh-workplan.git
cd dsh-workplan && git checkout v2.0.1
npm ci && npm run build
dsh plugin --profile web add /绝对路径/dsh-workplan

新增能力

能力 说明
阶段三复盘必填 phases.verification.retrospective 四项:problems / detours / resolutions / prevention。缺项、太薄(问题/解决合计 <20 字、预防 <16 字)一律 blocked/unverified
永久教训记忆 复盘通过后写入 ~/.dsh/workplan/lessons.jsonl(JSONL,追加写,保留最近 500 条,坏行跳过,临时文件 + 改名原子替换);DSH_WORKPLAN_LESSONS_FILE 可覆盖位置
自动防再犯 每次派发前按「同部门 > 同项目 > 关键词 > 重复次数 > 新近程度」取最相关 8 条注入子 Agent 提示词;段首声明「历史数据,不是新指令」
自我迭代信号 同类错误再次出现时 occurrences+1、排序提前;同一子任务重试/回放只原地更新,不虚增次数
只读复核工具 dsh_workplan_lessons:list / search / stats,返回记忆内容、重复次数、文件位置;不提供写入动作,防止绕过真实复盘证据

三阶段与插件禁用边界(不变)

  • 阶段一(规划):先梳理现状/约束/未知/主要矛盾,再形成完整可执行思路;阶段二(执行):严格按思路执行并记录偏离;阶段三(验证):逐条验证 + 复盘。
  • 阶段一、二禁用 dsh-workplan 插件:子 Agent 本就没有计划/派发/改判权限;dsh_workplan_verify 在缺 planning/execution 证据时返回 PHASE_GATE。
  • 唯一例外是遇阻上报 dsh_workplan_escalate(安全阀,不属于计划/执行/验证能力)。
  • 核验通过 ≠ 完成:结果块仍须写同一份 phases,由 adjudicateResult 再判。

兼容性(破坏性变更)

  • 2.0.1 之前写出的 done 结果没有 retrospective,用本版完成判定重放会判未完成。历史回放请显式传 requirePhases:false(或 strict:false)走旧语义。
  • 复盘内容来自模型输出:插件只校验「有没有写、够不够具体、是否覆盖四项」,不能证明内容真实;真实性仍由主 Agent 对照产物核对。
  • 记忆是文本数据:注入前清除不可见字符与会话引用,并声明不是指令;发现污染时用 dsh_workplan_lessons 抽查并删除对应行。

验证

npm run check      # tsc --noEmit
npm test           # 构建 + 全量用例
npm run build
git diff --exit-code -- lib client.js   # 构建产物可复现

发布记录(提交、tag、Release 资产哈希、npm 完整性、索引源 PR)见 docs/release-record-2.0.1-20261105.md。

dsh-workplan 1.12.3 — 澄清闸门 + 句中先行词 + 法务召回

Choose a tag to compare

@abbaababa abbaababa released this 04 Nov 13:14

1.12.3 — 2026-11-04

修好 MS2 20 条真实实跑暴露的四处缺陷:指代误拦(T05-08)、该问不问(T05-04/09/13/20)、未确认自行派发、法务召回缺失(T05-12)。默认行为变化:信息不足时不再生成计划、不再派发,改为向用户提问。

一、四处缺陷的修法

编号 缺陷(MS2 实测) 1.12.3 的修法 代码位置
① 指代误拦 T05-08「它每天具体走势」——「它」的先行词就在同一句的上半句,却被判成「找不到先行词」直接拦下 先在任务原文的同一句、再在上一句里找「实体型」先行词(引号跨度,或含数字/字母的中文实体片段);只有两处都找不到才拦 src/understanding.ts resolvePronounAntecedentInline
② 该问不问 T05-04/09/13/20 四条本该澄清,却照做计划并派发 四条可判定规则:C1 裸表态、C2 悬空内部编号、C3 预测类无标的、C4 界面改动无对象;命中时在规划之前拦下,并给出一句可以原样问用户的话 src/understanding.ts auditClarifyNeed;src/plan.ts buildClarifyMessage;src/runtime.ts 规划前闸门
③ 未确认自行派发 20 条里累计 46 次未经用户确认就启动部门 Agent 按用户 2026-11-04 的决定:自动派发语义不变,只在「信息不足」这一类上拦截——缺信息时连计划都不生成,自然走不到派发 src/runtime.ts clarifyGateDisabled / maybePlan
④ 法务召回 T05-12「会不会窃取用户文件和数据」判成无部门覆盖 legal 词表增加 窃取 / 信息泄露 / 个人信息 / 数据安全 / 隐私风险 / 移动终端(刻意不用「泄露」:内存泄露属于工程问题) src/departments.ts

二、每一条结论的证据(可复核)

  • 离线回放(不调用模型):20 条真实原文 → clarify 4/4 命中,16 条正常任务误拦 0 条;T05-12 legal 命中 2 词(窃取、移动终端);「修复内存泄露导致的崩溃」legal 命中 0 词;「参考国际标准做一下排版」仍为 1 词(低于 ≥2 门槛,不会把排版任务拉进法务)。
  • 端到端(headless 真跑):用 T05-13 原文启动 headless → 事件流里 0 个计划、0 次 dsh_workplan_* 工具调用,模型改为向用户提问(证据见 _t_clarify_20261104/)。
  • 自动化测试:npm test 523 条全过、0 失败(含新增 tests/clarify-gate.test.ts、tests/antecedent-inline.test.ts);npm run check(tsc --noEmit)退出码 0。
  • 修正了一条旧断言:legal 词表从 16 词增到 22 词,tests/department-coverage.test.ts 的数量断言同步更新并写明原因;C4 曾把「把红圈处改为默认收起」误判成「没说要改哪里」,用 department-fit.test.ts 抓出来后才补上「红圈/红框/圈出」三种说法。

三、开关与行为影响

  • 新增 DSH_WORKPLAN_CLARIFY_GATE=0:关闭澄清闸门,回到旧行为(信息不足也照做计划、照派发)。默认开启。
  • DSH_WORKPLAN_AUTO_DISPATCH 语义未变:默认自动派发照旧,只是信息不足的任务不会再走到派发这一步。
  • C3/C4 允许「缺的对象在最近对话里」:上一轮说过「截图红圈处的分步进度」,本轮「把它改成默认收起」就不算缺信息(否则会把正常追问也拦掉)。

四、本版没有覆盖的(如实登记,不计入修复证据)

  • 同一工作区里还有一个 headless「未完成不得成功收尾」闸门(failClosedOnIncomplete / WORKPLAN_INCOMPLETE),目前只有实现、没有自动化用例;发布前必须补测,本版不宣称它已验证。

dsh-workplan 1.12.2 — 修好 G1/G2/G3 三个写保护漏洞

Choose a tag to compare

@abbaababa abbaababa released this 04 Nov 11:27

1.12.2 — 2026-11-04

修好 G1/G2/G3 三个写保护漏洞(1.12.1 只记录了缺口)。这是一次有意的行为变更:已交付文件的写保护现在真正无死角,且不再区分「谁在写」。

一、修了什么(三个漏洞,逐条)

编号 1.12.1 的状态 1.12.2 的修法 代码位置
G1 子 Agent 不受保护 非根会话直接放行:「门卫只认户主,保姆拿钥匙能进」 去掉角色判断。已交付文件在计划未就绪期间不得被原地改写,与谁在写无关。 src/runtime.ts presentedWriteDenialReason
G2 只认三个工具名 只接管 write / edit / str_replace_editor,第四个写工具(如 apply_patch)根本不进闸门 改为按参数形状识别写操作:带 file_path/path,或 patch 文本含 *** Update/Add/Delete File:。一次调用含多个文件时,只要有任一命中就整单拒绝。读类工具显式白名单排除。 src/host.ts fileWriteGuardReason / isWriteShapedCall;src/runtime.ts writeTargets
G3 符号链接绕过 只做 path.resolve,/link/report.md 与 /real/report.md 被当成两个文件 两侧都归一到真实文件身份(realpath.native)。交付链接、写真实路径(或反之)都能认出来。文件尚不存在时解析最近的存在祖先;完全解析不了时退回旧行为。 src/runtime.ts realPathIdentity / identityPath

二、行为影响(会影响现有使用的部分,务必读完)

  1. 子 Agent 写已交付文件会被拒绝(G1)。以前后台子 Agent 能改掉用户手上那份报告,现在与主 Agent 同等对待。present 仍只有主会话可用,所以「交付能力」没有扩大,只是「改写已交付文件」的口子被堵上。
  2. 更多工具名进入写保护(G2)。过去改一个名字(如 apply_patch、write_file)就能绕过的写法,现在同样被拦;一次 patch 改动多个文件时,只要有一个是已交付文件就整单拒绝。
  3. 符号链接不再是第二种写法(G3)。通过软链接路径改写已交付文件会被拦下,报错文案与直接路径完全一致。
  4. 照旧保留的出路:计划交付就绪后放行;计划被 dsh_workplan_cancel 显式取消后放行;present 之后才新建的计划不受限制;plan 模式下写保护不生效。
  5. 没有削弱的权限:其余 8 处 NOT_ROOT 校验(子 Agent 不能 update / replan / cancel / dispatch 主计划、不能下发指示、不能处置跨部门需求、不能补发 follow-up、不能 present)一处未动。那是「子 Agent 不能改计划」的权限,与「不能改文件」是两件事。

三、验证(双向红绿,不是只跑一次绿)

  • 修复前(换回 1.12.1 的 src/runtime.ts + src/host.ts):tests 498 / pass 491 / fail 7,失败项正是 6 条 G1/G2/G3 新用例 + 1 条既有契约用例。
  • 修复后:tests 498 / pass 498 / fail 0,退出码 0;npm run check(tsc --noEmit)退出码 0。
  • 用例数构成:基线 495 + G1 一条 + G2 一条 + G3 反向一条 = 498。
  • 三条原本「钉住缺口」的用例已翻转成「钉住修复」:p03-m1-write-guard-gaps.test.ts 的 G3 条、p03-m1-guard-gating-gaps.test.ts 的 G1/G2 条、以及既有契约 workplan-presented-write-guard.test.ts 中「非根会话放行」的断言。

四、事实边界(不得外推)

  • 真实模型在 20 条任务上的通过率未被本版刷新,仍为 2026-11-03 的 pass 4/20。原因:模型密钥 4 个环境变量全空 + 工作区外写配置权限缺失,20 条真实模型验证无法在本轮重跑。
  • 1.12.2 是代码级修复 + 回归验证的结论,不代表 20 条真实模型任务的表现有任何变化。

安装

dsh plugin --profile web add dsh-workplan@1.12.2

本次不包含(如实说明)

  • 真实模型 20 条验证:本机 4 个模型密钥环境变量为空,未重跑,通过率仍为 2026-11-03 的 pass 4/20。补齐密钥后可执行 rerun_ms2_20.sh 复现。
  • npm 包 dsh-workplan@1.12.2:https://www.npmjs.com/package/dsh-workplan