IM / 队列 / 出站 — 架构不变量(短清单)
Tier1:与 AGENTS.md(仓库根)一致;修改消息链或出站路径时先对照本文,再更新 architecture-overview.md 中的流程描述。
IM 栈 — 入站
- 平台/SDK 组装
Message后,必须由Adapter.emit('message.receive', message)进入框架(见packages/core/src/adapter.ts)。 - 存在
MessageDispatcher时:await dispatcher.dispatch(message)先于根插件message.receive与adapter.on('message.receive')观察者。 - 业务路由、命令与 AI 互斥策略由 Dispatcher 与配置决定;不要把业务路由绑在仅
adapter.on('message.receive')上(该钩适合观测/控制台)。
IM 栈 — 出站(勿绕开)
- 业务发送须走
Message.$reply或Adapter.sendMessage→renderSendMessage(根插件before.sendMessage链)→bot.$sendMessage。 - 禁止在插件/业务代码中直接调用
bot.$sendMessage(除非你是适配器包内 Bot 实现本身)。否则绕过before.sendMessage与 Dispatcher 润色同源逻辑。CI 通过pnpm check:harness-paths对部分路径做静态扫描。 - Dispatcher 出站润色:仅当通过
replyWithPolish等路径时,getOutboundReplyStore()才有入站上下文;润色仍挂在根插件的before.sendMessage上。
队列栈(与 IM 平行)
本 monorepo 当前主分支若尚未包含 packages/queue-* 实现,以下仍作为契约与命名约定,供引入 qbot / 双队列时对齐(避免与 IM 各造一套键名):
- 队列模式业务出站入口:
enqueueOutgoing(及生产者侧claimOutgoing→executeOutbound);不要与 IM 栈的「经 Adapter 发送」混用或互相绕路。 - 事件载荷推荐形状见 event-contracts.md;与 IM 侧字段对齐见 queue-im-field-contract.md。
工具 / 策略(Agent 相关)
- 执行 shell 须经过
checkExecPolicy(packages/agent/src/zhin-agent/exec-policy.ts)与工具层封装;见 harness 测试packages/agent/tests/harness-inbound-tool-boundary.test.ts。 - 读文件:
read_file等工具组合使用isBlockedDevicePath(设备挂起路径)与checkFileAccess(敏感凭据路径);见packages/agent/src/file-policy.ts、builtin-tools.ts。