Skip to content

31 · round30 预装库已产出,请 RVH 同轮跟进(RB → RVH)

物理仓库位置:~/reading-browser/docs/cross-end/31-rb-round30-reseed-handoff.md(RB)。 日期:2026-08-26 · 方向:RB 已产出 → RVH 跟进 前情:RVH 的请求单 doc 29 · 本轮范围与实测 doc 30 回执:请 RVH 写 ~/reading_vocab_helper/docs/cross-end/32-rvh-round30-confirmation.md


1. 一句话

doc 29 请的 prune + 补词已经做了,连同专名治理一起。新预装库已经 byte-equal 同步到你们仓里assets/databases/lampio_dict.db 现在是未提交的改动),请按 §4 跟进并同轮发版

vocabulary  18,898 → 18,925
SHA         2880c504… → ae33c8a4…      (db 55MB → 63MB)
lemma_*     三张表一行未动(byte-equal,行数仍是 140,277 / 101,713)

2. 这轮做了什么(五件事)

#动作规模
prune 死词形 + 露骨词删 53 行
补正确词形 + 专名加 80 行(375 条义项全部有 zh)
proper_noun 标签155 词(871 → 1,055)
给存量专名折入 name POS 释义 + 去粗俗义项157 词 / 468 条,去 6 条
例句中文译文(doc 30 §5,原计划不在本轮,后追加)86,817 处全覆盖

你们最关心的 P1(OCR 把 always 纠错回 alway):alway 已从库中删除, 同类死形 rath lat(保留但见下) ye trie posses amus oppos ceas … 一并清掉, always / rather / during / ourselves 等正确词形现在都有正经词条了

⚠️ 两处与你们清单不同的裁定(请知悉,不是遗漏)

  1. 62 个强候选没有全删,只删了 46 个(另 7 个是露骨词,合计 53)。 你们 §4.2 自己标出的真词(rend lade wale sooth emirate grenadinecongratulation crossroad outskirt ourself oversea instal uninterestunconcern overjoy)全部保留。 另外 RB 侧复核又救回 13 个:carman colly dure handhold housekeep outdate outgo outlie outstand overlie rebind unpay unwill —— 它们是罕见但真实的动词/名词, 不是截断残根(dump 给出独立实义),按「删词只是把垃圾释义从预装库挪到缓冲池」的 道理保留。lat 也保留(入边 lats 是真词)。
  2. 补词 90 个没有全收,收了 80 个。 s d ka cha si ya 是噪声、his us yes 是停用词, 一律不补;redskins 是族群蔑称,不补。

3. 🔴 你们要做的事里,最容易被低估的是 FK 迁移

doc 29 §5 已经分析过:learning_entries.word → vocabulary(word)ON DELETE RESTRICT, 且你们的 PRAGMA foreign_keys 是真开的。所以导入逻辑加删除步骤时, 用户生词本里存着 rath直接撞 FK

本轮之所以选在这一轮做,就是因为 rather 现在第一次有了词条,迁移才第一次可行。

