主题
33 · 例句层露骨清理 + 校准闸门 1 + 补 per-POS cefr(RB → RVH,小补轮)
物理仓库位置:
~/reading-browser/docs/cross-end/33-rb-explicit-example-cleanup-handoff.md(RB)。 日期:2026-08-26 · 方向:RB 已产出 → RVH 跟进 前情:doc 31(round30 交接)· doc 32(你们的回执,已完成) 回执:如无异常,回执可并进你们下一份文档,不必单开一份
1. 一句话
你们刚接完 round30,很抱歉又来一轮 —— 但这轮对你们几乎零成本。 预装库又改了一次(ae33c8a4… → 06cbb4dc…,18,925 → 18,916 行), 已 byte-equal 同步进你们仓里。因为你们 doc 32 §4.1 落的 prune 是通用集合差 (「本地 source='preinstalled' 但新库已不含的词条」),不是硬编码的 53 词清单, 所以本轮删的 9 个词你们不用做任何事,导入时会自动被 prune 掉。
并且你们 doc 32 §5.2 报的 per-POS cefr 缺失也在本轮修掉了(§4)—— ourselves 等 9 个词现在拍照管线能正常筛到了。
vocabulary 18,925 → 18,916 (-9,见 §3)
例句 86,817 → 86,693 (-66 露骨例句,+ 义项/词条删除连带走的)
per-POS cefr 缺口 212 → 0 (新增词齐全率 46.2% → 100%,见 §4)
SHA ae33c8a4… → 06cbb4dc…
lemma_* 三张表仍然一行未动 → 你们的 assets/nlp/*.json fixture 依旧无需同步你们要做的(§6 详列):提交资产 + _preinstalledVocabVersion 28 → 29 + 跑一遍 preinstalled_prune_test.dart 的真机路径。没有新的 FK 决策,没有新的迁移映射表。
⏱ 为什么不等下一轮一起做:这是对预装库的行/列级改动,做一次就要走一遍 「改库 → sync → bump 版本 → 两端同轮发版」。本该赶在你们接收 round30 之前做掉、 并进 doc 31(那样协调成本为零),但实际动手时你们已经收完并回执了 —— 这一轮的额外协调成本是已经付出的,不是可以再省的。攒到下次只会更贵 (届时用户已经带着这些例句在用)。
2. 载荷 ①:例句层露骨清理(删 66 条例句 / 64 词 + 连带 8 条义项)
2.1 为什么非清不可 —— 是 round30 载荷 ④ 引入的净损害
round30 的露骨词清理只做了释义层,例句层没碰。立项时的粗估是「65 条挂在普通 可学词下」;正式扫描把召回面放宽后实际是 119 条候选 / 逐条裁定后删 66 条 (§2.2 给出完整口径)。A1/A2 两档就占 28 个词(删例句的 25 个 + 整条义项去掉的 3 个)。
而同一轮的载荷 ④ 给全部例句配了中文译文 —— 在此之前,中文母语学习者可能一眼 扫过英文脏话;之后 slur 是用母语呈现的。最刺眼的一条挂在 A1 词 date 上:
EN Black Superman could kiss his date, the little faggot.
ZH 黑色超人可以去亲吻他的约会对象,那个小同性恋。 ← 种族 + 性向双重蔑称date / excuse / ball / type 是最高频被学到的词,命中率远高于 cock 那类 没人会去学的词条。
💡 对你们的影响比 RB 小:doc 32 对 doc 31 §6 的订正已经查明
buildFallbackCloze在 RVH 全仓无人调用,你们的复习卡走buildContextCloze(真实语境), 不碰预装库例句。所以这些句子在你们那边只会出现在查词详情页,不会进复习卡。 RB 侧则两条路径都会命中。
2.2 怎么做的:逐条人工过,不按正则批量执行
🔴 正则只用来召回,不用来裁定。 早期一版正则把
turkey-cock/cock crowed/Dick Hudson/cocktail全部误命中 —— 按它批量删会毁掉一批正当例句。
86,817 条例句
└─ 词界锚定的脏话/蔑称/性内容词表 → 命中 498 条 / 173 词
├─ 379 条挂在词条本身即露骨词上(fuck/shit/cunt/cock…)→ 预期,不动
└─ 119 条挂在普通词上 → 逐条人工裁定
├─ DEL-EX 64 删该条例句
├─ DEL-SENSE 8 该义项的唯一例句必删 → 整条义项去掉
└─ KEEP 47
└─ 二次扫描(掩码/拼读变体)→ 再捞 2 条(见 §5)逐条裁定表:33-example-adjudication.tsv (~/reading-browser/docs/cross-end/33-example-adjudication.tsv)。判据:
| 裁定 | 判据 | |
|---|---|---|
| ① | 删 | 针对群体的蔑称 |
| ② | 删 | 作咒骂/侮辱使用的脏话 |
| ③ | 删 | 图解性的露骨性描写 |
| ④ | 留 | 同形误命中:turkey-cock、cock crowed、Dick Hudson、cocktail、Homo sapiens、拉丁 cum(兼任)、Galway/rugby/Richard Hooker、chink=缝隙、Cum on=Come on |
| ⑤ | 留 | 临床/法律/学术/新闻语域里作为题材出现(trigger 那条 "may be triggering for rape victims" 恰是该义项的标准例句) |
| ⑥ | 留 | 义项本身就是那个露骨概念 —— 删例句治不了,属义项层残留(见 §7) |
8 条 DEL-SENSE 的来由:它们的唯一例句按①②③必删,删完 examples 会空。 空保护一响,说明「这条例句该不该删」问错了 —— 正解是整条义项都不该留: date「The anus.」· dome「Head, oral sex」· jazz「To ejaculate.」· slick(omegaverse 体液) 是粗俗俚语义项;mud「A black person.」· rug「Ellipsis of rughead.」的 gloss 本身就是种族 蔑称(zh 已写「黑鬼(侮辱性用语)」);pause 的 intj 义项整块只为承载「no homo」; phantom「A Rolls-Royce Phantom automobile.」义项无害但对学习者零价值、唯一例句是硬蔑称。
3. 载荷 ②:校准闸门 1 —— 删 9 个露骨/网络垃圾词
blowjob bukkake creampie cunt deepthroat footjob handjob milf trackback
全部 cefr_inferred=1、来自 Google 词频源。RB 侧 C1/C2 且 cefr_inferred=1 的可学池 857 → 848。这是 RB calibration.ts 把校准上限从 B2 解封的硬前置之一。
这 9 个词就是你们 prune 会自动删掉的那批(本地有、新库无)。 不需要迁移映射 —— 同 doc 31 §3 末尾对露骨词的处理:它们没有「正确词形」可迁, 迁到 porn/sex 等于把它们放回学习池,与删除初衷相反。建议软删用户行。 量应该极小(这些词很少有人存进生词本)。
⚠️ 闸门 2 不在本轮(纯 RB 侧问题,与你们无关):C2 首屏 20 词里仍有 10 个人名 (
ajax austin barney barr barry beck benedict benny…)。它们在库里带 verb/adj/prep 词性(to beck=招手、to barney=争吵),被vocab_scope判据的第二半放行 —— 而那一半正是fox/march/turkey不被误杀的安全网。继续补标无效,瓶颈在判据形状。
4. 载荷 ③:补 per-POS cefr(回你们 doc 32 §5.2)
212 个 POS 块缺 cefr 键,已全部补上,取值 = 该行 primary_cefr_level。 新增 80 词的「全 POS 齐全率」46.2% → 100%,存量 98.7% → 100%。 你们点名的 9 个受损可学词现在都齐了:
ourselves primary=A2 pron:A2 measles C2 noun:C2 verb:C2
confetti C2 noun:C2 verb:C2 impending C2 adj:C2 verb:C2 noun:C2
insignia C2 noun:C2 undersigned C2 adj:C2 noun:C2
unqualified C2 adj:C2 verb:C2 bioethics C2 noun:C2
cheerleading C2 noun:C2 verb:C24.1 根因:100% 是 round30 自己造成的,两个载荷各漏一处
你们排除了 cefr_source 和 POS 键两个假设,是对的 —— 切不开是因为它根本不按词的属性分, 而是按哪条载荷写进去的分:
| 来源 | 缺口 | 为什么 |
|---|---|---|
_applyFold 造的 name 块 | 157 / 157 全缺 | 它从零构造 POS 块,代码里压根没写 cefr 这个键 |
_applyAdd 从 add_entries 直灌 | 55 / 168 | 那份载荷素材里 55 个 POS 块本就不带 cefr,直灌不补 |
| 合计 | 212 | = 全库缺口总数,一个不多 |
存量那 4 个「全缺」的专名(corey gary johnson virginia)也是同一批 fold 碰过的。 换句话说 round30 之前这个数接近 0,是那一轮把它推到 212 的。
4.2 修的方式,以及一条刻意没做的事
- 新增载荷
fix_cefr:全库扫描,只补缺失、绝不覆盖已有值。 - 两个根因各自堵死:
_applyFold造块时带上词级cefr;_applyAdd走_withPosCefr()兜底(素材带了就用素材的,没带才回落词级值)。 - 加了事后机械守卫:「缺口数只许降不许升」,一升就整轮回滚。 做了注入式反向验证 —— 把加固摘掉后守卫立刻咬(209 → 212,exit 1),还原后放行。 之所以要机械闸而不是「下轮记得看一眼」,正是因为你们那句 「单测和 SHA 校验都发现不了」 —— 这类缺陷只有真机才看得见。
🔴 刻意没做:不碰任何已有的 per-POS
cefr值。 per-POScefr对cefr_source='oxford'的词是权威且可以与primary_cefr_level不同的(Oxford 5000 给的就是分词性 CEFR:above.adj=B1而above.prep=A1)。 RB 仓里_archive/backfill_oxford_pos_cefr.dart记着一次事故:一个 CSV 转义 bug 让 per-POS 被拍平成 top-level,~6,271 个多词性词丢了分词性区分。 「无值 → 填词级答案」和「有值 → 改成词级答案」是两回事,本轮只做前者。这一条也顺带回答你们 backlog 里那个自查项(
primary_cefr_level与 per-POScefr谁是真相源):两者本就允许不同,不是二选一。词级值是「这个词大致什么档」, per-POS 是「这个词性什么档」。要统一的是谁在什么场景读哪个,不是把它们合并成一个。
5. 🔴 一条对你们也成立的召回教训:拼读脏话扫不到
词界锚定的词表扫不到按字母拆开拼读的脏话。eff you see kay why oh you. (= fuck you,挂在 see / why 两个词条下)在第一轮 498 条召回里一条都没进, 是补一遍掩码/拼读变体扫描(eff you see kay / f\*+k / sh[i1!]t / n-word…) 才捞出来的。doc 30 §5 验收时是肉眼撞见它的,doc 31 §7 原把它记作已知残留。
⇒ 如果你们也做类似的内容扫描,词界锚定的词表是必要不充分的, 补一层掩码/拼读变体规则。
顺带一条实现层的坑(RB 这边真踩到的)
pos_definitions[].definitions[] 里 examples / example_translations / example_source 是三个按下标配对的平行数组。删例句时只删其一 = 此后每条例句配的都是别人的译文和来源 —— 无异常、无日志、纯静默错位。 RB 的删除脚本把「三者长度不齐」在进事务之前判死,而不是猜一个对齐方式。 你们若将来要写任何按下标动这三个数组的代码,值得同款处理。
6. RVH 侧待办(很短)
- [ ] 提交已同步的资产:
assets/databases/lampio_dict.db已被 RB 的scripts/sync-rvh-vocabulary.sh覆盖为新库(byte-equal,SHA06cbb4dc…,18,916 行),目前是未提交状态。 ⚠️ 它覆盖掉了你们 doc 32 刚提交的ae33c8a4…。 - [ ] bump
_preinstalledVocabVersion28 → 29。 RB 侧对应常量已改为rb-18916-v28-poscefr-2026-08-26。 - [ ] 确认你们的 prune 自动覆盖这 9 个词(doc 32 §4.1 的方案 A 是通用集合差, 应该是自动的;跑一遍
preinstalled_prune_test.dart+ 真机路径确认即可)。 - [ ] 复验 §4:
ourselves等 9 个词在拍照管线里不再被判 UNKNOWN。 - [ ] 不需要:新的 FK 决策 / 新的迁移映射表 /
assets/nlp/*.json同步 (lemma_*一行未动)。
7. 本轮明知而未做的(不是遗漏)
义项层残留:有一类词,露骨的是义项本身,删例句治不了它 —— john(嫖客)· madam(老鸨)· commercial(男妓)· steady(固定客)· versatile(性角色)· parachute(阴囊环)· beaver(阴部)等。 它们的例句多为临床语域、并不比 gloss 更露骨,故裁定为 KEEP。 要处理它们就是义项层的产品决策(这些词条该不该有这个义项), 不属于「例句层清理」的范围,也不该顺手夹带。下次整库 reseed 时可一并裁定。
闸门 2(§3 已述,纯 RB 侧)。
doc 32 §5.1 请 RB 清 learning_entries 残行那条 —— 收到了,你们自己的判断 (「不可达,不是在发生的事」,双端用户数据 2026-08-25 已全清)RB 侧复核同意, 本轮未动。已记进 RB backlog。
你们 backlog 里那个 primary_cefr_level vs per-POS cefr 谁是真相源的自查 —— §4.2 末尾给了 RB 侧的看法,供参考,但那确实是 RVH 侧的设计决策。