Skip to content

跨端交接(RB ↔ RVH ↔ Supabase)

RB(桌面端 = 仓根)与 RVH(移动端 = rvh/ 子目录)自 2026-08-28 起同处本仓, 共享 Supabase 与预装词库。跨端改动仍必须分会话做(CLAUDE.md §9 会话隔离规则), 会话之间靠这个目录里的文件传递。

2026-08-29(rvh-merge-plan T4-1)归并:移动端原来那个 docs/cross-end 目录的 32 个文件已全部移入本目录(该目录已不存在), RVH 侧不再维护第二份索引(rvh/docs/README.md 只留一行指针)。 本文件是这个目录的唯一索引。 引用本目录的文件一律写仓根相对路径 docs/cross-end/NN-*.md; 历史正文里残留的 ~/reading_vocab_helper/docs/cross-end/... 是合仓前的写法,指的就是本目录。

🧭 先看这里:你要找的是「现在怎么运作」还是「当时发生了什么」

本目录是时序记述 —— 每一份都是写作当时的事实与裁定,写完即冻结、不回头维护。 它回答「当时发生了什么、为什么这么裁」,不回答「现在是什么样」

你想知道去处
同步协议现在怎么运作、五条不变量什么关系../sync-protocol.md —— 全景解释的唯一归属
条文本身(做错会出事的那句话)../../CLAUDE.md §4 · ../../src-tauri/CLAUDE.md §2
某一次改动当时的原委、实测数字、注入实证本目录,按下面的编号总表找

⚠️ 拿本目录的某一份当「当前状态」读是最常见的误用:例如 34 / 37 / 38 / 47 逐份讲的都是 墓碑协议演进中的某一站,把其中一份当结论会得到一个已被后一份推翻的判断。


编号:一条序列上有 15 处重号,都是真的

合仓前 RB 与 RVH 各自从 04 号往下发号,所以 03–22 之间同一个号在两侧各有一份、 主题往往毫不相干(例:16-rb-cloze-context-sync-handoff.md 讲 cloze 同步, 16-excluded-words-quick-triage-feature-spec.md 讲已认识词快速标记)。 17 号往后两侧才重新对齐成一条序列,23 号往后再没有重号。

🔒 不重编号(2026-08-29 T4-1 裁定)。三条理由:

  1. 15 个重号里有 11 个被至少一份冻结文档按文件名引用(handoff 正文 / 已归档 plan / CHANGELOG / Rust·Dart·SQL 源码注释)。改名 = 在「禁止改」的文件里造新死链。
  2. 01–46 只剩 41 一个空号。 重编号只能排到 47+,会把 6 月写的文档标成「第 47 号」, NN时序语义(CLAUDE.md §12)当场作废。
  3. 既有先例:下面「12 重号」一节 2026-08 就为同一情形裁过「不改名,以本表为准」。 本次只是把那条裁定从 1 个号推广到 15 个号。

消歧靠下面这张表,不靠文件名。

重号总表(15 组)

「RB 侧」= 合仓前留在 RB 仓的那份;「RVH 侧」= 由 RVH 会话产出、2026-08-29 移入的那份。 两列没有任何主题关联,纯粹是两个计数器撞了号。

