dingtalk-dsh-assistant 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +117 -443
  3. package/package.json +39 -28
package/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@
4
4
 
5
5
  ## [未发布]
6
6
 
7
+ ## [2.0.0] - 2026-10-16
8
+
9
+ ### 新增与改进
10
+
11
+ - 任务执行会话自主使用 DSH 原生工具,群常驻协调、任务接续、人工介入与执行恢复形成统一链路;保留业务验收和外部效果核对。
12
+ - 看板增加完整执行会话列表、累计运行时长和可缩放时间轴;展示消息结论、耗时、阶段标记与独立提示,保留原有状态颜色。
13
+ - 任务上下文改用索引、去重与文件按需读取,减少重复注入;支持执行短名和阶段进度展示。
14
+
15
+ ### 修复
16
+
17
+ - 修复历史引用及通知回声阻断消息处理、原任务续办、原生工具回执归属、执行 provider 恢复和文件前置拒绝后的纠正路径。
18
+ - 修复通知回读与对账、人工介入私聊及已答通知撤回、回复署名配置、任务归档入口和看板刷新后的页面恢复。
19
+
20
+ ### 不兼容变化与升级边界
21
+
22
+ - 适配 DSH `0.2.1-alpha.2`,要求 Node.js 24+;宿主仍是预发布版本,不承诺其他 DSH 版本兼容。Assistant、Observer 与宿主服务依赖须保持一致。
23
+ - 本次因不兼容变化升级主版本:旧插件内置 Git/Run/节点固定自动化编排退出,改由原生任务与执行会话使用当前配置开放的工具和技能;删除 1.0.0 公开的 `./execution`、`./platform-host` npm 子路径导出,移除任务电子表格同步,并切换任务会话架构和 DSH 宿主依赖。依赖旧导出的集成须先改用当前受支持入口;依赖表格同步的实例须另行安排替代方案。既有实例须先阅读任务会话清洁启动、DSH 兼容及本地部署说明,排空旧调度并审阅历史未决效果;不能仅替换包或直接覆盖历史数据。
24
+ - 三个发行包统一为 `2.0.0`;全新安装使用根包 `dingtalk-dsh-assistant@2.0.0`。包发布不代表实例升级,也不代表历史告警已清除。
25
+
7
26
  ## [1.0.0] - 2026-09-29
8
27
 
9
28
  ### 新增
@@ -275,3 +294,5 @@
275
294
  [0.5.1]: https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases/tag/v0.5.1
276
295
  [0.5.0]: https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases/tag/v0.5.0
277
296
  [0.4.0]: https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases/tag/v0.4.0
297
+
298
+ [2.0.0]: https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases/tag/v2.0.0
package/README.md CHANGED
@@ -2,123 +2,99 @@
2
2
 
3
3
  # DingTalk DSH Assistant
4
4
 
