Files
trade-message-center/.trellis/tasks/09-11-remove-image-dimensions/prd.md
T

5.3 KiB
Raw Blame History

从 OneTalk 图片链路移除宽高

Goal

让 Mind 发往 OneTalk 的图片在 OneTalk 原生发送成功并出现完整 live sent 事实后,能稳定取得 confirmed_sent;宽度与高度不再是任何公开或持久化图片事实、匹配条件、协议字段或展示元数据。

Background and confirmed facts

  • 当前链路存在矛盾:MAIN 上传回调的最终 relation metadata 容许没有 width / heightapps/chrome-extension/src/onetalk/main-page/image-send.ts:185-217),但 live decoder 和共享 OneTalkImageContent 将它们设为必填(apps/chrome-extension/src/onetalk/main-page/message-observer/content-decoder.ts:201-210apps/onetalk-contract/src/content.ts:18-30,282-296)。无宽高的真实图片因此变成 media_invalid_schema,不会参与 sendObservation,随后 timeout 为 delivery_unknown
  • OneTalkImageContent 写入 onetalk_message.content JSONB;严格读取投影会再次使用同一 guard(apps/server/src/onetalk/read-projection.ts:95-110)。只改运行时代码会让旧图片 JSONB 无法读取。
  • 当前 Mind 测试支架会校验并展示宽高(apps/mind-test-harness/src/harness/validators.ts:21-24apps/mind-test-harness/src/harness/messages.ts:21-26)。检索到的 /Users/ybf/work/trade-mind 工作副本把 Bright message content 作为通用 JSON 读取,未找到图片宽高字段消费者。
  • OneTalk 原始上游 payload 仍可能带宽高;本任务不控制或改写上游 payload,只规定在 MAIN 解码边界忽略它们,绝不跨出该边界。
  • 现有 WebSocket/消息合同采用 exact-shape v1 content 和 protocol v5。旧扩展会继续发送带宽高的 image content;新扩展会省略它们,因此这是跨版本协议兼容性决策。

Requirements

  1. 共享 OneTalkImageContent、其 exact-shape guard、全部 frame/result/public read model 仅保留图片的 fileIdextensionsizeBytesisOriginalmd5previewUrlurlScope;不得保留或接受 widthheight
  2. MAIN raw-image decoder 必须忽略上游 raw payload 的宽高,并且在其缺失、错误、超界或存在时均不会因宽高生成 anomaly;其余图片安全校验和 URL allowlist 不变。
  3. 图片发送的 post-upload metadata 和 live correlator 不再读取、保存或比较宽高;仍按候选 message ID 优先,或按同会话、sent 方向、图片 kind、size、md5/fileId(可用时)、时间窗和唯一性确认。歧义仍为 send_ambiguous,不以 SDK/HTTP 成功冒充确认。
  4. Mind 测试支架和当前仓库内的测试 fixture / validator /展示不得读取、传输或显示宽高。
  5. 新迁移必须从既有 onetalk_message.contentkind=image JSONB 中删除两个键;迁移不可修改既有 migration,且只影响图片事实。完成后所有历史图片应通过新的 strict guard 和读取投影。
  6. 当前非归档文档中定义图片 canonical contract、匹配条件或支架展示的内容必须同步为无宽高版本;保留原始 OneTalk payload 历史证据,但明确它被边界忽略。

Out of scope

  • 改动 OneTalk 上游原始 WebSocket payload、上传压缩策略、图片文件本身或 OneTalk 的 UI 尺寸行为。
  • 改变 confirmed_sent 的事实条件、45 秒图片预算、send result 三态、授权、会话路由、数据库幂等键或自动重试策略。
  • 修改外部 trade-mind 工作区;当前证据没有找到其字段级宽高消费者。
  • 修改归档 Trellis task 的历史记录。

Acceptance criteria

  • widthheight 不再出现在本仓库任何非归档的 image canonical type、validator、normalized content、send correlator expected metadata、Mind test-harness validator/rendering、fixture 或 public result/read payload 中。
  • 同一 image raw payload 无论是否包含任意值/类型的 width / height,都会在其它必填字段有效时解码为相同的无宽高 canonical image content;无宽高 live sent 图片可使匹配的 image attempt 得到 confirmed_sent
  • 保留候选 ID 优先、错误会话/方向不匹配、时间窗、相同内容并发歧义、下载/upload/native send 错误以及 45 秒 timeout 的既有安全语义。
  • 对迁移前带宽高的图片 JSONB,迁移后仅移除这两个顶层 content 键;非图片内容和其它 image 字段不变,新的 server read projection 可读。
  • shared contract、extension、server、harness 的受影响测试、类型检查、构建、格式检查和 migration check 通过;有 TEST_DATABASE_URL 时,PostgreSQL integration 以不超过 60 秒的超时验证数据迁移。
  • Chromium 复验一次 Mind 图片发送:图片在 OneTalk 出现后,live observation 得到 canonical 无宽高 message 并向 Mind 返回 confirmed_sent。若现场条件不可用,清楚记录为未验证而不声称完成。

Release decision

  • 用户已批准严格升级:wire protocol 从 v5 升到 v6,不接收或剥离旧 v5 image content 的宽高。旧端必须收到明确的协议升级错误,不能静默继续传递已废弃字段。
  • 因此需要协调停机窗口:先停止旧 server 对已迁移图片 JSONB 的读取,再执行一次性 JSONB 数据迁移,启动 v6 server,发布/重连 v6 extension 和实际 Mind client。部署不完整时的显式不可用优于隐藏兼容或错误确认。