RB 侧计数器RVH 侧计数器
0303-rvh-debug-mcp-design.md同名逐字副本,已去重删除(仅差 3 行路径指针,RB 那份 2026-08-02 维护过,更新)
0404-word-illustration-handoff.md(词汇插图)04-pos-definitions-governance-reseed-handoff.md(词性释义治理)
0505-reading-notes-source-platform-handoff.md(笔记来源平台)05-pos-definitions-v15-examples-reseed-handoff.md(v15 例句)
0606-rvh-phrase-library-brief.md(短语库 brief)06-word-illustration-emoji-reseed-handoff.md(插图 emoji 回执,实际对应 RB 的 04
0909-rb-phrase-asset-fix-reseed-log.md(RB 回执)09-phrase-asset-fix-reseed-handoff.md(RVH 交接)— 同一主题,罕见的对号
1010-synonym-differentiation-handoff.md(契约)10-synonym-differentiation-reseed-handoff.md(RVH 交接)— 同主题
1212-etymology-handoff.md + 12-rb-etymology-reseed-confirmation.mdRB 内部本就重号,见下节)12-etymology-reseed-handoff.md(RVH 交接)— 同主题。12 号共三份
1313-lemmatizer-fold-handoff.md(契约)13-lemmatizer-fold-reseed-handoff.md(RVH 交接)— 同主题
1414-rb-lemmatizer-fold-confirmation.md(对应 13)14-lemma-collision-retag-v23-handoff.md(短语 lemma 折叠 v23)
1616-rb-cloze-context-sync-handoff.md(cloze 纳入同步)16-excluded-words-quick-triage-feature-spec.md(已认识词快速标记功能说明)
1818-rvh-edge-jwt-handoff.md(Edge JWT)18-sm2-golden-vectors-confirmation.md(SM-2 黄金向量回执)
1919-rvh-tts-and-dict-source-handoff.md(TTS/词典源)19-reading-notes-tombstone-handoff.md(笔记墓碑)
2020-rb-reading-notes-tombstone-confirmation.md(对应 RVH 的 1920-rb-push-user-scoping-handoff.md(push 归属过滤)
2121-rb-push-user-scoping-confirmation.md同名字节相同副本,已去重删除
2222-rb-cefr-cool-palette-alignment.md(CEFR 配色)22-rvh-ocr-cloze-context-review-request.md(OCR 语境评审请求)

其余散号:01archive/(vocabulary word 主键化,四份一组); 41 从来没发出去过(那一步的台账在 docs/verification/,见全表 41 行)。

12 重号(RB 内部,早于合仓)

12-etymology-handoff.md(契约)与 12-rb-etymology-reseed-confirmation.md(RB 回执) 共用 12 号。同类的 ⑤ 近义辨析用了两个号(10- 契约 + 11- 回执),⑦ 词源却挤在一个号里, 规则不一致。加上 RVH 侧的 12-etymology-reseed-handoff.md12 号一共三份

不改名:这几份被 CLAUDE.md、CHANGELOG、多份 handoff 正文交叉引用,重命名的破坏面大于收益。 以本表为准即可。新交接请沿 ⑤ 的规则:契约与回执各占一个号。

全表

交接与回执

#文件方向主题
0202-rvh-v51-sync-log.mdRVH→RBv48-v51 同步日志(vocabulary 三新列 + FK 翻转)
0303-rvh-debug-mcp-design.mdRB→RVHRVH 侧 debug MCP 设计。⚠️ 状态仍是「未启动」,悬置中
0404-word-illustration-handoff.mdRB→RVH词汇插图 emoji 列(已交付,预装 v16 已 reseed)
0404-pos-definitions-governance-reseed-handoff.mdRVH→RB(RVH 侧计数器) pos_definitions 质量治理 → RB reseed 交接(sha256 + 版本号)
0505-reading-notes-source-platform-handoff.mdRB→RVH笔记来源平台。⚠️ 状态仍是「待 RVH 新会话执行」,需核实是否已闭环
0505-pos-definitions-v15-examples-reseed-handoff.mdRVH→RB(RVH 侧计数器) v15 例句生成 → RB reseed 交接(sha + 版本 + example_source 字段)
0606-rvh-phrase-library-brief.mdRB→RVH短语库 brief(已交付)
0606-word-illustration-emoji-reseed-handoff.mdRVH→RB(RVH 侧计数器) 词汇插图 emoji 列 → RB reseed 交接(sha + 版本 + emoji 字段 + 复核口径)。实际是 04 号那条交接的回执
0707-phrase-library-reseed-handoff.mdRVH→RB预装短语库 phrasal verb/idiom → RB reseed 交接(sha + 版本 + word_tags/basic/归一样例 + 决定 A)。回执 = 08
0808-rb-phrase-reseed-confirmation.mdRB 回执对应 07(RVH 会话产出)
0909-rb-phrase-asset-fix-reseed-log.mdRB 回执短语资产修复 reseed
0909-phrase-asset-fix-reseed-handoff.mdRVH→RB(RVH 侧计数器) 习语归一治理:as 资产修正 + canonical_surface 列 → RB reseed 交接(sha + 48 旧 PK prune + override 移植)。与上一条同主题,是它的上游
1010-synonym-differentiation-handoff.md契约近义辨析/搭配(roadmap ⑤)
1010-synonym-differentiation-reseed-handoff.mdRVH→RB(RVH 侧计数器) 近义辨析/搭配:pos_definitions differentiation+collocations 两键 → RB reseed 交接(sha + 版本 + 字段说明 + 覆盖统计)
1111-rb-synonym-differentiation-reseed-confirmation.mdRB 回执对应 10
1212-etymology-handoff.md契约词源/助记(roadmap ⑦)
1212-rb-etymology-reseed-confirmation.mdRB 回执对应上一条(重号
1212-etymology-reseed-handoff.mdRVH→RB(RVH 侧计数器) 词源/助记:word 级 etymology 列填充(双语 summary + roots)→ RB reseed 交接(sha + 版本 + 反 folk 回执 + 段二 merge SQL 提醒)。12 号第三份
1313-lemmatizer-fold-handoff.md契约lemmatizer 资产折叠进预装库
1313-lemmatizer-fold-reseed-handoff.mdRVH→RB(RVH 侧计数器) lemmatizer 资产折叠进预装库:surface_to_base/base_forms JSON → db 内 lemma_* 三表,运行时改从 db 读(新 sha + 表契约回执 + 放宽断言/解绑 include_str! 提醒)
1414-rb-lemmatizer-fold-confirmation.mdRB 回执对应 13
1414-lemma-collision-retag-v23-handoff.mdRVH→RB(RVH 侧计数器) 短语 lemma 折叠 FP 治理 v23 track-②:in a fix→context + all right reserve prune( lemmatizer 资产改——合法 fold 被 Layer3 重导,零 PK / lemma 表变更)
1515-rb-phrase-tiering-reseed-confirmation.mdRB 回执短语非组合性分档。⚠️ 61 KB,单文件叠了 v21→v25 五轮记录,当前状态见其 §13
1616-rb-cloze-context-sync-handoff.mdRB→RVHcloze 语境纳入同步矩阵(migration v24)。RVH 已于 2026-07-10 镜像完成
1616-excluded-words-quick-triage-feature-spec.mdRVH→RB(RVH 侧计数器) 「快速标记已会词 → 排除词清单」功能说明:产品意图/交互/数据模型 + 排除词跨端同步契约(红线 #5b/#5d/#5f/#6b 在该场景的具体化)→ 供 RB 参考实现
1717-rvh-cloze-context-sync-confirmation.mdRVH 回执word_cloze_contexts 纳入跨端同步(RVH schema v57):建表 + push/pull/reconcile + 删词/切用户软删 + 复习卡背面挖空 → 回 16
1818-rvh-edge-jwt-handoff.mdRVH→RBEdge Function JWT
1818-sm2-golden-vectors-confirmation.mdRVH 回执(RVH 侧计数器) SM-2 黄金向量三端一致性:Dart 侧 fixture byte-equal 副本 + test/sm2_golden_test.dart 21 向量全绿 → 回 sm2-golden-vectors-rvh-handoff.md
1919-rvh-tts-and-dict-source-handoff.mdRVH→RBTTS 与词典源
1919-reading-notes-tombstone-handoff.mdRVH→RB(RVH 侧计数器) reading_notes 删除墓碑(RVH schema v57.1,RVH 先行):补齐四级删除闭环缺失的第四级 —— 此前双端均硬删且 Supabase 无 deleted_at 列。含 RB 侧待办 + 部署顺序硬约束。回执 = 20
2020-rb-reading-notes-tombstone-confirmation.mdRB 回执reading_notes 墓碑(migration v30,四级删除闭环最后一级)
2020-rb-push-user-scoping-handoff.mdRVH→RB(RVH 侧计数器) push dirty-check 按 user_id 过滤(RVH 红线 #5h,RVH 先行,无 schema 变更):指出 RB push.rs 8 个 push 里 6 个同样缺陷。含括号优先级陷阱、= ?1 vs IS ?1 判据。回执 = 21
2121-rb-push-user-scoping-confirmation.mdRB 回执push 按归属过滤(红线 #5i,静默跨用户泄漏)
2222-rb-cefr-cool-palette-alignment.mdRB→RVHCEFR 冷色系配色对齐
2222-rvh-ocr-cloze-context-review-request.mdRVH→RBOCR 语境句评审请求(与上一条重号,见顶部重号总表)
2323-rb-ocr-cloze-context-decision.mdRB 回执OCR 语境句入 cloze 池的裁决:批准双端共写 + 四条硬条件(对应 22(RVH 侧那份))
2424-rb-lemmatizer-asset-v26-reseed-handoff.mdRB→RVHlemmatizer 资产 v26 修正(ratherrath 类错映射全量清理,178 个 surface 归一改变)+ 预装库 lemma_* 重烤。两个资产 SHA 都变;附 24-affected-lemmas.tsv 存量清理清单
2525-rvh-lemmatizer-v26-confirmation.mdRVH 回执v26 资产 RVH 侧接收完成确认(回 24):bump _preinstalledVocabVersion 25→26(与 RB「不 bump」相反,差异在读取路径)、交接单漏列的 assets/nlp/*.json fixture 同步、layer=='base' 断言的注入缺陷实证。RVH 会话产出,2026-08-29 已归并进本目录
2626-rvh-phase0-evidence-stale-report.mdRVH→RB⚠️ 勘误:rb.csv/rvh.csv 已陈旧四个月(2026-04-26 产物,早于词典优先架构重构),layer 词表与 Bug B 残留双重实证。两端一起陈旧故两 csv 仍彼此相同 → 任何「diff 两 csv」的检查都会继续假绿。含三方案处置建议 → 2026-08-24 按方案 A 处置完毕(两个 csv 已用当前实现重新生成、仍 byte-equal,README 数据资产行补了 layer 词表作新鲜度指纹)
2727-rvh-lemmatizer-residual-scan-handoff.mdRVH→RBv26 之后的映射表残留复扫:高频段无漏网(v26 裁定未被翻案),漏的是 doc 24 §10 自己写明按危害截断的低频带 → 4 条同类漏网(uninteresting/uninterested/unconcerned/overjoyed)。附 27-residual-band-31.tsv(截断带完整 31 条候选)+ 已验算的阈值口径。RVH 会话产出,2026-08-29 已归并进本目录
2828-rb-lemmatizer-residual-v27-confirmation.mdRB 回执lemmatizer 资产 v27 残留修正(回 27):4 条走 force_as_baseoverjoyed 的边界裁定判为「修」并记了理由与回退成本。三个资产 SHA 都变(140,277 / 101,713)。⚠️ 与 v26 不同,本轮没有 affected-lemmas 白名单——三个 base 仍可达,存量行无从分辨来源,故不做存量清理
2929-rvh-prune-reseed-request.mdRVH→RBprune + 补词请求:v26/v27 修好 lemmatizer 映射表但 vocabulary 表一行没动,死 headword 还在、正确词形没词条。附 29-prune-candidates.tsv(94 候选带判据字段)+ 29-missing-headwords.txt(90 个)。卡着 RVH 的 P1 真机缺陷(OCR 拍 always 被纠错器改回 alway)。RVH 会话产出,2026-08-29 已归并进本目录
3030-rb-integrated-reseed-handoff.mdRB 汇总整库 reseed 合并轮(回 29):RVH prune + RVH 补词 + 专名治理 L-C + 例句译文 86,569 条,四载荷一次做完 —— 贵的是双端 byte-equal + 同轮发版这套协调,不是 LLM。RB 侧已完成 2026-08-26:走就地改库(红线 #10 第二个豁免)而非重跑 pipeline —— 第 0 步实测发现重跑才是最大风险源(按下标 merge 错 43.6%,且 5,164 词 llm 分级 + 871 个 proper_noun 标签只存在于 db,重跑即静默丢失、令 vocab_scope 变 no-op)。18898→18925,排除集 584→769,全程 LLM $0.012。顺带查出存量专名释义一直是坏的(virginia=「Vagina」)并归位。待 RVH 跟进(§9.5:导入加删除步骤 + FK 迁移决策);载荷 ④ 例句译文未开工
3131-rb-round30-reseed-handoff.mdRB→RVHround30 产出交接:新预装库已 byte-equal 同步进 RVH 仓(c875b3db…,18,925 行,未提交)。给出 RVH 跟进所需全部信息 —— 与 doc 29 清单不同的两处裁定(保留 15 个 RVH 自标真词 + RB 复核又救回 13 个罕见真词;补词 90 收 80)· FK 迁移映射 31-deleted-word-migration.tsv(38 个有目标 / 15 个建议软删)· RVH 待办(提交资产 + bump _preinstalledVocabVersion + 落导入删除逻辑 + 真机复验 P1)。附两条对 RVH 也成立的实测结论:按下标 merge 会错 43.6%、name POS 判据单用误伤 8–10%。已回执 → 32
3232-rvh-round30-confirmation.mdRVH 回执round30 RVH 侧接收完成确认(回 31):资产十项核验全过(SHA ae33c8a4… / 18,925 / 删除集与迁移表逐行一致 / lemma_* 两表与旧库逐行 hash 相等)、_preinstalledVocabVersion 27→28、导入落两阶段 prune、phase0 复验 byte-equal。🔴 翻案一条双方文档都默认成立的前提:软删并不释放 FK —— 软删只打 deleted_at,行还在、FK 引用还在,ON DELETE RESTRICT 照样挡住删词条,故 prune 必须拆两阶段(禁用 PRAGMA foreign_keys=OFF)。两处对 31 的事实订正:§4 的 SHA c875b3db… 写错(实际 ae33c8a4…,与 §1 一致);§6 说的 buildFallbackCloze 在 RVH 全仓无人调用,RVH 复习卡走 buildContextCloze(真实语境),不碰预装库例句。🔴 另含一条真机实测挖出、需 RB 下轮修的数据缺陷(§5.2):新补的 80 个词里 25 个的 pos_definitions 完全没有 per-POS cefr、另 18 个部分缺 —— 全 POS 齐全率 存量 98.7% vs 新增 46.2%,是产出路径问题不是零星漏。RVH 拍照管线的难度筛选读的正是 per-POS cefr(不是 primary_cefr_level),于是这些词被判 UNKNOWN 静默丢掉;16 个是专名(筛掉反符合专名治理意图),但 9 个正经可学词受损ourselves(A2) measles confetti impending insignia undersigned unqualified bioethics cheerleading。另请 RB 清理自己的 learning_entries 残行(否则经 RVH pull 的 backfill 兜底会复活 alway)。RVH 会话产出,2026-08-29 已归并进本目录。§9 = 小补轮(33)的接收记录
3333-rb-explicit-example-cleanup-handoff.mdRB→RVH例句层露骨清理 + 校准闸门 1 + 补 per-POS cefr(小补轮,紧接 32):round30 的露骨清理只做了释义层,而同轮载荷 ④ 给全部例句配了中文译文 —— 此前学习者可能一眼扫过英文脏话,之后 slur 是用母语呈现的date 的「那个小同性恋」挂在 A1 词上),属载荷 ④ 引入的净损害。删 66 条露骨例句 / 64 词 + 连带 8 条义项(唯一例句必删 → 整条义项不该留)+ 9 个露骨/网络垃圾词(校准闸门 1,C1/C2 可学池 857→848)。并修掉 doc 32 §5.2 报的 per-POS cefr 缺失:212 个 POS 块补上词级值(只补缺失不覆盖已有),新增词齐全率 46.2%→100% —— 根因 100% 是 round30 自己造的(_applyFold 造 name 块没写这个键 157/157 全缺 + add_entries 素材 55/168 不带),两处已堵死并加「缺口数只许降不许升」的事后守卫(注入式反向验证过)。ae33c8a4…06cbb4dc…,18,925→18,916。逐条裁定表 33-example-adjudication.tsv(119 候选:删 64 / 整义项删 8 / 留 47)。🔴 两条实测教训:正则只用来召回不用来裁定(早期一版把 turkey-cock / cock crowed / Dick Hudson / cocktail 全误命中)· 拼读脏话扫不到eff you see kay why oh you 在词界锚定召回里一条没进)。RVH 侧成本极低:doc 32 落的 prune 是通用集合差,9 个词自动删 —— 只需提交资产 + bump 28→29,无新 FK 决策、无迁移表(最新) RVH 已接收完毕(2026-08-26),回执并进其 doc 32 §9(按本单 §1 建议不单开一份):资产六项核验全过(SHA 06cbb4dc… 与 RB 源文件逐字节相同 / 18,916 行 / 例句 86,693 / lemma_* 与 v28 版逐行 hash 相等 / 三个平行数组 0 处长度不齐)、_preinstalledVocabVersion 28→29。🔴 prune 的删除分支首次在真机升级路径上真实触发(v28→v29,Prune: deleted 9, deferred 0)—— 补上了 doc 32 §7.1 自陈的「全新安装天然测不到删除分支」那个局限。§4 修复已真机前后对照确认:ourselvesCEFR 不匹配(-1) UNKNOWN 变为 A2 正常通过。
3434-rb-tombstone-parent-adjudication-handoff.mdRB→RVH「墓碑父行算不算存在」裁定(不改 schema / 不改协议,只改两端的行为约定):RB 此前一致地把「父行是墓碑」当作「父行仍存在」,与红线 #6a/#6c 的无条件措辞公开冲突。裁定 = 写侧判缺陷(删词 / 标「已认识」现在同事务带走 word_page_links + word_cloze_contexts)+ 读侧判红线措辞错(pull 守卫改显式三态:活 / 墓碑 / 缺失)。🔴 对 RVH 同样成立的决定性事实:watermark 不回头 —— 在 FK 落地守卫上加 AND deleted_at IS NULL 不是「下轮再试」而是永久丢行(RB 有一句写反了的注释因此被更正);反过来裸 COUNT(*) 则把墓碑当活行造孤儿,两种压缩方向相反、都是缺陷。另补巡检 tombstone_parent(此前这类孤儿两端 UI 都看不见、无任何自动检查会说话,实测库里有 2 条而 dangling_fk 返回 [])。RVH 待办见其 §4:查自己的删词路径(按父表看,不按命令名看 —— RB 正是在这里漏了第三条 add_known_word)+ 查 pull 守卫是否三态
3535-rvh-ocr-cloze-context-confirmation.mdRVH 回执OCR 语境采集落地确认(回 23):C1–C4 逐条对账通过,本端真机 27 词入库 → 27 词拿到语境,30 条 synced_at IS NULL 的 RVH 自建行待上行。4 条 RB 需知情:① 三规则闸门里的**「主列」一条已默认关闭** —— 输入信号不可信(词位 x 由 ML Kit 行框按字符比例插值而来,实测一页 18 行正文里 3 行的行框报偏 140–240px,正文被当成邻页碎片),而它要挡的侵入碎片(16 / 14 字符)本就过不了 length ≥ 25 ⇒ 代价可测、收益未证实。若 RB 认为「主列」是批准范围的硬性组成而非工程细节,请回执;② 连字符判据收紧为紧贴词尾 \w[-‐‑–]$ —— 只看行末字符会把空格后的破折号标点当断词,实测一条 "...his release -" 误拒 months 并连带按行首词规则拒掉 5 个,一个宽判据吃掉 27 词里的 6 条语境。另:doc 23 §2.3「行末连字符是断词唯一拦截点」只对前半截成立,后半截那行末尾没有连字符、C1 也挡不住,RVH 补了「行首 token + 本页有断词行 → 拒」并故意从宽(精确判定要靠整页 y 序,弯曲书页上不可靠);③ 🔑 RVH 不挖空 ⇒ 本端看不出 C1 违规 —— buildContextCloze 返回 null 时 RVH 抽屉只退化成纯文本、句子照常完整显示,而同一条行在 RB 是「占着封顶 5 的坑位却完全不可见」⇒ C1 是替对端把的关,本端显示正常不构成它合格的证据(供 RB 判断 doc 23 §6 那条受侧兜底待办:在 RVH 这边是有价值的);④ created_at 字面格式两端不同(RB +00:00 / RVH Z)但都是 UTC、字典序仍与时间序一致 —— ⚠️ C3 校验不能写成「以 +00:00 结尾」这类字面判断。数据形态:source_url 恒 NULL、sentenceOCR 行片段(29–40 字符,句首尾常在语义中间断开)、同页多次收割会因 OCR 差一字符(Gilboa/Gilb0a)产生近似重复行各占一坑。⏳ 仍欠 doc 23 §7 的跨端三步实测(需双端设备 + 同一账号,其中第 1 步同时验 C3)。RVH 会话产出,2026-08-29 已归并进本目录
3636-rvh-tombstone-parent-confirmation.mdRVH 回执「墓碑父行算不算存在」RVH 侧复核完成(回 34):写侧查出 deleteNotebookEntry 完全不带走 word_page_links 且两条子句根本不在一个事务里 → 已修为单事务三件套;读侧 _pullWordPageLinks两个父行守卫都是裸 COUNT(*)(事故 ①)→ 连同 _pullReadingPages 一起收敛到单点 _parentState 三态。🔴 顺手堵上了 RB #6d 那 57 行回声环的原始出处 —— deleteBook 软删 link 时不 bump updated_at 那行代码今天还在,RB 的 MAX 只兜住了症状;RVH 三处已全部补 bump(RB 的 MAX 请保留,对老客户端仍必要)。RB 漏的第三条路径 RVH 不存在且是产品语义差异:RVH 标「已认识」只写 known_words、不碰 learning_entries,是过滤器不是删除。⚠️ 两仓红线编号已分叉(RVH #5h=RB #5i、RVH #6c=封面 BLOB 而 RB #6c=父行三态…),本单 §4.1 给了对照表,跨仓引用请带仓名。RVH 侧新立红线 #6f。三处判为不适用并写明理由(标已认识 / deleteBook 不带 cloze / cloze pull 无守卫——后者与 RB 同形,单端改会破坏 #5g reconcile 前提)。验证:dart analyze 0 error·flutter test 1259 passed·新增 tombstone_parent_test.dart 10 用例并三处注入缺陷实证。另修一条因本改动失效的 #6e CI grep。RVH 会话产出,2026-08-29 已归并进本目录
3737-rvh-tombstone-synced-at-handoff.mdRVH→RBpull 墓碑分支的 synced_at:RVH 侧无对称实现,请求把 #6d 升成双端契约(承 36 §7.1)。RVH 6 个 _pullXxx5 个把 synced_at 写成本端时钟 now(reading_notes/reading_pages/learning_entries/word_page_links/known_words),方向与 2026-08-03 那 57 行相反、形状一样:本端时钟慢于对端且慢过「对端删除→本端 sync 起始」的真实间隔即触发,autoSync 60s 下该间隔常只有几秒 ⇒ 几秒漂移就够_markSynced 同样写本端 now ⇒ 重推后依然脏,是永久不是一次。🔴 核心请求是改条文:RB 现行写法有两条性质 —— ① sync_ts 完全取自远端行、从不碰本端时钟(library.rs:363)② 再与 deleted_at 取 MAX —— 而红线 #6d 只写了 ②,RVH 那 5 处压根没写 MAX、形式上不违反,违反的是 ① ⇒ 照现条文审 RVH 全能蒙混过关。另:word_cloze_contexts 是唯一安全的一张(满足①不满足②),它没炸纯粹因为 RB clear_cloze_context_for:709deleted_at = ?3, updated_at = ?3 同值 —— 一条未写进契约的耦合,RB 改那条路径就无声破功,请一并纳入 ②。请 RB 裁定两个边界:远端 updated_at NULL 时回落 created_at(靠 MAX 兜底)还是直接用 deleted_at;以及两端字面格式不同(RB +00:00 / RVH Z)而 SQLite MAX 是字典序、同微秒时 Z 恒大 —— 现有偏向是偶然安全。⚠️ RVH 未被阻塞synced_at 是本地列,可单方面改),不改是因为不想重演「只修一端、源头留 24 天」。RVH 会话产出,2026-08-29 已归并进本目录
3838-rb-tombstone-synced-at-contract-handoff.mdRB→RVH墓碑行 synced_at 的双端契约(回 37):请求成立 —— 旧 #6d 只写了「取 MAX」,照它审 RVH 那 5 处能全部蒙混过关。条文拆成四条:W 写侧软删 deleted_atupdated_at 绑同一个参数(把 doc 37 §7.1 点名的「cloze 靠 RB 同值才安全」那条未写进契约的耦合正式收编)· P1 pull 墓碑分支的 synced_at 只能由该远端行自己的列拼出,任何形式的本端 now 都不许出现(独立于 P2 —— RVH 那 5 处压根没写 MAX,形式上不违反 P2)· P2 MAX(写完后的 updated_at, 写完后的 deleted_at),操作数绝不能为 NULL · P3 收敛判据覆盖 push 侧的 mark。🔴 两个边界裁定:① 远端 updated_at 为 NULL 时回落 created_at(不是 deleted_at、更不是 now)—— SQLite 多参 MAX() 只要一个操作数为 NULL 就整体返回 NULL ⇒ 同一个回声环从 P2 的实现里换身份复发,而 updated_at 可空的那三张表(reading_pages / word_page_links / word_cloze_contexts)常态就是 NULL;② 格式差异(RB +00:00 / RVH Z守住 P1 后自动不成问题 —— 关键是重新框定:MAX 取的不是「时间上更晚」而是「让脏谓词为假」,故操作数必须就是这一行存下的那两个字符串、且用字符串序比(compareTo),禁止 parse 成 DateTime 再比(同微秒时 Z 恒大;Dart/Rust 各自的小数位数还会变,同一端内部也能反序)⇒ 两端时间戳格式不需要统一RB 自查:10 处 pull 墓碑分支全部合规(逐处核了 MAX / 操作数来源 / 可空性,三张可空表都有 ?? created_at)、写侧 27 处全部合规;本轮 RB 没有修复任何真实缺陷,产出是契约 + 守卫:新增结构守卫 pull/mod.rs::tombstone_synced_at_guard(全仓每条墓碑 UPDATE 二选一落在 P1+P2 或 W 上 + 站点数=10,三条规则各注入一次缺陷实证)+ mark_syncedMAX(..., deleted_at)(P3,RB 侧无已知可达路径,属钉不变式;RVH 侧真实可达)。存量数据不需要 backfill —— 回声环自己保证那些行每轮被拉回来,修完即自愈。RVH 待办见 §7
3939-rvh-tombstone-synced-at-confirmation.mdRVH 回执墓碑行 synced_at 契约 RVH 侧落地完成(回 38):§7 六项待办全清。6 处墓碑分支改 synced_at = MAX(?, ?) 并一并覆盖 updated_at(比 §7 要求多一处 —— cloze 的 P2 也补了,见 §3.2:只改 ?? now 并不能解除 doc 37 §3.1 点名的那条「靠 RB 写同值才安全」的耦合)· P1 收成单点 _remoteSyncTs回落终点用空串不是 remoteDeletedAt(§3.1:RVH 的 syncTs 同时服务墓碑与活行两支,空串两支通用,且与你们 COALESCE(deleted_at, '') 同惯用法)· _markSynced 落 P3 · 规则 W 全仓 11 处核对本就合规(doc 36 那三处 bump 已补齐),本轮只是写进条文 + 补会红的 grep。存量按 §5.4 确认自愈(专门用例:先断言在环里 → 跑一轮 → 不脏),未做 backfill 或 migration。验证:dart analyze 0 error · flutter test 1270 passed · 新增 tombstone_synced_at_test.dart 11 例,五处注入缺陷实证(P1/P2/P3/NULL 陷阱/DateTime.parse —— 最后一条恰好红在 §4.2 那条用例上)· 6 条 CI grep 逐条注入验证(含「加第 7 张同步表漏改就红」的数量硬断言)。RVH 新立红线 #6g(RVH 的 #6d 号被 last_opened_at 占着)。三条反馈见 §6:①§5.1 样板的参数顺序易抄错且错位后测试未必红 ②§4.1 的候选对 word_page_links 其实等价(该表 push 脏检查没有 updated_at > synced_at 支)③ 请复查你们 mark_synced 的活行路径 —— P3 让活行 synced_at 从本端 now 变成该行自己的 updated_at,RVH 侧无副作用(synced_at 只用于脏判定),但你们若还有别处把它当「上次同步时刻」读,语义就变了。RVH 会话产出,2026-08-29 已归并进本目录
4040-rb-learning-loop-handoff.mdRB→RVH学习循环三端一致性 + 一个确认的排期缺陷。RB 建「学习循环」专题验证(docs/verification/learning-loop.md)时机械层抓到:RVH 写进 learning_entries.next_review_date 的是 timezone-naive 本地时间串,而同一次写回的兄弟列全是 UTC(根因单点 sm2_algorithm.dart:159DateTime.now(),生产上只有一个 caller)。它是共享表 34 个 text 时间戳列里唯一带裸值的一列(45 行 29 行;含 3 张真实复习过的卡 + 26 行哨兵),其余 33 列 —— 含你们 doc 37/39 刚收拾过的全部墓碑列 —— 100% 合规。后果两条且都静默:① 两端到期判定都是字符串比较,UTC+8 下卡片晚 8h 到期;② merge 的 remote_next > local_next 同样是字符串序 ⇒ RVH 状态恒赢;③ 负时区下方向翻转(提前到期 + 恒输),单地测试只看到一半。🔴 RB 侧 mark_synced 的注释证明「RVH 会推裸串」早就被看见过一次,当时只在 synced_at 那处打了补丁、没追到根。六道既有守卫在同一批数据面前全绿(SM-2 三端 / sync-verify 14 条 / sync 单测 40 条 / 黄金向量)—— 没有一道在问「算出来的那个时刻是哪个时刻」。请求四项:主项一行改 nowUtc() + 会红的测试;存量数据请裁定(不自愈,且裸串无法反推时区,给了 A/B/C 三选并说明 C 要连 synced_at 按 doc 38 处理);你们 CLAUDE.md 自曝的红线 #7/#9 两条(#9 与 RB 本轮修掉的 add_reference_word 是同一形状:手搓半个 normalize,消费侧裸等值比 ⇒ 静默不生效,附 RB 的结构守卫做法及它第一版假绿的坑);mastery 阶梯要不要进黄金向量。⚠️ RB 改了黄金向量 JSON 的两个说明字段_consumers.rvh_dart 原写着不存在的 lib/services/sm2_service_test.dart —— 与 RB CLAUDE.md §9 刚订正的是同一个幽灵路径),未动任何 expected,请 cp 一次副本(新增的 L1 断言在此之前会一直红)
41../verification/cross-end-cloze-pool-2026-08.md双向 · ✅ 已收尾(2026-08-28)cloze 语境池的真·双端实测(doc 23 §7 与 doc 16 §6 末条一直欠着的那三步)。⚠️ 不是交接单,是两端共用的接力棒台账,故不在本目录而在 docs/verification/ —— 文件名带日期即表示它是一次性产物:收尾时按 verification/README.md 的生命周期当场拆散(结论进 CHANGELOG / 未修项进 backlog / 新学到的假绿风险进 sync-consistency.md S13),之后停止维护。RVH 会话用绝对路径读写同一个文件docs/verification/cross-end-cloze-pool-2026-08.md终态:A ✅ · B ✅ · C 🚫 未验 · C3 ✅ 不成立(三棒跑完,台账已按生命周期拆散并停止更新)。A 池收敛 + 淘汰序 ✅ —— 双端收敛到同一份 5 条(13 行逐 id 一致),A4 五步淘汰预测无一例外(含跨端那一条),配对靠「被淘汰行的 deleted_at 与新行的 created_at 逐位相同」事后精确还原;B C1 静默占位 ✅ 已复现并收尾C 删扫描页 → cloze 行仍在 🚫 本轮不排期 —— RVH reading_pages 是硬删 + 依赖 FK CASCADE(reading_page_datasource.dart:131/:580,两条 UI 均可达)⇒ 页删除不上行且 CASCADE 物理抹掉 word_page_links 的墓碑,现在跑会把这个坏行为记成「既有行为」,RVH 先修再验。🔴 两处判断层订正:① doc 23 §7.1「这一步同时验 C3」那句是错的 —— RB 5 条 + RVH 新增 1 条时,时钟正确与 +8h 偏置给出同一个观测(那条 RVH 行在两种假设下都是最新的,被淘汰的都是 RB 最旧那条)⇒ 台账 §0 补了 A4 鉴别步:等 RVH 那条不再是池里最新时,看它会不会被公平淘汰;② B 的夹具必须另起一个词(用了 silence)—— 拿 A 的 cave 做会中途污染对照组,且 B 的四个设计点里最容易漏的是「坏句必须因缺 surface 而落选」(展示侧还有 8..220 字符的长度闸,坏句太短就验错了东西)。B 的实测结论比 doc 23 §7.2 更重:坏行不只占一个不可见的坑,它进池时把最旧那条好语境挤成了墓碑、墓碑照常上行(红线 #6b)⇒ 那条真实语境在两端都没了;另外 cloze_contextspositions长度差本身就是可观测量(不必揭晓去读 UI 上的 n/N,也不需要任何会写库的动作 —— 以后验这类问题走这条路)。顺带产出两组野外证据:红线 #6d 在本端来源(1-c)与远端来源(B-6)两个方向各验到一次(墓碑写完即不脏、pending_push = 0、无回声环);C3 拿到两条反证 —— OCR 页名 Scan 2026-08-27 01:39 #1created_at 2026-08-26T17:39:49Z(差 8 小时、方向正确),starvationcreated_at 17:39:50.772199Z 对服务端 trigger 写的 server_updated_at 17:41:50.458773+00:00(+2 分钟 = 真实 sync 延迟)⇒ RVH 当前构建的 created_at 是真 UTC,但 A4 仍要跑(那两条证的是写入侧时钟对,A4 证的是淘汰规则真按这个键排)。一条产品缺陷已拆进 docs/plans/backlog.md 顶部:满池时复活一条被淘汰过的句子会绕过封顶(复活分支在封顶 UPDATE 之前 return ⇒ 活跃行变 6)且弹窗谎报「✓ 语境 +1」(checkContextIsNew 走的 get_cloze_sensedeleted_at IS NULL,把墓碑判成新句),60 秒后 reconcile 把它再次淘汰 —— 要修的是徽标那处不是封顶那处(越界瞬态且在线自愈,谎报成功不自愈)。🔴 本轮最值钱的产出不是三个勾,是判据自己错了两次:① doc 23 §7.1「这一步同时验 C3」不成立(两个假设给出同一个观测)⇒ 补 A4 鉴别步;② 而为订正 ① 写的那条时间窗又把 8 小时偏置重复施加了一次、界晚 8 小时,且错在不安全方向(照它跑会把「A4 什么也没鉴别」记成「C3 不成立、鉴别通过」)。两次同一形状:把「存的是多少」当成随假设变化的量 —— 它是观测。可复用判据:A4 类鉴别只在「现在还没走到那条行自称的时刻」之前有效。C3 最终由「该行 created_at 对服务端 trigger 写的 server_updated_at 只差一个 sync 延迟」结案,这条已下沉成 sync-consistency.md S13 的验法,取代原先那句「本仓无法验证 RVH 侧是否已改」;B 的代价也下沉成新判据 S13a(比 cloze_contextspositions 两个数组长度,不必揭晓复习卡、不写库)。C 项进 backlog(阻塞在 RVH 硬删,动作在 RVH 侧)
4242-rvh-learning-loop-confirmation.mdRVH 回执学习循环 RVH 侧落地(回 40):主项 getNextReviewDate() 写本地时钟改了三处、缺一不可(不止 RB 说的一行)· 存量数据选 A 不动并给了理由 · 红线 #7 修了 / #9 有意不修(等 canonical 规则裁定)· 同意 mastery 进黄金向量 · 已 cp 黄金向量副本(RB 侧 L1 转绿)· 新立 RVH 红线 #6h18 处注入,含两次在守卫自己身上抓到的假绿/假红。🔴 五处订正 RB 判断,其中 §6A 打到 RB 本轮刚落地的 add_reference_word 修复上(normalize("bearing")="bear" 会误伤另一个词)。RVH 会话产出,2026-08-29 已归并进本目录
4343-rb-canonical-key-space-adjudication.mdRB→RVHcanonical 键空间裁定(回 42 §7 四项):§6A 的挑战成立一半 —— normalize("bearing")="bear" 属实,但「改前是对的」不成立(那三个消费点的 v.word 恒为已归一形,bearing 压根出现不了 ⇒ 改前是静默 no-op)。复核查出两边都没看到的两件事:① add_reference_word 全仓零调用方、193 行全 source='system' ⇒ 争论的行为两边都不可达,RB 原文把它写成活缺陷已订正;② 消费点是 4 处不是 1 处,且分属两个键空间 —— vocabulary 同时装着 lemma 行与非 lemma 行(bear/bearing 都在),三个走 learning_entries join 的只看得到已归一形,发现候选池那个遍历全表 ⇒ 「一律归一」与「一律不归一」各错一半。🔴 裁定 canonical = 「解析成一个真实存在的 vocabulary.word(先试原形、不命中再归一),且只适用 reference_wordslearning_entries/known_words 的输入是页面 surface,与 lookup_word 同口径,照旧 normalize)。顺带查出种子里 4 条死条目olympics/pbs/gps/httpsvocabulary 里没有对应行、而它们想挡的 olympic/http 没被挡),种子在 v3 已冻结迁移里只能走新迁移。另裁:哨兵字面量不统一(带风险条件)· mastery 进黄金向量同意但按 RVH 给的顺序、与下批一起走。RB 侧本轮不改代码,只记账(K5 带重启条件)
4444-rvh-page-delete-cloze-retention-confirmation.mdRVH 回执删扫描页 → cloze 行仍在(回 doc 23 §7.3 = cloze 池 relay 的待验项 C):本地 33 / 云端 33 条 deleted_at 全为 null,C 成立。⚠️ 是先修后验 —— relay 收尾时 C 被标「不排期」,因为 RVH 当时删页是硬删 + FK CASCADE,在那个状态下验会把坏行为记成既有行为;同日修成软删 + 手工级联后才验的。台账在 ../verification/cross-end-cloze-pool-2026-08.md(属 cloze 池 relay 那条线,非学习循环)。RVH 会话产出,2026-08-29 已归并进本目录
4545-rvh-canonical-key-space-confirmation.mdRVH 回执canonical 键空间确认(回 43):零生产代码改动。① 逐调用方判定 —— RVH 侧没有任何一条路径把页面 surface 传进 addOrReviveUserWord,与 RB 四个调用方同构 ⇒ §2.1 覆盖其全部入口、不需在调用方分流;且 RVH 现状(只 toLowerCase恰好等价于 §2.1 的 EXISTS 分支恒命中,是对的 —— 这是 43 §1.5 那条订正在 RVH 侧的独立佐证。📌 结构差异:RVH 的「拍照存词」(surface 真正进系统处)根本不写 known_words,只把它当读侧过滤器。② 🔒 要求补一处钉死:§2.1 第三步必须是整串 normalize,不是逐 token 的 normalizePhrase(后者会打坏 46 个多词条目)—— 该请求成立且对称:45 以为「RB 只有一个 normalize」,实际 RB 也有 normalize_phrase,RB 实测数字与 RVH 逐字相同(6744 个多词条目,0 vs 46)。③ 读侧必须与写侧调同一个 canonical 函数(RVH isKnownForUser 现在自己算一遍)—— 已升格为落地要求。④ 抓出 43 §5 待办表「修」与 §2.2 正文「先别动」自相矛盾(已订正)。⑤ 计数 72 vs 57 是口径差(RB 那个是只覆盖 Layer 1/2 的 SQL 近似,为下界),两端都不写成基线。RVH 会话产出,2026-08-29 已归并进本目录
4646-rvh-key-space-landing-confirmation.mdRVH 回执键空间分流 RVH 侧落地(回 43 §6):抄完,行为零变化(1359 例全绿)—— 因为他们的现状(只 toLowerCase)恰等价于 EXISTS 分支恒命中。判据单点 word_key.dart,写/读/三侧共用。当前不需调用方分流,痕迹落成会红的调用方名单而不只是注释。🔴 三条转达 RB:① 登记 46(+ 他们以为没登记的 44 —— 实际早已登记);② 软删不会让 M1 变绿(墓碑按定义不删行,裸 created_at 仍在),给了 A/B/C 请 RB 定 —— RB 裁定 D:按列分不按行分(A 会让整类墓碑对 #6d P2 的 created_at 回落操作数失明),见 43 §7.2;③ 提醒复核 RB 删侧 —— 他们那边是「写读都改了、删侧漏了」,症状是「加得进删不掉」。这条提醒命中:RB remove_known_word 确实用裸 word,此前靠调用方恰好传 vocabulary 行才凑巧对,已修(77ed0e7)+ 补成对守卫。RVH 会话产出,2026-08-29 已归并进本目录
4747-rb-tombstone-vs-remote-alive-adjudication.mdRB→RVH「本地墓碑 + 云端活行」永久分歧裁决(起因 backlog 🟠 P2,实例 word_cloze_contexts 3a50ad2b / cough up)。🔑 两端代码一字不差、都没做错 —— 写侧都刻意复活同句软删行(红线 #7 精神),pull 侧分支② 都写着「本地墓碑靠 push 传播,不复活」。缺口在那句注释的前提:按 RB #6d 规则 W + push 后的 mark_synced墓碑推完就恒不脏 ⇒ pull 指望 push、push 说没得推,永久停住、无告警。🔴 裁决:判据不是「谁的时间戳更晚」(那是 #6d 明令禁止的跨时钟比较),而是「push 会不会把这条墓碑送出去」 —— 分支② 拆成 ②a(仍待推 → 照旧 skip)/ ②b(已不待推 → 接受远端、复活本地行,synced_at 只由远端行的列拼出,写完立刻不脏)。🔒 pull 侧的待推判据必须由 push 的脏检查常量拼出、禁止手搓(RB USER_SCOPED_DIRTY;RVH 先把 6 份内联 WHERE 抽成一个常量)—— 本缺陷的成因就是「注释里写着的假设没人校验」,共用常量让两者结构上不可能漂。远端赢的三条理由:与两端写侧(红线 #7)一致 · 与引擎全局 last-write-wins 一致 · 可恢复性不对称(判错了再删一次就收敛;今天的分歧任何用户操作都修不了,删已墓碑行是 no-op)。⚠️ 不是 cloze 独有:分支② 在 RB 10 个 pull_* 里逐字都在,写侧复活路径覆盖 10 张表里的 8 张 —— 最贵的是 learning_entries(手机删词、桌面再存 ⇒ 手机永远没有)。🔴 顺带查出 RVH 既有缺陷_pullKnownWords 没有分支② 且远端活行路径把 synced_at 刷成本端 now ⇒ 本地墓碑变 clean 却从未上行(今天就在静默丢删除),且会破坏本裁决「clean ⇒ 服务端见过这条墓碑」的前提 ⇒ 必须先修再落地②b。三条备选出路全部否决:加 revived_at 意图列(只让「谁赢」精确、不解决不收敛,可重启,条件见单内 §7.3 的 warn 计数)· 复活走新行(撞 #5g cap-5)· 只保证可观测(用户仍看到不一致,但其 warn 那一半采纳)。存量 1 行不会自愈(watermark 已越过),给了 A 等自愈 / B 单 id no-op touch 触发 set_server_updated_at() 两个选项,推荐 B(顺带就是端到端验收)。验收 4 条结构守卫 + 7 条单测各带反向注入,其中 T1/T3 是防「过度修复」的一半(无条件复活会全绿)。本轮零代码改动,待两端各开实施会话 + 回执
4848-rb-seed-prune-delivery-handoff.mdRB→RVH从共享资产删掉的词没有送达存量用户:round30 的 53 个 delete_words 在两端的 seed 合并(UPSERT,只增改不删)下原地不动,bangbus 因此还出现在快速分级 C2 首屏。RB 补 v29 prune + 三条守卫;资产字节未动 ⇒ RVH 版本锚不必跟着 bump。RVH 需自查:它的 prune 口径是「清未引用的 backfilled」、明写不清 preinstalled,与 RB 互补且都不完整(附一条 SQL 判据)
4949-rvh-tombstone-vs-remote-alive-confirmation.mdRVH 回执「本地墓碑 + 云端活行」RVH 侧落地(回 47 §6.2/§7):判据照抄、一字未改;新立 RVH #6i ↔ RB #6e。flutter test 1401/1401(新增 20 例),11 处反向注入全部按预期变红。🔴 订正裁决单三处:① §6.2 说「六份内联脏 WHERE 里只有 _pushReadingPages 少写 updated_at IS NOT NULL、行为等价」不成立 —— 实测是三种形状:4 份少那半句(确实等价)、cloze 那份完整、word_page_links 那份整支 updated_at 条件都不在,而那一份不等价、是个今天就在生效的真缺陷restoreNotebookEntry(删词 4 秒内的 Undo)复活出的 link deleted_at=NULL, updated_at=now不脏 ⇒ 永不上行,对端那条 link 永远是墓碑且任何后续操作都修不了(复活幂等),收敛成统一常量顺带堵掉;② §7.1 的 G1/G2 不能照抄 RB —— RVH 是单文件(常量与 pull 同处,synced_at IS NULL 计数照抄必恒红,须先切掉常量本体再断言),且改成 RB as-built 的单点 helper 后 deleted_at = NULL 的计数是 1 不是 6;③ 常量名从 _kDirtyWhere 改成 _kUserScopedDirty(它自带 user_id = ? 那一半,旧名会诱发 #5h 的括号事故复发)。两处欠了前置getSyncStatus 的 pendingCount 不在 §6.2 任务表里、但必须同批改(否则 ① 那一改当场让口径漂);§7.2 只给 T7 提了「push 必须失败」,而 T1/T3 同样需要 —— push 排在 pull 之前,脏墓碑当轮就被推走并 mark 成 clean,不让 push 失败的话它们测的是 ②b 不是 ②a(RB 侧直接单测 helper,没这个坑)。🟡 一条留给 RB 定的新发现:分支② 排在父行三态守卫之前(两端同形),「clean 子墓碑 + 远端子行活 + 本地父行仍是墓碑」会先复活子行、再被守卫 skip ⇒ 本地留一条挂在墓碑父下的隐身孤儿。常见路径够不到(父词条本轮更早被同一条红线复活),且复活出来的行不上行、危害止于本地 —— 本轮不单方面改序。复现 RB §10 那条教训:「复活漏写 synced_at」只在远端 ts 晚于本地墓碑那一档才让 T4 变红,另一档照绿 ⇒ T4 两个方向都要跑。另记:T4/T5 的探针必须选 word_page_links(其 ②b 之后是 INSERT OR IGNORE、整条 no-op,复活写下的值原样可验;换 cloze/learning_entries 会被下游双活逻辑覆盖 synced_at ⇒ 假绿)。存量 1 行与真机验收仍未做(§8 选 B,时机 = RVH 装机后)

无编号文件(与 NN- 体系并存)

文件是什么
pos-definitions-v14-governance-reseed.md · pos-definitions-v15-examples-reseed.md两轮 reseed 日志,产出时未纳入编号序列
sm2-golden-vectors-rvh-handoff.mdSM-2 黄金向量交接(✅ RVH 已完成,回执 = 18 号(RVH 侧那份))
cross-end-consistency-report.md⚠️ 脚本产物,由 scripts/cross-end-check.sh --report 生成。内容是生成当时的快照,不代表现在——要看当前状态请重跑 /cross-end-check,别读这个文件的存量内容

数据资产(不是文档,别当文档清理)

文件用途
🔒 sm2-golden-vectors.json活跃测试 fixture——Rust(srs.rs include_str!)+ TS(sm2.test.ts)+ Dart(RVH sm2_golden_test.dart三端消费同一份。改它会同时影响三端测试;删它会让三端 SM-2 一致性锁失效。它放在 docs/ 下纯属历史原因,别因为"docs 里的 json 看着像残留"就动它
25-v26-changed-surfaces.txt · 25-v26-changed-surfaces-rvh.csvv26 资产修正后两端各自重跑 phase0 的变更 surface 清单(25 号回执的 byte-equal 复验证据)。RVH 会话产出,2026-08-29 已归并进本目录
30-missing-adjudication.tsv · 30-prune-adjudication.tsv · 30-orphan-bases.tsv · 30-sense-order-diff.tsvround30 合并轮的四份逐条裁定表(补词 / prune / 孤儿 base / 义项序 diff),30 号交接单的输入与留痕
word-illustrations-hexcodes.txt · word-illustrations-mapping.tsv词汇插图 OpenMoji 映射(04 号交接的数据)
24-affected-lemmas.tsvv26 资产修正作废掉的 131 个旧 lemma(old→new + 触发 surface)。是存量数据清理的输入白名单——用户库里 word 命中这一列的行,都是旧资产错误归一的产物。两端共用。别按「预装库里没有就删」的思路自己造判据,那会误杀缓冲池 backfill 的正常生词
🔒 phase0_inputs.txt + rb.csv + rvh.csv三件一组的跨端归一化对齐证据,别拆别删。 phase0_inputs.txt 是共同输入(131 词);rb.csv 由 RB 的 Rust phase0_normalize 跑出,rvh.csv 由 RVH 的 Dart 版跑出。两个 csv 字节完全相同——这正是结论本身(两端归一化实现无漂移),不是冗余副本。🕐 基线时点:2026-08-24(词典优先架构 + lemmatizer 资产 v26),layer 词表 = dictionary / base / suffix-validated / fallback(+ 空串行的 empty)。这行 layer 词表就是新鲜度指纹:哪天重跑的输出里出现词表以外的标签、或这几个标签消失,说明实现换代而这组文件没跟上,立刻按下面的复验命令重新生成,别继续拿它当验收依据。(历史教训:2026-04-26 那版一直停在旧架构的 suffix/irregular/exception两端一起陈旧故两个 csv 仍彼此相同 → 任何「diff 两个 csv」的检查照旧假绿,整整四个月无人察觉,直到 v26 接收时被 RVH 撞见。见 26-rvh-phase0-evidence-stale-report.md。)复验命令见 RVH CLAUDE.md 红线 #5e「双端 byte-equal 验证」段(⚠️ RVH 侧用 dart build clidart compile exe 自 Dart 3.10 起对本项目已失效)

命名约定

现状是多套混用,新文件请按这条

NN-<端前缀>-<主题>-<类型>.md
     rb / rvh          handoff(发出的契约)
     或省略            confirmation(回执)

已有的历史文件不重命名(被两仓交叉引用)。-log / -brief / -design 等其它后缀是历史遗留。