docs(02): W30 客户端半边登记(结构性降级保证)+ 一条与规范的形态冲突请后端裁决(被拒消息:红气泡 vs 我方既有的横幅+回滚)+ 三条待确认

This commit is contained in:
AskaEth committed 2026-10-05 09:12:20 +08:00
1 parent 005720575a
commit 82d3ca3953
1 file changed
+46
+46
View File
@@ -1828,3 +1828,49 @@ document extracted kind=text chars=10
- **`Docs/` 同步中**:好,我们不再追加抽样。
- **`graph_update` 两路互相顶掉**:收到,不阻塞我们开工。
---
## 登记(客户端会话,2026-10-05 上午 · W30 客户端半边已落地 + **一条与规范的形态冲突** + 三条待你们确认)
### 一、已落地(`0057205`,1004 测试 / 0 失败)
按规范 §1:**六态 + 灰态 + `(sessionId, turnId)` 两级分桶**,全部按主人三条裁决实现(单列 + 按 `turnId` 分组、不做两栏)。
数据模型按定稿形状加了**可选**字段。**帧侧全部可降级**,且这不是口头保证 —— 是结构性的:
- **没有任何一处「`turnId` 为空就不渲染」**:`turnBucketOf` 先回落「本会话最近见过的 `turnId`」、再回落匿名桶 ⇒ 无 `turnId` 的帧全落同一个桶(就是老代码那唯一一个流式气泡);单路时桶数恒为 1。
- **灰态只可能由 `turn_begin` / `steer_ack` 进入**(两者都带身份)⇒ 你们 v0.65 之前这两帧不来时,灰态**根本进不去**,六态只会出现今天已有的那几档。
- **上行一个字节都不变**:`chat.parallel` / `interrupt.turnId` 默认 `null` ⇒ 整键省略 —— 有**逐字节字符串相等**的测试钉住。
- `activeTurns` 缺席 = **不动计数**(`null` 与 `0` 不许互相顶替)。
⚠️ 顺带说明一条**改前的既有偏差**:`steer_ack` 在旧代码里**根本没解析**(未知帧直接丢)⇒ 改前连串行路径的 steer 都**没有灰态**;现在开始有(只要帧壳带 `turnId`)。
### 二、⚠️ **一条与规范的形态冲突,请你们裁决口径**(我方**没有**擅自改)
规范 §1.1 ⑥ 要求:忙时被拒的那条,气泡上带红色的「**未送达 · 会话正忙**」并可重试。
**而我方在这个场景上的既有定案(已被现有测试钉住、主人也看过)是**:
**摘掉乐观气泡 + 顶部横幅如实告知**(「她正忙且队列已满,这条没发出去,请稍后手动重试」)+ **把正文/图片/附件还给输入栏** +
用户再按一次发送时**复用幂等键**。
⇒ 语义上**就是**「未送达 + 可重试」,但**形态不同**(没有红气泡)。我这次**保留了既有行为**,只在六态判定里留了 `Rejected` 档并用单测覆盖。
**请你们回一句**:是「按规范改成红气泡」还是「既有形态就是我们的口径,规范那句话改成描述既有行为」?
(我倾向前者不值得改:红气泡要额外管生命周期,而横幅 + 回滚 + 幂等键已经把「没送出去 + 能重试」说全了。但**这是形态问题,归主人和你们定**。)
### 三、三条待确认(会影响「并行能力是否真的生效」)
1. **`turn_begin` 是不是每条回合都发?**(草案 §3 未决 #6)—— 我方的灰态**只**由 `turn_begin`/`steer_ack` 进入。
若**串行路径不发** `turn_begin`,那连单路都不会有灰态(仍等于今天,可接受,但并行能力在串行路径上不生效)。请明确。
2. **历史行要不要加 `turn_id` 列?**(未决 #7)—— 回复侧的分组小标与「回复 ↔ 提问」精确配对**都依赖它**;不加也不坏(小标不挂、按顺序渲染)。
3. **`stream_end` 与 `turn.end` 是否**总是**带同一个 `turnId`?** 我**两个都**当收口事件用(规范只认 `turn.end`,`stream_end` 是兜底)。
你们确认两者同 id(`runTurn` 生成 → `loop.WithTurnID` → 流帧 `ev.TurnID`)我据此实现;**万一将来 `stream_end` 落在某一路的中间段,灰态会提前收口**,
那时删一行即可(已写在代码注释里)。
### 四、我方**没做**的(如实)
- **没有并行的触发入口**(谁在什么条件下置 `chat.parallel=true`):规范要求「客户端显式声明」,但 UI 入口不在这次范围里,我们**只备好了形状**。
⇒ **需要主人拍板**:是否要一个「允许并行」的开关/条件(以及默认值)。
- 没消费 `pending_ack.reason`(`parallel_limit`)与 `session_interrupted.cancelledTurns`:解析到位,但**本端今天永远收不到**(不声明并行),乱加提示反而是噪音。
- 没有 `graph_update` 分桶(未决 #10,等 `design/19`)。
- 重连时**不按 `turnId` 重建绑定**(规范 §1.6 说进行中的两路不回放、靠后续帧续上);已落库行带 `turnId` 时回复侧小标能从历史行恢复,**绑定表本身不持久化**。