568 lines
30 KiB
Markdown
568 lines
30 KiB
Markdown
# DWS Multi IM 优化方案
|
||
|
||
> 状态:Phase 0–4 已在当前分支实施;无下层能力的项目已以 typed 负面边界收口
|
||
>
|
||
> 日期:2026-08-03
|
||
>
|
||
> DWS 口径:当前分支 `codex/multi-im-optimization` 及其工作树;
|
||
> 设计对比基线为 `017258e5b49517e3787a3d373f90953c128eaf58`
|
||
>
|
||
> 对照基线:本机当前安装的 `lark-im`、`lark-shared`、`lark-contact`、
|
||
> `lark-event`
|
||
>
|
||
> 详细证据:[Lark IM 与 DWS Multi IM Skill 设计对比](lark-im-vs-dws-multi-im-design-review.md)
|
||
|
||
## 1. 一句话结论
|
||
|
||
DWS Multi IM 已在不推翻 Golden Route、不复制 Lark 全量手册的前提下,完成
|
||
Runtime、Schema、Skill 根入口、task references、Event 子产品和发布脚本链路的统一。
|
||
Lark 中值得借鉴的精确 task reference、身份能力矩阵、Card 工作流和结果合同
|
||
已转化为 DWS 的 typed descriptor 和 drift gate,而不是独立手写事实表。
|
||
|
||
目标不是“看起来像 Lark”,而是:
|
||
|
||
```text
|
||
任何合法加载路径
|
||
→ 选择同一个任务级入口
|
||
→ 使用同一个 typed resolver / Runtime gate / DTO
|
||
→ 得到可验证、可继续编排的结果
|
||
```
|
||
|
||
### 1.1 2026-08-03 实施检查点
|
||
|
||
当前工作区已完成全部计划交付:
|
||
|
||
- 新增 9 条 reviewed 高频 IM intent route fixture,并把 policy 接入 `make policy`;
|
||
- policy 从 CommandRegistry 绑定真实 Cobra leaf、从 `ResolveMeta` 读取 confirmation,校验
|
||
marker、selection 正负场景、fallback 安全、source-ref 路径/锚点和脚本合同;
|
||
- Chat/Event 根 Skill、任务 references、Mono 入口统一到 Golden Shortcut;原子 leaf 只保留
|
||
显式底层 fallback;
|
||
- Chat/Event selection 已收窄,旧单文件 CommandRegistry provenance 已迁移到当前 product shard;
|
||
- Shared 的公开 flag、默认 JSON、无统一成功 envelope、typed error/retry/profile 合同已按当前
|
||
Runtime 修正;
|
||
- 3 个 Chat 第二 Runtime 入口、1 个公共 helper 及其 Mono 副本已退役;生成器不再发布它们,policy
|
||
用精确退役路径防止回流;
|
||
- 当前分支的群名 resolver 已由并行开发补齐全量分页、停滞游标和安全页数上限保护,并通过
|
||
Chat/targetresolver 回归测试。
|
||
- `+chat-messages` 已支持有界 `--page-all`、typed continuation、消息去重、完整性 ledger 和
|
||
工作区内 `.json` 原子导出;`+conversation-list --page-all` 同样遵守服务端页上限并公开截断。
|
||
- Bot 多群发送已下沉 `+messages-send --groups|--groups-file`,统一确认一次并输出
|
||
`im.batch-write.v1` 逐目标 ledger;
|
||
- `+group-members` 与 `+chat-members-list` 已实现用户桶全量分页、稳定 ID 去重、用户/机器人
|
||
分桶、有界 continuation 和中途失败的 partial ledger;`+chat-create` 支持显式 owner 或
|
||
歧义安全的 owner 自然查询;
|
||
- 身份、消息结果、Card 流程和 IM 能力边界均有 typed descriptor;
|
||
[`contracts.md`](../skills/multi/dingtalk-chat/references/contracts.md) 的标记区块由 policy 与 Runtime
|
||
descriptor 逐字节比对;
|
||
- Card 已拆为 create/update/callback/schema 任务 reference;Event IM 已拆为 keys、lifecycle、
|
||
output/handoff、operations,Chat/Event 交接 ID 映射由 policy 锁定;
|
||
- 评测中高频出现的群搜索历史路径/位置参数、`--chat`、单值 `--message-ids` 和冗余
|
||
`aisearch --type person` 已加入不改变业务语义的兼容层;稳定 ID 类型误用在下层调用前失败。
|
||
- 群机器人、邀请链接和指定群 `@我` 已接受自然群目标并复用同一歧义安全 resolver;撤回可由
|
||
单个消息 ID 只读补齐会话上下文。
|
||
|
||
对下层当前不存在的 Thread writer、Bot 富媒体、Card action callback 和资源断点续传,
|
||
本轮没有伪造实现;它们已进入 typed 负面能力矩阵,Schema/Skill 明确引导到当前可用替代路径。
|
||
当平台提供真实下层接口时,再按 `Runtime → Schema → task reference → root navigation` 新增正向能力。
|
||
|
||
## 2. 当前基础与主要问题
|
||
|
||
### 2.1 已经做对的部分
|
||
|
||
当前分支已经完成 IM 高频主链升级:
|
||
|
||
- Chat 根 Skill 只保留 Golden Route、关键结果语义和按需 reference 导航;
|
||
- `+dm`、`+send-to-group`、`+messages-send`、`+chat-messages`、`+search-msg`、
|
||
`+chat-create` 和 `event +listen-im` 复用 typed target resolver;
|
||
- 自然目标的零命中和多候选会在写入前停止,解析和执行复用当前 profile;
|
||
- 消息读取具有 `complete`、`hasMore`、`failures` 和资源下载 ledger;`+chat-messages` 已支持
|
||
有界 `--page-all` 与原子文件导出,`+search-msg` 支持游标全量搜索和批量富化;
|
||
- `+listen-im` 能从自然目标和事件意图确定 EventKey 集合,并复用一个 consume 生命周期;
|
||
- 参数、安全、selection 和 interface 由 reviewed Schema 输入与 Runtime 交付。
|
||
|
||
这里不把“显式稳定 ID 必然在写入前完成跨 profile 校验”列为现有能力。当前 Runtime 没有为
|
||
任意显式 ID 携带可验证的 profile provenance;这类 ID 的来源仍由调用方负责,也可能到下游
|
||
权限或组织边界才被拒绝。
|
||
|
||
这些设计不应回退。
|
||
|
||
### 2.2 基线审计发现的问题
|
||
|
||
以下是实施前基线的问题清单。第 1–9 项和可由当前下层支撑的 Runtime 等价能力均已处理;
|
||
第 10 项中尚无平台接口的部分以显式负面合同收口,不作为本轮未完成项。
|
||
|
||
1. `chat-message.md`、`chat-group.md`、`chat-bot.md`、`chat-conversation.md` 和
|
||
`event-im.md` 仍会把 Agent 从 Golden Shortcut 带回手工查 ID 或原子命令;
|
||
2. 某些原子写 leaf 的 confirmation 比对应 Golden Shortcut 更弱,reference 回流可能绕开
|
||
typed resolver、稳定 DTO 或 `typed_yes` gate;
|
||
3. Chat 发布包携带 3 个 Python 入口和 1 个公共 helper,其中两个入口直接选择第一个搜索结果;现已从
|
||
Multi/Mono 发布树删除,功能由 typed Shortcut 接管;
|
||
4. Mono/Multi 存在同名脚本副本且内容已经分叉;现已取消这组脚本的生成与发布,
|
||
policy 对全部退役路径 fail closed;
|
||
5. Shared 的全局输出、flag 和错误文档部分落后于当前 Runtime;
|
||
6. 现有 policy 主要证明根 Skill 预算和 Shortcut Runtime,不证明完整加载链一致;
|
||
7. reviewed selection 中仍有 Shortcut 与原子工具同时声明同一高频正向场景,修 reference
|
||
不能单独消除 Schema 选路歧义;
|
||
8. `selection/chat.json` 当前仍有约 120 个 `source_refs` 指向已不存在的旧版单文件
|
||
`schema_command_registry.json`;已迁移到 `schema_command_registry/products/chat.json`,
|
||
Event 同步迁移,并由 policy 校验锚点;
|
||
9. Mono reference 仍直接推荐或列出待迁移脚本;现已迁移到 Runtime 命令并清理发布路径;
|
||
10. DWS 缺少 Lark 已形成闭环的任意 Card 编译/callback、富 Thread 回复等能力;现已对
|
||
DWS 真实支持的 streaming-text Card create/update 建立子产品 reference 和 typed workflow,
|
||
对 callback/Thread writer 建立显式不支持边界。
|
||
|
||
## 3. 优化原则
|
||
|
||
### 3.1 一个意图只能有一个默认入口
|
||
|
||
同一用户终点可以有底层 fallback,但不能在不同文件中出现两个并列默认答案。
|
||
|
||
例如:
|
||
|
||
```text
|
||
按姓名发消息 → +dm
|
||
高级/Bot/Webhook → +messages-send
|
||
建群 → +chat-create
|
||
引用回复 → +messages-reply
|
||
监听个人 IM → event +listen-im
|
||
```
|
||
|
||
原子命令只在 Shortcut 未暴露的特殊字段、原始响应或底层运维控制场景出现,并必须写明
|
||
`fallback_reason`、能力损失和确认差异。
|
||
|
||
高频意图使用 reviewed、机器可读的路由清单固定默认工具与允许 fallback,例如:
|
||
|
||
```json
|
||
{
|
||
"intent_id": "chat.create",
|
||
"preferred_tool": "chat.shortcut_chat_create",
|
||
"allowed_fallbacks": [
|
||
{
|
||
"tool": "chat.create_group_conversation",
|
||
"reason_code": "shortcut_missing_required_field"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
清单建议位于
|
||
`scripts/policy/multi-im-skill-chain/testdata/intent_routes.json`,reference 只写精确的
|
||
`intent_id` marker。它只拥有高频任务的选路断言,不创建命令身份、CLI path、参数或安全事实:
|
||
canonical tool 必须由 reviewed CommandRegistry 解析,confirmation 必须由 `ResolveMeta` 读取,
|
||
selection 正负场景仍由 `schema_hints/selection/<product>.json` 拥有。
|
||
|
||
### 3.2 Skill 负责选路,Runtime 负责确定性执行
|
||
|
||
Skill 不应自己完成以下工作:
|
||
|
||
- 搜索后选择 `users[0]` 或 `groups[0]`;
|
||
- 手工拼接跨步骤 ID;
|
||
- 自己兼容多代 JSON envelope;
|
||
- 用脚本重新实现分页、下载、重试、幂等和 partial failure;
|
||
- 根据文案猜测 confirmation。
|
||
|
||
这些都应由 typed resolver、Shortcut、稳定 DTO 和最终 Schema/Runtime gate 承担。
|
||
|
||
### 3.3 Reference 只拥有一种主要职责
|
||
|
||
每个 reference 应明确属于以下一种类型:
|
||
|
||
| 类型 | 内容 | 不应包含 |
|
||
|---|---|---|
|
||
| Task reference | 默认入口、任务边界、结果、错误和 continuation | 全量原子 Catalog |
|
||
| Platform semantics | 对象区别、身份限制、平台不可推导规则 | 重复完整 flags 表 |
|
||
| Atomic fallback | Shortcut 未覆盖的底层能力 | 高频意图选路 |
|
||
| Static resource | emoji、枚举、Card 组件等受控数据 | 业务工作流 |
|
||
|
||
### 3.4 不改变现有稳定 Schema wire contract
|
||
|
||
优化应复用当前 CommandRegistry、ToolSpec、Schema Catalog 和 `ResolveMeta` 单一来源。
|
||
文档对齐不构成修改 JSON wire contract、重建第二套 identity source 或从生成物反向合并的
|
||
理由。
|
||
|
||
### 3.5 Profile 保证分层表达
|
||
|
||
- 自然目标:resolver 在当前 profile 内完成唯一解析,并由同一 RuntimeContext 执行;
|
||
- Agent 编排:reference 和 script 禁止缓存后跨 profile 复用解析结果;
|
||
- 显式稳定 ID:没有 provenance 时不承诺本地预写拦截,只能说明其来源由调用方负责;
|
||
- 若未来需要硬保证,应引入携带 profile/organization provenance 的 typed target,并让写入
|
||
Shortcut 验证它;不能只靠 Skill 文案宣称已经实现。
|
||
|
||
## 4. 从 Lark 借鉴什么
|
||
|
||
### 4.1 借鉴精确 task reference
|
||
|
||
Lark 为高阶 Shortcut 提供精确 reference,每个文件通常包含:
|
||
|
||
```text
|
||
适用任务
|
||
→ 身份/权限
|
||
→ 参数边界
|
||
→ 输出字段与完整性
|
||
→ 常见错误
|
||
→ 后续动作
|
||
```
|
||
|
||
DWS 不需要为 97 个 Chat Shortcut 各建一个文件,但高频且语义复杂的任务应采用这个
|
||
模板。优先覆盖:
|
||
|
||
- 消息发送;
|
||
- 消息读取/搜索/资源;
|
||
- 引用回复与转发;
|
||
- 建群与批量成员解析;
|
||
- Bot/Webhook;
|
||
- 实时 IM 监听;
|
||
- Card 创建/更新及未来 callback。
|
||
|
||
### 4.2 借鉴显式身份能力矩阵
|
||
|
||
Lark 会明确 user/bot 的 token、可见性、群成员关系和 Scope 差异。DWS 已在 Runtime 中
|
||
校验真实能力,但不能再由 Skill 手写一份独立事实表。应先在 `internal/shortcut/chat/` 抽取
|
||
typed identity capability descriptor,至少表达 identity、target kinds、content kinds、自然目标
|
||
解析支持和失败恢复类别,并让现有校验逻辑与测试共同约束它。
|
||
|
||
短矩阵由该 descriptor 与最终 leaf Schema/Help 受控生成或校验后再投影到 Skill。过渡期只链接
|
||
精确 leaf Schema,不复制 user/bot/webhook 能力表。矩阵只描述 DWS Runtime 已发布事实,不从
|
||
Lark 推导平台能力,也不成为新的身份或参数来源。
|
||
|
||
### 4.3 借鉴结果合同和富化说明
|
||
|
||
Lark 对 reaction、更新时间、thread、资源下载、分页和缺字段语义有精确说明。DWS 已有更强
|
||
的完整性 ledger,应把它固定为所有消息读取 Shortcut 的公共合同:
|
||
|
||
- 稳定消息投影字段;
|
||
- reaction/updateTime/resourceRefs 的来源;
|
||
- `--no-reactions` 与 `--download-resources` 的成本边界;
|
||
- `complete=false`、`hasMore=true`、单项 failure 的含义;
|
||
- 子消息 ID 与父 conversation fallback 规则;
|
||
- 下载的相对路径、默认不覆盖、原子落盘和跨主机 header 规则。
|
||
|
||
发布公共文档前,应在 `internal/shortcut/chatmsg/` 抽取 typed message result contract,使 Runtime
|
||
输出、分页/完整性测试和文档投影共享同一组字段定义。生成的 Markdown 片段只能单向发布到
|
||
Skill,不能反向作为 Catalog、参数或 Runtime 输入。过渡期 references 只链接精确 leaf Schema
|
||
并说明当前单页边界,不复制一张可能漂移的字段表。
|
||
|
||
### 4.4 借鉴 Card 子产品化
|
||
|
||
Lark Card 不是一个散落的 JSON 示例,而是独立的 workflow + schema + style + components +
|
||
callback 子树。DWS 若继续扩展卡片能力,也应采用同样的分层思想:
|
||
|
||
```text
|
||
card/
|
||
├── create.md # 创建/校验/发送流程
|
||
├── update.md # 流式状态与结束状态
|
||
├── callback.md # 当前负面边界;平台真实支持后升级
|
||
├── schema.md # DWS 卡片模型,不复制 Lark JSON
|
||
├── style.md # 可选的 Agent 设计规则
|
||
└── components/ # 仅收录 DWS Runtime 真正支持的组件
|
||
```
|
||
|
||
在 callback 或任意组件下层未真实支持前,Skill 必须明确 `avoid_when`,不能通过文档先行
|
||
伪造能力。
|
||
|
||
### 4.5 借鉴“脚本不是第二 Runtime”
|
||
|
||
Lark IM 没有产品脚本重新解析 CLI 输出;分页、富化、下载、目标解析和事件生命周期都在
|
||
Shortcut/CLI 内。DWS 应采用同一原则:
|
||
|
||
- 完全被 Shortcut 覆盖的脚本删除;
|
||
- 仍有通用价值的批量流程下沉为 typed Runtime Shortcut;
|
||
- 只有暂时无法下沉的纯结果格式转换才允许脚本存在,而且只能消费稳定 DTO,不调用原子
|
||
写命令,也不能自行做候选选择。
|
||
|
||
### 4.6 借鉴精确 Event 运维合同
|
||
|
||
保留 Lark 值得借鉴的 ready marker、stdin/SIGTERM 干净退出、结构化错误和禁止 `kill -9`
|
||
规则;继续使用 DWS 更适合 Agent 的多 EventKey 单生命周期和自然目标编译,不退回
|
||
“一 EventKey 一进程”。
|
||
|
||
## 5. 不应照搬什么
|
||
|
||
- 不复制 Lark 的 `open_id`、`chat_id`、`message_id`、Scope 和 EventKey;
|
||
- 不假设 DWS user/bot 对富媒体、Thread、Card 的支持与 Lark 对称;
|
||
- 不把 Lark Feed Group、Feed Shortcut、Flag 字段直接映射成 DWS category/Top/Favorite;
|
||
- 不强制所有正常 Chat 任务预加载完整 `dws-shared`;
|
||
- 不在 DWS 根 Skill 放完整原子 API、静态 Scope 表或 97 条 Shortcut Catalog;
|
||
- 不为文件数量对齐而机械创建 58 个 reference;
|
||
- 不采用一 EventKey 一进程的 Lark 实现限制;
|
||
- 不因借鉴 Lark 而修改 DWS 已发布的稳定 Schema wire contract。
|
||
|
||
## 6. 按文件的实施结果
|
||
|
||
### 6.1 Chat 根 Skill
|
||
|
||
文件:[`skills/multi/dingtalk-chat/SKILL.md`](../skills/multi/dingtalk-chat/SKILL.md)
|
||
|
||
保持了小根入口,没有重新展开完整 Shortcut 表,并已补充:
|
||
|
||
1. identity/message/Card/capability boundary 的单一 typed contract reference;
|
||
2. 消息分页/导出、Bot 多群 ledger、owner 选择和 Card 负面边界的精确入口;
|
||
3. 只包含 `intent_id` 的导航校验 marker,默认工具从 reviewed 路由清单解析;
|
||
4. Card create/update/callback/schema 子产品的直达链接。
|
||
|
||
### 6.2 Chat references
|
||
|
||
| 文件 | 实施结果 |
|
||
|---|---|
|
||
| [`01-messaging.md`](../skills/multi/dingtalk-chat/references/01-messaging.md) | 作为任务级编排主 reference,已接入 identity/result/fallback 合同 |
|
||
| [`chat-message.md`](../skills/multi/dingtalk-chat/references/chat/chat-message.md) | 默认发送/回复/读取/搜索已收敛到 Golden Shortcut;明确 Thread writer、callback 和 resume 的负面边界 |
|
||
| [`chat-group.md`](../skills/multi/dingtalk-chat/references/chat/chat-group.md) | 建群统一到 `+chat-create`;新增 owner 选择、成员全量分页和用户/机器人分桶语义 |
|
||
| [`chat-bot.md`](../skills/multi/dingtalk-chat/references/chat/chat-bot.md) | Bot/Webhook 发送统一到 `+messages-send`;补多群 ledger,明确 Bot 富媒体当前不支持 |
|
||
| [`chat-conversation.md`](../skills/multi/dingtalk-chat/references/chat/chat-conversation.md) | 按会话 Top/消息 Top/Favorite/category 分流,自然目标统一走 typed resolver |
|
||
| [`chat.md`](../skills/multi/dingtalk-chat/references/chat.md) | 已降级为低频原子 Catalog,不与高频 Golden Route 竞争 |
|
||
| [`intent-guide.md`](../skills/multi/dingtalk-chat/references/intent-guide.md) | 保留对象层级消歧和禁止回流原子写路径的负例 |
|
||
| `lite-recipes.md` | 已删除无信息中转层 |
|
||
| [`chat-emoji-list.md`](../skills/multi/dingtalk-chat/references/chat-emoji-list.md) | 已标注 reviewed snapshot 来源、更新日期和维护方式 |
|
||
| [`contracts.md`](../skills/multi/dingtalk-chat/references/contracts.md) | 新增 typed 身份、消息结果、Card 和能力边界投影,受 byte-exact policy 约束 |
|
||
| [`card/`](../skills/multi/dingtalk-chat/references/card/) | 新增 create/update/callback/schema 四个子产品 reference |
|
||
|
||
### 6.3 Event
|
||
|
||
已实施文件:
|
||
|
||
- [`skills/multi/dingtalk-event/SKILL.md`](../skills/multi/dingtalk-event/SKILL.md)
|
||
- [`event-im.md`](../skills/multi/dingtalk-event/references/event-im.md)
|
||
- [`event-im-keys.md`](../skills/multi/dingtalk-event/references/event-im-keys.md)
|
||
- [`event-im-lifecycle.md`](../skills/multi/dingtalk-event/references/event-im-lifecycle.md)
|
||
- [`event-im-output.md`](../skills/multi/dingtalk-event/references/event-im-output.md)
|
||
- [`event-im-operations.md`](../skills/multi/dingtalk-event/references/event-im-operations.md)
|
||
|
||
实施结果:
|
||
|
||
1. 保留 `+listen-im` 为消息/reaction/read/recall 的唯一高频入口;
|
||
2. 自动回复示例统一使用 `dws chat +messages-send`;
|
||
3. 将旧宽 reference 拆为 EventKey/Filter、lifecycle、output/handoff、operations/troubleshooting;
|
||
4. 根 Skill 只保留 ready、bounded/unbounded、干净退出等不可省略的宿主合同;
|
||
5. 订阅保护文件、重试预算和紧急恢复进入 operations reference;
|
||
6. 增加 Chat/Event 交接 drift gate,确保 `conversation_id` 和
|
||
`sender_open_dingtalk_id` 只映射到对应稳定 ID 参数。
|
||
|
||
### 6.4 Shared、Profile、Contact 与 AI Search
|
||
|
||
| 文件/产品 | 实施结果 |
|
||
|---|---|
|
||
| `dws-shared/global-reference.md` | 已按当前 Help/Runtime 修复默认输出、全局 flag 和 envelope |
|
||
| `dws-shared/error-codes.md` | 已修复 Chat text/flag、confirmation 和 profile 错误恢复说明 |
|
||
| `dws-shared/SKILL.md` | 已将最小契约覆盖说明收窄到真实发布边界 |
|
||
| `dingtalk-profile` | 继续拥有组织/profile 选择;Chat reference 只引用,不复制 |
|
||
| `dingtalk-contact` | 明确资料查询与完整手机号职责;普通 DM 不再要求先 Contact |
|
||
| `dingtalk-aisearch` | 保留人员语义和跨源搜索;普通发消息/读群不再成为强制前置 |
|
||
|
||
### 6.5 产品 scripts
|
||
|
||
| 退役 script | Runtime 替代 |
|
||
|---|---|
|
||
| `chat_history_with_user.py` | `+chat-messages --user-query --page-all --output *.json` |
|
||
| `chat_export_messages.py` | `+chat-messages --chat-query --page-all --output *.json` |
|
||
| `bot_broadcast.py` | `+messages-send --as bot --groups|--groups-file`,输出 `im.batch-write.v1` |
|
||
|
||
3 个入口和 1 个公共 helper 的 Multi/Mono 共 8 个发布路径已删除,生成器不再复制;
|
||
退役清单受 policy 精确路径校验。
|
||
替代能力已覆盖目标唯一解析、分页终止/停滞防护、页数/条数上限、partial failure、
|
||
完整性 ledger、安全输出路径、默认不覆盖、原子发布和批量写逐项结果。
|
||
|
||
### 6.6 Schema 与 Runtime
|
||
|
||
1. 不因文档修改机械改 reviewed CommandRegistry;当前分支的根清单位于
|
||
[`schema_command_registry/registry.json`](../internal/cli/schema_command_registry/registry.json),
|
||
Chat owning shard 位于
|
||
[`products/chat.json`](../internal/cli/schema_command_registry/products/chat.json)。只有
|
||
canonical identity、primary path、alias 或 visibility 真正变化时才修改;
|
||
2. selection 路由变化写入
|
||
[`schema_hints/selection/chat.json`](../internal/cli/schema_hints/selection/chat.json);
|
||
高频路由调整必须同时处理 Shortcut 和对应原子工具:Shortcut 承接普通正向场景,原子工具
|
||
只保留未覆盖字段/原始响应场景,并在 `avoid_when` 中明确普通任务走 Shortcut;
|
||
3. confirmation、runtime gate、interface 或参数 overlay 变化写入
|
||
[`schema_hints/metadata/chat.json`](../internal/cli/schema_hints/metadata/chat.json);
|
||
4. Event 同理修改各自 owning block;
|
||
5. typed resolver、消息投影、下载 ledger 和 Event consume 保持共享组件,不在每个 Shortcut
|
||
复制实现;
|
||
6. 修复 `selection/chat.json` 中指向旧版 `schema_command_registry.json` 的失效
|
||
`source_refs`,并增加精确路径存在性校验;
|
||
7. 新 Card/Thread/资源能力必须先有 Runtime 与 typed contract,再写 Skill reference。
|
||
|
||
## 7. 分阶段实施结果
|
||
|
||
### Phase 0:冻结正确主链(已完成)
|
||
|
||
- 9 个高频 intent 已有 reviewed route fixture 和精确 marker;
|
||
- canonical path 由 CommandRegistry 解析,confirmation 由 `ResolveMeta` 读取;
|
||
- policy 会拒绝孤儿/重复 marker、非法 fallback、安全降级、失效 source-ref 和根导航断链。
|
||
|
||
### Phase 1:selection、文档与 provenance 收敛(已完成)
|
||
|
||
- Chat/Event 根入口、冲突 references、Mono 产品索引和 Shared 合同已统一;
|
||
- Shortcut 承接普通正向场景,原子 leaf 仅保留特殊字段/原始响应 fallback;
|
||
- Chat/Event `source_refs` 已迁移到当前 product shard。
|
||
|
||
### Phase 2:Runtime 等价能力与脚本退役(已完成)
|
||
|
||
- `+chat-messages` 具备有界全量分页、typed continuation、去重、停滞防护、partial ledger
|
||
和安全 `.json` 原子导出;
|
||
- Bot broadcast 已下沉为 `+messages-send` 多群模式和 `im.batch-write.v1`;
|
||
- 3 个 Chat 入口、1 个公共 helper 及其 Mono 副本(共 8 个路径)已删除,policy 防止重新发布。
|
||
|
||
### Phase 3:精确 references 与 typed 合同(已完成)
|
||
|
||
- 发送、读取/资源、回复/转发、建群、Bot/Webhook 已按任务边界收敛;
|
||
- identity/message/Card/capability boundary 从 typed Runtime descriptor 投影到 `contracts.md`;
|
||
- Event IM 宽文件已拆为 4 个按需 reference,Card 已建立 4 个子产品 reference。
|
||
|
||
### Phase 4:真实能力闭环(已完成可实现范围)
|
||
|
||
| 能力 | 完成状态 |
|
||
|---|---|
|
||
| 群成员全量分页/分桶/partial result | 已实现,并将 `+chat-members-list` 纳入 reviewed Schema |
|
||
| 显式 owner/自然 owner 建群 | 已实现并去重 owner/member |
|
||
| streaming-text Card create/update | 已建立 typed workflow、flow-status validation 和精确 references |
|
||
| 身份矩阵 | 已实现 user/bot/webhook 目标、内容、自然解析、幂等和 ledger 合同 |
|
||
| Thread writer | 下层无接口;typed boundary 明确 `supported=false` |
|
||
| Bot 富媒体 | 下层当前仅 text/markdown;typed boundary 明确禁止宣告支持 |
|
||
| Card action callback | 下层无 callback 消费链;callback reference 只描述负面边界 |
|
||
| 资源断点续传 | 下层无 Range/resume;保留原子落盘与默认不覆盖 |
|
||
|
||
这些负面项不是文档遗漏,而是当前平台真实能力的 fail-closed 交付。
|
||
|
||
## 8. 已落地门禁
|
||
|
||
本轮已新增:
|
||
|
||
```text
|
||
scripts/policy/check-multi-im-skill-chain.sh
|
||
scripts/policy/multi-im-skill-chain/main.go
|
||
scripts/policy/multi-im-skill-chain/main_test.go
|
||
scripts/policy/multi-im-skill-chain/testdata/intent_routes.json
|
||
```
|
||
|
||
该布局沿用现有 `scripts/policy/*/main.go` 约定,已接入 `make policy`。
|
||
`intent_routes.json` 是 reviewed policy fixture,不是 CommandRegistry、参数或安全元数据来源。
|
||
|
||
至少检查:
|
||
|
||
1. Chat/Event 根 Skill 的所有相对 reference 链接可解析;
|
||
2. 每个受控 reference marker 都能精确映射到唯一 manifest intent,且没有孤儿或重复 ID;
|
||
3. manifest 的 preferred/fallback canonical tool 都能经当前 CommandRegistry 绑定到可执行
|
||
Cobra leaf;
|
||
4. 标记区块中的默认 CLI path 与 preferred tool 一致,不出现未允许的原子 fallback;
|
||
5. Shortcut 与对应原子工具的 selection 正负场景符合 manifest 的默认/例外关系;
|
||
6. 写路径的 Runtime confirmation 通过 `ResolveMeta` 获取并与文档声明一致;
|
||
7. `source_refs` 中的仓库路径和锚点可解析,不再接受旧 CommandRegistry 路径;
|
||
8. 退役脚本的 Multi/Mono 精确路径不得再出现;
|
||
9. Chat/Event 交接必须使用稳定 conversation/sender ID;
|
||
10. identity/message/Card/capability boundary 文档片段必须与 typed descriptor 逐字节一致;
|
||
11. Shared 文档中的 flag/example 能通过真实 Cobra command tree;
|
||
12. 新 `+chat-members-list` leaf 必须持续绑定真实 Cobra/Schema 命令;
|
||
13. 只扫描 manifest 和 marker 声明的精确文件/区块,不用自然语言相似度,也不使用会隐藏
|
||
未来命令的通配豁免。
|
||
|
||
## 9. 验证矩阵
|
||
|
||
当前分支的最终验证矩阵为:
|
||
|
||
```bash
|
||
python3 scripts/gen_skill_shortcut_sections.py --check
|
||
./scripts/policy/check-multi-im-skill-chain.sh
|
||
./scripts/policy/check-skill-context-budget.sh
|
||
./scripts/policy/check-skill-commands.sh
|
||
./scripts/policy/check-runtime-confirmation-truth.sh
|
||
./scripts/policy/check-schema-catalog.sh
|
||
./scripts/policy/check-generated-drift.sh
|
||
|
||
go test ./internal/shortcut/targetresolver -count=1
|
||
go test ./internal/shortcut/chat ./internal/shortcut/smart ./internal/app \
|
||
-run 'Test.*(NaturalTarget|MessageView|MessagesSend|MessagesReply|ChatCreate|ListenIM)' \
|
||
-count=1
|
||
go test ./internal/app -run '^(TestEventListenIM|Test.*ListenIM.*)$' -count=1
|
||
```
|
||
|
||
由于本轮修改了 Agent-visible command、selection、metadata 和参数,以下生成与交付校验为必跑项:
|
||
|
||
```bash
|
||
make generate-schema
|
||
./scripts/policy/check-runtime-confirmation-truth.sh
|
||
./scripts/policy/check-generated-drift.sh
|
||
./scripts/policy/check-schema-catalog.sh
|
||
```
|
||
|
||
真实写审计只在需要验证对应能力时运行,不能用 live audit 代替上述确定性门禁。
|
||
|
||
### 9.1 本轮最终结果
|
||
|
||
2026-08-03 在当前稳定工作树上复验:
|
||
|
||
- `make generate-schema` 成功:26 产品、849 工具、159 组参数别名;
|
||
- Multi IM policy 通过:9 个 reviewed intent;
|
||
- Skill 命令面通过:1009 条可执行 path;
|
||
- Runtime confirmation truth 通过:137 个 gated 工具;
|
||
- Schema Catalog、CommandRegistry 和两次独立生成漂移检查通过;
|
||
- `DWS_PACKAGE_VERSION=0.0.0-test go test -p 1 ./...` 通过;默认包级并行复跑曾因
|
||
`internal/helpers` 的共享测试环境竞争失败一次,该包隔离强制复跑通过;
|
||
- `go build -o /tmp/dws-multi-im-build ./cmd` 通过。
|
||
|
||
### 9.2 真实环境端到端审计
|
||
|
||
2026-08-03 使用当前分支构建的 CLI、有效个人登录态和真实 DingTalk 后端完成两组审计。
|
||
报告只保留命令名、下层工具名、数量和脱敏错误类别,不落业务 payload:
|
||
|
||
```bash
|
||
python3 scripts/run_chat_shortcut_live_audit.py \
|
||
--dws /tmp/dws-multi-im-final \
|
||
--out-dir /tmp/dws-im-live-audit-019fc653/read-current-branch \
|
||
--timeout 90 --max-group-probes 8 --max-member-probes 8
|
||
|
||
python3 scripts/run_chat_shortcut_live_write_audit.py \
|
||
--dws /tmp/dws-multi-im-final \
|
||
--out-dir /tmp/dws-im-live-audit-019fc653/write-current-branch \
|
||
--timeout 90 --yes-live
|
||
```
|
||
|
||
结果:
|
||
|
||
- 读链路共 34 项:28 项 `pass`,2 项 `pass_empty`,4 项 `fixture_blocked`,无投影
|
||
不一致、下层错误或超时;
|
||
- 写链路共 57 项:46 项 `pass`,11 项 `external_fixture_required`,无执行错误;
|
||
- 写审计使用单用户临时群,并在 `finally` 中恢复可逆开关、解散临时群;按 4 类审计
|
||
名称前缀复查,残留为 0;
|
||
- 未覆盖项都保留精确 fixture 原因:数字 `groupId`、真实 `openTaskId`、媒体消息、配置
|
||
完成的机器人/Webhook、第二测试成员和待审批入群请求;不使用业务数据伪造通过;
|
||
- `+conversation-mute-at-all` 和 `+conversation-mute-red-envelope` 均在真实环境通过,旧 Mono
|
||
reference 的“当前不可用”结论已移除;真实前置条件是先开启总免打扰,否则平台返回
|
||
`NotificationOffNotEnabled`;连续审计两个子开关时,红包应先于 @所有人,或在恢复
|
||
@所有人通知后重新开启总免打扰;
|
||
- `+at-me` 曾因上层同时提供 `messages`/`items` 兼容别名被审计器重复计数,现固定选择一个
|
||
canonical message projection;该问题属于审计器误报,不是 Runtime 数据丢失;
|
||
- 首轮 `+messages-list-unread-conversations` 出现一次瞬时后端超时,同一原子入口和最终
|
||
完整复测均通过,未将瞬时故障掩盖为 contract-only。
|
||
|
||
真实审计补充确定性门禁,但不替代 Schema、policy、单元测试和全量 Go 测试。
|
||
|
||
## 10. 完成定义
|
||
|
||
DWS Multi IM 优化完成应同时满足:
|
||
|
||
- 根 Skill、所有精确 references 和相关子产品对同一意图选择同一默认入口;
|
||
- 不存在自然目标取第一候选、reference 指示跨 profile 复用解析结果或第二 Runtime 猜
|
||
envelope;没有 typed provenance 时,不对任意显式稳定 ID 宣称本地跨 profile 硬校验;
|
||
- 写操作的 confirmation 在文档、Schema、Runtime 和最终交付路径一致;
|
||
- 单页和全量消息读取、资源下载始终暴露完整性/失败 ledger;全量替代脚本时具备明确分页
|
||
上限、终止和导出合同;
|
||
- 高频任务不需要预加载完整 Shared、产品 Catalog 或原子命令全集;
|
||
- 原子 fallback 有明确原因和能力损失说明;
|
||
- Shortcut/原子 selection 不为同一普通任务同时声明正向默认入口;
|
||
- reviewed `source_refs` 指向当前存在的 authored source 或可验证 Runtime evidence;
|
||
- 退役脚本不在 Mono/Multi 发布树中,且不会被生成器重新引入;
|
||
- Card、Thread、Bot、资源等能力只发布下层真实支持的正向范围,其余由 typed
|
||
负面边界防止误选;
|
||
- 所有生成、Schema、policy 和 focused Runtime tests 通过;
|
||
- 不改变未版本化的稳定 Schema wire contract。
|
||
|
||
## 11. Review 交接
|
||
|
||
当前工作树已同时包含路由/文档、Runtime 等价能力、脚本退役和真实能力边界四类改动。
|
||
Review 建议按以下四个逻辑分组查看,但不应将它们当作未完成的后续 PR:
|
||
|
||
1. reviewed intent route、selection/metadata、CommandRegistry 与生成 Catalog;
|
||
2. typed resolver、message/member/card/identity contracts 与 Runtime tests;
|
||
3. Chat/Event/Card references、Shared/Mono 消费者与 typed drift policy;
|
||
4. 退役脚本、生成器发布边界与防回流门禁。
|