根因:摄取结果只挂到「内存里的模型可见消息」(inbound.go 的 attachInboundAttachments), 落库时只传了 text、history.Message 没有 Document 字段 ⇒ 该列恒空 ⇒ 读侧 omitempty 导致 documents 键整个缺席 ⇒ 任何客户端只看到一条空消息。Web 侧不这样,是因为 gateway/session_persist.go 有 messageTextImageDocument 把 ContentTypeDocument 部件编码进该列 —— IM 路径缺的就是同一步。 修法:inboundAttachments.documentColumn() 复用 history.EncodeDocuments 同一口径写出该列; persistToMain/persistIsolated 增 document 参数并返回刚落库的消息;新增两段式第二段 persistTurnDocumentStatus 按 id 回写抽取结论(只补结论、按存储名匹配、匹配不到原样留), 与 gateway/session_document_status.go 逐字对齐。 契约零扩张:无新端点/帧/字段;0 附件 ⇒ 列空 ⇒ 键省略;形状即 web 的同一结构体。 测试 6 条(含元素 JSON 逐字断言、unreadable 带 reason、被拒不编造芯片、群聊隔离分支、 真循环端到端);变异两条(还原挂载 / 关闭结论回写)⇒ 各 4 条红。