5
- `dingtalk-dsh-assistant` 是一组运行在 [DeepSeek Harness(DSH)](https://github.com/deepseek-ai/DeepSeek-Harness) 中的钉钉数字员工插件。它把钉钉群聊直接接入 DSH,让 Agent 不再只是等待 `@` 后回答问题的机器人,而是一个能够理解完整群聊上下文、主动参与协作并持续推进任务的团队成员。
5
+ `dingtalk-dsh-assistant` 把钉钉群聊接入 [DeepSeek Harness(DSH)](https://github.com/deepseek-ai/DeepSeek-Harness)。当前 resident 使用“消息 → 话题 → 任务会话 → 独立执行会话”:消息只归属话题,既有话题协调器结合固定版本原文与新消息决定是否创建、续办、取消任务或仅讨论;任务会话持续负责完整目标,独立执行会话使用宿主实际工具完成受托工作。
6
6
 
7
- 在 DSH 与 DWS 已完成安装和登录的前提下,插件接收群消息并维护话题事实。已切换到 workflow-v2 的群先拆分、关联和判断意图,再由消息事项的原生 Agent 会话完成问答;需要持续交付的工作进入 Task 与阶段编排。各项执行独立保存进度,支持查询、等待补充、恢复和交付。
7
+ 当前源码不再装配固定 workflow、DAG、阶段或节点调度器。按清洁启动使用全新任务库与 Resident domain,旧任务数据可恢复地移出运行路径;当前服务不读取、导入或兼容旧任务,也不重新发送旧通知。既有实例不能直接热切换,先读[任务会话清洁启动 Runbook](docs/ops/task-session-clean-start.md)。本文描述源码行为,不表示已发布、已部署或通过真实钉钉验收。
8
8
 
9
- 插件不是独立 Agent 平台,也不自行实现第二套 Session、Agent 或任务执行引擎。Agent 身份、工作规则与可用工具由配置的工作区及其 `AGENTS.md` 决定,插件本身不包含个人姓名或数字分身设定。
9
+ ## 任务责任与执行边界
10
10
 
11
- 已切换群的入站门禁统一复用未变动的封存快照核验,并持续检查文件身份;追加群不再逐条消息重读完整历史快照。历史发件的替换关系使用邻接索引核对,保留环、未知目标和分叉拒绝。
11
+ - 原消息、话题单元、归属版本、摘要及决策操作记录继续持久保存。原路由与话题决策按角色使用原生协调会话,只解释、归属和交办真实来源,不执行业务工作;消息不直接保存任务关联。
12
+ - 每任务一个持久任务会话(Owner),独立维护当前目标、需求版本与控制版本。它可直接使用当前 Agent 配置提供的原生工具、按需读取技能,也可委派、读执行结果、取消执行及提交本轮结论;不另设统筹会话工具白名单。
13
+ - 每个受托执行有自己的 `executionId`、原生 Session、租约和工作目录。同任务可并行多个执行,同一执行只能单飞;续办沿原 Session 与递增输入版本,不伪造 Run/节点。
14
+ - 任务会话根据当前要求与真实结果自主判断继续、等待、提问或完成。Host 检查来源、版本、权限、未排空句柄与未决 operation 等一致性,不代替模型做业务阶段验收。
15
+ - 任务与执行会话均挂载实际配置的 DSH Agent preset,恢复时沿已持久选择;任务和动态执行会话均保留该配置的原生工具,不额外设置会话工具白名单;工作区指引、沙箱、审批及操作账身份仍以宿主和当前真实授权为准。会话可使用实际已配置的原生委派工具,具体操作仍须有当前用户授权。
12
16
 
13
- 旧消息可通过本机受控接口逐条重处理。没有业务命令、全消息澄清通知已独立确认送达且答复已接纳时,恢复会保留原通知并继承答复,不重复询问;发送结果未确认或已有业务命令时仍拒绝重处理。操作及回读要求见 [本地部署说明](docs/ops/resident-review-local-deployment.md)。
17
+ 话题决策先落原话题账,任务与用户来源再落 SQLite 账,然后创建会话。每任务沿配置工作区的 tasks/<taskId> 使用固定工作区,原生 workspaceRegistry 以任务标题显示;任务与独立执行会话的原生归属均为同一任务根目录。同一任务的任务会话与全部执行会话也在同一任务根目录实际运行,文件可共享;不同任务使用不同根目录。恢复保留相同工作区、运行目录和会话身份。任务会话标题使用任务标题,执行会话标题使用受托小目标名称。执行结果与唤醒任务会话的事件在同一事务提交;旧需求的迟到结果只作为历史证据,不能改变新要求。暂停或取消使旧分派权限失效,只有真实工具、会话及受管进程排空后才能释放执行占位。“取消请求已记录”不代表外部动作已撤销。
14
18
 
15
- ## 从群聊机器人到数字员工
19
+ ## 持久账、通知与恢复
16
20
 
17
- 常见的群聊机器人或 Agent 接入方式通常需要被 `@` 才会唤醒,只能获得当前消息附近的片段上下文,更适合问答、检索等单次工作。`dingtalk-dsh-assistant` 通过 DSH 原生 Session、subagent 与 Goal,把群聊协作变成可持续、可并行、可追踪的任务闭环。
21
+ 动态控制库独立记录 task、execution、operation、source、wake 和 notification,不依赖旧 Run/节点外键。命令回执和稳定分派键防重复;结果已写入原生日志而回调尚未落账时,恢复可以重收已确认提交,不再调用模型重做工作。
18
22
 
19
- | 能力 | 普通机器人 / Agent | DingTalk DSH 数字员工 |
20
- | --- | --- | --- |
21
- | 参与方式 | 被 `@` 后响应 | 常驻群聊,主动判断并参与 |
22
- | 上下文 | 当前消息或片段上下文 | 持续维护完整群聊上下文 |
23
- | 工作范围 | 问答、检索等单次任务 | 讨论、方案、排障、工具执行、功能开发 |
24
- | 任务处理 | 一次处理一件事 | 多个独立叶子任务并行推进 |
25
- | 持续执行 | 回复结束后停止 | 通过 Goal 持续执行、等待、恢复和完成 |
26
- | 结果交付 | 返回一次性答案 | 回到原群引用回复,保留证据与任务状态 |
23
+ 外部 operation 先持久登记再执行。`starting` 在重启后成为 `unknown`;原未知记录及其已有资源锁保留,不能换 ID 或换参数自动重放。新原生调用沿 DSH 自身的权限及并发合同,不再分配插件合成的通用写锁,也不因另一个操作未知而全局拒绝 GitHub/终端等查询;原操作对账和业务完成证据继续独立核验。
27
24
 
28
- ## 与 DSH 的关系
25
+ 业务完成与通知送达是两件事。完成结论和唯一完成通知意图同事务提交;话题确认、必要业务问题、用户主动状态查询也使用独立通知账,并投影回原群消息发件箱。话题决策的全部任务动作落账后才准备回复,动作失败不发送成功承接表述;恢复按原动作和通知身份去重。话题固定历史中的自身通知只作为上下文,不作为用户授权来源;同账号手动输入仍须精确版本准入。发送后必须独立核对目标群、真实消息及身份/引用证据。ACK、工具返回成功或业务完成均不等于通知送达;未知通知只回读,不重发业务或原消息。Web-only 来源不自动转成群聊外发。
29
26
 
30
- ### workflow-v2 的问答与调查
27
+ 发信箱使用“待发送、发送中、待回读、待核对、已送达、已替代”等短状态;待回读表示进入发送后核验,待核对表示发送结果未知,已送达表示回读已确认。状态提示保留具体原因,异常及撤回记录单独展示。
31
28
 
32
- 普通项目、代码、数据库问答使用 `answer.objective`:意图节点交付问题,执行 Agent 根据需要调用受信只读工具并组织答案,普通问答不创建业务 Task。一次问答拥有独立会话,同一执行的必要补充沿用会话;话题提供事实与来源,不维持永久增长的执行上下文。慢查询不阻塞后续消息的判断。
29
+ 收信箱处理状态按当前归类结果和话题处理版本展示为待归类、归类失败、话题处理中、已处理;不再展示旧工作流等待状态或“历史未记录处理过程”提示,已有处理记录仍可查看。
33
30
 
34
- 明确要求持续排查或独立调查交付时,Task Owner 选择统一的 `task-investigation`。调查 Agent 自主安排搜索、读文件、查询和反证,不为每次工具调用创建阶段。方案、PR评审、数据分析及复盘的专业要求集中到共享调查指引。修改代码、写库、提测与上线继续使用各自授权和验收编排。
31
+ 收信箱过滤已关联的自身通知及当前发送身份的 DWS 回流,保留底层历史;本人手动发送的正常消息仍经监听和历史补拉接纳。仅账号相同不能判定为通知。DWS 不返回原生 `@` 元数据时,只有精确发送状态 SUCCESS、消息 ID、发送者、原群、原生引用及完整正文全部吻合才确认送达,同时记录 `mentionVerification=unavailable`,不声称 `@` 已核验;明确不符的元数据仍拒绝。无精确回执的历史匹配继续要求原生 `@` 证据。
35
32
 
36
- 新接纳的验收条件在消息、Web、Owner 与工程准备入口共用合同:1–32 条,每条原始长度不超过 2000 个字符,去除首尾空白后不能为空。首阶段与后续阶段由各领域的准备合同处理,前序产物通过带类型、版本及生产阶段身份的 `handoff` 交接。新调查使用 v6,返回事实/判断/建议、未解决项和逐项验收意见;调查结束不代表开发或业务验收已经完成。已冻结的 v5 调查仍按原定义恢复。已取消任务仅保留历史,不再要求加载其退役的 Owner 阶段定义;暂停任务仍要求原冻结定义,以便后续恢复。
33
+ 更新运行实现后,启动时因未知操作而停住、没有人工问题且执行均已排空的任务,会按实现摘要和需求/控制版本补一次持久恢复唤醒。原任务先只读对账,不清除未知效果保护或重放原命令;同一实现的定时恢复和再次重启不重复唤醒。
37
34
 
38
- Owner 完成前核对当前成功阶段、逐项证据及必交文件清单。Host 将证据对应的验收项分派到生产领域,调用领域完成合同,全部通过才生成绑定当前决定和清单的 `businessValidation.status=accepted` 回执;Owner 只能汇总已接纳结果,不能用总结把调查不足改成满足。清单 `complete` 只证明结构、来源、版本与文件绑定有效;要求外发时仍须独立渠道回读,三者不能互相替代。
35
+ 开始、普通进度和内部诊断不会逐条群发。群内最终结果引用来源消息并按受信身份提及相关用户,正文直接写答复,不再重复被原生引用的消息原文;原始编号、诊断与过程留在任务详情。
39
36
 
40
- 新通用阶段 v6、外部操作 Owner v2 和文件投递 v2 均检查分派给本领域的验收项,混合流程不跳过业务检查。通用材料整理保留确定性快速路径,其他分派项使用原生模型零工具限定判断,并独立核验逐项结果及引用;缺少模型、超限、协议异常或证据不足不放行。调查沿用显式逐项意见,工程匹配冻结原需求和实际业务用例回执。工程消费者声明支持的交接类型/版本,目录结果合同从权威 Owner 合同派生。整体完成仍要求全部验收项满足,没有新增部分成功终态。
37
+ 人工介入按 `audience` 分流:缺省 `operator`,插件/任务/底座/登录/工具能力等技术问题保留在现有 Web 人工介入页,并发给当前 DWS 登录人私聊;身份从同一 profile 的认证回读取得,不取业务需求提出人。仅明确需要需求提出人回答的业务信息或业务决定使用 `requester`,才在原群询问。真人可在私聊引用申请回复结果;Host 核验原通知、会话、真实作者和当前申请版本,再沿原任务继续。无当前登录身份或未授权外发时保留 Web 入口,不退回业务群。私聊发送结果未知只回读,不重发。
41
38
 
42
- 失败诊断记录恢复类别、责任方及下一步,但不新增自动重试权限;未知外部结果继续先对账。旧定义按原摘要恢复,仅完成准入采用当前修正规则;回执分别保存冻结执行摘要与实际验收 policyDigest,不补造历史回执或重跑效果。本次合同调整不需要存储 schema 迁移,受理范围、职责和恢复边界见[节点合同](docs/api/workflow-node-contracts.md#workflow-v2-领域准备与交付合同)及[升级说明](docs/ops/workflow-storage-migration.md#本次领域合同调整的适用边界)。协议夹具验证不等于真实模型语义质量、部署或渠道验收。
39
+ ### 首版限制
43
40
 
44
- 消息处理详情显示“查询与答复”的状态、耗时和会话;结果正文与依据按需分页读取。取消问答时引用本人原问题;同一原消息有多个未完成事项时,先澄清选择,再核对身份和输入版本取消选定执行。
41
+ - 动态原生执行的显式后台调用校验并立即返回原生 job 身份,服务可供同一执行的后续工具使用;前台超时提升仍收集终态。后台 operation 在真实终态前不结算,执行结束或取消时停止残留 job、记录终态并排空所属进程。原生 job_list/job_output 固定为读取;旧版误记未知的缺失 job 读取只按原收据核验失败,不重放生产者命令。缺少可核验身份不能视为成功,已启动不等于服务就绪或业务完成。传统工作流节点仍保持既有后台限制。模型服务故障按[Provider 恢复机制](docs/spec/execution-provider-recovery-mechanism.md)有限退避,不重放已成功操作或未知效果。
42
+ - 通过原生 subprocess 服务创建的进程按该 provider 的 `terminate` / `waitForExit` 合同排空;无法证明排空时保留占位。这个保证不超过 provider 的实际受管范围。
43
+ - 动态任务执行不再挂接插件的文件路径拦截;任务日志及当前已授权文件沿原生文件工具、sandbox/approval 和实际操作系统权限读取。工作区与原任务/会话归属不变。
44
+ - 通用执行依赖实际 preset 能力;旧工程、UAT、Bytebase、文件交付等固定流程不再是新任务入口。保留源码和历史合同不代表动态任务已自动接通这些旧适配器。
45
45
 
46
- ### 任务产物发送到群聊
46
+ ## 工作目录与原生日志
47
47
 
48
- 明确要求“处理完成后把报告、Markdown、SQL或图片文件发到本群”时,工作进入同一个持久 Task。意图保存逐字引用的发送要求与完整文件清单;Owner 先生成并登记产物,再安排 `task-group-file-delivery`。目标绑定任务来源群与配置的 DWS profile。普通问答、Web-only 任务以及只要求生成文件的任务,不因此自动外发附件。
49
-
50
- `write-task-file` 可生成精确授权名称的 `.md/.txt/.sql/.csv/.json` 文件,UTF-8 内容最多 64 KiB。图片、Office、PDF 等传输保留真实原字节,但必须先有真实来源及已登记的产物;传输能力不提供这些格式的生成器,不能把文字改扩展名当文档。图片首版以可下载文件附件发送,不承诺聊天气泡预览。SQL 脚本交付不执行 SQL。
51
-
52
- 已有文件可通过 `import-task-file` 纳入当前 Task:Host 在 `workflow.generalFileRead` 配置固定 `root` 和精确 `readablePaths`,Owner 输入仅为 `{role,fileName,relativePath}`,同时受当前任务的角色/名称及 `readableFiles` 授权约束。Host 只读真实来源后冻结大小/SHA-256,执行时再次核对并复制原字节到受管快照;Owner 不提供绝对根或猜摘要。导入保留真实扩展名,不能靠改名转换格式。Office、PDF、图片已有可信文件时可直接登记交付;没有源文件时仍需实际生成器。
53
-
54
- 新任务的受管快照位于 `<Agent工作区>/tasks/<logicalTaskId>/outputs/<taskId>/<artifactId>/<fileName>`;升级前已有任务仍使用 `workflow.artifactDirectory/task-files/<taskId>/<artifactId>/<fileName>`。快照保留中文可读名称、需求版本、生产者和 SHA-256;文件元数据独立读回,二进制不塞入 JSON。当前 Host 默认每文件 20 MiB、每批 50 MiB、20 件,这些是本地保护值,不能当作租户平台上限。全部文件先预检,再逐件通过效果账发送;ACK 后查询真实消息并下载核对大小和摘要,全部必交文件通过才允许完成。未知发送保持待对账,不能重发来消除等待。
55
-
56
- 文件发送授权必须是当前消息的精确连续原文,可含句末标点或跨句;完整源句中的否定与其他群限制仍拒绝。Owner 使用通用写入时每轮仅安排一个阶段,核验产物后下一轮追加发送。复合验收项可联合读取该项明确绑定的当前任务成功阶段证据,各领域的结构和效果仍独立校验;投递回执不能代替业务结果证明。
57
-
58
- 本节描述源码能力,正式实例须按[本地部署与文件验收说明](docs/ops/resident-review-local-deployment.md#任务产物群聊文件交付切换与验收)完成安装和真实渠道回读。2026-09-29,PR #142 已合并,本地正式实例已安装合并版本,并完成专用群真实文件交付验收及重启后回读;结果见[最终验收报告](docs/acceptance/task-unified-file-storage/report.md)。其他实例仍须独立完成部署与渠道验收。
59
-
60
- ### 一个任务一个文件目录
61
-
62
- 新任务统一使用 `<Agent工作区>/tasks/<logicalTaskId>/`:`work/` 保存会话工作文件、JSON 工件、工程副本与验证记录,`tmp/` 保存受管检查和验收子进程的临时文件,`outputs/` 保存正式文件。逻辑任务 ID 复用现有任务关系;Web 重执行沿用同一个根目录,内部任务、节点及执行代次各自隔离。工程旁路证据位于源码副本之外。
63
-
64
- DSH 原始会话日志和公共附件仍由宿主管理。历史任务、工件及会话原路径恢复,不自动迁移;消息问答等非任务会话仍使用原职责目录。新 JSON 引用携带 `tasks/<logicalTaskId>/` 前缀,直接定位 `work/artifacts/`,无需额外索引。文件下载、发送和完成验收继续核对原有 descriptor、摘要和授权。目录约定覆盖插件受管入口;外部工具显式写入的其他绝对路径与公共缓存不因此被重定向。
65
-
66
- 升级后备份必须同时保留控制库、原工件/会话目录和 Agent 工作区的 `tasks/`;部署参数与回退边界见[任务目录部署说明](docs/ops/resident-review-local-deployment.md#任务文件统一目录的部署与备份)。
67
-
68
- 启用 workflow 后,在线切换 Agent 工作区会被拒绝,避免会话和工件落到不同根;同根配置及模型设置仍可更新。需要换根时先停稳并制定完整迁移方案,本次不提供自动迁移。任务备份明确排除受管工程源码副本中的可再生 `node_modules`,恢复后按锁文件重新安装依赖。
69
-
70
- 只读资源通过 `workflow.directQueries` 登记,由 `permissions` 显式声明 Agent 自身的资源授权,与发送者身份无关。不同群成员使用同一 Agent 职责范围,每次调用仍重新校验资源权限。数据库默认使用低权限只读身份;用户明确指定使用现有 UAT 账号时,仅对显式登记的 UAT 资源启用 Host 强制只读事务模式。模型始终不能获得连接凭据或提交任意 SQL。配置合同见 [Agent 查询工具](docs/api/agent-query-tool-contract.md),切换步骤见 [本地部署说明](docs/ops/resident-review-local-deployment.md)。
71
-
72
- 旧材料分析、固定规划/执行循环及逐次只读能力阶段退出新入口;切换前必须确认没有活动引用。历史记录继续按原状态读取,不重放旧命令。以下常驻主会话与叶子 Goal 说明适用于尚未切换的旧 Resident 群。
48
+ ```text
49
+ <Agent工作区>/
50
+ .dsh/task-sessions.sqlite 默认动态控制库
51
+ .dsh/task-sessions.sqlite.initialized
52
+ tasks/.session-routes/ 原生日志持久路由
53
+ tasks/<taskId>/materials/ 共享材料
54
+ tasks/<taskId>/outputs/ 任务产物
55
+ tasks/<taskId>/tmp/
56
+ tasks/<taskId>/ 原生工作区及所有任务会话 header.cwd
57
+ tasks/<taskId>/work/ 工作文件容器
58
+ tasks/<taskId>/.dsh/sessions/ 该任务全部原生会话日志
59
+ groups/<groupId的摘要>/ 群会话 cwd
60
+ ```
73
61
 
74
- 插件直接复用以下 DSH 机制:
62
+ 任务与执行的日志由官方 JSONL 后端直接写入任务目录,保持原生 replay、恢复和压缩能力;不是日志副本。群会话使用新 profile 配置的原生持久化根;旧会话不接入当前运行时,不能一概认定在 `%DSH_HOME%/sessions`。会话 ID、路由、控制库与工作目录需一致恢复。在线更换 Agent 工作区被拒绝;离线搬迁与恢复要求见[清洁启动 Runbook](docs/ops/task-session-clean-start.md#回退)。
75
63
 
76
- - `Session`:每个群一个常驻主会话,每个 Task 一个独立叶子会话。
77
- - `subagent`:主会话只协调,叶子会话独立执行任务。
78
- - `Goal`:维持叶子任务的持续执行、恢复和完成状态。
79
- - `systemPrompt.section`:向主会话注入群名称、群 ID、群职责与决策协议;向叶子会话注入任务流程和证据要求。
80
- - Agent Registry 与原生 descriptor:在 DSH Web 中展示并打开常驻会话、叶子对话和轨迹。
81
- - 默认模型、推理深度与权限 preset:由 DSH 原生服务保存和应用。
82
- - storage domain:持久化群订阅、消息、Task、可靠投递、人工介入事项和告警。
83
- - attachment service:将钉钉图片作为 DSH 原生多模态附件传入会话。
64
+ ## Web 看板与 HTTP 接口
84
65
 
85
- 插件只补充钉钉渠道和群聊工作流特有的能力:DWS 订阅与补拉、消息去重排序、任务准入与关联、可靠 outbox、人工介入、任务看板和运行告警。
66
+ 任务页展示一项完整任务、唯一任务会话和动态执行列表;支持独立新建任务,不把内部执行拆成多个业务任务。详情包含结果、执行状态、日志入口和未决阻塞,不展示补充需求与取消任务控件;群消息续办和后端控制 API 仍保留。模型会话入口是阅读上下文,不是绕过 Host 直接修改任务的控制口。
86
67
 
87
- UAT 部署、生产发布、数据变更与 UAT 同提交重建采用显式目标白名单和受信平台端口。UAT 部署只确认精确提交在目标环境运行;业务回归、提测与验收另行记录。 普通 UAT 构建在完整同提交扫描确认流水线已失败、且无成功或进行中的等价流水线时,保留失败收据并将节点及运行收口为失败;读取异常和未决状态继续只读对账,不重发原操作。 同提交重建也核对超时前已成功构建并部分部署的精确镜像来源;整条流水线失败不抹去已验证的构建事实。生产发布在创建 Tag 前等待真人审批,并逐段核对提交到运行镜像的来源链;数据变更经本机 PostgreSQL 连接对精确 UAT 库审查 SQL、事务演练并回滚,生产结构从天翼云只读副本回读;Bytebase 先创建 Sheet/Plan/Issue,在 Assistant 任务页真人审批后才创建 Rollout/Task 并执行。配置、平台只读检查与执行后回读的要求见[本地受信平台接入说明](docs/ops/trusted-platform-workflows.md);缺少任何必要能力时,流程目录保持不可发起。
68
+ - `GET /state/tasks/:taskId/detail`:当前任务及只读历史详情
69
+ - `GET /state/tasks/:taskId/executions`:动态执行或历史执行记录
70
+ - `POST /tasks`:Web 新任务,须配置受信 `webActorId`、指定订阅群并提供稳定 `requestId`
71
+ - `POST /tasks/:taskId/context`:补充要求,携带 `expectedRequirementRevision` 与 `expectedControlRevision`
72
+ - `POST /tasks/:taskId/cancel`:取消,携带 `expectedControlRevision`
88
73
 
89
- ```text
90
- DWS 群消息
91
- → dingtalk-dsh-assistant
92
- → DSH resident 主 Session(判断、沟通、协调)
93
- → DSH leaf Session + Goal(独立执行)
94
- → 主 Session(组织结果)
95
- → outbox + DWS 回读确认
96
- → 原群引用回复并 @模型从任务历史选出的相关参与人
97
- ```
74
+ Web 写入限制本机合法请求来源;操作者由 Host 配置,不接受模型提供身份。CAS 冲突须重新读任务,不能覆盖新版本。Web 的原始操作意图与来源同事务保存,重启不会交给群模型改判。
98
75
 
99
- 不依赖 Agent Studio,也不要再并行启动另一套会话或任务 Runtime。
76
+ 旧 `/workflows/*`、`/config/workflow-variables*`、`/config/workflow-bindings*`、工作流目录及旧阶段/重跑/暂停恢复/归档等写入口返回 HTTP 410。旧任务写入返回 `LEGACY_TASK_READONLY`;历史读取不赋予恢复权限。完整退役范围以 `http.js` 为准。
100
77
 
101
78
  ## 包结构
102
79
 
103
- - `packages/dingtalk-dsh-assistant`:核心业务插件。负责 DWS 接入、群与 Session 绑定、消息处理、Task 调度、阻塞时的人工介入、可靠回复和配置页面。
104
- - 任务表格同步:可在插件设置中绑定钉钉在线电子表格的一个工作表,由 Resident 纯脚本每 3 分钟将全部未归档 Task 全量覆盖写入;同步不调用模型,状态与失败原因在设置页单独显示。
105
- - `packages/dingtalk-dsh-observer`:DSH Web 展示扩展。提供群聊会话、任务看板、归档任务、人工介入和告警页面。
106
-
107
- 同一任务通过 Web 再次执行时,看板保持一张卡片。详情只展示当前完整计划的有效步骤与结果:保留未受影响的成功前段,重执行更新对应步骤,已移除步骤从列表删除,新增步骤按当前计划加入。不同阶段的同名步骤按工作流分组独立展示,并显示真实开始时间与本次耗时;需求变化后旧结果失效。卡片与详情使用最多32字符的简短标题,详情可展开完整任务目标;卡片内步骤列表使用中文名称及本次节点耗时。详情不提供历史切换,旧任务链接打开当前详情;完整正文、产物和当前步骤会话仍可读取。关联以已保存的重执行事件为准,不按相似标题合并。新的追加、取消、重执行和归档须携带当前执行版本;归档核对整项任务均结束且操作排空,底层运行记录保留。接口见[工作流节点契约](docs/api/workflow-node-contracts.md#任务汇总与当前完整详情)。
80
+ - `packages/dingtalk-dsh-assistant`:DWS 传输、群配置、任务会话服务、动态 SQLite 账与设置页面
81
+ - `packages/dingtalk-dsh-observer`:任务、来源消息、结果、执行会话和历史只读看板
82
+ - `task-resident-runtime.js`:不含旧调度器的 resident 传输/配置边界
83
+ - `task-session-service.js`、`task-session.js`:来源接纳、群关联、任务统筹与恢复
84
+ - `execution-session.js`:复用 DSH create/resume、preset、租约、工具与排空
85
+ - `dynamic-task-store.js`:事务账、效果锁、幂等回执、唤醒及通知
86
+ - `task-session-persistence.js`:官方原生日志的任务级持久路由
87
+ - `docs/ops/task-session-clean-start.md`:切换、核验、人工对账与恢复
108
88
 
109
- 旧版任务归档清理开发目录前核验提交已包含在 origin 当前公布的分支中,同名分支已推进或删除不等于代码未保存;无法证明提交保留、脏代码或未登记文件仍拒绝清理。目录已移除时,缺少归档摘要的登记文档只能从准确登记提交的普通文件恢复到任务专属归档目录,不使用同名文件猜测。预检不写文件,目标冲突、缺源或摘要不符会停止。
89
+ 旧 workflow/Goal/叶子调度文档仅供历史维护取证,不是当前 resident 的操作指引。不得同时装配旧 `workflow-service`、旧 Resident scheduler 或独立 execution 恢复进程写同一实例。
110
90
 
111
- 登记后在原分支继续开发的提交必须是登记提交的后代且已保存到远端,才可归档;路径、Git目录、主库、分支和 origin 身份仍须一致。清理进度记录本次核验的实际提交,文档复制后再次固定核对该提交,期间出现新提交则停止删除。
112
- - `.dsh/profiles/resident`:resident Runtime 的参考 profile 与 Cordis patch。
113
- - `.dsh/profiles/web`:Web contribution 的参考 profile。
114
- - `docs/spec`:关键状态机和工作流设计说明。
115
- - `test`:插件单元测试和 Runtime 契约测试。
91
+ 发布清单采用当前入口依赖的显式白名单。退役工作流、私人平台适配器、历史业务源码和个人技能均不进入 Assistant npm 包,旧 `./execution` 与 `./platform-host` 导出已移除;它们只保留在源码中作历史取证。通用群消息、资源清理和当前来源规则独立成模块,避免无关的旧引擎被传递打包。`test/task-session-package-native.test.js` 实际打包、解压,以已安装依赖运行解压产物的任务和 resident 健康检查;不等于已经部署用户实例。
116
92
 
117
93
  ## 环境要求
118
94
 
119
95
  - Windows 11 与 PowerShell 7。
120
96
  - Node.js 24 或更高版本。较低版本缺少 DSH Session JSONL 持久化所需的 zstd API。
121
- - 已安装 DSH `0.1.2-rc.1`,并能正常启动 `dsh web`。Assistant、Observer 与 DSH 核心包必须保持该版本边界,不能混装 `0.1.1-rc.2` 依赖树。
97
+ - 本分支适配 DSH `0.2.1-alpha.2`(用户指定的预发布版本),并要求能够正常启动 `dsh web`。Assistant、Observer、DSH 核心及服务 peer 依赖必须保持相同版本,不能混装旧依赖树。升级与会话格式边界见 [DSH 兼容说明](docs/ops/dsh-0.2.1-alpha.2-compatibility.md)。
122
98
  - 已安装并配置所选模型对应的 DSH provider。只有使用 ChatGPT/Codex 订阅时才需要 `dsh-codex-connect`。
123
99
  - 已安装并登录 DWS。只有启用真实钉钉订阅时才需要。
124
100
 
@@ -126,38 +102,40 @@ DWS 群消息
126
102
 
127
103
  ### Skill 文件路径
128
104
 
129
- DSH 根据 Session 的 Agent 工作目录发现项目级 Skill,同时加载用户级 Skill。默认扫描顺序如下,靠前的同名 Skill 优先:
105
+ 插件不内置个人 Agent 设定、技能正文、业务技能名单或业务目录。技能使用已配置 DSH 原生 `dsh-skill`、`dsh-skill-filesystem`、`dsh-tool-skill`;没有配置这些能力时不会自动安装个人技能或回退加载仓库历史工作流。
130
106
 
131
- 1. `<Agent工作区>\.dsh\skills\<skill-name>\SKILL.md`
132
- 2. `<Agent工作区>\.agents\skills\<skill-name>\SKILL.md`
107
+ DSH 根据 Session 的当前工作目录发现项目级 Skill,同时加载用户级 Skill。项目根是包含 `.git` 的最近祖先;没有 `.git` 时就是当前 Session cwd。每任务拥有独立的根目录 cwd,任务内所有会话共享此 cwd,因此不能假定 `<Agent工作区>/.agents/skills` 总会被自动发现。默认扫描顺序如下,靠前的同名 Skill 优先(不同 preset 的同名覆盖仍按 DSH 原生 scope 规则):
108
+
109
+ 1. `<项目根>\.dsh\skills\<skill-name>\SKILL.md`
110
+ 2. `<项目根>\.agents\skills\<skill-name>\SKILL.md`
133
111
  3. profile 显式配置的 `customSkillDirs`
134
112
  4. `%DSH_HOME%\skills\<skill-name>\SKILL.md`,`DSH_HOME` 默认是 `%USERPROFILE%\.dsh`
135
113
  5. `%DSH_AGENTS_HOME%\skills\<skill-name>\SKILL.md`,`DSH_AGENTS_HOME` 默认是 `%USERPROFILE%\.agents`
136
114
 
137
- 给本机所有 DSH 项目共享的 Skill,推荐安装到 `%USERPROFILE%\.agents\skills`;只服务当前 Agent 工作区的 Skill,推荐安装到 `<Agent工作区>\.agents\skills`。DSH 不扫描 `%USERPROFILE%\.codex\skills`,仅安装在 Codex Skill 目录中的 `write-pr`、`dingtalk-*` 等 Skill 不会进入 resident 或叶子 Session。
115
+ 给本机当前用户的 DSH 项目共享的 Skill,可安装到 `%DSH_AGENTS_HOME%\skills` 或默认 `%USERPROFILE%\.agents\skills`。只服务某个个人 Agent 的技能,配置该 Agent preset 内 `dsh-skill-filesystem` 的 `customSkillDirs` 为个人技能包的绝对目录;需要隔离时同时设 `includeDefaultRoots: false`。这些路径及正文保存在个人配置和插件仓库之外,不修改插件包。DSH 不扫描 `%USERPROFILE%\.codex\skills`。
116
+
117
+ 复制时必须保留完整的 `<skill-name>` 目录,不能只复制 `SKILL.md`,因为 Skill 可能引用同目录下的 `references`、`scripts` 或其他资源。原生目录只提供名称和描述,正文在 `skill(name)` 调用后才进入对应会话。任务会话据此分派小目标,可通过 `task_delegate.skillNames` 传递相关名称;独立执行会话自行加载适用入口,再通过实际文件工具按需读取引用资料。群会话只负责路由,不加载业务技能。
118
+
119
+ Skill 不提供动作授权,不恢复固定 DAG、参数绑定、审批门槛或产物格式验收;任务会话仍负责整体完成判断。原生 loader 仅读取注册表与正文,附属脚本不会由 `skill` 自动执行。插件将所选可信 preset 中挂载的准确 `skill` 工具对象作为只读入口,后续同名替换不能继承任务会话调用许可或执行会话的只读效果分类;不要配置不受信任的 preset 插件代码。普通加载失败可纠正,不应生成未知外部写入。
138
120
 
139
- 复制时必须保留完整的 `<skill-name>` 目录,不能只复制 `SKILL.md`,因为 Skill 可能引用同目录下的 `references`、`scripts` 或其他资源。目录被发现只表示 Skill 已进入会话目录;模型仍会在任务命中触发条件后调用 `skill` 工具加载完整指令。验证是否真正加载时,应在 Session JSONL 中同时确认对应的 `tool/call` 和 `isError: false` 的 `tool/result`,不能只检查文件存在。
121
+ 验证是否真正加载时,应在任务及执行 Session JSONL 中分别确认廉价目录,以及实际 `tool/call` / 成功 `tool/result`;还应确认无关正文没有自动注入、执行能读取所需引用资料、任务和执行会话均能使用已配置的原生文件与终端工具,取消、提交和租约变化仍阻止失效动作。`test/task-session-skills-native.test.js` 使用真实 DSH registry、filesystem provider、tool-skill 和会话运行时覆盖这些边界;它不代表具体个人技能的业务效果或真实平台发布已验证。
140
122
 
141
123
  ## 安装到 DSH
142
124
 
143
- 从 0.5.x 升级到 1.0.0 前,先阅读[大版本升级边界](docs/ops/npm-release.md#100-升级边界)和[更新日志](CHANGELOG.md)。旧存储需要独立检查,不能仅替换包后直接打开。
125
+ 2.0.0 起发行包包含任务会话架构切换。既有实例必须先按[任务会话清洁启动 Runbook](docs/ops/task-session-clean-start.md)停止旧调度、排空实际执行并审阅历史未决效果。历史版本安装方法仍见[大版本升级边界](docs/ops/npm-release.md#100-升级边界)与[更新日志](CHANGELOG.md)。
144
126
 
145
127
 
146
128
  推荐让 Web、resident Runtime 和看板运行在同一个 DSH Web 进程中,避免两个进程同时写同一份 Session JSONL 和 storage domain。
147
129
 
148
- 正式版本发布后,使用 DSH 原生插件命令安装根发行包;它会把 Assistant Runtime、Observer 看板和对应 bundle patch 一并装入 `web` profile。生产或验收环境建议固定版本:
130
+ 全新安装使用根发行包;它会把 Assistant Runtime、Observer 看板和对应 bundle patch 一并装入 `web` profile。以 2.0.0 为例,生产或验收环境固定版本:
149
131
 
150
132
  ```powershell
151
- dsh plugin --profile web add dingtalk-dsh-assistant@0.5.8
133
+ dsh plugin --profile web add dingtalk-dsh-assistant@2.0.0 --save-exact
152
134
  ```
153
135
 
154
- 需要跟随 npm 最新版本时可省略 `@0.5.8`。安装完成后必须重启 `dsh web`,仅看到依赖安装成功不代表插件 Runtime 已加载。
136
+ 安装完成后必须重启 `dsh web`;仅看到依赖安装成功不代表插件 Runtime 已加载。已有 profile 升级前须先确认安装形态,不能在仍直接依赖两个内部包时只添加根包。
155
137
 
156
- 版本历史见 [CHANGELOG](CHANGELOG.md),发行资产见 [GitHub Releases](https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases)。设置页会通过 GitHub Release 检查新版本;“设置 → 插件 → 钉钉个人助理”的“版本与更新”卡片显示版本状态,并提供手动检查与更新命令复制入口。检查失败会明确显示错误,不会误报为最新版本。升级使用:
157
-
158
- ```powershell
159
- dsh plugin --profile web add @zzusp/dingtalk-dsh-assistant@latest @zzusp/dingtalk-dsh-observer@latest --save-exact
160
- ```
138
+ 版本历史见 [CHANGELOG](CHANGELOG.md),发行资产见 [GitHub Releases](https://github.com/HiQ-AI/dingtalk-dsh-assistant/releases)。设置页会通过 GitHub Release 检查新版本;“版本与更新”卡片提供可复制的升级提示词,引导先核对 profile、在途任务及[大版本升级边界](docs/ops/npm-release.md#100-升级边界),再按[本地部署规程](docs/ops/resident-review-local-deployment.md)安全切换。根包安装与旧式双内部包安装的精确命令见[安装手册](docs/manual/install-and-configure-dsh-web.md#二安装或升级正式版本)。检查失败会明确显示错误,不会误报为最新版本。
161
139
 
162
140
  升级后重启 DSH Web,并依次确认:profile 中的包版本、`GET http://127.0.0.1:18998/health`、设置页/运行看板、真实群消息收发。四层证据不能互相替代。
163
141
 
@@ -174,8 +152,8 @@ dsh plugin --profile web add @zzusp/dingtalk-dsh-assistant@latest @zzusp/dingtal
174
152
  ```powershell
175
153
  git clone https://github.com/HiQ-AI/dingtalk-dsh-assistant.git
176
154
  Set-Location .\dingtalk-dsh-assistant
177
- pnpm install
178
- pnpm test
155
+ pnpm install --frozen-lockfile
156
+ node --test test/dynamic-task-store.test.js test/task-session-service-native.test.js test/task-session-http-integration.test.js
179
157
  ```
180
158
 
181
159
  #### 2. 将插件加入 DSH Web profile
@@ -209,6 +187,8 @@ pnpm test
209
187
 
210
188
  把 [`.dsh/profiles/resident/cordis.patch.yml`](.dsh/profiles/resident/cordis.patch.yml) 中的 resident 配置按需合并到实际使用的 Web profile patch。Web 基础 bundle 已包含 storage 相关插件,只覆盖 `storage-json` 配置并插入 `dingtalk-dsh-assistant/resident`,不要重复插入同名 storage 项。
211
189
 
190
+ 参考 patch 不替代任务控制库初始化。首次使用须在实际 resident 配置中明确设置 `taskSessions.dbPath`、`instanceId` 与经过确认的一次性 `initialize: true`;确认初始化成功后改回 `false`。必须显式配置 `ownerActorId`、`webActorId` 及现场记录的 `ingressEpoch`;不接入旧任务库。完整配置字段与停机边界见[清洁启动 Runbook](docs/ops/task-session-clean-start.md#必填配置和时间边界)。
191
+
212
192
  仓库模板有意保持以下安全默认值:
213
193
 
214
194
  ```yaml
@@ -220,11 +200,19 @@ dws:
220
200
 
221
201
  不要把个人群 ID、DWS profile、Agent 名称、工作目录或职责写入仓库模板;这些内容应保存在本机 DSH 配置和插件 storage 中。
222
202
 
203
+ ### 群回复署名
204
+
205
+ Agent 设置中的可选 `replySignature` 恢复读写;profile 的 `agentReplySignature` 仅在存储未设置时初始化。留空不追加,不从名称、群职责或历史报告推断私人身份。
206
+
207
+ Host 在完成、业务提问和实质性话题回复的完整正文组装后、通知持久化前统一落款一次。确认及中间消息不追加署名;模型仅生成正文。仅清理与当前配置精确相同的独立署名段落,保护引用、代码和业务列表,不替换其他姓名。通知的 digest、发送、重试和重启恢复沿用持久化正文,配置修改只影响新通知。
208
+
209
+ 群职责继续承担业务范围、授权边界和语气要求。部署后应核实 Agent 署名配置,再清理现场职责中的重复署名要求;代码修复不会自动修改现场职责或补发历史通知。详细边界见[通用 Agent 身份边界](docs/spec/generic-agent-identity.md)。
210
+
223
211
  #### 4. 安装 profile 依赖
224
212
 
225
213
  ```powershell
226
214
  Set-Location "$env:USERPROFILE\.dsh\profiles\web"
227
- pnpm install
215
+ pnpm install --frozen-lockfile
228
216
  ```
229
217
 
230
218
  #### 5. 启动 DSH Web
@@ -238,373 +226,59 @@ pwsh -NoProfile -File .\scripts\start-web.ps1
238
226
 
239
227
  `scripts/start-web.ps1` 使用当前用户的 `%USERPROFILE%\.dsh` 作为默认 `DSH_HOME`;若需要隔离 profile,可在启动前显式设置 `DSH_HOME`。脚本从当前项目根启动,并自动发现 `PATH` 中的 Node.js 和全局安装的 DSH。
240
228
 
241
- ## 首次配置
242
-
243
- 启动后,在 DSH Web 的“设置 → 插件 → 钉钉个人助理”中完成配置:
244
-
245
- ![已选中的钉钉个人助理插件配置](docs/manual/images/dsh-web-plugin-selected-annotated.png)
246
-
247
- 1. 设置 Agent 名称和别名,多个名称使用英文逗号分隔。群职责定义本群身份关系、负责范围和介入要求;需要作为任务称呼的名字同时加入别名配置。DWS 登录人姓名不享有特殊准入或静默规则。
248
- 2. 设置 Agent 工作区绝对目录。DSH 会从该目录原生发现 `AGENTS.md`。
249
-
250
- 新会话在该配置目录的 `session-workspaces/` 下按插件实际职责自动分配:消息问答、任务负责、任务执行、群聊常驻、消息归类、话题决策、结果审阅。名称使用事项或群名加职责,不展示内部编号。恢复历史会话保持原目录;子代理沿用父会话目录。消息意图判断直接调用模型,不创建原生会话或目录。
251
-
252
- 职责目录继承根目录指引依赖 DSH 原生 `agent-instructions.projectRootMarkers`:Git 工作区可使用 `.git`;普通工作区应将 `AGENTS.md`、`CLAUDE.md` 或已有的根标记加入该配置。插件不复制指引、不写入个人身份,也不覆盖宿主的指引配置。
253
- 3. 设置默认模型、推理深度和叶子任务并行上限,默认并行上限为 5。
254
- 4. 按需设置网络代理。
255
- 5. 已切换到 `workflow-v2` 的群使用代码注册的任务流程;配置页展示只读流程目录、消息处理阶段、准入状态、定义版本及节点职责。`GET /state/workflows/catalog` 提供该目录,不返回旧提示词正文。未切换群的旧版叶子任务配置折叠保留,历史 `taskPrompts` 数据不迁移或删除;只配置新流程群时,保存通用 Agent 配置不提交旧提示词字段。
256
- 6. 查询已有任务进展由平台内置 `task-progress-query@1` 即时流程处理:校验同群范围、检索候选、回读状态与交付标记、生成答复。定义见目录接口的 `builtInWorkflows`,四步摘要写入消息命令结果供审计;它不会创建任务看板任务。候选超过 8 项时回复明确说明截取范围,标题匹配不等于业务归属已确认。
257
- 7. 已切换群的身份识别读取当前 Agent 配置的 `agentNames` 名称和别名,状态问句、交办准入和恢复使用同一份配置;改名后不保留旧名称捷径,未配置不默认任何本机身份。通知首次准备时读取当前“会话职责”的确定性回复规则:明确指定唯一代回署名(例如 `- 资料助理代回`)时,持久正文末尾空一行附该署名;未指定则不自动添加,多个不同署名拒绝。要求引用回复时不允许缺来源而退化为普通群发。已保存通知的正文保持不可变,群职责后来调整不会阻断其发送或回读。第三方任务创建进展同步会静默入账,不生成追问或业务任务;引用能沿已送达通知定位唯一话题时,消息绑定该话题,否则在收信箱显示待归类。已完成的纯排查旧任务再次收到同一问题报告且没有明确修复交办时,先询问是否实施修复;肯定答复才准入新的工作流任务,不改写旧任务。澄清答复折叠进原消息后,结清答复留下的归类屏障;启动恢复以已送达澄清通知、引用消息和已解决请求三项持久证据补挂原话题,不重复派发业务任务。
258
- 8. 新消息完成话题关联后,先等待本群已收消息完成归类;同话题消息进入同一个批量意图判断,不同话题各自判断。判断中到达的同话题新消息会使旧候选失效并集合重判。已执行中的任务收到补充时,已应用动作保留,剩余动作重新判断;来源编辑使旧话题约束失效。原任务发送者明确说“暂停/取消/恢复这个任务”且目标 Task 已绑定时,可经过 Host 与持久账双重授权后越过无关消息的归类等待。新 Task 与负责会话先原子落账,初始没有业务阶段;意图节点只交接目标、验收和约束,唯一的 Task Owner 再按受信目录初始化或调整计划。Owner 可组合排查、方案、工程、UAT 和通用能力,每个阶段由独立 Run 执行,并能读取当前 Task 已成功阶段的真实产物。阶段成功不自动等于任务完成;未解决的限制或缺来源证据会阻止整体完成。任务级暂停、取消与恢复阻止旧确认或后续 Run 越过控制状态。IM 与 Web 补充均递增 Task 要求版本,运行中的旧 Run 输入保持冻结,Owner 据新版要求调整后续计划。已完成任务仅更改报告语言时,Owner 基于已核验产物重新报告,不重跑流程;纠正须指定精确报告身份。所有 Task 均可在授权范围内调用 `task-general-capability`,包括受信本地 Markdown 文件生成及独立回读;缺少实际调查、写入或目标验收能力时明确阻塞。旧 `task-general` 和 `task-general-intake` 仅供历史 Run 恢复。迁移及本地验证见[执行底座运维说明](docs/ops/execution-foundation-local.md)。
259
- 9. Task 看板区分流程结果与负责会话的整体验收;最终完成须覆盖全部当前验收项和真实阶段证据。负责人接纳的最终报告经原 Outbox 发送、ACK 与回读,单个流程成功不先冒充整体完成。历史承接和阶段结果保留各自证据,新增目标不自动撤回旧消息。通知撤回或补发仍经 `/workflows/notifications/operations` 逐条预检、执行与回读;群负责人授权消息须单独一行写 `撤回通知 <通知ID>` 或 `补发通知 <通知ID>`。ACK 后或外部结果未知时只查询原操作,不重发。
260
- 6. 运行看板中的新任务点击后查看节点执行详情:每个节点的状态、等待原因、产出记录和任务最终结果。节点确有模型会话时可从该节点打开会话记录;旧任务继续使用原有会话入口,卡片上的任务进度样式不变。新发起的工程发现任务由“检查并提出修改”节点按需列路径、搜正文、分段读取文件,不再建立整仓目录索引或单独选文件;Host 在实际写入前校验准入目录和文件哈希。节点领取次数仍由持久上限约束。文件发现、读取及工件交接不设置插件层字节上限,模型和运行环境的实际容量仍需由节点状态回读。
261
-
262
- 叶子的 `plan-confirmed` 必须用 `workflowAssessment` 绑定当前流程组合,说明沿用证据、不适用步骤以及例外依据。流程例外必须引用固定 Topic 中明确提出该要求的原始消息;主会话生成的目标、验收标准或旧摘要不能覆盖流程。常驻主会话结合可用流程索引和选择原因核查是否漏选,按需读取候选流程;允许有明确理由的无匹配和多个流程组合,不固化业务任务类型。读完已选流程后审阅计划,冲突时返回结构化拒绝。计划、阶段、审阅提交及最终落盘都核对当前启用流程的修订号;配置修改、停用或删除立即使受影响旧审阅失效,无需等待叶子重载。失效待审项归档到执行事件,历史证据保留,重新规划后才可推进。`stage-completed` 每次只提交上一检查点 `remainingItems` 的第一项,`completedItems` 不是累计历史。 checkpoint 按 kind 使用同源契约:plan-confirmed 才允许 workflowAssessment;stage-completed 必须有 stageTask 和非空 evidence;scope-conflict/evidence-gap/risk-changed 可用 stageTask/stageId 标明受影响阶段,但 completedItems 必须为空,不能推进阶段。工具 JSON Schema 由同一 Zod 投影到 DSH 支持的子集,kind/status 分支保留;长度及复杂关联约束由执行时 Zod 精确校验并返回字段路径。错误推进会得到 reviewStatus=rejected 的报告回执及具体缺口,原进度不变;核对该项真实证据并按回执修正,确认接受后再推进下一阶段。
263
- 6. 通过群名称模糊搜索添加常驻群,并为每个群配置会话职责。
264
-
265
- 确认页面的环境检查显示 DWS 已安装、已登录后,再在实际 profile 中启用:
266
-
267
- ```yaml
268
- dws:
269
- enabled: true
270
- writesAuthorized: false
271
- ```
272
-
273
- 先验证真实消息能够进入固定 resident Session,再将 `writesAuthorized` 改为 `true` 开放群聊回复。修改 profile 后需要重启 DSH Web。
274
-
275
- 完整的逐步安装、页面字段说明和“先收后发”验收流程见[安装插件并在 DSH Web 中完成配置](docs/manual/install-and-configure-dsh-web.md)。
276
-
277
- ## 群聊工作流
278
-
279
- 流程契约使用存储 domain v9。已有 v8 数据须按[工作流存储迁移](docs/ops/workflow-storage-migration.md)进行零写自检、独立目标转换和真实 SDK 回读;v6/v7 先按[旧 Topic 迁移](docs/ops/topic-storage-migration.md)得到 v8,再转换到 v9。不能直接用新 Runtime 打开旧存储。活动任务迁移后停在系统等待,显式恢复并重新确认结构化计划后才继续。下文说明代码契约,不代表该版本已发布或本机 profile 已升级。
280
-
281
- 任务负责人读取成功工程阶段时,Host 先核对同一运行、候选和提交的交付证明,再提供构建检查、本地验收要求、业务结果和清理收据的原始节点引用;PR 结果不单独代表业务验收通过。此材料展开不改变已冻结的工作流或重跑成功节点。
282
-
283
- 节点接口与恢复语义见[工作流节点契约](docs/api/workflow-node-contracts.md)。计划以稳定 criterionId/stageId、来源和版本为准;阶段产出引用产物及证据,完成提交包含逐项验收。报告 received、审阅批准、业务应用和通知送达分别记录。完成结果与通知意图同次持久化,通知失败恢复原意图,不重做业务。
284
-
285
- 已接纳 Decision 的已知本地瞬时存储错误最多尝试三次;未知错误进入 blocked,保留原 operationId 和冲突保留记录。普通消息重试不能解锁未知结果,Host 必须对账后按原操作恢复。Task 取消先保存 stopRequest,未确定的外部动作继续对账,不能把“取消已请求”显示成副作用已撤销。执行许可与 Task 状态分离,等待审阅时停止叶子并释放许可,恢复必须重新排队取得许可。
286
-
287
- 材料清单、版本和完整性检查由 Host 提前计算;只读注册检查器目前包含产物 SHA256 核验,摘要匹配不代表业务验收通过。外部动作账本只约束已注册适配器,未接入的任意 shell、SQL、部署不会自动获得去重或资源锁保障。
288
-
289
- ### 常驻主会话
290
-
291
- 每个群唯一绑定一个 resident Session。群名称、群 ID、职责和稳定决策协议通过 DSH `systemPrompt.section` 注入。消息明确指向已配置的 Agent 名称/别名、使用 `cc:`,或明确确认此前“是否需要我处理”的询问,并形成职责范围内的可验证目标时,主会话可以创建 Task;未明确指名但判断事项应形成任务时,主会话先在群里询问“这个事项是否需要我处理?”,收到肯定答复后再结合原消息和后续补充创建。Host 在接受 `new-task` 时再次校验群职责非空,并要求依据消息明确指向 Agent,或引用本插件此前持久化的 `task-proposal` 询问,不能只信任模型结论。主会话只负责选择 Task 路由;Runtime 使用原始群消息生成来源证据信封交给叶子,主会话生成的根因、完成度、方案优劣或排除性判断不作为叶子事实。
292
-
293
- 每条新消息先可靠持久化到 Inbox,接收接口随后返回;Resident 使用 `group_topic_route_submit` 对冻结的消息批次先拆分可独立补充、取消、交付、验收和反馈的事项 unit,再分别匹配持久 Topic。一个消息可包含多个 unit,每个 unit 有精确来源、唯一动作 owner 和自己的 `unitId + unitRevision`;四个属于同一交付目标的验收点保持一个事项,独立需求分别处理。超长路由原文通过 `group_topic_route_context_get` 按固定坐标读完,Host 在完整读取、范围覆盖和归属校验前不会接受部分路由。Topic 跨 turn 存在,已归类的无关话题不会使当前话题决策失效。已有 Topic 可与待路由批次交错准备决策;同群模型仍串行,有竞争时每个请求执行一个原生步骤并在工具结果落稳后让出。提交仍核对全部未知输入;返回 `routing-required` 后 Host 保留未接纳草稿,路由完成即按当前来源、版本和回复审阅结果重新校验提交,无需模型重算。同话题新增输入使旧草稿失效,重启则按当前输入重建。无限未分类输入下不承诺提交等待有固定上限。已接受的业务意图仍独立恢复;归类、Topic 决策与 Task 执行分别维护进度,DWS 补拉完成只证明可靠接收。
294
-
295
- 路由工具成功时只返回 `status` 和 `requestId`(重提已落盘请求另有 `recovered: true`),不在工具输出中复制待决策 Topic 的正文或临时 ID 映射。Host 将各 Topic 的 `[GROUP_TOPIC_DECISION]` 分别投递到常驻会话;`accepted` 仅证明路由落盘,不代表决策、Task 或群回复已完成。决策首屏优先提供本次事项、直接引用、原始点名和 Topic 摘要;同一消息的引用与原文只提供一份。超长段使用 `group_decision_context_get(requestId, section, offset)` 按固定请求连续续读;历史使用 `group_topic_context_get` 按需读取。
296
-
297
- Topic 的 `title` 是对齐 Task 名称的 8–20 字短语,最多 30 字,细节保存在 `summary`。v6 迁移形成的历史 Topic 如果摘要为空,Runtime 会先让 Resident 根据其固定版本引用消息生成独立摘要;随后再根据摘要重新概括标题并通过 `group_topic_title_submit` 原子写回,禁止直接截断摘要。摘要和标题分两步提交,每步都校验 Topic 快照,过期结果不会覆盖新内容。
298
-
299
- 入站消息引用其他钉钉消息时,Steer 信封只携带稳定的引用消息 ID;正常情况下 Resident 直接使用同一会话已经收到的正文。如果该正文因消息传递异常、会话恢复或上下文压缩而不在当前可见上下文,Resident 必须加载 `dingtalk-chat` Skill,并使用插件配置的同一 DWS profile 执行 `chat +messages-mget` 主动读取;取回的消息仍有 `quotedMessage.messageId` 时继续向上查询,直至整条引用链结束。查询结果必须校验完整性,必要时读取链上的图片或文件。查询失败、结果不完整、未命中或检测到循环时,不得要求群成员补发原问题、正文或截图,也不得猜测并回复;本次判断进入 `decision-retrying`,由 Runtime 在故障恢复后自动重试。
300
-
301
- `group_decision_submit` 每次提交一个 Topic 的决策,绑定 topicId、revision 和持久 decisionId。决策及每个 Task action 都携带 `basisUnitRefs`,Host 按事项逐动作校验 owner、当前增量和执行版本;接受一个事项不会消费同消息的其他事项。Task 仍只保存 topicRefs,固定版本读取只投影本事项的来源与共享背景。任何 Task 动作都必须带非空确认;确认先可靠写入 Outbox,再创建、续接或重开 Task,但单独确认不消费后续业务动作资格。取消仍优先发送止损信号。决策接受后保留动作回执,按固定 operationId 恢复,不通过重建 ID 重复执行。Topic 工具参数错误返回精简的 `invalid-arguments` 字段问题;归类请求过期时返回当前请求,已落盘的重复提交从 RouteHistory 恢复原回执,Resident 不猜测或盲目重放未知请求。
302
-
303
- 动作的条件必填字段由同一份规则生成 I/IB 提示和 Host 校验,例如 `report` 必须提供 `language`;缺参仍拒绝,不补默认值。
304
-
305
- 历史主会话回复候选按 Topic 决策或 Task 通知绑定并有界读取,不随全群历史重复注入。Resident 准备回复时调用 `group_reply_review_get`,完整审阅绑定快照;Topic ID、引用 ID 或关键词不能替代语义判断。重启后从持久的归类进度、Topic 未处理版本和已接受决策恢复;已归类话题的失败只阻塞该话题及共享 Task 的关联操作。
306
-
307
- 图片及其紧邻短消息在归类阶段共同理解;附件读取失败不能据标题或缩略图猜测正文并启动 Task。原始消息保存附件与事实版本,Topic 固定版本解析相应原始事实,重启后仍能追溯输入。
308
-
309
- Task 完成和信息阻塞通知使用 `group_reply_submit` 结构化提交,绑定 Task runSequence、inputVersion、事项来源、相关 Topic 版本及回复快照。每个事项完成后立即进入自己的验收和 Outbox 链路,不等待同消息其他事项;通知请求冻结创建时已接收入站的序号边界,边界后的无关新消息不会扩展旧请求。Resident 根据所引用 Topic 的原始消息选择 `replyToMessageId`;省略 `atOpenDingTalkIds` 时,Runtime 统一从被引用消息推导发送人,显式接收人仍必须属于当前 Topic。当前事项的 Topic 或执行版本变化会使旧通知失效,并在持久协调账中进入 `superseded` 终态。Outbox 待投递、DWS 发送和群回读确认分别计量;通知使用提交 requestId 派生稳定 Outbox 身份,运行层重启或调用方未收到返回值时可读取已接受回执,找不到回执的未知请求不会自动重发。
310
-
311
- Topic 决策产生非空回复时,Runtime 使用 DWS 原生引用回复,并验证选定消息属于当前 Topic 快照。原消息的引用链只提供上下文,不自动成为出站引用目标。发送人 ID 缺失时不得猜测引用参数。回读必须匹配正文与精确的引用消息 ID;同文但属于其他话题的引用回复不能认领为本次投递。
312
-
313
- 任何非空回复提交前,Resident 必须通过 `group_reply_review_get` 按请求 ID 读取 Runtime 绑定的历史确认、近期回复、内容相关回复和当前 Task 关联回复。Resident 根据正文、目标、动作范围和时间线判断同一事项,引用 ID 和相似度只定位候选。等价确认没有新信息时保持静默;必须补全或纠正时,完整审阅后选择当前群真实 Outbox。接纳前校验替换图,原子持久化新通知与替换关系;旧 pending 进入 superseded,不再发送,但这不证明历史从未送达。历史发送未知只核验,迟到回执仍记录实际 messageId。
314
-
315
- 替换通知先经原生幂等发送及 DWS 回读确认,再独立撤回已授权的旧消息(包括替换链)。撤回失败不再阻塞纠正通知,也不把旧消息伪标撤回:明确服务端拒绝停止自动重试;其它异常按 30 秒间隔最多尝试 3 次,之后等待核验。历史未知查询未命中保留 replacement_delivery_unknown,可由迟到回执继续恢复,不等于确认未发送。发送入口共享群级串行队列,实际外发前再原子检查旧意图未被替换。看板分别展示已替代、撤回待处理、待回读与已回读,保留审计原因。
316
-
317
- 普通发送遇到明确服务端拒绝时持久化 deliveryBlockedAt,看板显示发送待处理,停止对相同意图自动重试;读取失败或送达未知不冒充明确拒绝,继续保留原生幂等与回读保护。
318
-
319
- 无任何业务动作或投递记录的阻断通知,可由运维持证据通过 `reconsider` 重新决策;有副作用或结果未知的记录拒绝此操作。阶段成功事件沿用稳定身份,升级不会将相同完成观察当作新输入。若既有版本已产生重复事件,仅允许在维护排空后依据原完成决定和完全相同的事件内容原生对账,保留失败回合;不能据此重新判定业务完成。详见[本地部署与恢复规程](docs/ops/resident-review-local-deployment.md)。
320
-
321
- ### 群聊协调决策
322
-
323
- 决策首包提供固定版本的 `promptIndex` 和合法 `contextSections`;内联消息直接复用,只有分页指针需要 `group_decision_context_get`。流程正文通过同一请求的 `group_task_prompt_get` 批量读取,已有任务用 `group_task_list` / `group_task_context_get` 查询。流程版本改变会使旧读取失效并重新调度。
324
-
325
- 同群模型保持串行。存在竞争时,决策与审阅每次可连续执行最多三步,或在累计30秒后的步骤边界让出;不会中断正在执行的模型或提交工具。路由仍在步骤边界优先,两批路由后给其他请求公平执行机会。这个预算控制轮转,不承诺真实渠道端到端30秒内完成。
326
-
327
- 活动记录恢复在后台处理固定快照,再按序接续新事件;启动不等待运行任务的历史统计完全追平。失败保留水位并可恢复,关闭仍等待已排队记录落盘。
328
-
329
- ### 性能观测与协调资源读取
330
-
331
- `GET /state/performance` 是只读观测接口,可按 `day`、`sessionId`、`groupId`、`taskId`、`requestId`、`submissionId` 精确筛选。`rows` 按上海自然日返回模型和工具调用、首流事件/响应/工具耗时分布、上下文及 token 用量;分布包含 `count/sum/max/p50/p95`。`inputTokens` 是未缓存输入;`totalInputTokens` 合计已报告的未缓存、缓存读取和缓存写入,缺失分项另计,不能把未知用量当作已确认的零。模型/工具资源累计耗时与区间并集分别展示,不能把跨行累计值当作端到端等待时间。已有 `/state/task-timings` 继续提供 Task 状态耗时。
332
-
333
- `workflow.taskWaits` 从持久状态历史和报告收发边界派生排队、运行、系统等待、人工等待、信息等待及审阅等待,按日对每类区间取并集。旧历史没有 `waitingKind` 时记为 `unknownWait`,不借当前状态猜测历史;报告等待可能与运行状态重叠,不能把这些列当作互斥阶段相加。状态历史没有精确请求/会话/报告关联时,相应筛选返回缺失说明。
334
-
335
- `workflow.responses` 只匹配 `replyToMessageId` 精确指向入站消息、且已经保存送达消息 ID 和送达时间的回复;按入站日期归组。`firstReplyMs` 包含确认回执,`firstLabeledSubstantiveReplyMs` 只采用 `replyKind=substantive` 标签,标签不等于人工验证了实质回复内容。未匹配消息返回空值与缺失原因,不记为零耗时。
336
-
337
- `coordination.requests` 按请求汇总会话数量、模型输入、未缓存输入及协调消息正文序列化后的字节数;不将字节数折算成 token 或费用。`rows.coordinationQueueMs` 使用 `dingtalk/coordination-dispatched` 中真实入队、分派时刻的差,包含等待轮到本请求及准备会话的时间;重复分派同一消息不重复记录。缺失、倒序时间或请求身份不符单列缺失;旧队列边界没有自动回填。
338
-
339
- `observedSince` 和 `coverage=observed-events-only` 标明本投影的观测范围。缺失 usage、首流事件、step 起点或工具配对由缺失计数明确记录;fork seed 和重复投影不计作新模型调用。投影在现有 scheduler 表按会话分区保存,逻辑上更新某会话不改变其它会话的历史,但 single-json 后端仍会重写整个 Domain 文件;计量写入使用全局单写入器,将等待中的同会话事件合成一次持久写,避免多会话计量占满业务写队列,回执仍在持久化后完成;step 结束清理配对状态并压缩已完成步骤身份,缺失工具结果仍保留计数。精确分位频数、去重范围与每日区间并集随保留历史增长,`retention` 明示这一限制,不作任意条数截断。只持久保存计量元数据,不保存正文或工具参数。首流事件不等于首个可见字,更不等于首次实质回复;人工内容标注、全部外部阶段归因和账单计价仍未完成,不能据此承诺费用或真实业务响应收益。
340
-
341
- 请求会话通过 `group_message_get` 读取本请求消息及引用链,通过 `group_resource_get` 读取消息明确引用的附件或 URL。任意消息 ID、资源 ID 或 URL 被拒绝;分页须连续读取,身份、版本、格式或完整性不符会明确失败。公网文本读取仅允许无凭据的 HTTPS/443、公网 IPv4 DNS 结果;固定本次连接地址,不跟随重定向,不读取内网或环回地址。资源不支持、缺少读取器、图片不可用或正文未读完整时,不得猜测内容或当作证据齐全。
342
-
343
- 本轮源码实现及验证状态见[性能优化目标与验收记录](docs/acceptance/performance-flow-optimization/goal.md)。本轮尚未部署;独立 DSH glob 责任包只产出本地补丁,未安装到运行 profile。22条带固定前缀的历史失败搜索已完成对照,8条无固定前缀及4条宽 worktrees 查询仍需准确目录输入。上下文、首次实质回复与费用等真实流量收益仍待部署后独立观测,不能由本地用例通过代替。
344
-
345
- ### 叶子任务
346
-
347
- Task 可设置独立的简短标题用于看板展示;标题与 objective 分离,重命名不会改变任务授权范围、Goal 或验收标准。运行看板通过 DSH 官方 `sidebar.footer.action` 提供左侧菜单入口,并由 `shell.overlay` 承载右侧完整内容区域;点击运行看板时切换到看板并清除 Session 选中状态,点击任意 Session 时关闭看板、恢复该 Session 的选中状态与对话/轨迹。运行看板复用 Session 的实际选中背景色,不额外显示焦点边框。
348
-
349
- 运行看板 Header 的高度和字体规格与 Session 页面一致。各页不再重复显示页面标题和子标题;任务列按 Header 与主内容实际占用计算剩余视口高度,卡片在列内独立滚动,页面本身不会因状态桶高度产生额外补白或纵向滚动。人工介入列表区分待处理、已处理和已失效请求;只有待发送或等待回复的请求提供处理操作,未知状态以异常标记展示且不会导致整个看板崩溃。
350
-
351
- Runtime 使用 DSH 原生 subagent 和 Goal 创建叶子 Session。Task 保存标题、目标、验收标准、执行状态、结果,以及 `topicRefs: [{topicId, revision}]` 和 `inputVersion`;不保存 sourceMessageId、triggerHistory、messageHistory 或群消息正文副本。`group_task_context_get` 返回执行约定与 Topic 引用,原始上下文由 `group_topic_context_get` 按固定 revision 分页读取。只有确实影响任务的新增信息才推进 inputVersion,不向每个关联 Task 广播全部讨论。运行中和等待中的 Task 接纳上下文时继续原轮次;完成或归档 Task 只有被明确重开才开启新轮次。目标发生实质变化时,续接动作必须同时提交概括当前完整目标的新标题;Runtime 原子更新目标和标题,并由 objectiveHistory、titleHistory 与 runHistory 保留旧值。普通信息补充、等待恢复和异常唤醒不修改标题,归档不删除历史。叶子完成自身交付与必要自验证后即可提交 `completed`;原群参与者或其他机器人的后续检查属于 Topic 协作,不阻塞叶子 Task。若信息或人工介入确实阻塞本职交付,等待报告需列出 `blockedItems`(未完成要求、来源消息、必要依赖和原因),经 resident 内部审阅后才能进入 waiting。误把他人职责写入目标时,resident 按原消息修订 Task 目标、验收和阶段,保留已完成证据;外部反馈经正常 Topic 输入处理。历史 `coordination` 结果只读兼容,不再重发检查请求。
352
-
353
- 内部审阅预算等确定性系统故障会将原报告记为 `failed`,Task 进入 `waitingKind=system` 并释放运行名额;Host 通过可靠 Outbox 通知暂停,同一轮次、版本和错误码不重复通知,也不要求叶子反复改稿。恢复入口仍为 `POST /tasks/<taskId>/reports/<submissionId>/retry`。恢复前在 Task 提交锁内只读重建审阅输入,复核报告版本、轮次、当前流程、待处理输入和人工授权;探测失败保持系统等待,不启动叶子或清除故障。通过后在并发容量允许时处理原 submissionId,不能靠创建新报告或会话绕过故障。
354
-
355
- 派发及重开时,Runtime 从已登记的本地 worktree、已有报告工件、检查点证据和交接记录提取原生绝对路径,检查当前是否存在,随任务输入提供可确认的工作位置。不会遍历工作区寻找这些位置;无法确认时明确标记 unknown。位置存在不代表旧验收仍有效,也不扩大任务授权。优先在已确认的目录检索,避免重新扫描整个工作区。
356
-
357
- 叶子新建受管理工作区 `worktrees/` 下的 Git linked worktree 后,调用 `task_worktree_register` 登记路径、当前执行版本、创建归属和应保留的 `docs/<类别>/...` 文件清单;文档形成后再次登记更新清单。Host 校验真实路径、Git 身份、当前叶子 Session 及任务归属,并把记录保存到 Task 的 `localWorktrees`。提交 completed 时,`localWorktrees` 列出所有仍登记的目录路径,与 Task 记录一致。任务完成时保留目录和开发分支。归档时先只读预检:Git HEAD 与登记一致、远端分支指向该提交、代码无未提交修改,未跟踪文件全部已列为待迁出文档。然后将文档按原分类复制到当前 Agent 工作区 `docs/<类别>/<taskId>/<仓库名>/`,核对 SHA256,正常执行 `git worktree remove`,并分别回查实际目录及 Git 登记。借用的目录仅记录、不删除;归档失败保留 completed 且不写 `archivedAt`,任务看板显示原因并支持重试。开发分支不会随目录删除;跨轮续作仍使用同一分支。此流程不依赖 `goal.md` 或个人绝对路径。
358
-
359
- 消息的 `routingStatus` 表示待归类、已归类或归类失败;Topic 的 `processedRevision` 表示决策及所需动作已可靠落地;Task 的输入下发、输入确认与任务完成另行记录。任何一项均不能替代另一项。运行看板的“话题”页在左侧只展示名称与摘要,右侧分开展示完整标题、话题摘要、待解决问题和关联任务;固定版本消息列表直接展示并支持分页,每条消息所引用的上一条消息默认折叠。群消息状态由 `routingStatus`、Topic revision 与 `processedRevision` 投影为“待归类、话题处理中、已处理、归类失败”,不再把旧 `agentDeliveryStatus` 当成业务处理完成度。Task 卡片上的话题链接打开该任务接纳的版本。Topic 归属仅表示消息延续同一讨论目标,或实质改变该 Topic 的事实、范围、结论或动作;为回答问题查询旧分支、PR 或任务资料不会建立 Topic 归属。多 Topic 路由必须逐项声明关系和理由,并显式指定唯一动作主归属。路由回执最多 1 KiB,决策首屏及 `group_decision_context_get` 单页最多 12 KiB,均按完整 UTF-8 JSON 计费;Topic 历史分页仍按原有 40,000 字符预算读取。`omittedDeltaCount` 非零时,Resident 必须读完固定请求的 `messages` 段;其他标记为必要的来源或归属段也须读完。Host 在必要依据读完前拒绝决策,旧历史未读完不会阻塞本次事项。
360
-
361
- 每个协调 requestId 使用独立的路由、决策或审阅 Session;同一请求的多步读取与有限重试复用该会话,终态释放运行句柄并保留原生日志。Host 继续拥有 Topic、Task、授权、版本和 Outbox 的唯一提交权。工具调用检查当前 groupId、requestId、角色及请求状态,旧会话不能提交新请求或跨群动作。常驻群主会话保留管理用途和原配置权限;请求会话只开放本角色的读取及结构化提交工具,不暴露工程写工具或 Goal 工具。完整工具权限不扩大群消息或 Task 的业务授权,Task 动作仍经 Topic 决策和 Runtime 校验。任务授权与“明确交给其他人”的校验按动作引用的事项判断:从固定版本原文读取该事项之前最近的点名,即使称呼列为 ignoredRefs 也保留证据;同一消息中后续改为点名其他人时,不得借用前一事项的授权。`sourceRefs.quote`、`contextRefs.quote` 只引用当前消息中唯一出现的原文;被引用消息作为独立的 `quotedMessage` 背景提供,不填入当前消息的 `contextRefs`。Task 叶子会话由 Runtime 使用 DSH Goal 管理执行、阻塞、恢复与完成,权限 preset 同为 `danger-full-access`,可按 Task objective 和工作区规则使用完整本机能力。DWS 群通知仍只有 Runtime 一个出口;叶子不得绕过结构化结果链路直接向来源群发送消息。
362
-
363
- 主会话向运行中或等待中的叶子传递任务上下文、目标修订、真人批复、恢复提示和结果驳回时统一使用 DSH `steer`,在叶子的下一个 step 边界插入,不使用 `followup` 排队到下一 Turn。
229
+ ## 首次配置与启动核验
364
230
 
365
- 群成员明确撤销原任务授权,例如“不要处理、不用做、停止、取消、忽略刚才”时,Resident 将当前撤销消息关联到唯一的 queued、running 或 waiting Task,并提交 `task-cancel`,不得继续作为普通 `task-context` 发送给叶子。Runtime 在等待全局 Task 串行队列前同步调用 DSH `agent.cancel()`,立即中止叶子的当前 Turn 并清空尚未执行的输入;取消建立后拒绝叶子迟到提交的 checkpoint/result。任务随后持久化为已取消,撤销消息及其归属保存在 Topic 历史;叶子 handle 的 dispose 在状态落盘后异步收敛,不阻塞群消息回复或 Web 取消响应,Runtime 关闭时仍会等待其完成。没有待清理自有 worktree 时立即归档;有登记的自有 worktree 时在叶子释放后走同一归档清理流程,失败保留已取消但未归档状态和原因。模糊讨论、普通目标收窄或只暂停某一步不能推断为取消整个 Task。
231
+ 1. 在实际 profile 中设置 Agent 工作区、Agent preset 和模型;在插件设置中维护名称/别名、群订阅及职责。个人群 ID、DWS profile、操作者身份与凭据不要提交到仓库。
232
+ 2. 先按清洁启动 Runbook 初始化独立任务控制库;既有实例停稳旧执行并使用新 domain,确认 epoch 回补隔离后才开放新执行。不要用 `initialize: true` 绕过缺库或 epoch 身份不符。
233
+ 3. 默认保持 `dws.enabled: false`、`dws.writesAuthorized: false`。通过隔离夹具后,分别批准真实订阅与外发;配置开关不是新业务授权。
234
+ 4. 确认工作区根指引能通过 DSH 原生 `agent-instructions.projectRootMarkers` 被发现。插件不复制身份指引,也不把 Owner 提升为通用执行者。
235
+ 5. 核对实际安装包、唯一进程/PID、`GET /health`、`GET /state/dws-bridge`、新任务与执行日志、重启恢复和真实消息回读。任何一层证据不能替代其余层。
366
236
 
367
- 人工 Web Task 输入通过 `POST /tasks`、`POST /tasks/{taskId}/context` 和 `POST /tasks/{taskId}/reopen` 提交。三者均需由调用方提供稳定 `requestId` 与原始 `context`;新建还需 groupId、title、objective、acceptanceCriteria,可不提供 topicRefs,由 Runtime 建立 Web 来源 Topic。追加和重开需提供 topicRefs、inputVersion、runSequence,均从当前 Task/Topic 查询获得。相同 requestId 只可重试同一内容;版本或身份冲突返回 HTTP 409,持久接受但动作未完成返回 202。body 不接受 taskId、childSessionId 或伪造渠道来源。Resident 不持有这三个 Web 写入口,只通过带原始依据的 `group_decision_submit` 发起业务动作。
368
-
369
- 取消入口 `POST /tasks/{taskId}/cancel` 同样要求 requestId、topicRefs、inputVersion、runSequence,以 reason 保存人工原文。Web 来源不伪造钉钉引用或 @。Resident 已移除 `group_task_create`、`group_task_context_append`、`group_task_reopen` 直写工具;误归类通过 `group_topic_route_review` 提交修订,所有非空回复必须带 `replyReview.kind`。Task 补充输入按实际值判断范围变化,同值目标、验收和阶段数组不触发重规划。`preserve` 保留仍有效的已确认 checkpoints 及其原 inputVersion,不改写成新版本验收。确需否定既有进展时通过 `impactEvidence` 提供原始 basisMessageIds、原因与 affectedStageIds;从最早受影响阶段失效后续进展,保留此前证据,重新确认实际阶段顺序。明确影响证据不能被 preserve 忽略;未提供依据的同范围 replan 会被拒绝。阶段按稳定 stageId 关联,重复标题或冲突 ID 拒绝。跨 Topic 补充会合并固定版本引用,不覆盖此前执行依据。
370
-
371
- 叶子报告通过可选 submissionId 或规范内容身份持久接纳,同 ID 不同内容拒绝。回执 contractVersion=2,received:true 只表示已保存;reviewStatus=pending 表示尚未批准推进,approved/rejected/stale/failed 分别表示审阅通过、业务缺口、版本失效和系统故障;applicationStatus 单独表示是否应用;叶子等待 Runtime 事件,不重复提交探测状态。旧版本合法报告只归历史,不覆盖新目标;输入解除或重启从持久记录恢复,审阅和通知复用稳定身份。最终接受、阶段通过与业务验收仍独立核对。
372
-
373
- 生产发布与数据变更流程的前置核验、离线 revision 候选和配置 CAS 操作见[发布准备证据与流程修订](docs/ops/release-preflight-evidence.md)。缺基础对象为 FAIL,证据或依赖清单不完整为 UNKNOWN,均不能进入生产执行;检查脚本 PASS 仅表示证据契约完整。
374
-
375
- Topic 查询的 `processing` 提供最新未完成意图的 decisionId、status、appliedOperations、totalOperations 和有界 error,不返回动作正文。Observer 对应显示处理失败或处理中及动作进度,便于区分消息已接收、Topic 已决策与动作实际完成。
376
-
377
- 同一消息版本产生过已接受的 Task 动作或确认后,其执行归属保留在持久决策中;将消息从 Topic A 改归 Topic B 不会重新授予执行权。新的授权消息或新的事实版本需要重新判断,历史动作不会因归类修订而自动撤销。
378
-
379
- Task 创建和重开时即生成稳定 `stagePlan`,主会话查询与叶子输入使用同一份阶段身份;阶段 ID 的存在不代表计划已批准。`affectedStageIds` 只接受真实 ID,不接受标题或猜测值。创建、重开和上下文修订在 Store 原子接纳点校验阶段及修订参数,接纳和执行共用参数规范化;错误参数不会生成决策、预约或确认,主会话可读取当前上下文后用同一请求纠正重提。
380
-
381
- 历史已接受的无效上下文修订,仅在整份决策都是 `task-context`、动作映射完整、所有动作未执行且 Task 幂等账本和执行版本均确认安全时,原子标记 `rejected` 并释放自身预约。原消息、Task、历史回复和 processedRevision 保留,Runtime 使用新的稳定请求身份重新判断尚未处理的输入。部分执行、含取消动作或结果不明的记录不会自动退回重放;存储错误仍按原错误链处理。`rejected` 是意图终态,不代表业务输入处理完成。
382
-
383
- ### 阻塞与人工介入
384
-
385
- - 缺少任务信息:叶子进入 information waiting,由主会话结合 Task 所引用 Topic 固定版本的消息时间线,向真正能够补充该信息的一位或多位参与人询问。
386
- - Task 遇到操作红线、环境异常或需要真人判断时进入 `human-intervention`,页面“人工介入”和 DWS 登录人本人私聊共享同一阻塞状态机。批准只对应阻塞单中精确列出的动作;处理意见可以收窄执行方式,不能授权另一动作,和原动作冲突时任务必须继续停住并提交范围冲突。
387
- - waiting 不占 `maxConcurrentTasks` 执行名额;信息或人工回复到达时统一进入 FIFO queued,保留待恢复上下文。调度器把正在创建或恢复 Session 的 Task 计入容量,获得唯一名额后续接原叶子 Session 和 Goal。
388
- - 钉钉人工处理必须引用阻塞消息并提供非空意见;明确回复“拒绝”“不同意”或“不批准”时记为不执行,其余回复使 Task 继续,并保留完整原文。Runtime 使用独立的个人 IM 实时订阅按被引用消息的 `messageId` 精确关联并恢复 Task,历史查询仅用于离线恢复;等待不设超时。
389
- - 批准复用指纹绑定 taskId、runSequence、阻塞类别、规范化动作和风险;旧版本没有这些字段的记录不会自动授权当前轮次。
390
-
391
- ### 完成通知
392
-
393
- 任务完成后,叶子把结构化结果交回主会话。主会话结合 Task 所引用 Topic 固定版本的消息时间线选择最适合承接结果的历史消息,并通过结构化 `atOpenDingTalkIds` 通知所有确实需要获知结果或采取后续行动的参与人;Runtime 只接受所引用 Topic 版本中的消息和稳定人员 ID。发送前后均回读钉钉真实消息;包括组织未授权在内的读取失败不能绕过回读,发送受理或空回执不能代替送达证据。未确认的记录保持 pending。Outbox 记录尝试次数、最近尝试时间、失败环节和原因,看板区分待发送、发送受阻、投递异常与待回读。
394
-
395
- 信息等待通知由 Runtime 固定说明任务已暂停、已完成阶段、剩余缺口、所需资料和恢复条件,并引用相关消息通知反馈人与任务发起人。只有 Outbox 独立回读确认后才标为已送达;30 分钟无新信息提醒一次,2 小时后向发起人升级一次,随后不再自动催促。任务版本变化或恢复会使旧待发通知失效。任务进度、阻塞和完成通知只有 Runtime 一个群聊发送出口;叶子会话不得自行调用 DWS 向来源群发送通知。叶子提交完成结果后,Runtime 会把摘要、证据、交付物、部署信息和Task 所引用 Topic 固定版本的消息时间线交给常驻主会话组织群通知。叶子根据 DSH 注入的 Skill 描述自主选择适用 Skill;Runtime 不绑定具体 Skill,只要求已加载的 Skill 完成其资格判断、必要操作和验证闭环。工作区规则授权范围内的内部维护不扩大业务 Task 授权,也不得借此修改未授权的业务代码、业务数据、环境或外部系统。通知可合并重复表述,但必须保留不同关注点、限定条件、失败项和未验证/未部署边界,不能为了简短只复述摘要。Web 与内部恢复来源只用于触发内部操作,不得伪造群消息或参与人;历史 Task 必须经离线迁移生成可追溯 Topic 引用,不猜测缺失历史。同事或其 AI 助理发送的回复、任务回执和状态通知不会按文案或发送者在模型外过滤,而是进入常驻模型,由模型结合引用、上下文和任务索引决定忽略、回答或关联任务。判断复用已有任务还是新建任务时,必须综合消息前后文、连续消息的信息组、当时场景,以及候选任务的目标、动作范围、状态、完整消息历史和已记录上下文;关键词、词面重合或标题相似只用于寻找候选任务,不能直接作为关联或新建结论。
396
-
397
- 群消息中的图片、文档、文件、链接或其他外部资源如果承载任务所需信息,Resident 必须先完整读取。无法访问、下载、解析或读取不完整时,Resident 会先明确回复未获取到的具体信息并要求重新提供,不创建、不续接、不重开 Task;不得根据文件名、链接标题、缩略图或零散文字猜测资源正文。Runtime 还会对已知附件读取失败执行硬拦截,避免模型误判后提前启动任务。
398
-
399
- 叶子提交 `completed` 后,Runtime 会以 coordinator 内部上下文注入的方式,让常驻模型对照当前目标、runSequence、inputVersion 和 Topic 输入版本审查本轮结果和证据,并通过一次 `group_task_review_submit` 同时返回审阅回执与群通知草稿。审阅与回退通知最多内联 20 条、12,000 字符的相关 Topic 消息,整个请求限制为 40,000 字符。超长目标、验收、结果和索引保留 section 指针,通过 group_task_review_context_get 按 nextOffset 续读固定快照;长消息可通过同一工具或固定 Topic 原文分页读取。不能把截断片段当作完整证据。Runtime 只有在审阅通过且 Task 按当前版本原子完成后才将草稿写入发信箱;若期间出现新消息、Topic 或历史回复候选变化,则放弃旧草稿并重新协调。若新增或修订范围未完成、缺少验证,Task 保持 `running`,缺口反馈给原叶子继续执行,不生成完成通知。
400
-
401
- 除群成员明确撤销整个任务并提交 `task-cancel` 外,`running` 和 `waiting`(包括阻塞中)任务收到新增信息时只追加 `task-context`,继续同一执行轮次;只有 `completed` 任务(包括已归档展示)才允许 reopen 并初始化下一轮。完成轮次的 Session 空闲回收同时绑定 handle、Task 状态和 runSequence,不会释放已经重开的新轮次。Supervisor 发现 `running` Task 的叶子已 idle 时由 Runtime 幂等投递续执行请求;底层明确返回 Agent/Session unavailable 时,受控重建物理叶子并保留同一 Task、目标、Topic 固定版本和执行轮次,不让 Resident 绕用通用子代理消息接口。普通阶段 checkpoint 由 Host 校验版本、阶段身份和证据;按计划顺序推进可直接确认,跨序登记独立阶段必须交 Resident 审阅,不因此跳过业务前置条件。相同未审阅 checkpoint 以持久 checkpointId 复用同一审阅;Supervisor 只恢复该请求,不重复追加。scope-conflict、evidence-gap、risk-changed 在无计划、已拒绝或旧流程失效时仍可报告,不能携带完成项或修改剩余进度;新异常可抢占未确认审阅,旧待审项归档,迟到审阅不得回写。完成审阅发起时即记录 completion-review-requested,拒绝或失败也保留时间与关联尝试标识,Task 完成、通知入队及真实送达分别记录。
402
-
403
- ### 只读状态问答与模型重试
404
-
405
- 已明确关联 Task 的简单状态问答可使用独立、无工具的短模型请求,读取当前 Topic 增量、Task 事实快照、审批边界及回复候选;执行动作、授权、复杂冲突或上下文不足时交回常驻处理。短请求沿用当前 Provider、模型和推理设置,提交仍通过 Task 集合、事实版本、策略、Topic 及回复候选校验,并复用原有 Outbox。
406
-
407
- 直接调用 DSH `LlmRuntime` 不经过 `agent/request-error`,不能假定 AgentLoop 的重试插件会替短请求重试。短问答 handler 是这一条调用链唯一的重试执行者:通过 `prepareCall()` 获取原生 Provider policy,遵守可重试错误码、次数、指数退避、抖动和 Retry-After;所有尝试共享同一请求与输入身份,并受总30秒模型预算限制。失败的部分正文不会提交;耗尽、不可重试或超时才交回常驻。遥测分别记录尝试次数、累计 usage、原生 finish kind/code/status,不记录 Provider 原始错误正文或凭据。
408
-
409
- 重试规则的确定性测试与真实模型测量见[性能测量记录](docs/acceptance/resident-leaf-coordination-repair/performance-measurement.md)。短模型往返不含路由和钉钉发送,不能代替端到端响应指标。
410
-
411
- ## Web 运行看板
412
-
413
- `dingtalk-dsh-observer` 在 DSH Web header 中提供:
414
-
415
- ![钉钉个人助理任务看板](docs/manual/images/dsh-web-task-board-annotated.png)
416
-
417
- - 群聊会话:查看不同 resident Session 的分页收信箱和发信箱;状态固定在最左列,长内容最多显示两行,完整内容可通过悬停标题或详情查看。
418
- - 任务看板:按待执行、执行中、等待中、已完成展示 Task,并打开 DSH 原生叶子对话和轨迹。任务详情采用通栏步骤列表,每步左侧为编号、名称和状态,右侧显示耗时与业务产出;进入详情才读取产出,长文分页继续阅读,不展示原始 JSON。编号步骤显示本次执行耗时,运行中每秒更新,等待不累计后续等待时间,缺失记录明确提示;不增加诊断接口请求。无任务负责人会话且计划已成功的任务显示已完成,结果中保留“无法确认”等信息边界,不额外制造等待;有负责人会话的任务仍按当前版本验收结果展示。活动任务卡片中的“任务”面板默认收起,只显示完成数/总数和进度;展开后显示各阶段任务、状态和耗时。完成结果保留在卡片,完成通知已送达时不重复显示,待送达或受阻时显示状态;协调请求重试耗尽显示“系统协调受阻 · 待恢复”。执行轮次耗时统计不占用任务卡片空间,仍可通过 `/state/task-timings` 接口用于诊断。
419
- - 叶子活动投影写盘遇临时故障会有限重试并暂停该任务的后续投影;监督器按原 Session 事件序号补齐后解除当前故障。任务完成时先补齐活动再释放叶子 Session,持续故障保留恢复问题供排查。
420
- - Runtime 启动后还会逐个审计已完成 Task 的持久 Session;若曾在完成前后漏写活动,按原事件补齐。持续故障保留待审计队列和恢复问题,不会由下一条活动成功自动清除。
421
- - 若历史已完成 Task 的 Session 已不存在,审计将其标为不可回填并从重试队列移出;`/state/activity-audit` 显示待审计、已审计和不可回填项,`/health` 汇总数量。缺少历史来源不伪装成当前写盘故障。
422
- - Outbox 的 `deliveryAttemptCount` 表示投递流程轮数;`sendAttemptCount` 记录实际进入发送调用的次数,`readbackAttemptCount` 记录发送前后读群历史的次数。查询重复发送时应核对这两个计数和远端消息 ID,不能由投递轮数推断重复外发。
423
- - 工具活动从 DSH 的 `tool/call` 和 `tool/result` 关联工具名、错误位、耗时及结果字节数;缺少可关联调用时显示 `unknown`,不推断为成功。
424
- - Task 的 `activityProjection.aggregate` 保存上海本地日期的事件总数和类型计数;500 条活动明细裁剪后累计数仍在。旧存储若已裁剪历史,首次生成的聚合标为 `retained-only`,不可当作历史完整总量。
425
- - 同一消息拆出多个事项时,Resident 新建 Task 必须提供 `dispatchAssessment`:业务对象、当前 Agent 交付、他人后续、来源 Unit、当前流程引用与选择原因。Host 校验来源 Unit、流程启用和版本;单事项可选。业务对象及交付的语义仍由 Resident 按原消息判断。
426
- - Task 收到补充输入后,原版本待审报告转为历史并向仍在运行的叶子提示按当前版本核对后重提;不会自动重放业务操作。明确标记授权变化且有新来源消息时,原阶段批准保守失效,即使阶段名称不变也须重新核对。
427
- - 任务表格同步:在“设置 → 插件 → 钉钉个人助理”填写钉钉在线电子表格地址,检查连接后选择目标工作表并启用。插件启动时立即同步,之后每 180 秒全量覆盖所选工作表;归档 Task 会在下一轮移除。所选工作表由插件托管,手工内容会被覆盖。
428
- - 归档任务:查看已归档 Task,相关群消息仍可重新打开原任务。任务卡片不常驻展示工作目录和文档清单;有登记目录时点击“检查并归档”先核对迁出/清理范围,再确认操作。借用目录及其登记文档保留原处。归档失败在卡片提示,可查看原因后重试;归档后可按需查看目录记录。
429
- - 人工介入:以与消息表格一致的状态列、行高和内容密度分页查看阻塞事项,并在页面明确选择“批准该事项并继续”或“不执行”。
430
- - 告警:按类型查看当前异常和分页的已恢复历史。
431
-
432
- 看板不读取或重建 DSH Session JSONL,只通过插件状态接口展示业务投影;对话与轨迹仍由 DSH 原生页面负责。
433
-
434
- ## 状态与数据目录
435
-
436
- 正式运行使用标准用户级 `DSH_HOME`:
437
-
438
- - 插件状态:`%USERPROFILE%\.dsh\storages\dingtalk-dsh-assistant\`
439
- - DSH Session:`%USERPROFILE%\.dsh\sessions\`
440
- - profile:`%USERPROFILE%\.dsh\profiles\`
441
-
442
- 仓库不提交本机 Session、消息、Task、授权记录、DWS profile、群 ID、打包产物或凭据。
237
+ 启动脚本只负责启动,不证明旧工作已排空。既有 `restart-web.ps1`、`deploy-local.ps1` 及历史 maintenance/cutover 脚本可能依赖已退役接口,不能未经核对就用于这次架构切换。先执行[专用清洁启动步骤](docs/ops/task-session-clean-start.md#准备及隔离)。没有完成现场检查时,不报告部署或真实钉钉验收成功。
443
238
 
444
239
  ## 开发与测试
445
240
 
446
- 新增或组合任务流程,请先阅读[新任务流程编排建设手册](packages/dingtalk-dsh-assistant/README.md),按职责、业务阶段和验收合同设计,再查附录接入当前接口。领域合同随 Workflow digest 冻结,Owner 可以读取失败诊断;原会话可修正未执行的参数错误。设计依据见[职责与结果交接方案](docs/spec/workflow-session-responsibility.md),实施证据见 [round-41](docs/acceptance/topic-context-completeness/round-41.md)。升级前需按运维说明核对旧无合同活动任务。
241
+ 使用 Node.js 24+ 与锁定依赖:
447
242
 
448
243
  ```powershell
449
- pnpm install
450
- pnpm test
244
+ pnpm install --frozen-lockfile
245
+ node --test test/dynamic-task-store.test.js test/dynamic-execution-session-native.test.js test/task-session-persistence-native.test.js test/task-session-service-native.test.js test/task-session-http-integration.test.js test/task-filesystem-boundary-native.test.js test/task-notification-readback.test.js
451
246
  ```
452
247
 
453
- `pnpm test` 以4个文件并发显式运行 `test/*.test.js`,避免自动扫描 `docs/tmp` 中隔离验证的其他业务仓库,以及按CPU核数启动大量真实Git/SQLite测试进程相互争用资源。
454
-
455
- 测试接口仅在 `testApiEnabled` 显式开启时可用。生产状态接口默认只监听本机地址,不应直接暴露到外网。
456
-
457
- 关键设计说明:
458
-
459
- - [DSH 原生常驻闭环](docs/spec/dsh-native-resident-closure.md)
460
- - [任务 Supervisor](docs/spec/running-task-supervisor.md)
461
- - [人工介入中心](docs/spec/authorization-approval-center.md)
462
- - [钉钉人工介入回复实时生效](docs/spec/approval-reply-live-events.md)
463
- - [运行看板](docs/spec/dingtalk-resident-observer.md)
464
-
465
- ## 原生流程执行底座
466
-
467
- 独立入口 `@zzusp/dingtalk-dsh-assistant/execution` 提供 SQLite 控制账与受信顺序节点;消息业务由 `workflow-service.js` 装配 Task Owner、阶段计划、流程定义和交付适配器。独立 Host 注入与业务目录接入是不同步骤,详见[新任务流程编排建设手册](packages/dingtalk-dsh-assistant/README.md)和[执行底座本地运维](docs/ops/execution-foundation-local.md)。
468
-
469
- 当前实现已包含候选冻结、构建检查、本地业务验收、受控 Git/PR 交付及 UAT 平台适配,依赖显式受信配置。真实业务覆盖与运行配置须分别回读;这些能力不等于任意 shell/平台开放,也不代表生产发布已经真实验收。
470
-
471
- 受管代际目录从固定基线独立创建,新补充不会自动继承旧代的删除或未跟踪文件;目录归属和未知初始化结果通过同一控制账对账,保留旧目录及用户修改。
472
-
473
- ### 消息同源编辑与接纳边界
474
-
475
- 工作流以渠道认证的 `sourceKey + sourceVersion + actorId` 去重。高版本正文完全相同通过 `message.source.alias` 保留原任务与已接纳命令;别名不进入消息处理或通知扫描。正文改变重跑事项拆分、关联和意图判断,并在同库设立源屏障。既有任务必须关联原任务后提交修订、取消、暂停或恢复;无法确定是否新增事项时创建持久澄清请求,不能猜测并重复创建任务。只有明确回答“新增独立任务”才允许新增。
476
-
477
- 已完成的纯排查事项再次被报告且未明确交办修复时,工作流向原提问者澄清。原提问者和已配置的任务所有者可通过引用该澄清消息答复;其他成员的引用不会消费该请求,也不会阻断群消息补拉。肯定答复仅准入本次消息的新任务,旧任务仍为只读。
478
-
479
- 消息节点按 S(事项拆分)、R(话题与任务关联)、I(意图)独立计量。当前原文在 S 输入只出现一次;历史消息使用本次快照内的短引用,补取时还原真实来源 ID。R 保留明确引用候选,候选完整详情和已解决材料以持久引用回读,必要证据跨节点传给 I。固定代码产出的节点仍记录执行结果,但不占模型并发或模型额度。节点字节门槛是请求保护值,不等同于提供商 token 容量;账本中的 token 预留仍以请求字节作保守上界,实际 token 以返回 usage 为准。关键材料超过本节点容量时保持可见的待处理状态,不以裁剪后的材料推断无关。
480
-
481
- 尚未创建执行实例的任务由 `message.task.control` 原子修订或取消原命令;暂停状态在修订后保持暂停。已有实例的修订必须先由 Controller 接纳输入,才能释放编辑屏障。`message.command.reject` 只对 pending 命令生效,确定性拒绝不会进入未知执行状态,并产生可通知的拒绝事实。模型意图节点只获得任务状态投影,不携带整个执行账对象。
482
-
483
- 消息账分页 `message.list({limit,beforeSequenceId})` 返回 `sequenceId`;历史页与通知待发、未知回查使用独立游标,避免旧未知消息阻塞新通知。必需附件经 `message.material.record` 首次记录后成为同一消息运行内不可变材料,重复读取内容变化拒绝,不能在任务创建时重新读取不同正文。
484
-
485
- 当前执行控制库使用 schema v5;旧 v4 库须按[话题事实离线迁移](docs/ops/execution-foundation-local.md#话题事实-v4--v5-离线迁移)停机、自检、备份、转换并独立回读,服务启动不自动升级。话题事实按来源与状态保存于 `message_topic_facts`,历史不再受整个话题最多 256 条限制;`message.topic.facts` 提供分页原事实,`message.topic` 的前 256 条有效事实视图以 `hasMoreFacts` 标记未返回部分。来源失效与事实变化递增 `contextRevision`,接纳时拒绝基于过期上下文的判断。存储可增长不等于单次模型输入无限,必要上下文仍超限时保持明确阻塞并保留依据。
486
-
487
- ### 话题上下文与处理过程
488
-
489
- 消息拆分、关联和话题意图批次仍使用独立判断。IB 的公共话题上下文仅提供一次,完全相同的任务事实也只提供一次,各事项保留自己原有事实的明确引用;原生任务历史及话题正文的相同副本可完整还原,不同事实内容不合并,并保存来源清单、上下文摘要和任务事实版本;接纳事务再次核对任务状态、控制和授权版本。同一发送人逐字相同的事实只在当前投影合并,完整历史仍保留;不同发送人或不同条件不会合并。原提出人明确撤销条件时,记录旧事实的替代来源和范围,其他发送人不能借话题关联撤销限制。
490
-
491
- 旧话题和任务候选按游标检索,R 每页核对最多 8 个普通候选,明确引用优先保护。超过 12000 字节的必要材料先分块提取逐字引文并记录覆盖范围;未完成覆盖、伪造引文、歧义或剩余条件仍超限时不会派发。所有分页与材料节点共同受已配置的累计调用和 token 预算约束;默认最多 21 次调用,不为每页重置预算。模型提取仍可能语义遗漏,覆盖记录不能证明理解完全正确。
492
-
493
- 看板“群消息”的“处理过程”直接展示步骤、判断结论、耗时与同批来源消息,不传输或渲染原始技术详情。话题页可独立翻阅事实与判断批次。任务详情以编号时间线完整展示当前计划的全部阶段及有效步骤,突出等待事项与当前结果;当前步骤正文分页加载并绑定详情版本,已绑定会话提供入口。尚未确定的动态阶段明确提示,不显示整个任务100%完成。步骤耗时取当前有效执行,任务时长注明累计口径。当前结果与消息送达状态分开展示。只读接口及游标合同见[工作流接口说明](docs/api/workflow-node-contracts.md#workflow-v2-上下文只读接口)。
494
-
495
- ### 工作流任务的本机 Web 操作
496
-
497
- 当前新入口可运行通用材料分析、五类按已提供材料区分的只读审查,以及已配置仓库的受管工程交付。五类只读审查分别对应排查、方案、PR 材料、数据口径材料和复盘;它们不读取实时 PR/数据库,也不创建导出文件。UAT 部署、生产发布、UAT 同提交重构建和数据变更已开始代码节点化,但没有可信平台适配器时不进入消息准入,不会假装完成外部操作。迁移矩阵与验证范围见[第 27 轮记录](docs/acceptance/runtime-redesign/round-27.md)。
498
-
499
- `POST /tasks/:taskId/context` 和 `/cancel` 对新工作流任务直接进入代码控制器,不调用旧话题协调器。配置须显式提供 `workflow.webActorId`,该本机操作者仍须拥有任务权限;仅接受 loopback 连接及允许的 Web Origin,不接受请求体伪造 actor、任务身份、执行目录或远端基线。
500
-
501
- 请求必须包含稳定 `requestId`、任务视图中的 `inputVersion` 和 `runSequence`。补充请求传 `context`,取消请求传 `reason`;可附空 `topicRefs`,新任务不要求旧 Topic。相同请求重投复用持久事件,改变同一 requestId 的内容返回 409。补充完整保留旧需求字段和安全约束,仅追加新要求;暂停期间接纳补充不会自动恢复。待处理输入或陈旧版本返回 409。准备事件后进程中断由恢复通路续接稳定 Controller 命令。
502
-
503
- 新工作流任务当前不支持 Web 归档、改名和重开,对应路径明确返回 `WORKFLOW_WEB_ACTION_UNSUPPORTED`,不写入旧任务账。旧任务仍使用原接口。执行器无法证明排空时,看板显示等待及 Controller 错误原因,不能继续显示为正常运行。
504
-
505
- 工程固定检查支持 Host 显式配置总预算及每步预算,并将失败检查已采集的受限日志保存为失败节点证据;参数范围、超时归属和准入要求见[检查阶段预算与失败证据](docs/ops/execution-foundation-local.md#工程固定检查的阶段预算与失败证据)。调整预算不等于构建通过。
506
-
507
- Run 领取预算耗尽后,受信本机 Web 用户可按当前 `budgetContinuation` 绑定明确提交 `continue-budget`。Host 按剩余节点数 × 3 追加有限额度,同 Run 最多一次;累计消耗、generation、候选与已完成验收保持不变。过期状态、待处理输入和未知效果会阻止续行,不允许模型自动续费。见[预算续行运维说明](docs/ops/execution-foundation-local.md#run-领取预算显式续行)。
508
-
509
- 话题事实 v4→v5 本地升级支持早期未显式保存状态的事实,按来源版本保留有效/失效状态;任务历史来源查询包含 answer 创建的任务。具体检查与回退见本地运维文档。
510
-
511
- 消息处理详情默认展示原文、中文步骤结论及执行限制;耗时按本次实际开始/完成时间显示。连续同话题消息在共享判断内列出来源并高亮当前消息,可切换查看;页面不提供技术详情,接口只返回步骤结论、耗时和来源消息,不传原始输入输出。
512
-
513
- 任务详情使用紧凑编号时间线:标题与耗时同排、产出按标签展开、进度条表示已完成步骤比例。节点产出补充材料正文、文件清单、变更和已记录检查结果;此次需同时安装 Assistant 与 Observer,沿用只读分页接口及既有备份/回读流程,无 schema 变更。
514
-
515
- 新工程任务采用交付物契约 v9:确认项目与修改起点、创建独立 Git 工作目录、编写修改方案、检查修改方案、按方案修改文件、构建与检查修改结果。方案节点持久化可下载的 `修改方案.md` 文档工件和可应用补丁;应用前检查文档非空、长度和变更文件覆盖,这不等于证明方案技术正确。工作目录回执包含实际位置和来源仓库,当前使用独立 Git 仓库而非 git worktree。检查报告明确打包、构建、测试及跳过测试的范围,不把命令成功当成业务验收通过。历史节点保留原定义;未保存方案说明时仅提供由实际补丁整理的 `修改记录.md`,不补造理由或重跑任务。
516
-
517
- 节点产出统一核对当前分析/工程链:只读分页附带 overview,文件数量依据完整工件去重;默认显示读取、修改、索引或方案涉及数量,展开后才渲染正文与清单。提交/推送准备、执行回执、PR 草稿/创建/回读分别呈现,不相互冒充。未知结构标明“已保存节点产出,暂未提供可读展示”。
518
-
519
- 方案编写及方案检查节点只显示实际方案工件路径,不展示正文、文件数量、展开或下载入口。当前文档与补丁持久化在 JSON 工件中,因此显示真实 JSON 路径,不虚构独立 Markdown 文件路径;其余节点保持原展示。
520
-
521
- 新工程流程 v10 将“构建检查”和“业务验收”拆成两个节点。构建成功只允许进入业务验收;缺少受信验收用例、没有实际值或实际与预期不符时,业务验收保持等待,阻止后续提交,不自动循环重试。验收通过展示验收项、预期、实际和结论。既有 v1–v9 记录保持原定义,不补造历史业务验收节点;v10 用于新任务与受管重发。部署仍需双包更新、备份及独立回读,无 schema 迁移。
522
-
523
- ## 开发 PR 的 UAT 环境选择
524
-
525
- 开发任务必须由用户明确指定 `uat1`~`uat9` 中的一个环境。Host 固定映射为 `feature/uat1-base`~`feature/uat9-base`,例如 `uat4` 对应 `feature/uat4-base`。缺少环境、范围描述或多个候选时先询问,不能从仓库默认分支、历史部署环境或模型判断中猜测。
526
-
527
- 消息参数使用 `uatEnvironment`,目标随任务要求及工程运行配置冻结;发起前检查对应远端分支存在,创建 PR 时核对冻结的精确目标。`baseRef` 仍表示开发代码基线,不作为 PR 目标的默认值。重发任务只可复用此前明确的环境,或提供新的明确环境。
528
-
529
- 合并 `main` 使用独立 `task-main-pr-merge` 上线任务,要求精确 PR/SHA、UAT 和业务验收证据及真人批准。未配置受信 `mainMergeAdapter` 时该流程不可发起;普通开发流程不能代替上线流程。现存 PR 不会因规则更新自动改目标或合并。
530
-
531
- 任务详情顶部右侧显示总耗时(包含排队、等待和重试):未结束时每秒更新,已结束时截止到终态记录更新时间;缺失时间明确标注,沿用现有任务接口,不额外加载历史。
532
-
533
- 任务详情同时显示总执行时长:累计全部业务步骤及重试的实际执行区间,并行区间只计一次,排除排队与等待;不含消息判断和任务负责会话。缺失记录会明确标注。
534
-
535
- ## 开发流程的本地业务验收
536
-
537
- 新工程流程 v11 在构建后依次核对本地验收条件、编写验收用例、准备验收环境、启动服务并执行验收、核对验收与清理结果,通过后才提交代码。用例必须覆盖本次任务的全部验收条件;运行修改后的本地服务,通过受信场景执行真实业务操作并记录预期、实际与判定。服务启动、业务操作、数据清理及进程停止在同一有界执行中管理,避免服务生命周期跨节点失控。
538
-
539
- Windows 本地验收以 PID 与创建时间共同核对进程归属和停止结果,排除历史父 PID 复用造成的无关进程关联;原任务子孙仍存活或创建时间无法确认时继续阻断。进程快照输出上限为 1 MiB,超限按检查失败处理。
540
-
541
- `uat1`~`uat9` 仍须用户明确指定并映射对应 PR 目标分支;九个环境共用同一套 UAT 数据库。本地验收使用任务专属数据标识,只清理本任务数据。验收失败、未得到实际结果、清理未确认或回执不属于当前代码与方案时,流程停止在提交之前。
542
-
543
- 每个项目通过 `repositories[].localAcceptance` 配置固定命令及仓库外的共享 UAT 连接文件,详见 [受信平台工作流](docs/ops/trusted-platform-workflows.md)。缺少配置时显示待补充原因,不自动选择数据连接或生成任意执行命令。实际接入支持 `dataset` 与 `dataset-web` 两个项目,当前受信配置仅接受用户明确选择的 UAT2;配置生成、真实 runner 验收、profile 激活与实例重启分别回读,不把生成配置当成部署成功。
544
-
545
-
546
- ### Dataset 与 Dataset Web 的受信只读验收
547
-
548
- 两项目复用三个 Host 脚本:`scripts/local-acceptance-project.mjs` 准备候选并启动本地服务,`scripts/local-acceptance-readonly.mjs` 执行受限 API/浏览器读取及会话清理,`scripts/configure-project-local-acceptance.mjs` 将已验收配置接入目标 profile。项目配置与登录材料均在仓库外,Agent 只按登记场景提供参数。
549
-
550
- - Dataset 使用 JDK11/Maven 在候选目录构建,启用真实鉴权并显式关闭后台任务;执行真实 UAT2 登录及本地候选只读查询。
551
- - Dataset Web 使用固定 Node22、Yarn1.22.21 和锁文件准备真实前端,伴随启动按 SHA256 固定的本地后端 JAR;代理与浏览器回执核对后端 origin 和制品 SHA,SSO 明确使用 UAT2。
552
- - 当前场景不创建业务数据,只读接口限于登记的单位分页、草稿和工作区查询,浏览器禁止未登记请求及外发遥测。登录页或通用查询无法证明修改功能时,必须补对应场景,不能冒充业务验收通过。
553
- - 清理确认覆盖本次认证会话注销、独立失效回读、浏览器关闭及本地服务停止;当前无业务数据写入,因此不执行共享数据库删除。
554
-
555
- 依赖路径、配置 bundle 生成、实际 runner 验收与激活命令见 [双项目接入步骤](docs/ops/trusted-platform-workflows.md#dataset-与-dataset-web-实际接入步骤)。只有实际回执、安装配置及重启后的独立回读均完成后,才能报告对应阶段完成。
556
-
557
- 更新既有验收配置时,配置工具的 `--apply` 必须携带已审阅 profile 的 `--expected-sha256`;`--check` 零写入,应用使用独占锁、原文备份及回读,保留 `!!js`。本次后端 UAT3、前端 UAT2 的合并策略通过可选 `--merge-policy` 接入,仅接受已登记的业务场景;具体命令见 [历史任务配置更新](docs/ops/trusted-platform-workflows.md#两项历史任务的配置更新dataset-uat3--dataset-web-uat2)。
558
-
559
- 开发流程 v12 在创建独立工作目录前检查本任务(重执行时为原任务)的已登记开发分支:存在则从远端最新提交继续开发,不新建分支;不存在才创建。任务身份与开发分支身份分开。目录产出显示开发分支、复用/新建结论及 UAT 提测目标;目录仍为独立 Git 仓库。远端分支有并发变更时停止,不能覆盖。
560
-
561
- 工程流程 v14 补齐方案与应用修改节点的起点依赖,保留旧流程冻结定义。失败重执行通过正式取消与新请求保留审计;完整验证仍包含业务验收、清理、PR、UAT 合并及部署回读,见[部署规程](docs/ops/resident-review-local-deployment.md)。
562
-
563
- 取消任务待执行排空后展示“已结束 / 已取消”,不再被历史 Owner 错误覆盖为等待。暂停和取消期间保留未读事件,但不领取 Owner 回合;重新授权恢复后才继续处理。正在取消仍显示等待执行结束,不提前宣告终态。
564
-
565
- 工程构建或业务验收明确失败后,Owner 可读取真实失败日志并提交 `repairCurrentStage`,在同一 Run 创建新代修复;`wait` 不会启动修复。Host 核对当前要求版本、Run 版本与代次、排空和外部效果状态。上一失败候选只作为保留有效改动的只读材料,新的候选须重新构建、验收和清理。见[工程失败修复合同](docs/spec/task-engineering-failure-repair.md)。
566
-
567
- ### 工程恢复与 UAT 合入并发保护
568
-
569
- 确定性节点失败不会由定时恢复反复重派;明确暂态错误最多三次持久化退避重试,未知外部效果只允许对账。工程补丁歧义/基线冲突由 Owner 在同 Run 新代读取冻结旧工作区与失败方案修复,保留预算消耗和证据。UAT 合入使用已验收 head、祖先关系及显式 expectedBase 租约,仅允许快进;保留 PR、required checks、分支保护和实际合入回读,不能借管理员权限绕过保护。详见 [受信平台运维](docs/ops/trusted-platform-workflows.md#uat-原子合入与确定性失败恢复)。
570
-
571
- ### 编译产物的后台关闭证明与后端专项检查
572
-
573
- `prepare-dataset` 在打包后、启动共享 UAT 配置前运行受信 `LocalAcceptanceBackground.java`。探针利用候选 JAR 的 Spring 类库建立隔离上下文,验证关闭模式下七个既有后台入口不注册、黑名单缓存只执行首次读取而不定时刷新;同时检查开启及默认模式,扫描候选类中的调度、事件、消息监听与 Runner/Lifecycle 入口。新增未审阅入口直接阻断。探针禁止网络、外部进程和文件写入,不启动完整业务应用;普通 `@PostConstruct` 不自动认定为后台任务。证明记录 JAR 与探针 SHA256,不能用源文件注解字符串替代。
248
+ 默认运行与修改直接相关的测试。需要全量回归时运行 `pnpm test`;它限定 `test/*.test.js`,避免扫描 `docs/tmp` 中已有隔离业务仓库。保留已有 `.test-runs/` 与 `docs/tmp/` 数据。
574
249
 
575
- 后端专项 Host 检查使用 `scripts/verify-dataset-unit-tests.mjs --java <JDK11/java.exe> --maven-home <Maven目录>`,在当前候选目录运行 `MergePreviewCalculatorTest`、`MergeWeightAllocatorTest`。固定 Surefire 2.22.2,使用原生 `surefire.reportNameSuffix` 为每次执行分配唯一报告后缀;JDK XML 校验要求两类均有实际用例、零失败/错误/跳过。准备工具 `docs/acceptance/topic-context-completeness/scripts/prepare-backend-unit-checks.mjs <请求JSON绝对路径> <新提案JSON绝对路径>` 只生成 dataset-package 的新版本 steps 提案;请求含 checks、toolsDirectory、nodeExecutable、javaExecutable、mavenHome。提案必须经正式冻结配置流程接纳,旧任务检查不被改写。
250
+ 测试覆盖真实原生 Session/preset/持久化、事务故障注入、独立进程重启、取消与动态调度,但脚本化模型、隔离平台和测试进程不能代替现场 provider、OS 沙箱、生产服务或钉钉交付验收。测试接口只在显式 `testApiEnabled` 时启用,resident 不应直接暴露公网。
576
251
 
577
- 受控本地部署使用持久维护屏障和封存停机许可;新实例完成恢复、备份与认证 Web 回读后才恢复派发。包摘要和 profile 摘要分别核验,详情见 [部署规程](docs/ops/resident-review-local-deployment.md#维护屏障与部署许可)。
252
+ 历史实现与运维资料仍保留在 `docs/spec`、`docs/api` 和 `docs/ops`。遇到与本文冲突的固定工作流、阶段验收、Owner 原生工具或权限自动提升说明,以当前任务会话源码及专用清洁启动 Runbook 为准;不要据旧资料恢复已退役的写入口。
578
253
 
579
- 工程 v15 支持“已有实现符合要求,重新验收”:方案明确选择无需修改,Host 核实实际读取、工作区与冻结树后继续完整构建和本地验收,任务步骤会明确显示无需修改的结论。旧工作流不原地改变。
254
+ 宿主 DSH 联合升级的历史验收与配置接纳证据见 [PR170 归档规程](docs/ops/dsh-unified-host-upgrade.md)及[离线续接记录](docs/acceptance/dsh-unified-upgrade/continuation.md)。这些资料保留宿主 alpha2 修复来源;本次任务数据仍执行清洁启动,不恢复旧任务迁移。
580
255
 
581
- 工程节点猜错允许范围内的文件路径时会得到 `not_found` 与 list/search 提示,可在同会话纠正后继续;越界、权限、链接和身份错误仍立即停止,不把任意工具错误放宽为可重试。
582
- 分页读取每次最多16000字符,list/search每次最多200条;正整数limit超限返回`invalid_limit`和建议参数,不读取正文,模型纠正后继续分页。
256
+ 任务统筹上下文只保留一份当前Host快照:旧快照及旧版历史标记在原生请求生命周期内退出模型surface,原始审计日志不删除。短文本直接展示;历史任务正文、重复材料及完整执行结果通过contentRef按需读取。执行目录保留身份、版本、目标、状态及结果入口,终态执行不再重复附带旧阶段进度;不能仅凭目录中的成功状态宣布业务完成。当前用户来源、作者、更正和约束保留,完整来源与执行目录始终可读。
583
257
 
584
- 交付节点等待 `DELIVERY_RECONCILIATION_REQUIRED` 时,任务恢复仅对同节点、同代、同输入的既有 unknown 操作执行只读对账。全部效果确认成功后才恢复原节点并复用持久回执;未知、明确失败或身份不一致均不重发写操作。GitHub 合并元数据短暂延迟、构建仍运行可由后续对账收敛。维护、暂停、停止、待处理新输入仍阻止派发;正常维护封存条件不变。
258
+ 当前运行中的原执行自行消费普通工具成功/失败,不逐条唤醒统筹。阶段成果、执行结束、真实未知效果、恢复/迟到结果和用户新指令仍触发统筹;已有十分钟真实日志巡检保留。统筹按阶段判断进展,避免连续工具调用造成重复快照和空等回合;正常工具/助手历史仍由原生上下文压缩管理,本机制不保证整个长期会话总长度恒定。
585
259
 
586
- UAT 构建提测和同提交重建的批准请求会展示在授权列表,包含冻结的 UAT 目标标识、仓库、服务及提交。可读 Web 任务与已配置群任务使用相同来源门禁;显示请求不增加批准权限。审批终态通知 Owner 使用固定长度身份摘要,重复或相反重复决策沿用首个持久终态,只产生一次 Owner 事件,避免批准已生效但接口因事件 ID 过长报错。
260
+ 模型返回已识别的上游过载或fetch failed时,不标业务blocked、不消费唤醒,按现有退避沿原统筹会话继续;已提交决定优先。旧版已误标TASK_SESSION_NO_SUBMISSION的任务,仅在原session当前lease的末尾turn/end精确证明临时模型错误、任务排空且无业务问题时补一次持久唤醒;普通配置错误不自动恢复。
587
261
 
588
- Web 明确指定的“开发 → UAT 合并 → UAT 部署”任务,若第三阶段取得可信流水线失败终态,Host 保留成功开发和合并阶段,在原任务中仅将第三阶段替换为一次同提交重建。重建项目、环境和提交来自原失败部署的冻结证明,目标须与原部署配置唯一对应;仍执行原有预检、阶段确认和重建审批。旧失败运行保留,重建再次失败不会自动重复重建,也不会重新开发或合并。
262
+ 任务统筹wait等待排队、运行或未排空的小目标时,看板仍归执行中;真实问题、业务阻塞或暂停归等待中。
589
263
 
590
- 任务列表与详情的顶层等待原因、阶段确认和预算续行入口只在当前任务确实等待时展示。已完成、执行中或排队任务不显示历史恢复原因;原始运行与节点记录仍保留用于内部恢复和排错,任务详情仅展示当前有效信息。
264
+ 任务统筹遇到无法自行解决的事项或授权边界时调用task_request_human,持久登记具体问题、原因、证据和已尝试动作并进入等待中。人工介入页只对当前任务待答事项开放原文答复;答复按受信Web身份留存来源,核对请求和版本后沿同任务/会话唤醒进入执行中。原群中被明确路由为该任务补充的本人答复也按相同来源核对闭环。答复仅针对申请事项,不代表无限授权或已完成验收,未知效果保护仍有效。
591
265
 
592
- 工程远端引用读取(仅 `git ls-remote`)对明确网络暂态最多尝试三次,每次 15 秒、间隔 250/500 毫秒。耗尽后显示 `ENGINEERING_REMOTE_READ_TRANSIENT`,受原有三次持久化退避限制;认证、权限、证书及不存在的分支不自动重试。其它 Git 命令没有新增重试。历史通用 `NODE_EXECUTION_FAILED` 不自动归类为网络错误,须按具体证据恢复。
266
+ 明确交办“部署到UAT”已包含该任务在目标UAT的实际部署,不能先做准备再申请同一发布的“最终批准”。提交、集成、构建、镜像摘要核验、目标工作负载更新和验证按既有范围持续完成;需要人工时说明尚未满足的具体条件,不能只因规则含“需批准”就忽略已经收到的批准。用户后续暂停或缩小范围仍优先,生产及数据操作等越界事项不由UAT授权推导。
593
267
 
594
- 已封存工作流接入全新空群使用 `scripts/cutover-message-workflow.mjs --enroll-empty-group`;它保留旧群封存记录,独立保存新群快照并 CAS 更新 profile 的工作流群列表。维护、停机、checkpoint 与中断恢复要求见 [本地执行基础运维](docs/ops/execution-foundation-local.md#已封存实例接入全新空群)。
268
+ 执行中的会话每10分钟进行一次真实日志巡检,十分钟时钟及观察序号保存在执行账中,重启不重置。Host从当前输入/租约对应的持久会话记录提取实际事件后唤醒统筹;统筹必须调用task_execution_progress读取记录,再对照目标判断进度和方向。最多返回最新8条、每条640字符的脱敏摘录及序号/摘要,未结束调用仅给引用;不重复注入整份日志。没有新日志不证明停止,running/进程存活不证明业务推进;不自动重放或取消。人工等待和暂停不会被巡检绕过。
595
269
 
596
- ### 群聊回复用语
270
+ 任务会话记录的查看不拥有任务写入权。已注册的任务/执行会话只由Host原生create/resume取得写句柄;普通会话页面仍可读取历史,但其后台激活不能抢占这些会话。未排空任务的空重试不清除原故障告警。此约束针对会话生命周期归属,不限制会话已配置的原生业务工具。
597
271
 
598
- 公开回复使用业务语言说明结果、限制、下一步和待确认问题,不展示插件任务/会话编号、内部调度机制或原始错误码。内部记录保留追踪信息;问答和负责人公开摘要在提交时检查,通知与恢复发送在外发前检查明确的内部标签。命中时拒绝发送,不自动改写已准备正文;需在内部诊断中排查并重新生成合适回复。正文检查是明确模式检查,不保证识别所有自然语言泄漏。业务代码、文件名和 PR 链接可正常提供。
272
+ 原生网页读取和搜索沿固定工具对象身份识别为只读,普通读取错误不再进入未知写效果账。旧版误记的网页读取错误通过 task_operation_reconcile 核验原调用、参数/结果摘要及同轮正常结束记录,执行已排空且无活动会话/job 才转为 failed;保留原 unknown 审计,不重放请求、不视为读取成功。原生 edit/write 的读取、版本、文件类型/大小和字面匹配前置拒绝按 Host 结构化 FS 错误码记为 failed/noEffect,保留错误与结果摘要,由原会话读取当前文件、纠正请求后继续,不因这类错误转人工。旧文件 unknown 通过同一 task_operation_reconcile 核验原生日志 data.error 错误码、精确调用与同轮正常结束证据后转 failed,保留审计,不按错误文字或当前文件内容推断原调用成功。取消、IO/权限/沙箱、未知错误及缺失真实终态仍保留未知保护。
599
273
 
600
- 新版工作流任务可在 Web 完成或取消后归档,归档时间写入原生控制账并在重启后保留;运行中、等待中、未排空租约或未知外部效果会拒绝归档。归档不重新执行任务、不发送群消息、不删除工程产物。旧版任务仍沿已有登记工作目录的预检、文档迁出和清理规则归档,安全门禁失败须先处理原因。
274
+ 原生工具错误若仍为未知效果,模型不能凭错误文字自行清账。操作人可在当前技术申请的本机Web回复中显式提供 `nativeFailureResolutions`(原operationId及摘要);`POST /tasks/:taskId/human-requests/:requestId/reply/check` 零写核验原日志、正常回合结束、排空和绑定只读调查。正式reply在单个事务内记录受信来源、结算全部指定失败并答复申请,保留完整原账和 `partialEffectsPossible`,不标成功或无效果、不重放。未确认的写效果仍受unknown保护。
601
275
 
602
- Web重执行任务卡片保留可读取原任务的群聊名称;本次执行来源和通知渠道仍为Web,未关联可读群聊时显示Web任务。
276
+ Web对原任务的补充、重开和取消沿已有话题继续,保留原文和独立意图收据。旧版本产生的Web重复话题可按原任务/applied关系在本机Check后归并;默认列表只展示当前话题,历史归并记录可通过includeMerged及原ID读取,不删除来源或重放动作。
603
277
 
604
- 任务卡片显示创建任务命令绑定的真实话题;Web重执行继承可读取原任务的话题,点击或键盘打开使用原话题群聊。话题页的关联任务包含这些Web重执行卡片。
278
+ 任务授权连续性:统筹和执行共同核对原始有权来源及近期补充,不以最初需求人身份过滤后续操作人指令。模型输入保留原始来源和最近19条来源(总计最多20条),完整来源可按目录读取;旧摘要不能覆盖新原文。技术恢复答复不新增授权,不自动撤销既有交办;后续明确暂停、撤销、改环境仍优先。已授权的必要准备继续完成,真实最终审批先准备后提出具体缺口;未知效果及原生权限拒绝继续有效。等待说明先说进度和具体缺口,再说需要用户决定什么,技术清单放证据。
605
279
 
606
- 话题创建规则:日常寒暄、随口聊天和无具体事项的泛泛感谢不创建话题、不强行关联已有话题,完整原文记为ignoredRefs并收口。混合消息只处理具体事项部分;与已有问题或任务相关的反馈、确认、继续跟进仍归入原话题,独立新事项才新建。此为Resident语义归类指引,不使用关键词正则判断。
280
+ 话题决策通过 `topicUpdate.summary` 维护累计摘要,供历史话题检索及后续决策使用;已处理且摘要为空的话题沿现有只读摘要请求补齐,不重新执行任务或发送群回复。
607
281
 
608
- 消息工作流的拆分节点允许以语义判断 `no_action` 结束无待办消息(闲聊、问候、无执行请求的收信测试等),必须完整覆盖原文并有成功节点记录,不创建话题、任务或澄清通知。明确的测试操作请求仍走正常事项流程。合法终态 `no_action` 不再占用未归类屏障;后续新消息可继续派发,真正尚未归类的消息仍阻断话题执行,无需改写历史状态。收信箱等待状态细分为“等待澄清”“等待补充材料”,提示显示当前待补充问题;真正失败仍显示“关联受阻”。
282
+ 通知回读允许已核验的 DWS 顶层无序列表项间换行(包括空行)消失;不删除正文中的空格、列表标记或段落边界,不变换代码围栏内列表。仍须独立核验原发送回执、目标群、发送者和原生引用;unknown 状态只回读,不重新发送。
609
283
 
610
- 领域完成验收的语义输入附带 Host 已核验的阶段执行事实:当前任务的阶段与 Run 身份、前驱输出、Run 时间/代次、节点执行器与状态,以及已应用的 Owner initialize/append 及原生 appendStages 规划回执。拒绝候选不作为已执行规划;超过 200 条规划回执时停止完成验收,不能用截断历史推断执行顺序。原始领域产物检查和冻结工作流定义不变。
284
+ 执行续办以 `executionId` 保留会话身份;`task_delegate.key` 是单次委派请求的幂等键。同一请求重试复用原 key 与目标,已完成后的新输入、新步骤使用新的稳定请求 key,并保留原 executionId。相同 key 改目标仍拒绝;不得通过换 key 绕过未知操作保护或重放已完成动作。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dingtalk-dsh-assistant",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "在 DeepSeek Harness 中运行的钉钉群聊个人助理与任务看板",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -41,35 +41,46 @@
41
41
  "node": ">=24"
42
42
  },
43
43
  "dependencies": {
44
- "@zzusp/dingtalk-dsh-assistant": "1.0.0",
45
- "@zzusp/dingtalk-dsh-observer": "1.0.0"
44
+ "@zzusp/dingtalk-dsh-assistant": "2.0.0",
45
+ "@zzusp/dingtalk-dsh-observer": "2.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@deepseek-ai/cordis": "4.0.2",
49
- "@deepseek-ai/cordis-plugin-loader": "1.0.3",
50
- "@deepseek-ai/dsh-agent": "0.1.2-rc.1",
51
- "@deepseek-ai/dsh-agent-instructions": "0.1.2-rc.1",
52
- "@deepseek-ai/dsh-agent-loop": "0.1.2-rc.1",
53
- "@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
54
- "@deepseek-ai/dsh-code-runtime": "0.1.2-rc.1",
55
- "@deepseek-ai/dsh-fs": "0.1.2-rc.1",
56
- "@deepseek-ai/dsh-goal": "0.1.2-rc.1",
57
- "@deepseek-ai/dsh-goal-round-driver": "0.1.2-rc.1",
58
- "@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
59
- "@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
60
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
61
- "@deepseek-ai/dsh-sandbox": "0.1.2-rc.1",
62
- "@deepseek-ai/dsh-scope": "0.1.2-rc.1",
63
- "@deepseek-ai/dsh-session": "0.1.2-rc.1",
64
- "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.2-rc.1",
65
- "@deepseek-ai/dsh-session-title": "0.1.2-rc.1",
66
- "@deepseek-ai/dsh-storage": "0.1.2-rc.1",
67
- "@deepseek-ai/dsh-storage-domain": "0.1.2-rc.1",
68
- "@deepseek-ai/dsh-storage-json": "0.1.2-rc.1",
69
- "@deepseek-ai/dsh-subagent": "0.1.2-rc.1",
70
- "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
71
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
72
- "@deepseek-ai/dsh-user-approval": "0.1.2-rc.1",
48
+ "@deepseek-ai/cordis": "4.0.5-alpha.1",
49
+ "@deepseek-ai/cordis-plugin-loader": "1.0.6-alpha.1",
50
+ "@deepseek-ai/dsh-commands": "0.2.1-alpha.2",
51
+ "@deepseek-ai/dsh-launch-environment": "0.2.1-alpha.2",
52
+ "@deepseek-ai/dsh-sandbox-policy": "0.2.1-alpha.2",
53
+ "@deepseek-ai/dsh-settings": "0.2.1-alpha.2",
54
+ "@deepseek-ai/dsh-shell": "0.2.1-alpha.2",
55
+ "@deepseek-ai/dsh-subprocess": "0.2.1-alpha.2",
56
+ "@deepseek-ai/dsh-util-time": "0.2.1-alpha.2",
57
+ "@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
58
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
59
+ "@deepseek-ai/dsh-agent-instructions": "0.2.1-alpha.2",
60
+ "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.2",
61
+ "@deepseek-ai/dsh-attachment": "0.2.1-alpha.2",
62
+ "@deepseek-ai/dsh-credentials-local": "0.2.1-alpha.2",
63
+ "@deepseek-ai/dsh-fs": "0.2.1-alpha.2",
64
+ "@deepseek-ai/dsh-goal": "0.2.1-alpha.2",
65
+ "@deepseek-ai/dsh-goal-round-driver": "0.2.1-alpha.2",
66
+ "@deepseek-ai/dsh-home-paths": "0.2.1-alpha.2",
67
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
68
+ "@deepseek-ai/dsh-permission-presets": "0.2.1-alpha.2",
69
+ "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.2",
70
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
71
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
72
+ "@deepseek-ai/dsh-session-persistence": "0.2.1-alpha.2",
73
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
74
+ "@deepseek-ai/dsh-working-directory": "0.2.1-alpha.2",
75
+ "@deepseek-ai/dsh-session-persistence-jsonl": "0.2.1-alpha.2",
76
+ "@deepseek-ai/dsh-session-title": "0.2.1-alpha.2",
77
+ "@deepseek-ai/dsh-storage": "0.2.1-alpha.2",
78
+ "@deepseek-ai/dsh-storage-domain": "0.2.1-alpha.2",
79
+ "@deepseek-ai/dsh-storage-json": "0.2.1-alpha.2",
80
+ "@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
81
+ "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.2",
82
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
83
+ "@deepseek-ai/dsh-user-approval": "0.2.1-alpha.2",
73
84
  "js-yaml": "4.1.1",
74
85
  "react": "^18.2.0",
75
86
  "undici": "^7.16.0",