Slate v2 Phase 9 Richtext 决策实录:用跨仓库对比矩阵把“模糊未覆盖”收口为 Comparison-Only
2026/9/15 20:13:25 网站建设 项目流程

Slate v2 Phase 9 Richtext 决策实录:用跨仓库对比矩阵把“模糊未覆盖”收口为 Comparison-Only

【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate

导读

本文围绕 Slate v2 替换工程(replacement envelope)中 Phase 9 的richtext家族决策展开:它不是一个“实现新功能”的计划,而是一次证据纪律层面的收口——通过向替换兼容性矩阵(replacement compatibility matrix)新增一条 legacyrichtext对比行,并用跨仓库本地运行器在真实浏览器环境中验证该行,从而把家族账本(family ledger)里richtext的“模糊、尚未覆盖”状态锐化为明确的comparison-only(仅对比、不宣称当前实现覆盖)。读完本文,你将理解替换矩阵的运转机制、run-cross-repo-local.sh双仓库运行器的用法、如何用一条矩阵切片阻止“假装 parity”与“夹带实现”两类工程失真的具体操作,以及该决策如何为后续 Phase 9 各家族(tables、embeds、editable-voids 等)提供方法论模板。

背景:替换包络中的矩阵、账本与记分板

Slate v2 的替换工程围绕三个互相约束的控制文档展开,richtext决策正是同时作用于这三者:

  • 替换兼容性矩阵:即replacement-compatibility.test.ts对应的浏览器对比行集合,它是证明“当前 v2 在哪些行为缝(seam)上可以与 legacy Slate 对照”的实证载体。其顶层状态由 replacement-gates-scoreboard.md 维护。
  • 替换家族账本(family ledger):replacement-family-ledger.md 按家族记录当前 v2 栈“保留(Preserved)/重定义(Redefined)/仅对比(Comparison-only)/有意延后(Intentionally Later)”四种状态。
  • 主路线图(master roadmap):master-roadmap.md 规定 tranche 顺序与执行教义,是所有 Phase 9 支持计划的“当前队列真相”来源。

本决策文档(docs/plans/2026-04-06-slate-v2-phase9-richtext-decision.md)被明确标注为Supporting plan,即它不取代路线图,而是路线图某一 slice 落地的过程记录。

Goal:让richtext家族在替换包络中不再模糊

Make therichtextfamily less vague in the replacement envelope.

模糊(vague)在这个语境里有具体所指:此前richtext在家族账本中的存在更像一个“后来再处理”的占位符——既没有被否认、也没有被证明,处于既不诚实也无从验证的灰色地带。本决策的目标是把这种模糊压缩掉,让richtext在替换包络中的位置可由一条矩阵行直接回答

Scope:本 slice 只做三件事

决策的范围被刻意收敛为三项,全部是“证据层”动作而非“实现层”动作:

  1. 为替换兼容性矩阵新增一条 legacyrichtext——注意是 legacy 行,即“legacy 侧存在该表面、当前 v2 尚未覆盖该表面”的对比条目;
  2. 用该条证据锐化家族账本——把richtext从泛化的“尚未覆盖”措辞改为逐家族、可核验的 comparison-only 措辞;
  3. 保持当前 v2 侧诚实——不发明一个虚假的richtext当前表面(no pretend current surface)。

三条范围项共同指向同一个原则:矩阵行的职责是让家族“可见且诚实”,而不是替实现团队预支承诺。

Constraints:三条不可逾越的纪律

范围之外,决策文档还显式列出三条约束,它们本质上是本次工作的验收红线:

  • 不假装当前的 richtext parity:任何“当前 v2 已达到 richtext 平级”的表述都不被允许,即使局部行为(如某个 mark 的切换)看起来可用。
  • 不在矩阵切片内隐藏大范围 richtext 实现批次:矩阵行是“对比证据”,不是“实现入口”。如果某个 slice 实际上承载了一个 broad richtext implementation batch,它就违反了本约束,哪怕矩阵行本身通过验证。
  • 必须通过当前端口3010的跨仓库本地运行器验证:证据不能停留在纸面,必须跑起来。

这三条约束与记分板规则中的一条一脉相承:“a gate is not green because nearby proof is green”(邻近证明为绿不代表该 gate 为绿),以及“parity success does not close a north-star gate automatically”(parity 成功不会自动关闭北星 gate)。可见本决策是整个替换工程“诚实证明文化”的一个切片级落地。

关键机制:跨仓库本地运行器与双仓库对比

要理解验证命令,先要理解背后的运行器。跨仓库对比基建在 2026-04-06-slate-v2-cross-repo-comparison-and-scoreboard.md 中完整落地,核心资产包括:

  • scripts/run-cross-repo-local.sh:跨仓库本地运行器,负责把当前仓库(plate 侧的 slate-v2 栈)与本地另一个slate仓库同时拉起;
  • playwright/integration/examples/replacement-compatibility.test.ts:替换兼容性对比行所在的 Playwright 测试;
  • 替换占位符基准与替换超大文档基准脚本;
  • 根 package.json 中对应的本地命令(如yarn test:replacement:compat:local);
  • 记分板文档 replacement-gates-scoreboard.md。

从本决策文档给出的实际命令可以看到运行器的调用形态:

bash ./scripts/run-cross-repo-local.sh 3010 /examples/rich-inline ../slate 3210 /examples/richtext "yarn build:slate-browser:playwright && yarn exec playwright test playwright/integration/examples/replacement-compatibility.test.ts --project=chromium --workers=1"

