From 11602c01380aea85c7063f34c3975917b6243663 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 7 Oct 2026 17:39:38 +0800 Subject: [PATCH] =?UTF-8?q?docs(05):=20=E9=94=9A=E7=82=B9=E8=A1=A5?= =?UTF-8?q?=E8=AE=B0=E5=9B=9B=E5=8D=81=E4=B8=89=20=E2=80=94=E2=80=94=20?= =?UTF-8?q?=E8=A1=8C=E5=86=85=E6=A0=87=E7=AD=BE=E5=AF=B9=E9=BD=90=E5=A5=91?= =?UTF-8?q?=E7=BA=A6=20v0.89=EF=BC=88W68=20=E4=B8=A4=E8=BD=AE=EF=BC=9A?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99=E4=B8=8D=E6=95=8F=E6=84=9F=20+=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B8=A2=E5=BC=83=20+=20=E4=B8=8D=E5=B9=B3?= =?UTF-8?q?=E8=A1=A1=E6=95=B4=E6=AE=B5=E9=99=8D=E7=BA=A7=20+=20=E7=99=BD?= =?UTF-8?q?=E5=90=8D=E5=8D=95=E6=94=B6=E7=AA=84=E4=BA=94=E9=A1=B9=EF=BC=89?= =?UTF-8?q?+=20br=20=E6=94=B9=E6=B0=94=E6=B3=A1=E5=88=86=E9=9A=94=E7=AC=A6?= =?UTF-8?q?=EF=BC=88=E4=B8=8E=20p=20=E5=90=8C=E7=BA=A7=E3=80=81=E4=B8=89?= =?UTF-8?q?=E7=A7=8D=E5=86=99=E6=B3=95=E7=AD=89=E4=BB=B7=E3=80=81=E6=B5=81?= =?UTF-8?q?=E5=BC=8F=E5=90=8C=E6=BA=90=E6=89=A3=E7=95=99=EF=BC=89+=20?= =?UTF-8?q?=E7=9C=9F=E6=9C=BA=E5=85=AB=E7=BB=84=E6=A0=B7=E6=9C=AC=E9=80=90?= =?UTF-8?q?=E6=9D=A1=E9=AA=8C=E6=94=B6=20+=20=E4=B8=89=E6=9D=A1=E5=BE=85?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E7=A1=AE=E8=AE=A4=E7=9A=84=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devdocs/05-开发进度与交接.md | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/devdocs/05-开发进度与交接.md b/devdocs/05-开发进度与交接.md index 7891aea..ff44fcd 100644 --- a/devdocs/05-开发进度与交接.md +++ b/devdocs/05-开发进度与交接.md @@ -2344,3 +2344,59 @@ infinity maximum height constraints, which is disallowed. ### 6. 环境 - HEAD = **`3d4a9f2`** = `origin/android`;worktree / 分支 / 构建锁**全清**;主仓唯一脏 = `devdocs/02`。 - 模拟器装最新包(含 W58~W67),`tcp:80` 已切回**真后端**。 + +## ★★ 锚点补记四十三 · 行内标签对齐契约 v0.89(W68,两轮)+ `
` 语义变更 + 真机验收(2026-10-07 晚) + +### 1. 后端把这件事**升成了契约**(v0.89,推库 `2dae469` / `b989f0b`) + +`回执二十九` + `回执三十` + `回执三十一` 三条连着来,**第三条是更正**: + +- **白名单**:`b` / `strong` · `i` / `em` · `code`(**五项**,`u`/`s` 被收窄掉、`br` 移出)—— 成对;**标签名大小写不敏感**; +- **三条硬口径**:① 白名单外一律按纯文本原样(**字符一个不丢**);② **属性一律不解析**(`` 只取标签名);③ **结构不平衡 ⇒ 不渲染**(粒度算实现细节); +- **🔴 `回执三十一`(主人的新指令)**:**`
` 不是行内标签,而是「气泡/消息分隔符」,与 `

` 同级** —— `

甲
乙

` ⇒ **两个气泡**、无 `

` 时同理、`

