Skip to content

RVH 并入 RB 仓 —— 可行性评估

物理仓库位置:~/reading-browser(RB 桌面端)。对端 RVH = ~/reading_vocab_helper(Flutter/Dart)。 创建:2026-08-28 · 由用户发起("双端维护成本 / 测试协调成本 / 不一致纠错成本明显偏高")。

✅ 已决策并实施完毕(2026-08-29 归档)

状态:go —— 2026-08-28 用户拍板(plan P0-5),当日完成合仓,2026-08-29 五阶段全部收工。 本文件的倾向结论(合并可行且值得做,硬前置 = 根 CLAUDE.md 先瘦身下沉)被实施验证, 顺序也照办了(阶段 1 先做)。实施记录见 rvh-merge-plan.md(同在本 archive 目录)。

🔴 本评估里有一处收益估算后来被实测推翻,引用前务必知道: §「可删/可简化」那张表把 65MB 预装库去重算作历史体积收益 —— 不成立。 git 按内容寻址,byte-equal 的两份天然只存一个 blob(实测 HEAD 两路径同一个 blob; 全历史 distinct blob 并集 8,不是 13)。symlink 换来的是判据结构化 + 工作区 checkout 65MB,不是仓体积、也不是 clone 下载量。详见 plan 的「T4-5 结果」§2。 同表把 verify-rvh-alignment.sh 列作「大幅简化」也不成立(它零跨仓断言,见 plan「T4-6 结果」②)。

以下为 2026-08-28 写作当时的原始评估,保持原样。 本文件只管为什么值不值;那份只管怎么做。两份都别写成对方。

关联:archive/admin-merge-plan.md §6 曾于 2026-07-19 明确写下 "RVH 不合并"——本文件是对那条结论的重新评估,见 §1。 archive/landing-split-plan.md 是反向先例(拆分而非合并), 其判据(爆炸半径隔离)在本案中不适用,见 §7。