逐段拆解:

参数含义
3010当前仓库(slate-v2 侧)的本地端口,验证过程固定使用3010以满足约束
/examples/rich-inline当前仓库侧用于承载对比行为的示例路径
../slate被对比的 legacy 仓库相对路径(本地 sibling 目录)
3210legacy 仓库侧的本地端口
/examples/richtextlegacy 仓库侧被对比的richtext示例路径
"yarn build:slate-browser:playwright && yarn exec playwright test ..."先在浏览器侧完成构建(slate-browser的 Playwright 构建),再以单 worker 的 Chromium 项目跑替换兼容性测试

注意--workers=1--project=chromium:单 worker 保证双仓库并行服务下浏览器断言的可复现性;Chromium 是替换工程浏览器证明的默认事实标准(scoreboard 中 v2-only 示例行同样全部以 Chromium 证明)。命令中的构建步骤说明:矩阵验证依赖slate-browser的 Playwright 构建产物,而不是直接对源码做单元级断言——这是浏览器级(browser-proof)而非运行时级(runtime-proof)的证据。

Progress:从“加一行”到“账本锐化”的落地顺序

决策文档记录的进度严格按 Scope 推进:

  1. 新增一行:向替换兼容性矩阵加入 legacyrichtext行;
  2. 跑通证明:通过上述跨仓库本地运行器把该行跑绿(该步同时验证了/examples/richtext这条 legacy 对比缝在双仓库并联下真实存在、可加载、可断言);
  3. 锐化账本:基于该证据更新家族账本——richtext现在被明确定位为comparison-only,即“legacy 可见性存在,但当前家族声明尚不存在”,不再是模糊的 not-yet-covered;
  4. 同步上层文档:同步记分板与顶层 v2 文档,让落地的 Phase 9 slice 在路线图栈中可见。

这四条顺序本身就是方法论:证据先于措辞,措辞先于同步。任何一步颠倒都会回到“模糊”状态。

事后验证:richtext家族账本的最终形态

把视角拉到决策落地之后,家族账本中richtext的条目已经不再是 comparison-only 的“历史快照”,而是被后续批次继续推进为Redefined(replacement-family-ledger.md 的 Richtext Family 条目):

  • 浏览器证明覆盖strongemcodeblockquoteheading-one、扩展选区(expanded selection)加粗的添加/移除、段落缝上的持续输入;
  • 运行时证明覆盖:任意 intrinsic 标签、renderLeaf(...)宿主所有权、扩展选区 mark 添加/移除;
  • 明确“不是什么”:不是对所有旧 richtext 行为的 blanket parity,也不是旧工具栏/插件架构。

同时,example-parity-matrix.md 中richtext行在 2026-04-15 的 git-diff 重基线后被升级为recovered:源码与 legacy 的相似度0.874、diff 行数225,Chromium 证明覆盖渲染、浏览器文本插入以及“撤销恢复被删除的选中富文本”。这一行也从侧面印证了本决策的价值:矩阵行先保证了“可见”,后续批次再逐缝把“可见”推进为“已恢复”,每一步都有独立证据,没有一步是跳步的。

另一个有意思的收尾在 legacy Playwright 漂移表:legacyselect.test.ts(三击段落选择意图)的当前所有者被显式映射到richtext.test.ts的当前浏览器缝上——这意味着richtext这条缝后来承担了不止一个 legacy 测试意图的所有权,成为浏览器边界证明的汇聚点。

方法论模板:本决策如何复制到其他家族

本决策并非孤例。紧随其后的 2026-04-07-slate-v2-phase9-structural-comparison-families.md 完全复用了同一套模板,把tablesembedseditable-voids从泛化的“later”桶中拉出来,变成有矩阵行支撑的 comparison-only 状态,验证命令结构完全一致(仅更换 legacy 示例路径与端口对)。这说明该决策文档沉淀出的是一套可重复的家族收口协议

  1. 在替换矩阵中加 legacy-only 对比行(不伪造当前支持声明);
  2. 用跨仓库本地运行器以固定端口对(当前侧 3010)跑绿该行;
  3. 依据证据把家族账本从模糊措辞锐化为逐家族 comparison-only;
  4. 同步记分板与顶层路线图,保证 slice 在栈中可见。

配套的 Phase 9 家族决策还包括 placeholder-matrix、paste-html-matrix、highlight-matrix、code-highlighting-matrix、plaintext-readonly-family、anchor-matrix、browser-boundary-family 等,共同构成 Phase 9 的“逐家族证据收口”全景。

结语:一条矩阵行的工程意义

从表面看,本决策只做了一件小事——加一行、跑一次、改一段账本措辞。但它真正回答的是替换工程中最容易被含糊带过的问题:“某家族当前到底处于什么状态?”通过把richtext收口为 comparison-only,工程团队获得的是:

  • 对 legacy 侧的诚实:不假装已覆盖;
  • 对当前侧的诚实:不发明虚假表面;
  • 对实现计划的约束:矩阵切片不得夹带实现批次;
  • 对后续工作的可验证起点:任何“已恢复”的升级都必须有独立的浏览器/运行时证据。

这正是 Slate v2 替换工程把“替换”做成可审计过程而非一次性重写的核心原因。对于任何正在做“重写式替换”的编辑器团队,这份决策文档都是一份值得照抄的流程样本:先让证据可见,再让措辞精确,最后才轮到实现。

【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询