主题
RVH 预装词库 pipeline → RB 迁移正式 plan(Q3 第二步)
物理位置:
~/reading-browser/docs/plans/rvh-vocab-pipeline-migration-plan.md(跨端 plan 统一存 RB,§9) 创建:2026-07-19 · 承接:~/reading-browser/docs/plans/rvh-vocab-pipeline-inventory.md(只读盘点) 性质:正式迁移方案,待用户确认后实施。本 plan 只规划 RB 侧动作;真正改 RVH 仓(移除/改造它那份 pipeline)必须另开 RVH 新会话(§9 会话隔离),清单见 §八。 敏感度:触红线 #10(byte-equal 预装库),比 admin 合仓更敏感 —— 任一步破坏 byte-equal 会触发 sync backfill skip +log::warn+VOCABULARY_SEED_VERSION失去版本语义。故 §四 / §六给出双端 byte-equal 断言护栏,作为不可跳过的验收闸。 全部跨仓引用用~-锚定绝对路径。
一、目标与非目标
目标:把 RVH 预装词库 pipeline(~/reading_vocab_helper/tools/vocabulary_builder_v3/,Dart)lift-and-shift 迁入 RB 仓,消除「RB 产 lemmatizer JSON → 跨仓喂 RVH pipeline → 烤 db → sync 回 RB」的环状 split-brain,使词库内容决策与产出同仓(RB),RVH 降级为纯消费方。
本会话非目标(明确排除):
- ❌ 不动 RVH 仓任何文件(移除旧 pipeline、删
assets/nlp、改 RVH skill 均属 §八,RVH 新会话做) - ❌ 不重写为 Rust/TS(inventory §六结论:ROI 低,Dart 工具能跑就保留)
- ❌ 不借迁移之机改词库内容(治理规则 / 例句 / tag 一律不动 —— 迁移必须内容 byte-identical,见 §四)
- ❌ 本 plan 不执行任何动作,仅规划;实施在用户确认后另起
二、当前拓扑(split-brain 环,已实测锚定)
┌─ RB 仓 (~/reading-browser) ──────────────────────────────────────┐
│ build_dict.rs (examples/) │
│ └─ 产出 → src-tauri/assets/nlp/{surface_to_base,base_forms}.json│ ← lemmatizer 权威源
│ (force_as_base + picked/passed/trying correction 已内置) │ (红线 #5e)
│ sync-rvh-vocabulary.sh │
│ └─ 方向 RVH→RB:cp RVH db → src-tauri/assets/reading_vocab.db │ ← 消费方(当前)
└──────────────────────────────────────────────────────────────────┘
│ nlp JSON 跨仓复制(byte-equal) ▲ db 跨仓复制(byte-equal)
▼ │
┌─ RVH 仓 (~/reading_vocab_helper) ────────────────────────────────┐
│ assets/nlp/{surface_to_base,base_forms}.json ← RB 产物的副本 │
│ tools/vocabulary_builder_v3/ (Dart pipeline, 25 bin + lib+data) │ ← 产出方(当前)
│ config.yaml: │
│ lemmatizer_* → ../../assets/nlp/*.json (读 RVH 副本) │
│ app_db → ../../assets/databases/reading_vocab.db │
│ generate_db.dart → 把 nlp JSON 烤进 lemma_* 表 + 产 db │
│ data/kaikki_english.jsonl.gz → symlink ~/Downloads/(457MB,外部) │
│ data/{differentiation,etymology,generated_examples,phrase_*}.json│ ← LLM cache(入仓,沉没成本)
│ assets/databases/reading_vocab.db ← pipeline 产物, cp 给 RB │
└──────────────────────────────────────────────────────────────────┘实测锚定(2026-07-19):
~/reading-browser/src-tauri/assets/nlp/surface_to_base.json↔~/reading_vocab_helper/assets/nlp/surface_to_base.jsonbyte-equal ✅…/base_forms.json两端 byte-equal ✅~/reading-browser/src-tauri/assets/reading_vocab.db↔~/reading_vocab_helper/assets/databases/reading_vocab.dbbyte-equal ✅- lemma 表契约:
lemma_surface_to_base140,370 行 /lemma_base_forms101,646 行(sync 脚本硬断言) - kaikki 真身:
~/Downloads/kaikki.org-dictionary-English.jsonl.gz(457 MB,gitignore + symlink)
环的本质:build_dict.rs(RB 产 lemmatizer JSON)→ 副本喂 RVH pipeline → 烤进 db → db sync 回 RB。lemmatizer JSON 是 RB 产物却物理躺在 RVH 且被 RVH 消费;db 是 RVH 产物却最终服务 RB。迁移把 pipeline 移入 RB 后,两个 artifact 都在 RB 内闭环,环打开。
三、目标拓扑(迁移后)
┌─ RB 仓 (~/reading-browser) —— 词库单一事实源 ────────────────────┐
│ examples/build_dict.rs │
│ └─ 产出 → src-tauri/assets/nlp/{surface_to_base,base_forms}.json│
│ │ (同仓路径, 无跨仓) │
│ ▼ │
│ tools/vocabulary_builder_v3/ (迁入) │
│ config.yaml: │
│ lemmatizer_* → ../../src-tauri/assets/nlp/*.json (同仓) │
│ app_db → ../../src-tauri/assets/reading_vocab.db (同仓) │
│ generate_db.dart → 烤 lemma_* + 产 db (直接落 RB asset) │
│ data/kaikki_english.jsonl.gz → symlink ~/Downloads/(约定位置) │
│ data/*.json ← LLM cache (随目录迁入, byte-identical) │
│ sync-rvh-vocabulary.sh (方向反转 RB→RVH, 断言不变) │
│ └─ cp RB db → ~/reading_vocab_helper/assets/databases/…db │
└──────────────────────────────────────────────────────────────────┘
│ db 跨仓复制(byte-equal, RB→RVH)
▼
┌─ RVH 仓 —— 纯消费方 ─────────────────────────────────────────────┐
│ assets/databases/reading_vocab.db ← 接收 RB 产物 │
│ (无 pipeline; assets/nlp/ 可删 —— 运行时读 db 内 lemma_*) │
└──────────────────────────────────────────────────────────────────┘关键收益:lemmatizer JSON 从 build_dict.rs 输出后同仓直接被 pipeline 消费(config 相对路径 ../../src-tauri/assets/nlp/,不再 ../../ 穿仓);db 也同仓产出直落 RB asset。环彻底消除。
四、红线 #10 byte-equal 护栏策略(本 plan 最敏感处)
byte-equal 有两个独立层面,迁移必须分开对待,否则会误触发全量 reseed:
4.1 结构迁移层 = 内容零变更(默认路径)
迁移是 lift-and-shift + 改路径 + 反转 sync,不重跑 pipeline、不重产 db。迁移完成后:
- RB 的
src-tauri/assets/reading_vocab.db保持迁移前的原字节(不动) - sync 脚本反转方向后首次跑 =
cp RB db → RVH db,两端仍是迁移前那份字节 - 验收闸 A(必过):迁移前后
shasum -a 256三处(迁移前 RVH db、迁移前 RB db、迁移后 RB db、反转 sync 后 RVH db)四者相等 - 结果:无内容漂移 → 不 bump
VOCABULARY_SEED_VERSION→ 已安装用户零 reseed
这是核心纪律:结构迁移绝不改一个 db 字节。红线 #10 在结构迁移阶段的语义 = 「搬家不换家具」。
4.2 生产复现层 = 确定性 dry-run(验证 pipeline 迁移无损,非发版)
单独、可选地在 RB 内从迁入的 pipeline 重跑 generate_db.dart(Step 6 单点,读同一批 data/*.json + 同一 nlp JSON),产出 output/reading_vocab.db,与仓内现役 db 对比:
- 理想:内容 diff = 0(vocabulary / lemma_* 全表 diff 空)。SQLite 二进制可能因页布局/rowid 分配非 byte-equal,故用表级内容 diff(
sqlite3 .dump或逐表EXCEPT)而非裸cmp作判据。 - 若表级内容 diff = 0:证明 pipeline 迁移无损、确定性保持 → 迁移合格。但不拿这个新 db 发版(避免仅页布局差异触发的伪 reseed);继续用 4.1 的原字节 db。
- 若表级内容 diff ≠ 0:说明迁移引入了路径/环境/确定性回归(如 nlp JSON 读错副本、locale 影响排序、绝对路径泄漏)→ 阻断迁移,定位修复,禁止发版。
4.2 是「迁移正确性」的探针,不是「发版动作」。发版走 §八 RVH 新会话之后、下一次真实内容变更时才发生(那时才 bump 版本 + 双端 reseed)。
4.3 lemmatizer 层 byte-equal(红线 #5e 顺带守护)
迁移不改 build_dict.rs、不改 nlp JSON 内容。迁移后 config 指向 ../../src-tauri/assets/nlp/*.json(RB 权威源,非 RVH 副本)。验收闸 B:迁移后 pipeline 读到的 nlp JSON 与迁移前 RVH 副本 byte-equal(本就同源,实测已相等)—— 确保「换读源」没引入差异。
五、迁移步骤(RB 侧,有序)
全程在
~/reading-browser仓操作;每步给验证。Step 0–7 全在 RB,不碰 RVH。
Step 0 — 预检 & 基线锚定(只读)
bash
cd ~/reading-browser
# 三处基线 SHA(迁移后逐一比对)
shasum -a 256 src-tauri/assets/reading_vocab.db # BASE_DB_SHA
shasum -a 256 src-tauri/assets/nlp/surface_to_base.json src-tauri/assets/nlp/base_forms.json
shasum -a 256 ~/reading_vocab_helper/assets/databases/reading_vocab.db # 应 == BASE_DB_SHA
# 环境就绪
dart --version # 期望 3.10.x
ls -la ~/Downloads/kaikki.org-dictionary-English.jsonl.gz # kaikki 真身在
git -C ~/reading-browser status --short # 记录已有脏文件, 迁移改动隔离写下 BASE_DB_SHA 到 plan 执行记录 —— 这是 §4.1 验收闸 A 的锚。
Step 1 — 迁入 pipeline 目录
git mv/cp -a把~/reading_vocab_helper/tools/vocabulary_builder_v3/整目录搬到~/reading-browser/tools/vocabulary_builder_v3/- 含:
lib/bin/(25 dart +patch_lemmatizer_assets.py)data/(含全部入仓 LLM cache + 词表骨架)config.yamlpubspec.yamlpubspec.lockscripts/README.md.gitignore - 排除(gitignore 已列,不搬):
output/.dart_tool/data/kaikki_english.jsonl.gz(symlink,Step 4 重建) - 决策点(§十 开放问题 Q1):RB 已有
tools/{agid-2016.01.19,wordnet,phrase_eval,build_dict.report.txt}(build_dict 输入 + 短语评测)。迁入的vocabulary_builder_v3/与之平级共存于tools/,命名无冲突,建议保留原名整目录迁入。
- 含:
cd tools/vocabulary_builder_v3 && dart pub get(用迁入的pubspec.lock锁定版本)
验证:dart analyze 通过;ls data/*.json 五个 LLM cache 尺寸与 §二锚定一致(differentiation 7MB / etymology 5MB / generated_examples 5MB / phrase_library 3.6MB / phrase_idiomaticity)。
Step 2 — 理顺 lemmatizer 环状接缝(config 路径重定向)
改 ~/reading-browser/tools/vocabulary_builder_v3/config.yaml:
| key | 迁移前(RVH 相对) | 迁移后(RB 相对,同仓) |
|---|---|---|
lemmatizer_surface_to_base | ../../assets/nlp/surface_to_base.json | ../../src-tauri/assets/nlp/surface_to_base.json |
lemmatizer_base_forms | ../../assets/nlp/base_forms.json | ../../src-tauri/assets/nlp/base_forms.json |
app_db | ../../assets/databases/reading_vocab.db | ../../src-tauri/assets/reading_vocab.db |
- 接缝理顺后的单向链:
build_dict.rs→src-tauri/assets/nlp/*.json→ pipelineconfig.yaml读同一文件 →generate_db.dart烤lemma_*→src-tauri/assets/reading_vocab.db。环变成线,单一产源。 patch_lemmatizer_assets.py:现为 legacy(build_dict.rs已内置force_as_base+ picked/passed/trying correction,红线 #5e)。迁入但标注「历史修正脚本,当前 build_dict 已内置,勿在常规流程调用」—— 保留作审计锚点,不接入 build_all。
验证(验收闸 B):迁移后 config 指向的 nlp JSON 与 Step 0 基线 SHA 相等(同源,必然相等,防手滑指错文件)。
Step 3 — kaikki 外部 dump 纳管
- 不入仓(457MB)。约定固定位置:保持 symlink 模式
data/kaikki_english.jsonl.gz -> ~/Downloads/kaikki.org-dictionary-English.jsonl.gz - 在
tools/vocabulary_builder_v3/README.md(或data/KAIKKI.md)文档化:来源 URL(kaikki.org English Wiktionary dump)、期望文件名、ln -s重建命令、大小校验。gitignore 已含该 symlink 条目(随目录迁入)。 - 决策点(§十 Q2):是否把 kaikki dump 移到仓内固定路径(如
~/reading-browser/tools/vocabulary_builder_v3/data/.kaikki/)而非~/Downloads。建议维持~/Downloadssymlink(零拷贝、已 gitignore),仅补文档。
Step 4 — 反转 sync 方向(RVH→RB 改 RB→RVH)
改 ~/reading-browser/scripts/sync-rvh-vocabulary.sh:
| 项 | 迁移前 | 迁移后 |
|---|---|---|
| 语义 | RVH 产 → cp 到 RB | RB 产 → cp 到 RVH |
SRC | ~/reading_vocab_helper/assets/databases/reading_vocab.db | ~/reading-browser/src-tauri/assets/reading_vocab.db |
DST | src-tauri/assets/reading_vocab.db | ~/reading_vocab_helper/assets/databases/reading_vocab.db |
幂等 cmp -s skip | 保留 | 保留 |
| 4 表白名单断言 | 保留 | 保留不变(lemma_base_forms/lemma_meta/lemma_surface_to_base/vocabulary) |
| lemma 行数断言 140370/101646 | 保留 | 保留不变 |
| 机器污染检查(audio_local_path/last_accessed_at 全 NULL) | 保留 | 保留不变 |
| 版本提示 | 提示 bump RB VOCABULARY_SEED_VERSION | 提示 bump RB VOCABULARY_SEED_VERSION 且 RVH 侧版本锚(§八 协调) |
- 断言逻辑对源 db跑(现在源 = RB asset),目标是 RVH。所有 hygiene 断言对源不变,方向反转不削弱护栏。
- 脚本头注释更新:source/target 互换、方向说明、红线 #10「产出方 RVH→RB」措辞。
Step 5 — 迁移后结构 byte-equal 验证(验收闸 A,§4.1)
bash
# RB asset 未被任何步骤改动 → 应 == BASE_DB_SHA
shasum -a 256 ~/reading-browser/src-tauri/assets/reading_vocab.db # 期望 == BASE_DB_SHA
# 反转后 sync(RB→RVH),跑一次
bash ~/reading-browser/scripts/sync-rvh-vocabulary.sh # 幂等应 "Already in sync"
# 双端 cmp
cmp ~/reading-browser/src-tauri/assets/reading_vocab.db \
~/reading_vocab_helper/assets/databases/reading_vocab.db && echo "✅ 双端 db byte-equal"四者(BASE_DB_SHA / 迁后 RB / 迁后 RVH / sync 幂等结果)全等 → 结构迁移零内容漂移,不 bump 版本。 任一不等 → 停,查哪步误动 db。
Step 6 — 确定性 dry-run(验收闸 §4.2,验证 pipeline 迁移无损,不发版)
bash
cd ~/reading-browser/tools/vocabulary_builder_v3
dart bin/generate_db.dart # 只跑 Step 6, 读现有 data/*.json + nlp JSON, 产 output/reading_vocab.db
# 表级内容 diff(非裸 cmp —— SQLite 页布局可能差)
sqlite3 output/reading_vocab.db '.dump vocabulary' | sort > /tmp/new_vocab.sql
sqlite3 ~/reading-browser/src-tauri/assets/reading_vocab.db '.dump vocabulary' | sort > /tmp/cur_vocab.sql
diff /tmp/new_vocab.sql /tmp/cur_vocab.sql && echo "✅ vocabulary 内容 diff=0"
# lemma_* 三表同法比对(surface_to_base / base_forms / meta)- 内容 diff = 0 → pipeline 迁移无损,确定性保持,接缝正确。丢弃 output/ 的新 db,不发版。
- 内容 diff ≠ 0 → 迁移回归,定位(多半是 config 路径读错源 / locale 排序 / 绝对路径泄漏),修到 diff=0 才算迁移完成。
Step 7 — 两端 CLAUDE.md + skill 措辞更新(RB 侧部分)
- RB
CLAUDE.md红线 #10:产出方RVH pipeline 单点产出→ 改为RB tools/vocabulary_builder_v3 pipeline 单点产出;sync-rvh-vocabulary.sh方向说明 RVH→RB 改 RB→RVH;lemmatizer JSON「cargo run --example build_dict产物 + pipeline 构建输入」保留(build_dict 仍在 RB,语义不变,只是消费者从跨仓变同仓)。 - RB
CLAUDE.md红线 #5e(若有镜像条款):pipeline 位置 RVH→RB 更新;「RB 产 JSON 喂 RVH pipeline」环状描述改为「RB 内闭环」。 - preinstalled-db-update skill 归属(§十 Q3):该 skill 现在 RVH(
~/reading_vocab_helper/.claude/skills/preinstalled-db-update/),orchestrate 整条 pipeline→reseed→RB 交接。pipeline 迁 RB 后,skill 逻辑主体应迁到 RB(触发词「更新预装库/发布词库/reseed」在 RB 执行dart bin/build_all.dart+ 反转 sync 给 RVH + 生成 RVH 交接文档)。本 plan 只在 RB 侧新建/改 skill;删 RVH 旧 skill 属 §八。 迁移期间两端 skill 短暂并存可接受(RVH 旧 skill 会因 pipeline 已迁走而 Step 报错,需在 RVH 会话同步废弃)。 - RB
CHANGELOG.md/docs/README.md/decisions.md:记 pipeline 迁入 ADR(词库产源归位 RB)。
RB 侧不改 RVH 的 CLAUDE.md / skill / assets —— 全列入 §八。
六、双端 byte-equal 验证程序(红线 #10 验收,汇总)
迁移「完成」的判据 = 下列全绿:
| 闸 | 检查 | 命令 | 通过判据 |
|---|---|---|---|
| A(结构·必过) | RB db 未变 | shasum -a256 src-tauri/assets/reading_vocab.db | == BASE_DB_SHA |
| A | 反转 sync 后双端相等 | cmp RB_db RVH_db | 无输出(相等) |
| A | sync 幂等 | 再跑 sync-rvh-vocabulary.sh | 打印 "Already in sync" |
| B(lemmatizer) | config 指向 nlp 源未变 | shasum -a256 src-tauri/assets/nlp/*.json | == Step0 基线 |
| C(确定性·探针) | 重跑 generate_db 内容无漂移 | .dump 逐表 diff | vocabulary + lemma_* 全 diff=0 |
| D(护栏存活) | sync 断言未削弱 | 读脚本 | 4 表白名单 + 140370/101646 + 机器污染检查在 |
任一红 → 迁移未完成,不提交、不发版。 A/B/C 全绿方可 commit「结构迁移」批(不 bump 版本,不 reseed 用户)。
七、提交与回滚
提交(RB 侧,结构迁移批):
feat(vocab-pipeline): lift-and-shift vocabulary_builder_v3 into RB; reverse RVH sync direction- 走 RB 提交流程(
/code-review视需要);明确 commit body 声明「db 字节未变、无 reseed、VOCABULARY_SEED_VERSION 不 bump」。 - 不改 RVH 仓 —— RVH 侧动作全在 §八 新会话,独立 commit。
回滚:结构迁移不改 db 字节、不 bump 版本,回滚安全 = git revert RB 迁移批 + 恢复 RVH pipeline 目录(若已 git mv,RVH 侧尚未删则原样还在;若用 git mv 跨仓不可行——见 §十 Q4)。sync 脚本方向回退即恢复 RVH→RB。因结构迁移零内容变更,回滚不涉及用户数据 / reseed。
八、RVH 侧协调清单(必须新会话,§9 会话隔离)
本 plan 不执行下列任何项;实施在 RVH 新会话,以本 plan §三目标拓扑为准。
- [ ] RVH 移除/归档
~/reading_vocab_helper/tools/vocabulary_builder_v3(迁出后避免双份漂移;建议git rm并在 commit 注明「迁至 RB,见 rvh-vocab-pipeline-migration-plan.md」) - [ ] RVH
assets/databases/reading_vocab.db确认为接收 RB 产物(消费方),本地不再产 - [ ] RVH
assets/nlp/{surface_to_base,base_forms}.json:确认 RVH app 运行时只读 db 内lemma_*、不再需 JSON(红线 #5e:cross-end/13 已折叠)→ 可git rm这两个副本;若仍有运行时引用则先解耦再删 - [ ] 确认 RVH app 运行时只 ATTACH 只读
reading_vocab.db,不依赖 pipeline 在 RVH 仓内(grepvocabulary_builder_v3无源码引用) - [ ] RVH
.claude/skills/preinstalled-db-update/废弃/迁移:pipeline 已在 RB,该 skill 的cd tools/vocabulary_builder_v3步骤在 RVH 会失败 → 迁到 RB(Step 7 已在 RB 建对应 skill)或改为「RVH 仅接收 db」精简版 - [ ] RVH
CLAUDE.md红线 #10 / #5e:产源 RVH→RB、sync 方向、pipeline 位置措辞更新(与 RB Step 7 对称) - [ ] RVH
CHANGELOG.md记 pipeline 迁出 - [ ] 双端 byte-equal 联测:RVH 会话完成后,RB 端跑 §六 全表 diff 再确认一次两端 db 仍 byte-equal(迁出不应改字节)
九、风险
| 风险 | 缓解 |
|---|---|
| 破坏红线 #10 byte-equal(最严重) | §4.1 结构迁移绝不重产 db;§六 验收闸 A 四处 SHA 全等才算过;违反即阻断 |
| 重跑 generate_db 内容漂移(确定性回归) | §4.2 dry-run 表级 diff 探针;diff≠0 阻断定位(config 路径 / locale 排序 / 绝对路径泄漏三大嫌疑) |
| lemmatizer 接缝指错源 | §5 Step2 config 显式改指 src-tauri/assets/nlp/;验收闸 B SHA 比对 |
| kaikki 外部 dump 丢失/换机不可复现 | §5 Step3 文档化来源+重建命令;维持 gitignore symlink |
| 双份 pipeline 漂移(迁移期 RVH 未删) | §八 明确 RVH 新会话 git rm;迁移期不并行跑两端 pipeline |
| skill 断裂(RVH preinstalled-db-update 失效) | Step7 RB 建对应 skill;§八 RVH 废弃旧 skill;迁移期短暂并存已知可接受 |
| 误 bump 版本触发全量 reseed | 结构迁移批 commit body 明令不 bump;发版留到下次真实内容变更 |
十、开放问题(请用户先确认,再实施)
- Q1 目录落位:迁入
~/reading-browser/tools/vocabulary_builder_v3/(与现有tools/{agid,wordnet,phrase_eval}平级)—— 认可否?还是想收拢到tools/vocab/子目录统一命名?(建议:保留原名平级迁入,改动最小) - Q2 kaikki dump:维持
~/Downloadssymlink + 补文档(建议);还是移到仓内固定路径纳管? - Q3 preinstalled-db-update skill:主体迁 RB(建议);RVH 保留精简「仅接收」版还是完全删除?
- Q4 搬迁方式:跨仓无法
git mv保留历史 —— 用cp -a+ RVH 侧git rm(历史留在 RVH 旧 commit,RB 视为新增)即可,还是需要git filter-repo迁移子目录历史?(建议:cp -a,不迁历史,简单且够用) - Q5 实施时机:本 plan 确认后,RB 侧结构迁移 = 本会话续做还是另起?RVH 侧必新会话(§9)。
附:关键路径速查(~-锚定)
| 用途 | 路径 |
|---|---|
| RVH pipeline(迁移源) | ~/reading_vocab_helper/tools/vocabulary_builder_v3/ |
| RB pipeline(迁移目标) | ~/reading-browser/tools/vocabulary_builder_v3/(新) |
| lemmatizer 产源 | ~/reading-browser/src-tauri/examples/build_dict.rs |
| lemmatizer JSON(RB 权威) | ~/reading-browser/src-tauri/assets/nlp/{surface_to_base,base_forms}.json |
| RB 预装库 asset | ~/reading-browser/src-tauri/assets/reading_vocab.db |
| RVH 预装库 asset | ~/reading_vocab_helper/assets/databases/reading_vocab.db |
| sync 脚本 | ~/reading-browser/scripts/sync-rvh-vocabulary.sh |
| kaikki dump 真身 | ~/Downloads/kaikki.org-dictionary-English.jsonl.gz(457MB, 外部) |
| RB 版本锚 | ~/reading-browser/src-tauri/src/db/helpers.rs::VOCABULARY_SEED_VERSION |
| 只读盘点 | ~/reading-browser/docs/plans/rvh-vocab-pipeline-inventory.md |
十一、RB 侧实施状态(2026-07-19 已完成)
RB 侧结构迁移已实施并提交:commit 6a4d0a8(refactor(vocab-pipeline): lift-and-shift …)。
- ✅ pipeline 迁入
~/reading-browser/tools/vocabulary_builder_v3/(72 文件镜像 RVH,含全部确定性 LLM cache) - ✅ config.yaml 三路径重定向到
../../src-tauri/assets/(闸 B:nlp 源 SHA 未变,解析到 RB 同仓) - ✅ sync 脚本反转 RB→RVH(断言/白名单不变,REPO_ROOT 锚定 cwd 无关)
- ✅
.gitignore收复:RB 顶层全局data/误伤 → pipeline 内!data/,跟踪清单逐字节镜像 RVH 72 文件 - ✅ vocab-reseed skill v2.0.0;CLAUDE.md #10/缓冲池;CHANGELOG
- ✅ 闸 A 通过:迁移前后预装库 SHA 恒为
b2821764adcdc48b5fe919032bb83d19aa608a69455c25f00d4b871034ec1795,双端 byte-equal,未 bump 版本、零 reseed - ✅ 闸 C 机械部分:
dart analyzeNo issues found(完整复现型闸 C 推迟到下次真实内容变更 reseed)
RVH 侧 assets/nlp 实测(供 §八 决策):RVH assets/nlp/{surface_to_base,base_forms}.json 不是 clean delete —— Flutter app 运行时已折叠读 db 的 lemma_*(lemmatizer_flutter_loader.dart,pubspec 已停 bundle),但仍有 3 个活跃消费方:bin/phase0_normalize.dart(红线 #5e 验证工具)、bin/normalize_phrases.dart、test/core/nlp/lemmatizer_test_setup.dart。删除会断这些 CLI/测试 → §八「先解耦再删」是待决策项(保留作 fixture / 重构到 db 二选一)。
十二、RVH 会话交接 Prompt(可直接粘贴到新 RVH 会话)
交接 Prompt:Q3 收尾 —— RVH 侧移除旧 vocab pipeline(RB 会话已完成迁移,本会话=RVH 镜像收尾)
⚠️ 会话隔离(CLAUDE.md §9):本任务只改 RVH 仓 ~/reading_vocab_helper,绝不碰 RB 仓 ~/reading-browser。
跨仓引用一律用 ~-锚定绝对路径。所有危险操作(git rm / 删 assets)按 CLAUDE.md 安全规则先 AskUserQuestion。
## 背景
预装词库 pipeline(tools/vocabulary_builder_v3,Dart)已在 RB 会话 lift-and-shift 迁入 RB 仓
(~/reading-browser/tools/vocabulary_builder_v3),RB 成为单一产源,sync 方向反转为 RB→RVH。
RB 侧结构迁移已完成、提交 commit 6a4d0a8、byte-equal 验收全绿
(db 双端 SHA 恒为 b2821764…,零内容变更、零 reseed)。
正式方案 + RVH 协调清单权威源:
~/reading-browser/docs/plans/rvh-vocab-pipeline-migration-plan.md(读它,§八 = 本会话任务清单,§十一/十二 = RB 实施状态与本 prompt)
## 本会话任务(执行 plan §八,RVH 侧镜像收尾)
1. 移除 RVH 旧 pipeline:git rm ~/reading_vocab_helper/tools/vocabulary_builder_v3(72 个跟踪文件)。
commit 注明「迁至 RB,见 rvh-vocab-pipeline-migration-plan.md」。历史留旧 commit,不迁 git 历史(Q4 决策)。
2. ⚠️ assets/nlp/*.json 是「待决策」非「直接删」:已实测 RVH 仍有 3 个活跃消费方——
- bin/phase0_normalize.dart(红线 #5e 跨端 byte-equal 验证工具,dart:io 读 assets/nlp/*.json)
- bin/normalize_phrases.dart
- test/core/nlp/lemmatizer_test_setup.dart(lemmatizer 测试 fixture)
运行时(Flutter app)已不读 JSON(走 db 的 lemma_* 表,lemmatizer_flutter_loader.dart 已折叠,
pubspec.yaml 也已停止 bundle assets/nlp)。故删 assets/nlp 会断上述 CLI + 测试。
→ 请 AskUserQuestion 让用户在两条路里选:
(A) 保留 assets/nlp 作 CLI/测试 fixture(它是 RB build_dict 产物的 byte-equal 副本,小而稳;
最省事,但双份资产存在需在文档注明「RB 权威、RVH 仅测试镜像」)
(B) 重构 CLI/测试改从 reading_vocab.db 的 lemma_* 表装载后再删 assets/nlp(彻底去重,工作量大)
建议 (A)。无论哪条,红线 #5e 双端 byte-equal 验证义务不变(验证脚本见 plan §5e / RVH CLAUDE.md #5e)。
3. 确认 RVH app 运行时只 ATTACH 只读 reading_vocab.db、不依赖 pipeline 在 RVH 仓内:
grep -rn "vocabulary_builder_v3" lib/ pubspec.yaml —— 已知残留 2 处 doc 注释需更新(非代码依赖):
- pubspec.yaml:132 「tools/vocabulary_builder_v3 config 路径指向此处」→ 改为「pipeline 已迁 RB」
- lib/core/utils/example_text_cleaner.dart:11 引用 tools/vocabulary_builder_v3/bin/... → 更新为 RB 路径或删
4. 废弃/精简 RVH skill .claude/skills/preinstalled-db-update/(204 行,orchestrate 整条 pipeline→reseed→交接):
pipeline 已迁 RB(RB 的 vocab-reseed skill 已升级 v2.0.0 兼任产库)。RVH 此 skill 的
cd tools/vocabulary_builder_v3 步骤在 RVH 已失效。
→ AskUserQuestion:完全删除,还是改成「RVH 仅接收 RB 产物 + bump _preinstalledVocabVersion」精简版?
5. RVH CLAUDE.md 措辞更新(与 RB 对称):
- 红线 #5e:pipeline 位置 RVH→RB;「RB 产 JSON 喂 RVH pipeline」环状描述改「RB 内闭环,RVH 纯消费」
- 若有 #10 镜像 / 「RVH pipeline 单点产出」措辞 → 改「RB pipeline 单点产出,RVH 纯消费」
- 「项目当前状态」里凡述及 vocabulary_builder_v3 产库流程的,指向 RB
- _preinstalledVocabVersion=25 版本锚常量本身不动(结构迁移零内容变更,不 reseed);
仅记「未来 reseed 时该常量与 RB VOCABULARY_SEED_VERSION 双端同步」
6. RVH CHANGELOG.md 记 pipeline 迁出。
7. 更新 RVH memory:project_phrase_library_rvh / project_vocabulary_builder_v3 等提及 pipeline 在 RVH 的
条目,标注已迁 RB(避免下次会话按旧位置找)。
## 收尾验收(必跑)
双端 byte-equal 联测(迁出不应改任何字节):
cmp ~/reading_vocab_helper/assets/databases/reading_vocab.db \
~/reading-browser/src-tauri/assets/reading_vocab.db # 必须 byte-equal (SHA b2821764…)
若选了方案 (A),再验 assets/nlp 双端 byte-equal:
cmp ~/reading_vocab_helper/assets/nlp/surface_to_base.json \
~/reading-browser/src-tauri/assets/nlp/surface_to_base.json
cmp ~/reading_vocab_helper/assets/nlp/base_forms.json \
~/reading-browser/src-tauri/assets/nlp/base_forms.json
红线 #5e 归一回归(plan §5e / RVH CLAUDE.md #5e 有完整命令):RB/RVH lemmatize 输出 diff 须为空。
## 红线 / 纪律
- 红线 #10:预装库双端 byte-equal,本次迁出零内容变更,不 bump 版本、不 reseed。任何 cmp 不等即停。
- 红线 #5e:lemmatizer 资产双端 byte-equal 义务照旧(无论 assets/nlp 保留还是重构)。
- 危险操作(git rm / 删 assets/nlp / 删 skill)逐个 AskUserQuestion 确认,列受影响文件、标「不可撤销」。
- 先出计划给用户确认再动手(本会话是执行会话,但删除类操作仍须逐项确认)。