⚠️ 本文不含任何红线锁标记,是刻意的:/arch-check S28 扫 docs/plans/*.md 里的锁标记, 基线是 4 份(全部已裁定为"引用")。本文件不定义任何新红线,只按编号引用既有的。 合并真正落地后,需要新增或收敛的红线按 CLAUDE.md §4「红线归属规则」写进稳定归属, 不留在本文件——plan 会归档,红线不会。


0. 一句话

~/reading_vocab_helpergit subtree 迁入本仓 rvh/,像 admin/ 一样作为卫星子项目存在。 前置条件:根 CLAUDE.md(当前 ~20.7k tokens,每会话恒加载)必须先拆分下沉到 src-tauri/CLAUDE.md / src/CLAUDE.md,否则 RVH 会话的固定开销会从 ~28k 涨到 ~49k。


1. 为什么现在重新评估

archive/admin-merge-plan.md §6 在 2026-07-19 给出过三条"RVH 不合并"的理由。 两个月后逐条复核,三条里有两条已被事实推翻

2026-07 的理由2026-08-28 复核
「异构 Flutter/Dart,混合上下文易出错」仍成立。但答案是 scoped CLAUDE.md + scoped skill(admin/ 已验证一个多月),不是分仓。分仓等于用"物理上不可能"去解决"应该分流"的问题,代价过高。
「合 git 省不掉你主动想要的会话隔离」已推翻。跨端契约(红线 #6d / #5i / #6c)现在必须在一个会话里同时看两端才改得对。今天的实际做法就是在一个会话里用绝对路径读另一个仓——隔离早已名存实亡,只是省不掉手工同步的成本。
--add-dir 只读挂载够用」已推翻。够用的前提是"只读"。2026-08 的三条 cross-end 工作(#6d 契约升格、#6f 三态守卫、cloze 池 relay)都要两端同时写

分界事件(都发生在 2026-07-19 那份计划之后):

  • 2026-07-19 预装词库 pipeline 迁入 RB,RVH 降级为纯消费方(红线 #10)。共享资产从"各自产出"变成"RB 单点产出 + RVH 拷贝"。
  • 2026-08-05 红线 #5i(push user-scoping)与 RVH #5h 成对出现,两端各写一遍 grep 守卫。
  • 2026-08-26 红线 #6a / #6c 的裁定同时约束两端删除路径与 pull 守卫。
  • 2026-08-27 红线 #6d 由「RB 侧实现细节」升格为双端契约(RB ⇄ RVH 同文)——这是决定性的一条: 文档里明写"同文"的东西,物理上却存在两个仓的两个文件里。

2. 分仓的实际代价(2026-08-28 实测)

下面所有数字都是当天的快照。复现命令见附录 A —— 别照抄数字当事实(docs/cross-end/40 的行数一天就从 29/45 漂到 54/73,教训见 commit db0a9ae)。

2.1 RVH 已有三分之一的工作量是镜像 RB 契约

近 3 个月(2026-06-01 起):

commit 总数docs/cross-end/
RB62865(10%)
RVH11441(36%)

RVH 每 3 条提交就有 1 条是跨端对齐。它已经不是"并行开发的独立客户端", 而更接近"RB 契约的第二个实现"。

2.2 docs/cross-end/ 是一条编号序列被物理劈成两半

01–41 是单一时序序列docs/cross-end/README.md 的编号总表), 但 RB 存 35 份、RVH 存 30 份,交错编号。直接后果记录在最近三条 commit 里:

db0a9ae docs(cross-end): 交接单 40 别写死行数 —— 一天就从 29/45 漂到 54/73
f6c9032 docs(cross-end): 交接单 40 别把回执编号写死 —— 41 已被并行会话占掉
2a21c31 docs(cross-end): 编号 41 = cloze 池 relay —— 登记一条指向 verification/ 的在途台账

并行会话抢编号 + 为防抢号而额外维护一本在途台账—— 这两项开销 100% 由"同一账本存在两个 git 仓"造成,合仓后归零。

而且这条劈裂已经把一道守门脚本变成恒红(2026-08-28 写本文件时顺手实测): node scripts/check-doc-links.mjs 报 19 处悬挂引用,其中 8 处是 docs/cross-end/README.md 指向只存在于 RVH 仓的回执,另有 1 处是 31-rb-round30-reseed-handoff.md → 32-rvh-round30-confirmation.md

25-rvh-lemmatizer-v26-confirmation.md          ✅ 在 RVH 仓
27-rvh-lemmatizer-residual-scan-handoff.md     ✅ 在 RVH 仓
29-rvh-prune-reseed-request.md                 ✅ 在 RVH 仓
32-rvh-round30-confirmation.md                 ✅ 在 RVH 仓
35-rvh-ocr-cloze-context-confirmation.md       ✅ 在 RVH 仓
36-rvh-tombstone-parent-confirmation.md        ✅ 在 RVH 仓
37-rvh-tombstone-synced-at-handoff.md          ✅ 在 RVH 仓
39-rvh-tombstone-synced-at-confirmation.md     ✅ 在 RVH 仓

这 8 份文件都存在,只是在另一个仓。脚本本身是对的(它用 lookbehind 排除了 带 ~/reading_vocab_helper/ 前缀的合规跨仓引用),是编号总表在裸写相对路径。

危险的地方在于脚本给出的诊断是错的:它末尾打印 「多半是 plan 归档后没跟着改路径——补上 archive/ 即可」, 照这句去修会把 8 条跨仓引用改成指向不存在的 archive/ 路径。 这与 §2.4 是同一个病:一道因与所守之物无关的原因而恒红的闸门,和没有闸门是一回事, 且这一道还会主动误导修它的人。合仓后这 9 处自动变绿,无需改任何引用。

2.3 契约被维护两遍

CLAUDE.md §4 红线 #6d 自己写着「双端契约(RB ⇄ RVH 同文)」。 而 ~/reading_vocab_helper/CLAUDE.md 的「跨端 Sync 协议红线」一节 = 728 行 / 67KB,占它整个控制文件的 68%,内容是 #5b/#5d/#5e/#5f/#5g/#5h/#6b/#6c/#6d/#6e/#6f 的 Dart 侧镜像 + 各自手写的 grep 守卫。

这正是 /docs-audit 天天在抓的「第二本账」,只是它跨了仓所以扫不到。 漂移证据已经写在 RVH 自己的控制文件里:

⚠️ 2026-08-27 守卫改三态(#6f)后,原来那句 grep -q "FROM reading_notes WHERE id = ? AND deleted_at IS NULL" 已失效

2.4 cross-end-check.sh 永远进不了 CI(最大单项收益)

scripts/cross-end-check.sh 331 行, 其中 11 处硬编码 $RVH_ROOT

105: RVH_VOCAB="$RVH_ROOT/assets/databases/lampio_dict.db"
158: RVH_DDL="$RVH_ROOT/assets/sql/01_create_tables.sql"
201: RVH_SM2="$RVH_ROOT/lib/core/algorithms/sm2_algorithm.dart"
249: RVH_SYNC="$RVH_ROOT/lib/features/sync/data/repositories/sync_repository_impl.dart"

grep -rn 'cross-end\|verify-rvh\|sync-rvh' .github/workflows/ =

它跑不了 CI,因为 CI 里没有第二个仓。所以三端一致性这道最关键的闸门, 今天只在「你本机 + 手工触发 + 两个仓恰好都 checkout 到正确 commit」时才有意义。 按本仓自己的标准(.gitattributes 里那段"一道恒红的闸门和没有闸门是一回事"), 一道"只在特定人的特定机器上、且要靠人记得跑"的闸门同样不合格。

合仓后它可以路径相对化并进 CI。这是整个合并最大的单项收益。

2.5 65MB 预装库存了两份,各自在 history 里滚了 20+ 版

06cbb4dcde22205d777cd218c1910dacc926cc38d7d8cc95683bfcf0b37b6d59  src-tauri/assets/lampio_dict.db
06cbb4dcde22205d777cd218c1910dacc926cc38d7d8cc95683bfcf0b37b6d59  ~/reading_vocab_helper/assets/databases/lampio_dict.db
  • 单文件 65,777,664 B,两仓 SHA 完全相同(红线 #10 要求 byte-equal)。
  • history 版本数:RB 21 版 / RVH 31 版。
  • .git 体积:RB 214M / RVH 442M(RVH 的 top 大对象全是历次 reading_vocab.db)。
  • 每次 reseed = 两个仓各长约 65MB。

红线 #10 与 124 行的 scripts/sync-rvh-vocabulary.sh 存在的唯一理由,就是这个文件被存了两份。

2.6 其他纯粹为跨仓而存在的东西

规模合仓后
scripts/sync-rvh-vocabulary.sh124 行可删(同一个文件,无需同步)
scripts/verify-rvh-alignment.sh337 行大幅简化
docs/cross-end/sm2-golden-vectors.jsonRVH test/fixtures/逐字节副本一份,三端消费
跨仓绝对路径约定(CLAUDE.md §9)一整节 + 30+ 份文档里的 ~/reading_vocab_helper/...整条规则消失
lemmatizer Layer 3/4Rust 751 行 / Dart 180 行,手工对齐(红线 #9)仍需两份实现,但对齐可进同一条 CI

2.7 产品认知层的漂移(比代码漂移更隐蔽)

双端已经是一个产品两个客户端(同账号、同 Supabase、同预装词库、同 SM-2, 2026-07 三端表名已统一)。但文档层它还是两个产品:

  • docs/product.md(RB,7.1KB):「Lampio —— 把你感兴趣的英文内容,变成你的英语课堂」
  • ~/reading_vocab_helper/docs/product.md(14.6KB):「reading_vocab_helper(阅读词汇助手) —— 基于 CEFR 智能过滤的阅读场景词汇习得工具

后者的定位(拍照识别 + 背单词闭环)与 Lampio 现在明确写在 CLAUDE.md §1 的 「竞品是浏览器/Kindle 阅读器,不是 Duolingo 等教育产品」直接冲突, 而且它还在用改名前的产品名。分仓让这份过期定位在自己的仓里活得好好的。


3. 记忆文件问题 —— 唯一的硬前置

3.1 实测体量(2026-08-28)

文件字节≈tokens
CLAUDE.md71,999~20,700
~/reading_vocab_helper/CLAUDE.md97,904~27,900
admin/CLAUDE.md22,163~6,200
landing/CLAUDE.md6,745~1,900

token 数按 CJK 启发式估算(附录 A 给了脚本),方向可靠,绝对值 ±20%。

关键机制:根 CLAUDE.md 每会话恒加载,子目录的 CLAUDE.md 碰到对应文件才叠加 (本仓已在 admin/ + landing/ 上跑了一个多月)。

3.2 三种场景的算术

场景今天天真合并(RVH 原样搬入)先拆分再合并
只改 RB 桌面端20.7k20.7k~15k
只改 RVH27.9k48.6k(+134%)~19k
跨端改一个契约20.7k + 手工读 27.9k,且两边可能不同步48.6k~27k,且契约只有一份

天真合并这条路不能走。 但拆分之后,两端会话都比现在更轻。

3.3 根 CLAUDE.md 按节实测 + 拆分目标

  118行  ≈3599tok  §2 项目结构
   76行  ≈1592tok  §3 架构要点        ← 桌面端专属
   62行  ≈5132tok  §4 技术红线        ← 约一半桌面端专属,一半是双端契约
   51行  ≈1758tok  §5 数据库          ← 桌面端专属
  123行  ≈2449tok  §9 双端整合
   84行  ≈1930tok  §8 开发工作流
   51行  ≈1696tok  §7 项目 Skills

目标结构:

CLAUDE.md              ~6-7k   仓库地图 · 双端契约红线(#5i/#6d/#9/#10) · git纪律 · 安全 · 文件组织 · skill 索引
src-tauri/CLAUDE.md    ~7-8k   §3 架构要点 + §4 桌面端红线(#1~#8,#11) + §5 数据库迁移纪律
src/CLAUDE.md          ~2k     UI/组件/strings 约定(或仅留指针到 ui-standards.md)
rvh/CLAUDE.md          ~10k    Flutter 专属(去掉 728 行镜像红线之后剩下的)
admin/CLAUDE.md        不动
landing/CLAUDE.md      不动

⚠️ §4 不能整块下沉:#5i / #6d / #9 / #10 明写着是双端契约, 那部分正是应该留在根、并且合仓后第一次拥有唯一物理归属的东西。 RVH 那 728 行镜像红线的绝大部分,合仓后应该并进根的这几条, 而不是原样搬进 rvh/CLAUDE.md(那只是把第二本账换个位置继续记)。

这件事不合并也该做。 根文件 20.7k 已经偏大; ~/.claude-cli/projects/ 下已有一个 claude-md-trim worktree 目录,说明这个方向早已在考虑中。

3.4 必须先验证的地基假设

上面所有算术都建立在「子目录 CLAUDE.md 按需加载」上。 这是本仓文档里的断言,也和 admin/ 的实践一致,但它是整个方案的地基

阶段 0 必做:开一个只碰 admin/ 下文件的会话,确认 admin/CLAUDE.md 确实是在触达时才注入、而非启动即加载。半小时以内能做完,做不通则整个方案的收益模型作废。


4. 合并引入的问题

4.1 动手前必须解决

(1) Gitee 仓库体积上限 — 待用户确认.git 合并后 ≈ 650M,可能超过 Gitee 免费仓配额。 GitHub 侧 ttfishnet/lampio私有仓、当前 diskUsage 约 75MB,问题不大; Gitee 是双推备份之一(CLAUDE.md §8「分支卫生」),需要先确认配额。

若卡上限,可选:

  • 只对 RVH 侧做一次 git-filter-repo 清掉 31 个历史 dict blob(约省 200M+),再 subtree add。
  • 绝对不要改写 RB 历史——红线 #11 的 src-tauri/src/db/shipped_migrations.txt 真相源是发布 tag,改写历史会让 tag SHA 全变。

(2) RVH history 的完整 secret scan —— 🔴 已跑,查出真密钥

本条的初版结论("抽查都是占位模板,问题不大")已被 2026-08-28 的实跑推翻。 那次抽查只看了 .env.production.env.development,两份确实是 GOOGLE_VISION_API_KEY=your_g… 占位模板 —— 但唯一带真值的是没抽到的 .env.staging。 同族文件里"抽两份都干净"证明不了第三份干净,这是"抽查不是审计"的活标本。

gitleaks git ~/reading_vocab_helper --log-opts="--all" 报 8 条,其中 4 条是真密钥BAIDU_OCR_API_KEY + BAIDU_OCR_SECRET_KEY(熵 4.42),2026-01-02 起躺在 .env.stagingassets/.env.staging 的历史里,而 Baidu OCR 至今仍在 RVH 代码中使用lib/features/ocr/data/engines/baidu_ocr_engine.dart 等四处),即凭据大概率仍然有效。 另 4 条是 YOUR_PROJECT_REF 占位符误报。

这是阶段 1 的阻塞项:先轮换密钥,再决定历史清不清。 处置步骤见 rvh-merge-plan.md §2 的「P0-3 结果」段。

顺带扫了 RB 自己:10 条 finding,0 条新问题——测试夹具 4 条、占位符误报 2 条、 已知已接受的 anon key 4 条(全仓无 service_role)。RB 侧不构成合仓阻塞。

(3) 个人文件会跟着进来USER_NOTES.md(95KB,tracked)、USER_NOTES.md完整流程使用说明.pdftracked)、 QUICKSTART.md(tracked)。个人记录.rtf 未 tracked(安全)。 合并前决定:迁进 rvh/docs/,还是从 RVH 侧先移除。

4.2 需要设计但 admin 已趟过

(4) 并行会话爆炸半径变大 今天 RVH 里一条 git reset --hard 炸不到 RB。合仓后一棵工作树覆盖两端—— CLAUDE.md §8 记录的路径 B(工作树级静默丢失,不看文件域)作用域直接翻倍。 缓解:默认 Agent(isolation:"worktree")。这条纪律已经写了,合仓后从"推荐"变"必须"。

(5) 会话隔离从物理保证降级为约定 CLAUDE.md §9「涉及 RVH 的修改必须在新会话中执行」今天由文件系统强制。 合仓后没有东西拦着一个会话同时读 Rust 和 Dart。

反过来看这也是收益:跨端契约改动本来就应该在一个会话里做(正是 admin 合仓的核心论据)。 合适的规则是分流而非隔离——照根 CLAUDE.md 开头那段 admin/landing 路由提示的形状, 加一段「只碰 rvh/ 就直读 rvh/CLAUDE.md」。

(6) Skill 作用域 RB 的 /arch-check /build-check /code-review /ui-check 要排除 rvh/。 模式已经固化——.claude/skills/arch-check/SKILL.md:105 明写:

新增规则时保持路径限定在 src/ / src-tauri/,禁止写成根级 glob,否则会把 admin/ 误纳入 RB 不变式

RVH 的 8 个 skill 变 scoped:rvh:code-review / rvh:clean-arch-check / rvh:preinstalled-db-update / rvh:i18n-check / rvh:ui-compliance-check / rvh:doc-sync-check / rvh:doc-consistency-check / rvh:code-check-before-restart。 同名冲突(code-review / doc-sync-check 三方同名)由 scoping 处理,admin 已验证。

(7) CI 新增 .github/workflows/ci-rvh.ymlpaths: rvh/**照抄 ci-admin.yml 的形状—— 包括它头注释里那条踩过的坑(on.pathsworkflow 级不是 job 级, 所以必须独立成文件,不能往 ci.yml 加 job)。 RVH 现有 ci.yml 的 4 个 job(analyze / architecture / test / coverage)原样搬。 Ubuntu ×1,成本可忽略。

(8) .mcp.json 根文件加 rvh-debug(8 个工具),两个 debug MCP 并存,路径从绝对改相对。


5. 目录整合方案

不是简单搬迁。分四类:

A. 原样搬进 rvh/

lib/ test/ android/ ios/ assets/(除 dict db)pubspec.* analysis_options.yamll10n.yaml local_packages/(opencv_dart)third_party/(sqlite3 二进制)bin/rvh-debug-mcp/ .gitignore CHANGELOG.md docs/(除 cross-end)

CHANGELOG 建议保持两份。根 CLAUDE.md 说「CHANGELOG.md 是唯一的 as-built 日志」, 但那是对桌面端而言;171KB + 234KB 合成一份没人读得动,且两端发版节奏不同。 改成 rvh/CHANGELOG.md,根 CHANGELOG 加一行指针即可。

B. 必须合并到根(收益所在)

RVH 侧去处理由
docs/cross-end/ 30 份docs/cross-end/单一编号序列复原,抢号问题消失
test/fixtures/sm2-golden-vectors.json引用根 docs/cross-end/sm2-golden-vectors.json逐字节副本 → 一份
assets/databases/lampio_dict.db引用 src-tauri/assets/lampio_dict.db见 D
CLAUDE.md 的 728 行镜像红线CLAUDE.md §4 双端契约条目契约获得唯一物理归属

C. 死历史,合并时清掉

  • ~/reading_vocab_helper/supabase/migrations/ —— 它自己的 README 第一行就写着 「纯历史留痕,真相源已全部迁至 RB」。合仓后连"留痕"的理由都没了(git history 就是留痕)。
  • ~/reading_vocab_helper/tools/vocabulary_builder/ —— 旧 pipeline, v3 已于 2026-07-19 迁入 RB tools/vocabulary_builder_v3/(红线 #10)。

D. 待实测:65MB 预装库能不能只存一份

理想形态:rvh/assets/databases/lampio_dict.db → symlink 到 src-tauri/assets/lampio_dict.db(git 原生支持 symlink)。收益:

  • 每次 reseed 少长 65MB;
  • 红线 #10 从"靠脚本断言"变成"结构上不可能违反"—— 一整条红线 + sync-rvh-vocabulary.sh 124 行同时作废。

风险:Flutter 对 symlink 资产的处理需要实测(pubspec.yaml 的 assets 路径必须在 package 内; flutter build 是否跟随 symlink;Android / iOS 打包是否都可以)。

退路:若 symlink 不行,改成 build 步骤 copy——收益略降(工作区仍两份)但 git 里仍只有一份

这一项单独实测,不作为合并的阻塞项。


6. 实施路径

阶段 0  验证机制(半天)—— 全部只读,零风险
  ├ 实测子目录 CLAUDE.md 确实按需加载(§3.4)★ 不通则整个方案作废
  ├ 确认 Gitee 仓库体积上限(§4.1-1)
  └ RVH history 完整 secret scan(§4.1-2)

阶段 1  拆 CLAUDE.md(1-2 会话)—— 此时还没合并
  ├ 根 20.7k → 6-7k
  ├ 下沉 src-tauri/CLAUDE.md + src/CLAUDE.md
  └ 立即受益:现有 RB 会话就变轻了
      ↓ 若阶段 1 收益未兑现,到此可停,什么都没损失

阶段 2  subtree 合入(1 会话)
  ├ git subtree add --prefix=rvh <gitee-rvh-url> master   ← 保留 429 条 commit
  ├ RVH CLAUDE.md 去掉 728 行镜像红线 → rvh/CLAUDE.md
  ├ RB skill 加 rvh/ 排除;RVH 8 个 skill 变 scoped
  ├ 新增 ci-rvh.yml(照抄 ci-admin.yml 形状)
  ├ .mcp.json 加 rvh-debug
  ├ 清 §5-C 的死历史;处理 §4.1-3 的个人文件
  └ 老 gitee 仓归档(只停推、不删),停止双仓开发

阶段 3  兑现收益(合仓后逐步做,不必一次做完)
  ├ docs/cross-end/ 两半归并、编号复原                     ← 抢号问题终结
  ├ cross-end-check.sh 路径相对化 → 进 CI                  ★ 最大单项收益
  ├ sm2-golden-vectors.json 去重(RVH fixture 改引用)
  ├ 红线 #6d / #5i / #9 / #10 收敛为单一定义
  ├ 预装库 symlink 实测(§5-D)→ 可能作废红线 #10 + 删 sync 脚本
  ├ 删 sync-rvh-vocabulary.sh、简化 verify-rvh-alignment.sh
  ├ CLAUDE.md §9「跨仓库路径约定」整节删除
  └ 合并 docs/product.md(顺便修 RVH 那份过期定位,§2.7)

回滚:阶段 2 之后若后悔,git revert 掉那条 merge commit, 老 gitee 仓仍在(归档不删)。窗口期内可逆。 阶段 3 开始动共享资产后,回滚成本上升——阶段 3 之前是最后的自然决策点。


7. 被否决的替代方案

方案否决理由
维持现状 + 加强跨仓自动化无论怎么加强,cross-end-check.sh 都进不了 CI(§2.4)。抢编号、双份契约、双份 65MB 资产也都还在。
抽第三个"共享契约仓"三个仓,协调成本 O(n²),比现在更糟。
git submodulepin 到某个 commit,契约漂移变成"submodule 指针过期"——比现在还难发现,正好是 §2.3 那类静默漂移的加强版。
squash 导入(丢 RVH 历史)仓体积最小,但丢掉 429 条 commit 的 blame。本项目的红线大量来自"为什么当时这么写",blame 是活的资产。

8. 待用户拍板

  1. 阶段 1 与阶段 2 是否分开做 —— 强烈建议分开(阶段 1 独立成立、可停可回)。 一次做完也可以,只是少一个回滚点。
  2. CHANGELOG 合不合 —— 建议保持两份(§5-A),但取决于翻阅习惯。
  3. Gitee 配额 —— 只有用户能查(§4.1-1)。

阶段 0 的另外两项(按需加载实测 / secret scan)可由 Claude 直接跑。


附录 A:数字的复现命令

本文所有数字都是 2026-08-28 的快照。别照抄,重跑:

bash
# §2.1 近 3 个月 commit 与 cross-end 占比
git log --since=2026-06-01 --oneline | wc -l
git log --since=2026-06-01 --oneline -- docs/cross-end/ | wc -l
(cd ~/reading_vocab_helper && git log --since=2026-06-01 --oneline | wc -l)
(cd ~/reading_vocab_helper && git log --since=2026-06-01 --oneline -- docs/cross-end/ | wc -l)

# §2.2 双端 cross-end 份数
ls docs/cross-end/*.md | wc -l
ls ~/reading_vocab_helper/docs/cross-end/*.md | wc -l

# §2.2 劈裂造成的恒红守门(悬挂引用里有几条其实在对端仓)
node scripts/check-doc-links.mjs
# 注意只取箭头右边(目标),左边是发出引用的源文件,别一起判
node scripts/check-doc-links.mjs 2>&1 | grep '❌' | sed 's/.*→ //' | sort -u | while read f; do
  b=$(basename "$f")
  if   [ -f "$f" ];                                       then r='在 RB 仓(不该报错,去查脚本)'
  elif [ -f ~/reading_vocab_helper/docs/cross-end/"$b" ]; then r='★ 在 RVH 仓 —— 劈裂造成'
  else                                                         r='真悬挂(或已归档)'
  fi
  printf '%-58s %s\n' "$b" "$r"
done

# §2.3 RVH 镜像红线段体量(起止行号会漂,先 grep 定位小节标题)
grep -n '跨端 Sync 协议红线' ~/reading_vocab_helper/CLAUDE.md

# §2.4 CI 是否覆盖跨端检查(应为空)
grep -rn 'cross-end\|verify-rvh\|sync-rvh' .github/workflows/
grep -c 'RVH_ROOT' scripts/cross-end-check.sh

# §2.5 预装库 byte-equal 与 history 版本数
shasum -a 256 src-tauri/assets/lampio_dict.db ~/reading_vocab_helper/assets/databases/lampio_dict.db
du -sh .git ~/reading_vocab_helper/.git
git log --oneline --all -- src-tauri/assets/lampio_dict.db src-tauri/assets/reading_vocab.db | wc -l

# §3.1 / §3.3 CLAUDE.md 体量与分节 token 估算
wc -c CLAUDE.md admin/CLAUDE.md landing/CLAUDE.md ~/reading_vocab_helper/CLAUDE.md
python3 - <<'PY'
import re
s=open('CLAUDE.md',encoding='utf-8').read(); lines=s.split('\n')
idx=[(i,l) for i,l in enumerate(lines) if re.match(r'^## ',l)]+[(len(lines),'EOF')]
for (a,t),(b,_) in zip(idx,idx[1:]):
    seg='\n'.join(lines[a:b]); cjk=sum(1 for c in seg if '一'<=c<='鿿')
    print(f'{b-a:5d}行 {len(seg):7d}B ≈{int(cjk+(len(seg)-cjk)*0.28):6d}tok  {t[:60]}')
PY

# §4.1 GitHub 仓库可见性与体积
gh repo view ttfishnet/lampio --json name,visibility,diskUsage,isPrivate