# 发给自己：跨主题延展与详情一致性回归

## 问题与根因

场景：未分类快记 A 被延展为 B，之后仅将 B 放入主题。

- 聚合个人列表带有 A 的引用，但主题分页中的同一 B 可能完全没有 `parent_record_uid`。
- `records/detail` 和批量读取的基本记录也没有该关系；不能用“主题列表没给引用”判断“消息没有来源”。
- 现有 `/api/v1/records/extensions/tree` 能返回 B 的顶层 `parent_record_uid`，以及 A 的记录，即使 `tree` 以 B 为中心、`edges` 和 B 的子回复都是空数组。
- 原详情只消费列表附带的引用，因而不同入口显示不一致。
- 相关快记原有读取已按记录身份查询，不按主题过滤；加载期间原来完全隐藏，易被误认为缺少内容。

## 本次处理

1. 复用既有云端延展树；独立解析当前消息的直接来源，不误用整棵树的根或兄弟节点。
2. 新增插件内部只读操作 `source.message-extension.parent`。仍需有效来源和签名消息操作引用，不接受任意记录 UID 读取。
3. 个人消息列表仅为可见区域及附近缺失引用的记录补读，最多并行 2 个；同一来源版本已完成的记录不重复读取，切换账号或来源取消旧请求。
4. 完整详情从消息自己的延展关系补齐来源；主题外的来源可经“全部”定位打开，并支持返回原子消息。
5. 详情始终显示消息所属主题；时间线气泡仍保持不重复展示当前主题的简约规则。
6. 相关快记以轻量文字提示正在加载；成功刷新期间保留当前内容；错误可重试，真实空结果仍不占空间。
7. 原有私聊、群聊引用定位方式不变；私密、不可访问或已删除的来源不泄露正文。

## 验证

- 类型检查、构建、差异空白检查通过。
- 13 个相关测试文件，共 858 项通过，包含消息发送/目录、详情、角色头像、服务授权和插件操作分发。
- 后续补充的跨主题气泡点击及取消信号分发测试通过。
- 3100 独立预览更新，浏览器实际验证：
  - “未分类 A → 延展 B → B 移入主题”：B 的主题气泡恢复引用；主题内外详情都显示 A、正文、所属主题；点击 A 打开详情，A 的回复列表含 B，可返回 B。
  - 另一条已有内容的消息在全部与主题内均显示 1 条相关快记、2 条延展，包含正确的本我头像及本地角色表现。
  - 无回复时不显示空的延展区域。
- 验证仅使用已有消息读取和页面导航，未发送、移动或删除真实消息；未修改已安装桌面客户端，未推送代码。

## 云端待排查：相关快记结果波动

本次联调同一用户、同一记录、同一组参数的 `/api/v1/records/related/query`，先返回 20 条，随后返回 0 条，再次打开后又返回 20 条。直接请求云端也捕获到 HTTP 200、业务 code 0、`items: []`（另有 `recall_mode` 字段），不只是前端渲染现象。

固定参数形状：`record_uid`、`record_owner_user_id`、`context_type: "record"`、`limit: 20`；不传主题条件。前端没有把空结果替换成历史结果，也没有合成相关内容。

请后端排查同一记录的召回策略、索引就绪状态及空结果稳定性。如果空表示“索引/召回暂未就绪”而非“确实没有关联”，建议提供明确状态或可重试标记，使各端能区分暂不可用与真正为空。本次不能保证云端在不同时刻返回完全相同的相关条目。