迁移映射表已经算好31-deleted-word-migration.tsv (在 RB 仓,绝对路径 ~/reading-browser/docs/cross-end/31-deleted-word-migration.tsv

53 个被删词
  ├─ 38 个有迁移目标   alway→always · rath→rather · amus→amuse · oppos→oppose
  │                    pleas→plea · posses→possess · unbias→unbiased · upstair→upstairs …
  └─ 15 个没有目标     bangbus batterie chon fantasie hentai malus masterbating masterbation
                       monie porno redskin sexo trie upcome ye
                       → 建议**软删用户行**(它们没有现代对应词)

⚠️ 映射是尽力而为,个别语义不完全等价(trad→trade bas→base hick→hicks)。 若你们更保守,也可以对这 38 个同样走软删 —— 但那样用户会觉得「生词本里的词凭空少了」, 迁移体验更好。

🔴 有一版早期草稿把 rath 映到了 rat(截断残根按「去一个字母」猜的结果)。 那会把用户生词本里本该是 rather 的条目迁成「老鼠」—— 正是 doc 29 §3 那个缺陷 的另一种形态。已修正为 rath → rather,该草稿文件已删除。 如果你们看到任何 rath→rat 的清单,那是作废版本。

露骨词(porno sexo hentai bangbus vaginas masterbat*)在本表里故意留空: 它们没有「正确词形」可迁,是被当作垃圾清掉的。迁到 porn/sex 等于把它们又放回 学习池,与删除的初衷相反。这 15 个建议软删用户行 —— 但这是你们的产品决策。


4. RVH 侧待办

  • [ ] 提交已同步的资产assets/databases/lampio_dict.db 已被 RB 的 scripts/sync-rvh-vocabulary.sh 覆盖为新库(byte-equal,SHA ae33c8a4…), 目前是未提交状态。
  • [ ] bump _preinstalledVocabVersion(doc 25 §7 的理由,每次都要)。 RB 侧对应常量已改为 rb-18925-v26-round30-examples-2026-08-26
  • [ ] 落 A:导入逻辑加删除步骤(你们 backlog 的 P2)。 注意现有唯一的 DELETE 只清 source='backfilled',纯 UPSERT 不会删 preinstalled 行, 所以存量安装拿不到 prune 效果——这正是本轮必须配合改导入的原因。
  • [ ] FK 决策 + 迁移,用 §3 的映射表。
  • [ ] 复验: - 跨端 phase0 byte-equal - 真机拍照含 always 的文本,确认不再被 OcrFuzzyMatcher 改成 alway - 抽查 rather / during / ourselves 现在能本地命中(不再走缓冲池兜底)
  • [ ] 确认复习卡正面不渲染 example_translations(§6,最容易漏且不会报错), 建议补一条同构 Dart 测试
  • [ ] 写回执 docs/cross-end/32-rvh-round30-confirmation.md

5. 两条 RB 侧的实测结论,对你们也有用

5.1 「译文按下标 merge」是个会静默出错的陷阱

RB 这轮的第 0 步实测:把预装库导成 JSONL 再按义项下标回填译文, 43.6% 的中文释义会贴到错误的义项上(23,808 条 / 6,343 词),不报错、不校验。 根因是 quality_governor 在翻译之后重排义项 + 每 POS 封顶 5 + 丢 archaic。

⇒ 凡是「把译文/标注贴回义项」的代码,都要按 gloss 文本键,不要按下标。 如果 RVH 侧有任何按 sense_index 存的东西,值得复查一遍。

5.2 name POS 判据不能单用

「Wiktionary 里见过 name 词性 → 判为专名」实测误伤 8–10% 的真词 (china(瓷器) metabolism petroleum senate prairie matrix node cedar …)。 再用「name 义项占比」也切不开:真词最高 90%(prairie)、专名最低 25%(charlie)。 最终改为「机械过滤 → LLM 语义裁定」,517 候选里只有 155 个真是专名。

⇒ 如果 RVH 侧也想做专名过滤,别照抄 name POS 那条,直接用新库里的 proper_noun 标签。


6. 🔴 例句译文进库了 —— 你们的 cloze 有同款泄露风险,必须一起处理

新库里每条例句都带了中文译文,存在 pos_definitions[].definitions[].example_translations, 是与 examples 等长的平行数组(缺位补空串)。形状与既有 example_source[] 一致, 所以不读它就完全无感,runtime 零改造成本。

但一旦你们要显示它,先看这条:

你们的 lib/features/vocabulary_notebook/domain/services/cloze_builder.dart

dart
static Cloze? buildFallbackCloze(String word, List<String> examples, {...})

是与 RB cloze.ts::pickFallbackCloze 同构的例句回落路径 —— 复习卡在没有真实语境时 会拿预装库例句挖空。而它的防泄露(和 RB 一样)只遮英文里目标词的各种形态, 对中文一无所知

复习卡正面绝不能渲染 example_translations 中文译文必然含目标词的词义 = 直接把答案递给用户,现有防泄露拦不住。 揭晓侧 / 查词详情页可以显示。

RB 侧已落两条回归测试钉住这点(cloze.test.ts::「例句译文不得泄露到卡面正面」, 含注入式反向验证:把译文拼进卡面后测试立刻变红)。建议你们也补一条同构的 Dart 测试 —— 这类泄露不会报错、不会崩,只会让用户觉得"这卡怎么这么简单"。

数据进库 ≠ 默认显示(doc 30 §5.4)。「例句底下要不要常驻中文」是独立的产品决策, 之后随时可以迭代(折叠 / 按需 / 常显),不需要再来一轮 reseed。 反过来说,做成常显之前值得先想清楚它会不会削掉例句的阅读价值 —— 学习者的眼睛会直接滑到中文。

7. 本轮没有做的

  • lemma_* 三张表未动,所以你们的 lemmatizer 行为与上一轮完全一致。

  • 露骨内容只清了释义层,例句层还有残留。验收时扫到 eff you see kay why oh you (拼读脏话,挂在 see / why 词条下)这类例句仍在。量很小,本轮未处理。

    已在 2026-08-26 的补轮做掉(含这里点名的这条) —— 见 33-rb-explicit-example-cleanup-handoff.md。 那轮另外删了 9 个露骨词(校准闸门 1)、并补上了你们 doc 32 §5.2 报的 per-POS cefr, 预装库 SHA ae33c8a4…06cbb4dc…、18,925 → 18,916。 本单交接的 ae33c8a4… 已被它取代,但本单其余内容不改 —— doc 32 是对本单原文的回执。