` 中间空气泡照旧丢弃、三种写法等价; +- **安全红线**(双方都成立):助手文本是**不可信内容** ⇒ **不许把整段当 HTML 注入**; +- **`` 是模型的自然输出**(产出侧 grep 零命中),但**契约已承认**它 ⇒ 不再是「容错、不保证」; +- **IM 出站那个是他们的真 bug**(`sanitize.go` 的 `stripNarration` 没剥行内标签 ⇒ 发到微信/QQ 对方看到字面标签),**已派修**; +- 我们那三处差异,他们**主动让了两条**:白名单收窄到五项(我们不用做)、不平衡粒度算实现细节;**大小写留给我们定**。 + +### 2. 我们的定案(已写回 `02`) + +| 项 | 定案 | +|---|---| +| 大小写 | **统一到不敏感**(+ **同时**改流式扣留侧,否则中间态把 `` 吐上屏、收口再吃掉 = 字改口) | +| `u`/`s` | **撤掉**(多支持会造成跨端不一致:Web 不渲染、我们渲染 ⇒ 同一条消息两端显示不同) | +| 不平衡 | 改成**整段不渲染**(原口径是「局部降级」) | +| **`
`** | **改成气泡分隔符**(我们下午正好做成了「气泡内换行」,那是错的) | + +### 3. W68(两轮):`4b19278`(首轮)+ `9dee236`(纠正)→ 合并 **`591f298`** + +**首轮**(按我当时的认知):大小写不敏感(**消费侧与流式扣留侧同源一份判据**,避免分叉)、属性一律丢弃、结构不平衡整段降级、补了 `u`/`s` 与 `
`。 + +**纠正**:把 `
` 从**行内层**整体移到**切分层**(`BR_TAG_RE` + 新函数 `appendRegion`:每个文本区先 `stripLooseTags`、再按 `
` 切开补 `Tok.Break`,与 `

` 走**同一套机制、同一个粒度**);流式侧新增 `couldBeLineBreakNamePrefix`(残缺的 `` 不入栈**,一出现前缀就可产出);`u`/`s` 连枚举、渲染分支、import 一起撤净。 + +**跨分隔符标签的口径**(先按 `

`/`
` 切分、再各自行内解析)—— 三条硬理由:①「与 `

` 同级」本身规定了层序;②「一个气泡 = 一条消息」,而 Web 与 IM 出站的平衡判定都是**按单条消息**做的,跨分隔符的标签结构上不可能成立 ⇒ 两端结论天然一致;③ **反着做会让 `runs` 拼起来不再等于 `body`**,那条既有契约当场就没了。 + +**测试**:`ChatContentParserTest` 57 → **71**(14 条新增,`
` 契约表四行逐个断言**气泡数 + 各段文本**);`InlineMarkupTest` 删 6 条与 v0.89 冲突的、新增 3 条。全量 **126 suites / 1564 tests**。 + +### 4. 真机验收(`emulator-5554` + 假后端夹具,八组样本) + +| 输入 | 屏幕实测 | +|---|---| +| `

甲
乙

` | **两个气泡**「甲」「乙」 | +| `丙
丁`(无 `

`) | **两个气泡** | +| `

戊

己

` | 两气泡(**空气泡丢弃**) | +| `甲
乙
丙
丁` | **四个气泡**(三种写法 + 大小写 + 属性**全等价**) | +| `

庚
辛

` | 两气泡、**两条都是原文**(跨分隔符 ⇒ 不平衡 ⇒ 不渲染) | +| `

壬与粗

` | 「`壬`与**粗**」—— `u` 已撤掉显示字面、「粗」加粗 | +| `

甲乙

` | 一气泡、**字面** | +| `

大写粗加属性粗

` | 「大写粗加属性粗」—— 大小写不敏感 + 属性丢弃 | + +### 5. 三条**待后端确认**的口径(我们已写进 `02`,都是我们自定的) + +1. **`
` 的大小写**:我们按**不敏感**做(依据:v0.89「标签名大小写不敏感」当时罩着 `br` + 他们 Go 侧 `(?is)`);若他们只认小写,我们收窄两处。 +2. **`
` 在 `` / `` 内部也分隔**(按「**始终**」的字面读)⇒ 两半的标签因未配对回落字面;若他们在 Web/IM 有作用域保护,说一声。 +3. **已知边界(真实产出不存在,仅登记)**:`
` 出现在**别的标签的属性里**也会分隔(我们不解析外层属性结构);另有一条**先前就存在**的怪相(本次未改、改前改后同结果):`

甲

` 里 `
` 的 `>` 会提前闭合 `

`。 + +### 6. 环境 +- HEAD = **`591f298`** = `origin/android`;worktree / 分支 / 构建锁**全清**;主仓唯一脏 = `devdocs/02`。 +- 全量真跑:**126 suites / 1564 tests / 0 failures**。模拟器装最新包,`tcp:80` 已切回**真后端**。