主题
合仓后仓库优化 —— 实施计划
物理仓库:
/Users/larry/reading-browser(合仓后单仓,RVH 在rvh/) 创建:2026-08-29 · 状态:✅ 已完成并归档(13/13,2026-08-30 全阶段收尾 —— 阶段 0/1/2/3/4 全绿) ⚠️ 唯一一项改判:T4-2 不重写 git 历史,走 P5 自带的降级出口(理由见 §1 阶段 4 表下与 §3 T4-2)。 立项自archive/rvh-merge-plan.md收尾评估 —— 那份管「合仓怎么做」, 本份管「合仓做完之后,正式功能迭代开始前还欠什么」。
0. Context
RVH 合仓(2026-08-28/29,五阶段十项)的结构性目标全部达成:双端契约有唯一物理归属、 共享资产只剩一份、cross-end-check.sh 与 ci-rvh.yml 都进了 CI 且绿。这些不可逆的改善不在本计划范围。
本计划处理的是合仓收尾评估当场量出来的四类欠账:
- token 预算退化 —— 合仓计划自己把「根
CLAUDE.md先瘦身」定为唯一硬前置, 阶段 1 做到了(73.0 KB → 50.5 KB,-30.8%),但阶段 4 又把它涨回 65.8 KB。 真正严重的是 RVH 单端会话:27.9k → 43.7k tokens(+57%)。 - 合仓新造的假话 —— 根
CLAUDE.md两处写着CHANGELOG.md是「唯一的 as-built 日志」, 而rvh/CHANGELOG.md(248 KB,比根的还大)还在独立更新。 - 同型的病还剩七个 —— 合仓治好了「
cross-end-check.sh只在特定人的特定机器上手工跑」这一个, 但sync-verify/ops-verify/privacy-verify/release-verify/migration-verify/learning-loop-verify/db-audit七个脚本一个都没接 CI(CI=0、package.json=0、skill=0)。 - 正在流血的两处 —— 四个 verify 脚本的静默截断缺陷(backlog 已标 🔴 未修)、
rvh-debugMCP 连不上(本会话实测CONNECTION_CLOSED)。
为什么是现在:以上每一条都会按会话次数持续计费(token)或静默失效(闸门), 功能迭代开始后只会更贵、更难排期。
0.1 关键诊断:token 退化的三个机制性原因
不是「文档写太多」这么简单。逐层挖到底是三条:
原因 1 · 持久记忆库完全空置 —— CLAUDE.md 在兼任记忆库
~/.claude-cli/projects/-Users-larry-reading-browser/memory/ → 空目录
MEMORY.md → 不存在记忆系统的设计是「一事一文件 + 按相关性召回」(按需)。这条通道从没启用过, 于是每一条值得长期记住的事实只有一个落点:恒加载的 CLAUDE.md。 这就是棘轮的动力源 —— 不存在更便宜的地方,任何新裁定都只能往上加。
对照证据:合仓 T4-4 与 T4-7 都是去重任务,结果都净增(+5.9 KB / +3.4 KB)。 归并掉的是内容,累加上去的是元记述(为什么改判、实测证据、双向指针)—— 那些恰恰是典型的「记忆」而不是「指令」。
原因 2 · 把「红线的稳定归属」和「恒加载」绑死了
CLAUDE.md §4 立的规则(红线必须写进稳定归属、不能只活在会归档的 plan 里)完全正确, 但它被实现成了「稳定归属 = 恒加载文件」。二者本可以分开:
| 红线需要什么 | 是否要求恒加载 |
|---|---|
| 唯一权威位置 | ❌ 任何稳定文件都行 |
| 改代码时找得到 | ⚠️ 只需要索引在恒加载处 |
| 机械可执行 | ❌ 靠 CI 脚本,与文件位置无关 |
本仓已经证明分得开:16 条红线正文下沉进 src-tauri/CLAUDE.md,根只留索引行,至今没出事。 只有 4 条双端契约红线是例外 —— 而它们占 21.6 KB(根文件的 33%)。
原因 3 · 按需加载只有一层深,而 RVH 的重量全压在一个子领域
rvh/CLAUDE.md 83.1 KB 里,「跨端 Sync 协议红线」一节 = 57,487 B / 839 行 / 占 69%。
⚠️ 这一节的内容质量是好的,别去删。 抽查 RVH #6g / #5d 的形状完全正确: 开头 **契约** → 根 CLAUDE.md §4 #6d(指针,不复述),随后才是 Dart 落点表、 本端独有证据、真机验证记录、守卫 bash。它不是重复,是深度。
问题在加载时机:rvh/CLAUDE.md 在你碰 rvh/ 下任何文件时注入 —— 改一个 Flutter widget、改一行测试、动一下 pubspec.yaml,都要先付 23.7k tokens, 其中 16.4k 是这次会话根本用不到的 sync 契约细节。
✅ P0-1 实测校正(2026-08-29,判定 A)—— 注入的是「祖先链全量」,不是「最深一层」: 触达
rvh/lib/features/sync/**/*.dart时,rvh/CLAUDE.md(深度 1)与rvh/lib/features/sync/CLAUDE.md(深度 4)一起注入。 ⇒ 下沉的机制不是层级替换,而是按目录条件命中: 不碰 sync 目录的会话省下那 57 KB;碰的会话两份都来、总量不减。🔑 这不削弱 T2-1,反而给了它一个可量化的判据 —— 关键变量是「多少比例的 RVH 会话 会碰
lib/features/sync/」。实测(2026-08-29):近 3 个月动过rvh/的 138 个 commit 里, 碰lib/features/sync/的只有 10 个(7.2%);全历史 30 / 453 = 6.6%。 ⇒ 收益落在约 93% 的 RVH 会话上。📐 由此得到一条可复用的放置原则(下次再想下沉什么时按它判,别再按"层级替换"想): 把内容放在「需要它的会话集合最窄」的那个深度。推论有两条 —— ① 某子树里多数会话都需要的东西,留在该子树根部才对,下沉反而让它被读两遍; ② 下沉后留在原位的索引行是净增成本(对下沉进去的那些会话而言),所以索引要压到最小。
🔴 顺带订正一处合仓台账:T3-8 的验收记着「去镜像 105415 → 78365 B,-25.7%」, 但这一节 728 行 → 839 行,占比 68% → 69%。字节降的 14% 全部来自 「重述改成指针」,结构上一寸没动。T3-8 正文的目标
<40000 B没达成,原因就在这里。 归档件不改(历史记述),此处记录供后来会话对照。
0.2 合仓对 token 的真实影响(分场景三种命运)
换算口径 = 合仓评估同一套 CJK 启发式 ≈3.5 B/token,方向可靠、绝对值 ±20%。 复现命令见 §6 附录 A —— 别照抄这些数字当事实。
恒加载 20.0k = 根 CLAUDE.md 18.8k + 12 个根 skill 的 description 1.1k + 全局偏好 0.3k。 scoped skill 不恒注入(本仓工具集里平时没有 rvh:* / admin:*),但 P0-1 实测发现 它与 CLAUDE.md 注入共用同一个触发条件 —— 碰 rvh/ 下任何文件时,8 个 rvh:* skill 一并注册(+0.68k)。下表已计入。
| 会话类型 | 恒加载 | 按需叠加 | 今天 | 合仓前 | 判定 |
|---|---|---|---|---|---|
| 只改 RB 前端 | 20.0k | src/ 2.1k | 22.1k | 20.7k | 略涨 |
| 只改 RB Rust | 20.0k | src-tauri/ 6.2k | 26.2k | 20.7k | +27% |
| 只改 RVH | 20.0k | rvh/ 23.7k + skill 0.68k | 44.4k | 27.9k | +59% 🔴 |
| 改 admin | 20.0k | admin/ 6.4k | 26.4k | 26.9k | 持平 |
| 跨端改契约 | 20.0k | 6.2k + 23.7k + 0.68k | 50.6k | ~48.6k(且两端可能不同步) | 持平,换来必然同步 ✅ |
T2-1 落地后的投影(按 P0-1 的祖先链全量口径重算,非层级替换):
| RVH 会话 | 占比(实测) | 今天 | T2-1 后 | 变化 |
|---|---|---|---|---|
不碰 lib/features/sync/ | 约 93% | 44.4k | 28.6k | −36% ✅ |
碰 lib/features/sync/ | 约 7% | 44.4k | 45.0k | +1%(多出来的是留在原位的索引) |
占比来自 git 实测:近 3 个月动过
rvh/的 138 个 commit 中 10 个碰 sync(7.2%); 全历史 30 / 453(6.6%)。复现命令见 §6 附录 A ⑨。 期望值 ≈ −33% —— 这就是 T2-1 值不值得做的全部依据,比立项时的估算更硬。
结论:合仓在它被论证的那个场景(跨端契约)持平且换来了正确性,是真收益; 代价全部落在单端会话上,其中 RVH 单端 +57% 是唯一严重的一处, 且 100% 由原因 3 造成 —— 所以 T2-1 单独做完就能把它拉回合仓前水平。
0.3 上下文体系的层级 / 加载时机 / 勾稽关系
┌─ 恒加载(每会话固定 20.0k)──────────────────────────────┐
│ ~/.claude/CLAUDE.md 全局偏好(语言 / 代理端口) │
│ CLAUDE.md 仓库地图 · 双端契约红线 · git 纪律 · 索引│
│ 12 × 根 skill description │
│ MEMORY.md ❌ 不存在 —— 按需召回通道空置(原因 1) │
└───────────────────────────────────────────────────────┘
↓ 触发:用 Read / Edit / Write 碰到该目录下的文件
↓ ⚠️ Bash 的 cat / grep 读同一个文件**不触发**(合仓 P0-2 实测的限定)
┌─ 按需叠加(当前只有深度 1,互不相干)─────────────────────┐
│ src/ 2.1k src-tauri/ 6.2k rvh/ 23.7k │
│ admin/ 6.4k landing/ 1.9k + 该目录的 scoped skill 描述 │
└───────────────────────────────────────────────────────┘
↓ 无自动注入,靠显式 Read
┌─ 文档层(241 份 md / 27 MB)────────────────────────────┐
│ docs/*.md 13 · plans/ 20 活跃 + 162 归档 │
│ cross-end/ 63 · verification/ 8 · archive/ 12 │
│ rvh/docs/ 62 份(自成一套,未与上面归并) │
└───────────────────────────────────────────────────────┘机械勾稽是健康的(这是本仓的真实优势):check:claude-paths(7 份 CLAUDE.md 全覆盖)+ check-doc-links(悬挂 0)+ cross-end-check.sh(18 ✅ / 0 ❌)都在 CI 里。
断掉的两处:① 「唯一 as-built 日志」是假话(T1-3 修); ② docs/README.md 不存在 —— 13 份根层文档没有索引,而 plans / archive / cross-end / verification / tools / supabase 每个目录都有 README,唯独 docs/ 自己没有(T3-2 补)。
0.4 四个子项目的逻辑关系(决定什么该合、什么该留)
真实拓扑不是「1 主 + 4 卫星」,而是**「1 个契约中枢 + 3 个消费者 + 1 个无关静态站」**:
supabase/ ← 契约中枢(sync-tables.sql + 12 edge functions)
│
┌──────────────┼───────────────┬──────────────┐
RB 桌面端 rvh/ admin/ landing/
(根本体) (Flutter) (Next.js) (Next.js)
│ │ │ │
手抄绑定 手抄绑定 编译期绑定 无绑定
sync.rs sync_repository_impl gen-types —
└────── 共享 10 表 / 其中 6 表 · SM-2 · 预装库 · lemmatizer ──┘| 关系对 | 契约耦合 | 工具链共享 | 合仓判断 |
|---|---|---|---|
| RB ⇄ rvh | 极强 | 零 | ✅ 合仓正确 |
| RB ⇄ admin | 中(同 schema,编译期绑定) | 零 | ✅ 合仓正确 |
| RB ⇄ landing | 零 | 零 | 🟡 留在仓里成本近乎为零,但白白触发桌面端 CI(T3-3) |
| rvh ⇄ admin | 零(但同一个 Supabase 项目) | 零 | — |
结构性观察:rvh/ 与 admin/ / landing/ 在目录树上平级,性质却不同 —— 前者是另一个产品端,后两者是配套。这一点 §2 仓库地图已写对。 真正的不对称在于 RB 本体散在根目录,这也是根 CLAUDE.md 必须同时扮演 「仓库总图」和「桌面端控制文件」两个角色的根源 —— §2「项目结构」那 6.9 KB 里有相当一部分其实是桌面端专属内容。 本计划不动这个结构(收益不确定、风险高),仅登记为观察。
1. 进度台账
完成一个任务:把 ⬜ 改成 ✅,填日期与 commit 短 SHA。放弃 / 改判的写 ⏭ 并注明原因。 顺序:先跑 P0-1(它决定 T2-1 能不能做),其余阶段之间无硬依赖,可乱序、可分多会话。
阶段 0 · 探针(只读,零风险)
| ID | 任务 | 会话 | 状态 | 日期 / commit |
|---|---|---|---|---|
| P0-1 | 实测嵌套 CLAUDE.md 在深度 ≥2 是否仍按需加载 | 必须新开一个 | ✅ 判定 A | 2026-08-29 |
P0-1 结论(2026-08-29 · 判定 A = 深度 ≥2 仍按需加载):触达
rvh/lib/features/sync/data/repositories/sync_repository_impl.dart之前 Q1(探针口令)与 Q2(OcrClozeGate)均答不出、控制题 Q0 答得出;之后两题都答得出 —— 深度 4 的rvh/lib/features/sync/CLAUDE.md确实随触达按需注入。T2-1 前置成立。⚠️ 但注入的是祖先链全量,不是最深一层:同一次触达把
rvh/CLAUDE.md(深度 1)与探针 (深度 4)一起注入了。所以 T2-1 的收益口径必须改写为「不碰lib/features/sync/的 RVH 会话省下那 57 KB」,而不是「碰 sync 目录时也只付一份」—— 碰的时候两份都来,总量不减 (还多一次文件读取)。方案仍成立,但 §2 里按「层级替换」估的节省额需按此口径重列。附带观测:同一次触达还注册了
rvh/.claude/skills/下的 8 个 skill(rvh:code-review等), 即 skill 注册与 CLAUDE.md 注入走同一个「触达rvh/下文件」的触发条件。
阶段 1 · 止血(正在流血的,全是机械活)
| ID | 任务 | 会话 | 状态 | 日期 / commit |
|---|---|---|---|---|
| T1-1 | 修 4 个 verify 脚本的「变量后接中文标点」静默截断 | RB | ✅ | 2026-08-29 |
| T1-2 | 修 rvh-debug MCP 连不上(provisioning 缺口) | RB | ✅ | 2026-08-29 |
| T1-3 | 修根 CLAUDE.md 两处「唯一 as-built 日志」假话 | RB | ✅ | 2026-08-29 |
T1-2 结论(2026-08-29):
pnpm --dir rvh/rvh-debug-mcp install跑通,postinstall: tsc产出rvh/rvh-debug-mcp/dist/index.js(16,615 B);直接 import 该产物 能打印starting stdio transport/connected,即服务端自身可启动。步骤已补进rvh/QUICKSTART.md开头那张表(第 4 行)+ 命令块 + 小节标题「两步」改「三步」,未新建第二份说明。 协议层验收(2026-08-29 补做):拿.mcp.json里那条确切配置(node /Users/larry/reading-browser/rvh/rvh-debug-mcp/dist/index.js)起进程,走 stdio 做完整 JSON-RPC 握手 ——initialize返回serverInfo {name: rvh-debug, version: 0.2.0},tools/list列出 7 个工具(rvh_snapshot/rvh_logs/rvh_state/rvh_widget_tree/rvh_navigate_log/rvh_db_query/rvh_supabase_query)。即服务端侧已无缺口: 同一条通路上客户端该拿到的东西都拿得到。✅ 收尾已验(2026-08-29,下一会话开头):新会话启动时
mcp__rvh-debug__*7 个工具 全部出现在工具集里,CONNECTION_CLOSED消失。⇒ 根因就是 provisioning (dist/从未构建过),装完 + 重启客户端即好,客户端配置一侧无缺口。本条闭环。
T1-1 结论(2026-08-29 · 动态验证已完成,坑 1 已绕过):装了
brew install libpq并brew link --force libpq(psql 18.6 进 PATH)⇒ privacy / ops 的 DB 段真的跑到了, 不是 SKIP 蒙混。29 处$var→${var}全改完,四个脚本头部补陷阱说明 + 自检命令; 修完全仓 14 个.sh扫描均为 0。🔑 四个脚本此前的断点(修前逐个实测):
release-verify死在 R1(R2–R15 从未执行)·privacy-verify死在 P7 ·ops-verify死在 M3 ·migration-verify死在 D4 之后 (D5–D9 从未执行)。修后各整跑一次:PASS 16 / 17 / 24 / 10,FAIL 0,SKIP 0。捞到 1 个新 FAIL 并当场修掉:
migration-verifyD9 只扫根CLAUDE.md,而红线 #11 正文 已下沉到src-tauri/CLAUDE.md(根只留索引),于是init_data.sql/seed_reference_words.sql判为「文档没提」—— 文档不窄,是断言指错文件(红线分表时没人回头改它,而它从来没执行过, 所以一直没暴露)。改为扫 CLAUDE.md 家族后转绿。按docs/verification/README.md落账: 修好的进 CHANGELOG,backlog.md里那条 🔴 记录删除,不留报告文件。
阶段 2 · 拿回 token 预算(收益最大)
| ID | 任务 | 会话 | 状态 | 日期 / commit |
|---|---|---|---|---|
| T2-1 | rvh/CLAUDE.md 的 57 KB 红线节下沉到 rvh/lib/features/sync/ | RB(见任务内说明) | ✅ | 2026-08-29 |
T2-1 结论(2026-08-29):
rvh/CLAUDE.md83,107 → 30,601 B(−63%),正文进rvh/lib/features/sync/CLAUDE.md(55,072 B)。搬入内容与原文逐字节 diff 为空(含前言)。 原位留下的索引 1,676 B(≤2 KB 目标达成)+ 顶部一行注入告警;编号对照表按计划留在rvh/CLAUDE.md(2,977 B —— 这是验收里「≤28 KB」没达成的全部原因:那条口径按「整节都搬」估的, 与动作 2「对照表留下」冲突,以离场条件 30k 为准,见下)。 验收:check:claude-paths绿(清单已加第 7 份)·check-doc-links绿 ·cross-end-check18 ✅ / 0 ❌。 离场条件达成:RVH 单端(不碰 sync)44.4k → 29.84k tok(−33%),< 30k。 碰 sync 的那 ~7% 会话 45.58k(+2.7%,即索引 + 对照表被读两遍的净增,计划预估 +1%)。 ⇒ 期望值 ≈ 30.9k(−30%)。顺带修的指针落点(不改内容,只改落点,否则全部悬挂):根
CLAUDE.md4 条双端契约红线的 「RVH 落地」+ §4 形状说明 + 顶部导航表 ·scripts/cross-end-check.sh§人工 checklist 3 ·docs/verification/learning-loop.mdK7 ·rvh/docs/plans/backlog.md·doc-sync-check/SKILL.md·rvh/CLAUDE.md对照表末两行的「本文件 §跨端契约镜像 backlog」。 「6 份 CLAUDE.md」的三处计数同步改 7 份。 | T2-2 | 删两份通用 Claude Code 教程(67.5 KB)+ 修 7 处引用 | RB | ✅ | 2026-08-29 |
T2-2 结论(2026-08-29):两份删掉(-67.5 KB / 2,904 行)。 ⚠️ 实际引用点比正文列的 8 处多 6 处 —— 正文漏了
rvh/docs/guides/README.md的 45 / 56 / 102 / 108 / 113 / 182 行(不只表格那两行:「按场景查找」两小节和「学习路径」中级/高级各有 一段是专为指向这两份而写的),以及rvh/docs/guides/doc-maintenance-guide.md的 283 / 1751 / 1752。全部一并修掉,删后引用为 0(rvh/CHANGELOG.md:956历史记述按令未动)。🔑 正文列的「1 处死过滤」实际是两处,第二处正文没提:
rvh/scripts/doc-consistency-check.shStep 3/6 整步都在查「旧路径引用」—— 文件删掉后这道闸门恒绿且没有对象。已就地改指今天的判据(断言这两份不复活,含引用; 排除 CHANGELOG),不删步、不重编号 ——rvh/docs/plans/backlog.md有 3 处按 「Step 6」引用它,重编号会造死链。反向注入实证过(塞一处引用 → 当场红,去掉 → 绿)。 这跟 T1-1 修migration-verifyD9 是同一类修法:断言指错对象,不是判据太窄。验收:残留引用 0(除本文件与 CHANGELOG)·
check-doc-links绿 ·check:claude-paths绿 ·cross-end-check18 ✅ / 0 ❌ ·rvh/scripts/doc-consistency-check.sh6/6 全绿。
阶段 3 · 补闸门与索引
| ID | 任务 | 会话 | 状态 | 日期 / commit |
|---|---|---|---|---|
| T3-1 | 把 verify 脚本不依赖线上凭据的那部分接进 CI | RB | ✅ | 2026-08-29 |
T3-1 结论(2026-08-29):新建
.github/workflows/ci-verify.yml(动作 2 的「二选一」 选了新建,不并进ci.yml—— 后者是前端 job,pnpm install+vite build会把一道 <1 分钟的门拖成 3 分钟,而这两个脚本一个node_modules都不需要)。未加paths过滤 (那是 T3-3,混在一起会让两项的触发效果分不开)。接了 2 个,不是 3 个:
migration-verify.sh --max-skip=2+learning-loop-verify.sh --max-skip=1。 🔴release-verify.sh实测后暂缓(正文按静态处数把它排在第一优先,此处按证据改判): 它的 SKIP 数是网络可达性的函数而不是环境常量 —— 同机同码连跑两次,SKIP 分别是 4 和 11 (第二次latest.json没取到 ⇒ R7-R11 连带全 SKIP)。给它钉任何--max-skip基线都会得到 一道随网络天气变红的门,正是阶段 3 前言那条离场条件要防的东西。接它需要先把网络段与 静态段拆开(R1-R4 那批是零网络的),记为独立一笔。 ✅ 接线的两个前置已经做好、已提交:①release-verify.sh也拿到了--max-skip; ②PROXY的取值从${RB_PROXY:-…}改成${RB_PROXY-…}—— 冒号版把显式空串也当 「未设置」塞回默认代理,于是 CI 里根本关不掉代理,每个 curl 都打向不存在的 127.0.0.1:7897 ⇒ 全 SKIP ⇒ 假绿。去掉冒号后RB_PROXY=才真的表示直连。选这两个的判据 = 静态段零网络(读文件 / git / python3)⇒ SKIP 数在 CI 里是常量 ⇒ 基线钉得住。 基线来历(在剥掉 psql / gh / Keychain / 本机存量库的沙箱里实测): migration-verify PASS=8 FAIL=0 SKIP=2(无本机存量库 D5 + 连带 ledger 对照 D6)· learning-loop-verify PASS=7 FAIL=0 SKIP=1(M 段部署态无 psql/凭据)。
反向注入实测 3 次,全部本机完成、当场还原(动作 3 的硬要求): ① 全仓多放一份
sm2-golden-vectors.json副本 → learning-loop L1 FAIL → exit 1 · ② 改掉src-tauri/src/db/shipped_migrations.txt里一个 sha → migration-verify FAIL → exit 1 · ③RVH_ROOT指向不存在的路径(判据的对象消失,不是判据变错)→ SKIP 1→3 > 基线 →--max-skip自身把它判红 → exit 1。第 ③ 条是这道门存在的全部理由: 没有它,一个因缺凭据全 SKIP 的脚本会永远显示绿色 —— 假绿闸门比不接更糟。 三次注入撤销后各复跑一次均回到 exit 0。⚠️ 顺手修的一处自伤:
ci-verify.yml头两版注释里写了脚本的带扩展名全名, 当场把check-schema-frozen.mjs与cross-end-check.sh的 CI 列从 0/1 刷成 1/2 —— 接线矩阵的 CI 列是机械 grep,注释里的一次提及就能把没在跑的脚本标成在跑。 已改写注释并把这条纪律写进 workflow 文件头 +scripts/README.md§2 的读法陷阱 ②。
scripts/README.md的矩阵已同步重算(T3-2 刚建的那份不能留着旧数): 🔴 三列全 0 11 → 9,并从两类拆成三类 —— 「还没接、该接」4 个 (sync-verify/privacy-verify/ops-verify/db-audit,= 阶段 3 剩余工作面)· 「暂缓、有明确理由」1 个(release-verify)·「刻意手工」4 个(备份 / 拉资产 / 生成映射 / 清测试数据 —— 它们是动作不是判据,没有「应该恒真」的东西可守)。验收:本机 CI 模拟两步均 exit 0 · 反向注入 3/3 变红 · 不传
--max-skip时三个脚本行为 逐字不变(本机仍是 0/1/2/3 四态)·check-doc-links绿 ·check-claude-md-paths对两份 README 绿 ·cross-end-check18 ✅ / 0 ❌ · 全仓.sh中文标点扫描仍为 0。 ✅ CI 绿跑:run33259344385(2026-08-29,双远端已 push)。CI 实测数与沙箱预测逐字相同: migration-verify PASS=8 FAIL=0 SKIP=2 · learning-loop-verify PASS=7 FAIL=0 SKIP=1。🔑 首跑是红的,而那次红正是这道门的价值证明(run
33259292953):CI 里 SKIP=3 > 基线 2, 多出来的是 D4(指纹清单 vs 发布 tag)——actions/checkout默认depth=1且不带 tag, D4 在 tag 上git show取不到东西只能 SKIP。修的是成因不是基线:抬到 3 等于白白让掉 一条零凭据、真能抓事的判据,故改为fetch-depth: 0(commit9ea51b81),基线维持 2。 换句话说--max-skip上线第一天就拦下了一次「少验了一条却看起来绿」—— 这正是 §0 第 3 类欠账的病根形状。
T3-1 续(2026-08-29 同日第二轮):又接了
sync-verify.sh --max-skip=1,并把剩下三个 从「还没接」改判为「接不了 / 不该接」—— 这一轮的产出主要是判据不是接线。🔴 方法论的坑(下一个人会重踩,写在这里):量「哪些检查不依赖凭据」时必须先把 gitignored 的
admin/.env.local藏起来。四个脚本都会set -a; . 它(里面有 service_role + anon key),于是本机沙箱里一大片「看起来是静态」的检查其实在拿本机凭据 读线上库。第一次没藏,ops-verify报 PASS=19 / SKIP=1,我据此把它推荐成最佳候选; 藏掉之后真实数字是 PASS=0 / SKIP=8 —— 接了就是一道 100% 假绿闸门。 同理要剥掉psql/gh/ Keychain(security) 与$HOME。四个候选的实测结论:
脚本 无凭据 判定 sync-verify.shPASS=1 SKIP=1 ✅ 已接 —— 唯一零网络零凭据的真断言(N0:shell 表清单 vs Rust PENDING_PUSH_TABLES)。覆盖面只有 1 条,但那条只有这里守ops-verify.shPASS=0 SKIP=8 ❌ 接了 = 100% 假绿 privacy-verify.shPASS=7 SKIP=8 ❌ 那 7 条(P8-P13)全是打 admin.lampio.app的线上 HTTP,不是静态判据。按 commit 触发 = 让第三方 uptime 决定 CI 红绿,且验的是「已部署的站点」不是「这次改动」。要守它该走 schedule,是另一个设计决定db-audit.sh无凭据直接退出 ❌ 纯生产数据巡检,没有静态段,不是 CI 候选 🔑 接
sync-verify时抓到一个真缺陷并修掉:它的汇总退出逻辑被抄了三份 —— N1-N7 那两条「无凭据 / psql 连不上」的早退路径各自printf …; exit 2,绕开文件末尾那份。 后果是--max-skip在唯一会走到的那条 CI 路径上完全无效(沙箱实测:传了--max-skip=1仍然 exit 2)。已收敛成单一finish(),三处调用同一实现。 这与 T1-1 修migration-verifyD9、T2-2 修doc-consistency-checkStep 3/6 同型: 判据本身没错,错在它挂在一条没人走的路径上。反向注入(本机,当场还原):把 shell 侧表清单抄漂一张(
reading_notes→reading_notez) → N0 FAIL → exit 1;撤销后 exit 0。另验四种退出路径:本机不传参 exit 0 · 沙箱不传参 exit 2(旧行为不变)· 沙箱--max-skip=1exit 0 · 沙箱--max-skip=0exit 1。🔴 三列全 0 9 → 8,且这 8 个现在分三类:接不了/不该接 3 · 暂缓有理由 1 · 刻意手工 4。 ✅ 第二轮 CI 绿跑:run
33261136610(sync-verify PASS=1 FAIL=0 SKIP=1,与沙箱预测一致)。 「还没接、该接」这一类现在是空的 —— 阶段 3 的接线工作面到此为止, 剩下的都是「有实测理由不接」或「要先改脚本结构才谈得上接」。 | T3-2 | 补docs/README.md+scripts/README.md| RB | ✅ | 2026-08-29 | | T3-3 | 根ci.yml加paths过滤 | RB | ✅ | 2026-08-29 |
T3-3 结论(2026-08-29):四个子项目目录(
admin/landing/rvh/supabase/) 不再触发根ci.yml。🔴 用
paths+!取反,不是正文建议的paths-ignore—— 按实测改判,理由是正文 自己那条风险提示(「写窄了让真该跑的不跑,比 CI 白跑严重得多」):paths-ignore不支持取反,而ci.yml的check:claude-paths校验 7 份 CLAUDE.md, 其中 4 份就住在要忽略的目录里(admin/CLAUDE.md·landing/CLAUDE.md·rvh/CLAUDE.md·rvh/lib/features/sync/CLAUDE.md)。直接 paths-ignore ⇒ 「只改rvh/CLAUDE.md」的提交彻底绕开那道门。 改用paths: ['**', '!admin/**', '!landing/**', '!rvh/**', '!supabase/**', '**/CLAUDE.md']: 以'**'起头 + 逐个!排除 = 语义等价 paths-ignore,但能把 CLAUDE.md 再 include 回来; 且不是正文警告的正向白名单(起点是全仓,新目录默认在内,漏不了)。顺序有意义 ——**/CLAUDE.md必须在三条!之后。各门的输入逐条写进了ci.yml文件头,作为将来加新!排除时的自查清单。实测三次真实 push(短命分支
ci-paths-probe,验完即删,main 未被污染):
探针 改了什么 根 CI其它 ① 02b09e7e只加 rvh/下一个文件❌ 未触发(达成) CI (rvh)✅ 触发 ·CI (cross-end)✅ 触发② f6a86bc3只加 src-tauri/下一个文件✅ 触发且 success(run 33261400364)CI Rust✅ 触发③ 2d0c9c21只改 rvh/CLAUDE.md✅ 触发且 success(run 33261448528)证明 **/CLAUDE.md那条捞回来的确生效探针 ③ 是正文没要求、但本版设计特有的一条:没有它,这次改动会静默地把 4 份 CLAUDE.md 移出守门范围 —— 收窄触发面最容易造的就是这种「省了算力、丢了断言」的暗账。
⏭ 顺带观察,登记不做:
ci-verify.yml目前没有paths过滤(T3-1 刻意留白, 免得两项的触发效果分不开)。三次探针里它每次都跑 —— 它 <1 分钟且零依赖安装, 代价可接受;要不要给它也配触发面是独立一笔。
T3-2 结论(2026-08-29):两份索引落地 ——
docs/README.md7,600 B (根层 13 份逐条 + 6 个子目录归属)·scripts/README.md10,504 B (25 个脚本逐条 +scripts/lib/4 个共享实现)。 ⚠️ 正文的「25 个脚本」现数为 26 个条目 —— 那 26 里含scripts/lib/目录本身,脚本仍是 25 个。接线矩阵按附录 A ⑤ 现生成,未手抄;顺带盘出两个读法陷阱(已写进 README §2, T3-1 直接复用这张表时必须带着):①
CI=0≠ 不在 CI —— 经package.json间接进ci.yml的有 8 个(check-no-inline-zh/en·check-schema-frozen·set-version·audit-locale-coverage·check-claude-md-paths·check-doc-links·build-content-script); ②CI=1≠ 在 CI 里跑 ——scripts/release.sh那个 1 是release.yml的一行注释。 真正被 workflow 直接run:的只有 3 个(cross-end-check.sh·check-vocab-asset.sh·gen-latest-json.mjs)。🔴 三列全 0(没有任何东西在自动执行)= 11 个:6 个
*-verify.sh+db-audit.sh(这 7 个是 T3-1 的工作面)+ 4 个刻意手工的工具(backup-supabase-storage.mjs·fetch-openmoji-assets.sh·gen-word-illustrations.py·reset-dev-data.sh—— 它们没有「应该恒真」的断言,不接 CI 是知情选择)。README 用 🔴 把这两类区分开, 因为分不出「忘了接」与「刻意不接」正是这 11 个长期没人管的成因。
docs/ui-standards.mdvsrvh/docs/ui-guidelines/已写明是刻意的、不是漂移 (docs/README.md §1 的 🔑 块):两端设计系统不同源(CSS 变量+Tailwind@themevs Material 3 elevation/color-role/typography),合并会产出一份两边都不能执行的东西; 真正要三端一致的是数据与算法,归属在CLAUDE.md§4 / §9。未加任何红线锁标记 (README 是索引不是红线归属,本计划刻意不进/arch-checkS28 集合)。验收:
check-doc-links绿(docs/README.md已自动进 activeFiles)·node scripts/check-claude-md-paths.mjs docs/README.md scripts/README.md绿 ·cross-end-check18 ✅ / 0 ❌。⏭ 遗留(另一笔活,登记备查):这两份 README 的路径校验目前只能手工跑 —— 刻意没有加进
package.json的check:claude-paths清单,因为那条命令的语义是 「CLAUDE.md 家族」,掺进 README 会让它名不副实。要常态化守门需要一条新的check:readme-paths(或让check-claude-md-paths.mjs支持第二个文件集), 与 T3-1 的 CI 接线一并考虑。
阶段 4 · 清理与收口(择期,互不依赖)
| ID | 任务 | 会话 | 状态 | 日期 / commit |
|---|---|---|---|---|
| T4-1 | 给 docs-governance-plan.md 一个了结 | RB | ✅ | 2026-08-30 |
| T4-2 | 删 22.3 MB 归档 SQL(改判:不重写历史,走 P5 自带的降级出口) | RB | ✅ | 2026-08-30 |
| T4-3 | 两份 backlog 分片 + rvh/docs/plans/ 补归档节律 | RB | ✅ | 2026-08-30 |
| T4-4 | docs/mcp-primer.md 归档(不删) | RB | ✅ | 2026-08-30 |
T4-2 改判(2026-08-30):P5 的 ROI 算式在动手前重算已不成立 (
.git实为 328 MB 非 72 MB,目标 blob pack 后 7,941,186 B ⇒ 回收 2.3% 非 10%; 真正的大头是红线 #10 必须保留的预装库 35 blob / 94.21 MB)。 又实测发现两处 P5 没算的代价:仓里还有feat/admin-ops-console分支 + GitHub open PR #1 会被一并作废;两个远端 tag 集合不对称(GitHub 11 个 / Gitee 1 个)。 ⇒ 用户选 P5 原文写着的降级路径:仅工作树删除 +docs/archive/README.md标注, 不重写历史、11 个 tag 与全部 commit SHA 一律不动。 因此正文那条「先把 tag 风险补进 P5」是条件句、本次判定不适用,归档件未改。 详见 §3 T4-2 的完成记录。
📋 阶段 4 与阶段 3 尾项的交接 prompt 见
post-merge-phase4-handoff.md(2026-08-30 建)—— 那里只装「下一个会话拿什么开工」,不含方案(方案仍以本文件 §3 为唯一真相源)。 它同时记着两条本文件正文没有的信息:① T4-4/T4-3 与 2026-08-29 新建的docs/README.md/scripts/README.md的耦合;② 实测确认 P5 没写 tag 那一段, 故 T4-2 的第一步是补方案而不是执行。阶段 4 做完后随本文件一起归档。
2. 冷启动开工指引(新会话先读这段)
你如果是没有上下文的新会话:读 §1 台账找第一个 ⬜ → 读该任务所在阶段的前言 → 读该任务本身(每个都写了「会话 / 前置 / 动作 / 验收 / 回滚」,不需要回看创建它的对话)。
三条硬约束
- A. P0-1 必须新开一个干净会话做,且不许先读本文件(读了就污染,测出来是假的)。 理由与合仓 P0-2 完全相同。
- B. T2-1 在 P0-1 判定为「按需」之前不许动手。判定为「恒加载」则 T2-1 作废, 改走 §5「退路」。
- C. 每个任务做完先跑验收命令,再回写 §1 台账,再提交。 顺序反了会留下 「做没做完看不出来」的状态 —— 那正是
README.md点名的病。
并行会话纪律
本计划 90% 是文档 / 脚本改动,但 T1-3 / T2-1 碰的是控制文件(CLAUDE.md 家族), 命中 CLAUDE.md §8 的枢纽文件清单。动手前自查 git status / git worktree list; 探到并行痕迹就开独立 worktree(Agent(isolation:"worktree"))。 即使不碰枢纽文件,「每完成一个可编译小步就提交」仍是硬要求(路径 B 只认未提交状态,不认文件域)。
禁止事项
| 禁止 | 为什么 |
|---|---|
在本文件里定义任何新红线(含锁标记 —— 本行刻意不写那个字符,rg -l 出现即计数) | /arch-check S28 基线 = 4,本文件刻意不进那个集合。发现新不变量按 CLAUDE.md §4「红线归属规则」写进稳定归属,这里只留指针 |
删 rvh/CLAUDE.md 红线节的内容 | T2-1 是搬家不是删除。那 57 KB 内容质量是好的(见 §0.1 原因 3) |
| 把 T4-2 与任何其他改动同批提交 | 它要重写 git 历史,必须工作树干净、双远端已同步时单独做 |
改 docs/plans/archive/ 与 docs/cross-end/ 里的历史记述 | 它们是写作当时的事实记录。只改操作性文件 |
照本计划末尾去回填 CLAUDE.md §2 文件清单 | README.md 明令:那两处已于 2026-08-14 撤销,回填 = 把烂账种回去 |
3. 任务正文
阶段 0 前言
不变量:全程只读,不改任何文件。失败可原地停下,零代价。 离场条件:P0-1 给出判定 A/B/C,写进台账。
P0-1 实测嵌套 CLAUDE.md 深度 ≥2 是否按需加载
会话:必须新开一个(不能在写本计划的会话做,上下文已污染)· 前置:无
为什么必须验:本仓所有 CLAUDE.md 实例(admin/ landing/ src/ src-tauri/ rvh/) 都是深度 1,合仓 P0-2 也只验了深度 1。T2-1 的全部收益建立在 「rvh/lib/features/sync/CLAUDE.md 只在碰该目录(含子目录)下的文件时才注入」上。不通则 T2-1 作废。
🔴 探针设计有两条硬要求,初稿踩过其中一条(2026-08-29 立项当天自查发现并改): ① 答案不能在别的恒加载文件里出现。初稿的 Q2 问「RVH #6g 的四条子规则叫什么」, 而答案
W / P1 / P2 / P3根CLAUDE.md§4 #6d 里就写着 —— 只加载根文件的会话 第 1 步就能答对,测出来是假的通过。这正是合仓 P0-2 结果段留下的那条备注 (「Q1 探针不干净,数字泄漏在根 §2 索引行,下次换探针」)。 ② 口令不能写进任何被提交的文件,否则新会话读一眼计划就知道答案。 所以下面不写字面口令 —— 实施时现取一个全仓 0 命中的随机串。
动作:
- 取一个全仓 0 命中的随机口令(先验证:
grep -rl '<口令>' . | grep -v node_modules | grep -v '^./.git'无输出)。 - 建临时探针文件
rvh/lib/features/sync/CLAUDE.md,正文只放一句 「本目录的探针口令是<口令>」,并在开头注明它是探针、用完即删。 ⚠️ 不要提交它 —— 保持 untracked(顺带一个好处:reset --hard不会抹掉未跟踪文件)。 - 新开会话,把下面的交接 prompt 整段贴过去。
- 判定回写台账后,删除探针文件(T2-1 会重新正式建立它)。
三道题的设计(每道都已机械核验过唯一性,见 §6 附录 A ⑧):
| 题 | 答案只出现在 | 第 1 步期望 | 作用 |
|---|---|---|---|
| Q0 Tauri CLI 版本 | 根 CLAUDE.md | 答得出 | 控制题 —— 答不出说明整个注入机制异常,本次实测作废 |
| Q1 探针口令 | 探针文件(深度 4) | 答不出 | 主探针 |
| Q2 OCR 采集必经的闸门类名 | rvh/CLAUDE.md | 答不出 | 深度 1 对照 —— 用来区分「嵌套完全不加载」与「只加载最近的一层」 |
交接 prompt(整段复制给新会话,把 <口令> 换成第 1 步取的那个串):
text
这是一次只读实测,别改任何文件,别用 Agent/子会话,别读 docs/plans/ 下的任何文件。
按顺序做四步,每步如实回答。
【第 1 步|先别看任何文件】
不要读取、grep、cat、ls 任何文件。仅凭你此刻上下文里已有的内容回答:
Q0. 本仓 CLAUDE.md 的「环境信息」里,Tauri CLI 的版本号是多少?
Q1. rvh/lib/features/sync/ 目录下的控制文件里,写的「探针口令」是什么?
Q2. RVH 的 OCR 语境采集路径,规定必须经过哪一个闸门类(类名)?
答不出就明确说「上下文里没有,答不出」。不许猜、不许推理、不许"根据常见做法"作答
—— 这一步的价值全在于诚实报告你能不能看见。
同时报告:你此刻上下文里出现了哪几份 CLAUDE.md?
【第 2 步|触达 sync 目录下的文件】
读 rvh/lib/features/sync/data/repositories/sync_repository_impl.dart 的前 20 行。
只读这一个文件。不要读任何 CLAUDE.md 本身,也不要读 docs/plans/ 下的任何文件。
【第 3 步|再答一次】
重新回答 Q1、Q2,并报告:现在上下文里出现了哪几份 CLAUDE.md?
【第 4 步|结论】
判定属于哪一种,一句话说清:
A. 深度≥2 按需加载 —— 第 1 步 Q1 答不出,第 3 步答得出
B. 只加载深度 1 —— 第 3 步 Q2 答得出、但 Q1 仍答不出
C. 恒加载 / 异常 —— 第 1 步 Q1 就答得出,或 Q0 答不出,或其他情况
然后做三件事:
(a) 把结论回写 docs/plans/post-merge-repo-optimization-plan.md 的 §1 台账 P0-1 那行
(状态 ✅ + 日期 + 判定字母 + 一句话依据),并同步顶部状态行的 0/13 计数;
(b) 删掉临时探针文件 rvh/lib/features/sync/CLAUDE.md;
(c) 提交:
git add docs/plans/post-merge-repo-optimization-plan.md
git commit docs/plans/post-merge-repo-optimization-plan.md \
-m "docs(plans): P0-1 实测 —— 嵌套 CLAUDE.md 判定 <字母>"
背景(读完就够,不必翻别的):本仓 rvh/CLAUDE.md 有 57KB 的 sync 协议红线,占该文件 69%,
但它在你碰 rvh/ 下任何文件时都会注入 —— 改个 UI widget 也要付这笔钱。计划把它下沉一层到
rvh/lib/features/sync/,收益全建立在「深度≥2 仍按需加载」上。这一步就是验证这半句。
判定 B 或 C 则该方案作废,走计划 §5 退路。验收:台账 P0-1 有判定字母 + 顶部状态行同步 + 探针文件已删 (ls rvh/lib/features/sync/CLAUDE.md 报不存在)。
回滚:删探针文件即可,本任务不改任何既有内容。
阶段 1 前言
不变量:三个任务互不依赖,可任意顺序、可分会话。每个都能独立提交。 离场条件:三项验收全绿。
✅ 开工前实测(2026-08-29,本机)—— 两个正文没写的坑
坑 1:
psql没装,而它恰好挡住 T1-1 最有价值的那一步。 陷阱只在那行被执行时才触发(set -u下当场终止),段落 SKIP 掉就验不到。 而陷阱最多的privacy-verify(10) /ops-verify(5) 的 DB 段正是靠 psql。 ⇒ 不装 psql 的话,T1-1 只能做到「静态扫描归零」,做不到 「跑起来看有没有从未执行过的段落冒出新 FAIL」—— 而后者才是这条任务的真正收获。 动手前先brew install libpq并把它 link 进 PATH(或brew install postgresql@16)。 装不了就在台账里写明「T1-1 只完成静态部分,动态验证欠 psql」,别默认它做完了。其余凭据本机齐备(实测):
admin/.env.local✅(privacy / ops 从这里取 URL 与 key)· Keychainlampio-supabase-db✅ · 本地存量库~/Library/Application Support/com.lampio.dev/lampio.db✅ 55 MB(migration-verify那条「最有价值的证据」拿得到)·gh✅(release-verify 的 Release 段)。坑 2:T1-2 的验收跨会话。
pnpm install完成后 MCP 不会当场连上 —— 要重启 MCP 才生效(本仓rb-debug-mcp同理,见根CLAUDE.md§2)。 ⇒ 本会话只能验到「dist/index.js生成了」,「rvh-debug真的连上」要到下一个会话开头才看得到。 台账照实写,别把「装完了」记成「连上了」。
T1-1 修 4 个 verify 脚本的静默截断
会话:RB · 前置:无 · 来源:backlog.md 已记为 🔴,本任务是执行
缺陷:set -u 下裸 $var 后紧跟非 ASCII 字节(全角 )、破折号等)会被 bash 并进变量名 → 判为 unbound → 当场终止。与 locale 无关,bash 3.2(macOS 系统 bash)逐字复现。
⚠️ 危害不是报错,是静默截断:脚本半路死掉,前面全绿、后面从来没跑过, 汇总行压根不打印。已经吃过两次 —— cross-end-check.sh 崩在 §B(§E/§D/§F 从未执行, 当时以为"一直是绿的");learning-loop-verify.sh 崩在 M1(M/N 两段从未跑过,修完立刻暴露 2 个真 FAIL)。
当前计数(2026-08-29 本会话实测,与 backlog 记录逐字吻合):
| 脚本 | 处数 |
|---|---|
scripts/privacy-verify.sh | 10 |
scripts/release-verify.sh | 10 |
scripts/ops-verify.sh | 5 |
scripts/migration-verify.sh | 4 |
动作:
bash
# 扫描(对每个脚本跑一次)
perl -ne 'while(/\$([A-Za-z_]\w*)([^\x00-\x7F])/g){print "$.: \$$1\n"}' scripts/<脚本>逐处 $var → ${var}。⚠️ 别只修报错那一行 —— 潜伏的那些在「平时走不到的 else 分支」里, 只有按模式全扫才找得全。修完照 cross-end-check.sh / learning-loop-verify.sh 的先例, 在每个脚本头部写死陷阱说明 + 自检命令。
验收:
bash
# ① 四个脚本扫描均为 0
for f in privacy-verify release-verify ops-verify migration-verify; do
echo -n "$f: "; perl -ne 'while(/\$([A-Za-z_]\w*)([^\x00-\x7F])/g){print "x\n"}' scripts/$f.sh | wc -l
done
# ② 每个脚本整跑一次,确认汇总行打印出来了🔑 真正的收获在第二条:看有没有此前从未执行过的段落冒出新的 FAIL。 改语法本身是次要的 —— 新 FAIL 要按 docs/verification/README.md 的规矩 拆进 CHANGELOG(修好的)/ backlog(待修的)/ 清单的「已知未修」,不要留报告文件。
回滚:git revert 单条 commit。这四个脚本目前不在任何 CI 里,改坏不阻塞任何流程。
T1-2 修 rvh-debug MCP 连不上
会话:RB(Node 构建,非 Flutter) · 前置:无
现象:本会话启动时 rvh-debug (CONNECTION_CLOSED),其工具 mcp__rvh-debug__* 全部不可用。
根因(2026-08-29 实测,不是代码问题):
rvh/rvh-debug-mcp/dist/ ❌ 不存在
rvh/rvh-debug-mcp/node_modules/ ❌ 不存在而 .mcp.json 指向 rvh/rvh-debug-mcp/dist/index.js。对照 rb-debug-mcp/ 两者都在。 ⇒ provisioning 缺口:合仓把源码带了过来,但 dist/ 是 gitignored 产物,没人在新仓里构建过。
动作:
bash
pnpm --dir rvh/rvh-debug-mcp install # package.json 有 postinstall: tsc,装完即构建
ls rvh/rvh-debug-mcp/dist/index.js # 确认产物在然后把这一步补进 provisioning 文档 —— rvh/QUICKSTART.md 开头已有「新机器先做这三步」 (local_packages/opencv_dart · .env · assets/icons/,2026-08-29 commit 6f26239a 加的), 本步骤是第四条,落点相同。⚠️ 别新建一份 provisioning 说明,那是第二本账。
验收:ls rvh/rvh-debug-mcp/dist/index.js 存在 · 重启 MCP 后 rvh-debug 不再报 CONNECTION_CLOSED · rvh/QUICKSTART.md 里能 grep 到这一步。
回滚:无需回滚(只产生 gitignored 产物 + 一段文档)。
T1-3 修根 CLAUDE.md 两处「唯一 as-built 日志」假话
会话:RB · 前置:无
事实:合仓后仓里有三份 CHANGELOG —— 根 196 KB · rvh/CHANGELOG.md 248 KB(还在独立更新, 比根的还大)· admin/CHANGELOG.md 3 KB。而根 CLAUDE.md 两处仍写着「唯一」:
CLAUDE.md:87 ├── CHANGELOG.md # 唯一的 as-built 日志
CLAUDE.md:778 | 做过什么、怎么做的(as-built) | CHANGELOG.md —— **唯一**执行日志 |这与 docs-governance-plan.md P0 抓的那批「控制文件在说假话」同型, 区别是这一处是合仓新造出来的。
动作(选低成本那条,不做 CHANGELOG 合并):改口径为「每端各一份」, 两处都写明去处(桌面端 / admin → 根;移动端 → rvh/CHANGELOG.md)。 ⚠️ 真合并 4400+ 行历史代价大、收益低,明确不做 —— 见 §4「不做什么」。
验收:grep -n "唯一.*as-built\|唯一.*执行日志" CLAUDE.md 无输出 · pnpm run check:claude-paths 绿 · node scripts/check-doc-links.mjs 绿。
回滚:git revert。
阶段 2 前言
不变量:这是本计划收益最大的一段。T2-1 搬家不删内容;T2-2 删的是通用教程、不是项目知识。 离场条件:RVH 单端会话开销回到 30k 以下(按 §6 附录 A 复现命令量)。
T2-1 rvh/CLAUDE.md 的 57 KB 红线节下沉
会话:RB 会话即可 —— 依据 CLAUDE.md §9「实践边界」:改 rvh/CLAUDE.md 这类 不需要跑 Flutter 就能验收的改动在 RB 会话做是安全的(验收走 check:claude-paths / check-doc-links,本来就是根侧脚本)。不碰任何 rvh/lib/** 的 .dart 文件。
前置:✅ 已满足 —— P0-1 于 2026-08-29 实测判定 A(commit 6def2e18)。
收益口径(P0-1 校正后,别按"层级替换"想):注入是祖先链全量 ⇒ 本任务是按目录条件命中,不是按层级替换。实测占比:约 93% 的 RVH 会话不碰 lib/features/sync/,它们省下 57 KB(44.4k → 28.6k,−36%);剩下约 7% 两份都注入、 总量持平(+1%,多的是留在原位的索引)。期望值 ≈ −33%。数据与复现见 §0.2 与 §6 附录 A ⑨。
现状:
rvh/CLAUDE.md 83,107 B
└ 「跨端 Sync 协议红线」一节 57,487 B / 839 行 / 占 69%
├ 编号对照表
├ 14 条红线(#5b #5d #5e #5f #5g #5h #6b #6c #6d #6e #6f #6g #6h)
├ 守卫 bash 代码块 12,433 B(占该节 21.6%)
└ 跨端契约镜像 backlog动作:
- 建
rvh/lib/features/sync/CLAUDE.md,把整节原样搬入(内容一个字不改 —— 它的「契约 → 指针 / 本端落地 / 本端独有」三段式形状是 T3-8 + T4-4 收敛的成果,别动)。 rvh/CLAUDE.md原位留索引:14 条一行一条(编号 + 一句话 + 「正文在lib/features/sync/CLAUDE.md」), 照根CLAUDE.md§4 全量红线索引的写法。编号对照表留在rvh/CLAUDE.md(它是消歧工具,任何 RVH 会话都可能需要,不该跟着下沉)。 ⚠️ 索引要压到最小(目标 ≤2 KB) —— 祖先链全量注入意味着,对那 7% 会下沉进去的会话来说 索引是净增成本、被读两遍。索引行只给「编号 + 一句话标题 + 去哪找」, 不复述理由、不抄判据;想多写一句时记住它会被收两次费。- 在
rvh/CLAUDE.md顶部加一行告警,抄根文件那条:走 Bash 干活时注入不触发, 改 sync 代码前请显式读一次rvh/lib/features/sync/CLAUDE.md。 - 更新根
CLAUDE.md§4 四条双端契约红线里指向rvh/CLAUDE.md的双向指针 (#5i → RVH #5h · #6d → RVH #6g · #9 → 镜像 backlog · #10 → RVH #5e), 改成指向新位置。⚠️ 这四条的正文不动,只改指针的落点。
验收:
bash
wc -c rvh/CLAUDE.md rvh/lib/features/sync/CLAUDE.md # 前者应 ≤28 KB(含 ≤2 KB 索引),两者之和 ≈ 原 83 KB + 索引
pnpm run check:claude-paths # 必须绿(rvh/ 在 ROOTS 里)
node scripts/check-doc-links.mjs # 必须绿
bash scripts/cross-end-check.sh # 18 ✅ / 0 ❌ 不变⚠️ check-claude-md-paths.mjs 的文件清单要加第 7 份 —— 该脚本的 ROOTS 与 package.json 的 check:claude-paths 命令行清单是两处(合仓 T3-7 已在脚本里 留了注释说明"新增子项目要动两处")。不加 = 新文件里的路径不受校验。
回滚:git revert 单条 commit(纯文档移动,无代码依赖)。
T2-2 删两份通用 Claude Code 教程
会话:RB · 前置:无
对象:
| 文件 | 体量 | 判据 |
|---|---|---|
rvh/docs/guides/claude-code-tips.md | 41.5 KB | 通用 Claude Code 使用教程,开头钉着「适用版本:V2.1.29+」 |
rvh/docs/guides/claude-skill-guide.md | 26.0 KB | 通用 Skill 编写教程,同样钉着版本号 |
为什么删而不是归档:① 它们不是项目知识,是第三方工具的教程, 而该工具每周都在变 —— 钉版本号的教程只会越来越错;② 模型自带这部分知识, 且本环境有 claude-code-guide agent 专门答这类问题;③ 归档只是把腐烂搬个地方。
引用点(删前必须一起改,共 7 处 + 1 处死过滤):
rvh/docs/README.md:85,86,153,154,305,306,427 ← 6 处链接 + 1 处目录树
rvh/docs/guides/README.md:11,12 ← 表格两行
rvh/.claude/skills/doc-consistency-check/SKILL.md:60 ← grep -v "claude-skill-guide" 过滤,删后成死过滤⚠️ rvh/CHANGELOG.md:956 也提到它们,但那是历史记述,不要改。
验收:
bash
grep -rn "claude-code-tips\|claude-skill-guide" --include='*.md' . | grep -v node_modules | grep -v CHANGELOG
# 期望:只剩 docs/plans/archive/ 与 rvh/CHANGELOG.md 里的历史记述
node scripts/check-doc-links.mjs # 必须绿回滚:git revert(文件在历史里,随时能取回)。
阶段 3 前言
不变量:补的是闸门与索引,不改任何业务行为。 离场条件:新接的 CI 闸门至少绿跑一次(一道恒红的闸门等于没有闸门 —— 本仓 2026-08-18 连红 6 天的教训)。
T3-1 verify 脚本的静态段接进 CI
会话:RB · 前置:T1-1 必须先做完(否则接进 CI 的是一个会静默截断的脚本)
现状(2026-08-29 实测接线矩阵):
| 脚本 | CI | package.json | skill | 线上凭据依赖 | 纯静态检查处数 |
|---|---|---|---|---|---|
sync-verify.sh | 0 | 0 | 0 | 6 | 11 |
ops-verify.sh | 0 | 0 | 0 | 16 | 5 |
privacy-verify.sh | 0 | 0 | 0 | 25 | 16 |
release-verify.sh | 0 | 0 | 0 | 7 | 27 |
migration-verify.sh | 0 | 0 | 0 | 0(只依赖本地库) | 9 |
learning-loop-verify.sh | 0 | 0 | 0 | 6 | 27 |
db-audit.sh | 0 | 0 | 0 | 4 | 0 |
这与合仓前 cross-end-check.sh 的病完全同型:一道只在特定人的特定机器上、 且要靠人记得跑的闸门,按本仓自己的标准不合格。合仓治好了那一个,还剩七个。
动作(照 cross-end-check.sh 进 CI 的先例,不要贪多):
- 不要求整体上 CI —— 多数确实需要线上凭据。做法是把不依赖凭据的段落抽出来, 优先级按上表最后一列:
release-verify(27)·learning-loop-verify(27)·migration-verify(9,且零凭据,最容易)。 - 新建
.github/workflows/ci-verify.yml(或并进现有ci.yml,二选一,别两处都放)。 - 必须带「防全 SKIP 假绿」机制 —— 抄
cross-end-check.sh的--max-skip=N。 没有这个,一个因缺凭据而全部 SKIP 的脚本会永远显示绿色。
验收:新 workflow 至少绿跑一次(贴 run id 进台账)· 本机跑同样命令结果一致 · 故意注入一个缺陷能让它变红(反向注入实测,不做这一步不算完)。
回滚:删 workflow 文件。
T3-2 补 docs/README.md + scripts/README.md
会话:RB · 前置:无
缺口:docs/ 下 13 份根层文档没有索引,而 plans/ archive/ cross-end/verification/ tools/ supabase/ 每个目录都有 README。scripts/ 25 个脚本同样没有。
动作:
docs/README.md:13 份根层文档一行一条(做什么用 / 谁在引用它)。 ⚠️ 同时写明「两套 UI 规范是刻意的,不是漂移」 ——docs/ui-standards.md(60 KB, Tailwind/桌面端)与rvh/docs/ui-guidelines/(193 KB,Material 3/移动端)各管一端、 不合并。不写清楚,下一个人会当成漂移去"修"。scripts/README.md:25 个脚本一行一条 + 接线状态(CI / package.json / skill / 只有文档引用)。 接线矩阵直接用 §6 附录 A 的命令现生成,别手抄。
验收:node scripts/check-doc-links.mjs 绿 · 两份 README 里每个提到的路径都存在。
回滚:删文件。
T3-3 根 ci.yml 加 paths 过滤
会话:RB · 前置:无 · 来源:合仓评估 §7 已登记(当时判「留着」)
为什么现在改判:合仓前只有 admin/ landing/ 会误触发;合仓后 rvh/ 也进来了, 触发频率翻倍。改 rvh/ 的纯文档 commit 会跑一整套桌面端 CI(Rust 编译 + 前端构建)。
⚠️ 风险提示:改的是桌面端主闸门。paths 写窄了会让真该跑的不跑 —— 比 CI 白跑严重得多。建议用 paths-ignore 列出四个子项目目录,不要用 paths 正向白名单 (正向名单漏一个新目录就静默失守)。
验收:改 rvh/ 下一个文件推一次 → 桌面端 CI 不触发、ci-rvh.yml 触发 · 改 src-tauri/ 下一个文件推一次 → 桌面端 CI 触发。两次都要实测。
回滚:git revert。
阶段 4 前言
不变量:四项互不依赖,可任意排期。T4-2 有特殊纪律。 离场条件:无(本阶段是清理,不阻塞功能迭代)。
T4-1 给 docs-governance-plan.md 一个了结
会话:RB · 前置:无
现状:该计划 2026-08-14 立项,至今 P0.1 / P0.4 / P0.7 / P1.1 / P1.4 / P1.5 / P3.1 / P3.3 / P3.4 无完成标记,其中 P0.2 与 P3.1 仍标 🔴。
它正在变成它自己批判的那种东西 —— 开篇写的正是「状态行与实况冲突,比没有更坏」。
动作:逐项核实真实状态(有些可能已被后续工作顺带做掉,例如 P0.5 已标 ⏭、 P0.6 的前提已随合仓 T4-7 消失)→ 做完的标 ✅ → 仍要做的转 backlog.md → 补顶部状态行 → 归档进 archive/。
验收:docs/plans/archive/docs-governance-plan.md 要么带完整状态行留在活跃区、 要么已在 archive/ 且 node scripts/check-doc-links.mjs 仍绿(归档会造悬挂引用)。
✅ 已完成(2026-08-30):逐项现场重验 18 项 → 归档进 archive/,顶部加「逐项核实结果」表 (判定 + 依据,每条都指得出证据)。
发现的两件事值得留在这里:
- 两个挂着 🔴 的(P0.2 红线指针指反、P3.1 四个 skill 缺 frontmatter)早在两周前就修好了, 只是没人回来标记 —— 这正是该方案开篇批判的「状态行只在创建时写一次,比没有更坏」原样复发在它自己身上。 P0.1 / P0.4 则是以撤销 / 换写法代替修正(枚举清单整体撤销、skill 触发条件不再抄第二份), 照原文去「做完它」反而会把烂账种回去。
- 7 条尾巴转
backlog.md§文档治理尾项(eslint 入闸 ·admin/AGENTS.md· 4 份文档的日期行 ·temp/11 份 handoff · Edge Function UA ·tools/两条)。 其中 UA 那条原文写「×3」,重数是 5 处 / 4 个函数。
⚠️ 归档当场造出 1 处悬挂引用(backlog.md 新写的那句指向它), 本文件与 post-merge-phase4-handoff.md 里的 4 处 markdown 链接也一并补了 archive/ 前缀。check-doc-links 在 git mv 之后、补前缀之前确实红了一次 —— 这道门是有效的。
T4-2 删 22.3 MB 归档 SQL + 重写历史
会话:RB · 前置:🔴 工作树干净 + 双远端已同步 + 无其他会话在动这个仓
对象:docs/archive/rvh-schema-export/04-vocabulary-data.sql(22,289,665 B)—— 2026-03 的 4,953 条预装词 INSERT 导出,已被 lampio_dict.db 完全取代。
已立项:docs-governance-plan.md P5 写了完整步骤(含 filter-repo 命令), 本任务只是执行它,别在这里重写第二份方案。
⚠️ 必须单独做、不与任何改动同批。⚠️ 重写历史会让所有 tag 的 SHA 变化 —— CLAUDE.md §4 红线 #11 的 shipped_migrations.txt 真相源是发布 tag, 动手前必须确认这一点已被 P5 的方案覆盖(该方案写了就照做,没写就先补上再动)。
验收:按 P5 自带的验收清单。
回滚:动手前打 tag + 本地镜像 clone(照合仓 T3-1 的做法)。
✅ 已完成(2026-08-30)—— 走 P5 自带的降级出口,不重写历史
P5 的 ROI 算式(「.git 共 72 MB,删 7.6 MB ≈ 回收 10%」)在动手前重算已不成立, 用户据此选了 P5 原文写着的降级路径:仅从工作树删除 + docs/archive/README.md 标注。 动作 = git rm docs/archive/rvh-schema-export/04-vocabulary-data.sql + 该 README 补一段说明。
重算出来的三个数(2026-08-30 实测,取代 P5 里那组):
| 量 | P5 写的 | 实测 |
|---|---|---|
.git 总量 | 72 MB | 328 MB(pack 151.13 MiB × 3 + 松散 175.67 MiB / 4889 对象,未 gc) |
| 目标文件 | raw 21.3 MB / pack 7.6 MB | raw 22,289,665 B,全历史仅 1 个 distinct blob(3e42910f),pack 后 7,941,186 B |
| 预装库(真正的大头) | 「单 blob pack 后 16 MB」 | 按 4 个历史路径名合计 35 blob / 94.21 MB on disk(合仓把 RVH 的历史也带了进来) |
⇒ 回收 7.57 MiB / 328 MB ≈ 2.3%(对 gc 后的 pack 也只有 ~5%),不是 10%。 而预装库那 94 MB 是红线 #10 要求保留的必需资产,动不了 —— 即「重写历史」这把刀 砍不到仓库真正的重量所在。
两处 P5 与本任务正文都没算到的代价(本次核实时发现,是选降级的加权项):
- 仓里不止
main一条分支:feat/admin-ops-console=01a96d47,双远端都有, 且 GitHub 上有refs/pull/1/head(一个 open PR)。git filter-repo重写的是所有 ref, 这条分支的 SHA 一样会变,强推后那个 PR 会变成 head 与分支对不上的僵尸状态。 - 两个远端的 tag 集合本来就不对称:GitHub 有全部 11 个 tag, Gitee 只有
pre-rvh-merge一个(2026-08-30git ls-remote实测)。 所以「双远端 tag 强制同步」不是一条对称操作。
🔑 本任务正文要求的「先确认 P5 覆盖了 tag SHA 风险,没写就补」—— 判定为不适用。 2026-08-30 实测确认 P5 确实没写 tag 那一段(只有 filter-repo 命令 + remote 重加)。 但那条要求是条件句:它防的是「重写历史让红线 #11 的 shipped_migrations.txt 真相源 (发布 tag)换 SHA」。降级路径下 11 个 tag 一个都不动,风险不存在, 故没有补 P5(也因此 §2「不改归档件历史记述」那条纪律本次无例外)。 将来若有人重新捡起重写历史的想法,这一段仍要先补。
前后对照:
| 量 | 前 | 后 |
|---|---|---|
| HEAD | e4d08322 | 本次提交(无 SHA 重写,历史线性追加) |
.git | 328 MB | 328 MB(不变) —— blob 留在历史里,这是降级的代价 |
docs/archive/ 工作树 | 21.6 MB | 312 KB |
| 全部 commit SHA / 11 个 tag / 双远端 / PR #1 | — | 全部不受触碰 |
blob 仍可取回:git show e4d08322:docs/archive/rvh-schema-export/04-vocabulary-data.sql。
顺带处理:rvh/pubspec.lock 有一处 opencv_dart 从 hosted 改回 path 的既有改动 —— 按 rvh/pubspec.yaml 第 202-203 行明令(「仓里提交的是 hosted 那版,本机那次改写属预期噪音, 别提交回去」)还原,未提交。它由本机专属的 pubspec_overrides.yaml 生成, 下次 flutter pub get 还会再出现。
⚠️ 另一处过期前提:交接单记的「4 个未推送 commit,HEAD=55dd9402」到 2026-08-30 已不成立 —— git ls-remote 实测双远端 refs/heads/main 都已是 e4d08322,无需 push。
T4-3 两份 backlog 分片 + rvh/docs/plans/ 补归档节律
会话:RB · 前置:无
现状:
docs/plans/backlog.md 253 KB / 72 个顶层条目(含 5+ 条已标 ✅ 未移走)
docs/plans/backlog-archive.md 45 KB
rvh/docs/plans/backlog.md 114 KB
rvh/docs/plans/backlog-archive.md 10 KB
rvh/docs/plans/ 29 份 plan,❌ 无 archive/ 目录任何读 backlog 的会话现在要吃 72k tokens。且根侧 backlog 里已有 5+ 条标着 「RVH 新会话」的跨端条目 —— 两本账实际上已经在互相渗透。
动作:① 分片(docs-governance-plan.md P1.5 已提方案,未执行); ② 把已标 ✅ 的条目移进 backlog-archive.md(保留裁决推理,不删 —— README.md 的规矩); ③ 建 rvh/docs/plans/archive/ 并跑一次批量归档; ④ 跨端条目定一个单一落点(建议根侧 backlog,rvh/ 那份只留指针)。
验收:node scripts/check-doc-links.mjs 绿 · 两份 backlog 里 ## ✅ 条目数为 0。
✅ 已完成(2026-08-30)。⚠️ 上面「现状」那五行是 2026-08-29 快照,执行时四行里有三行已漂: 根 backlog 是 255 KB / 72 条 / 只有 4 条 ## ✅(正文写「5+」); rvh/docs/plans/backlog.md 是 114 KB / 35 条,其中 18 条是 ✅ —— 清理面在 RVH 侧比正文描述的大得多, 正文只盯了根侧。只有「29 份 plan、无 archive/」是准的。
结果:
| 文件 | 前 | 后 |
|---|---|---|
docs/plans/backlog.md | 255,267 B / 72 条 | 124,804 B / 55 条(−51%) |
docs/plans/backlog-archive.md | 44,939 B | 136,935 B |
rvh/docs/plans/backlog.md | 114,644 B / 35 条 | 56,638 B / 30 条(−51%) |
rvh/docs/plans/backlog-archive.md | 9,977 B | 95,384 B |
rvh/docs/plans/ 活跃 plan | 29 份,无 archive/ | 25 份 + archive/(4 份 + README) |
四个动作的落地形状:
- ① 分片:搬走的不只是
## ✅。根侧还搬了三块已结案但体量极大的留痕 —— EPUB 9 条缺陷(47.7 KB,8/9 已闭环)、外部 backlog 第二/三轮逐条裁定(19.9 + 10.8 KB)。 另把「短语自动高亮 B 方案」(24 KB)外迁成phrase-highlight-followups-plan.md—— 它有阶段编号 + gate 判据 + 跨端接力顺序,形状早已是 plan 不是 backlog 条目。 一个字都没删,全部逐字换位置。这两款判据已写回README.md的归档节律。 - ②
## ✅清零:根侧 4 条 ✅ + 1 条 ❌ 否决、RVH 侧 18 条 ✅,各进本端backlog-archive.md。 - ③
rvh/docs/plans/archive/:已建 + 写了归档节律 README。只归档了 4 份 —— 判据必须是 RB 会话能机械核实的(app_database.dart的 schema 版本注释 v53/v57、rvh/rvh-debug-mcp/dist与 rvh 侧 tools/ 目录的存在性)。剩 23 份要读 Dart 现状才能判, 按CLAUDE.md§9 是 RVH 会话的活,已登记成rvh/docs/plans/backlog.md的一条待办。 ⚠️ 那 4 份里rvh-debug-mcp-plan.md的状态行明写「未启动」而事实早已完成 —— 别照状态行判。 - ④ 跨端落点 = 「谁执行谁持有」(用户 2026-08-30 定,改判了本文件原建议的「根侧统一持有」): 正文只存一份、落在将来真正动手那一端,另一端留指针;两端都要动的(契约类)落根侧。 依据是核实时发现的三处两本账各记一半,而证据更全的那份每次都在执行端 —— 例如
push 75→4,根侧写「71 条没推上去」,RVH 侧早已算出「缺口是 63,扣掉 8 个被错标 'rvh' 的 RB 行」 且把三个诊断分支收敛到了clean=75。按原建议搬会把更差的那份留下来。 落地:11 条迁往rvh/docs/plans/backlog.md、1 条真重复合并(保留 RVH 那份)、 规则本体写进两份 backlog 的头部(不是只写在这里 —— plan 会归档,规则不会)。
⚠️ 归档 4 份 rvh plan 当场打破了 pnpm run check:claude-paths: rvh/lib/features/sync/CLAUDE.md 引着 word-cloze-contexts-sync-rvh-plan.md。 已补 archive/ 前缀(连同 rvh/docs/database/schema.md 那处)。 docs/cross-end/17、rvh/CHANGELOG.md、docs/plans/archive/rvh-merge-plan.md 里的同名引用 刻意没动 —— 历史记述。
T4-4 docs/mcp-primer.md 归档
会话:RB · 前置:无
判据:19.7 KB 的 MCP 通用入门教程,全仓只有 1 处引用且在归档件里 (docs/plans/archive/rb-debug-mcp-plan.md:9)。
⚠️ 执行时重数为 3 处(2026-08-30):上面这个 1 是 2026-08-29 的快照,此后 T3-2 新建的
../README.md(根层文档索引)与本文件自身各多引一处。索引那处是真耦合, 归档时必须回改(份数 13→12 + 删行 +archive/那行补一句),否则索引说假话。
动作:git mv docs/mcp-primer.md docs/archive/ + 在 docs/archive/README.md 登记。 归档不删 —— 与 T2-2 的区别是:这份是自己写的、讲本项目 MCP 设计的材料, 有史料价值;T2-2 那两份是第三方工具的通用教程,只会腐烂。
验收:node scripts/check-doc-links.mjs 绿 · docs/archive/README.md 有新条目。
✅ 已完成(2026-08-30):git mv 进 docs/archive/,docs/archive/README.md §其它 加一行; docs/README.md 改 12 份 + 删 Runbook 组那一行 + archive/ 行补提它。两道检查绿。 副产:docs/mcp-primer.md 移走后不再被 check-doc-links 的活跃区扫描(它只扫 docs/*.md 顶层), 但它内部引的 docs/plans/archive/rb-debug-mcp-plan.md 本来就在,无悬挂。
4. 不做什么(明确排除,防止后来会话扩大范围)
| 不做 | 理由 |
|---|---|
| 合并三份 CHANGELOG | 4400+ 行历史,代价大收益低。T1-3 改口径即可 |
| 合并两套 UI 规范 | Material 3 vs Tailwind 是真的不同,不是漂移。T3-2 里写清楚就够 |
| 把根 §4 四条契约红线正文下沉 | T4-4(合仓)的裁定成立:下沉等于藏进"只有改 Rust 才可见"的地方。且 T2-1 做完已能拿到约 80% 的收益,风险低得多。等 T2-1 落地后再评估是否还需要 |
| 统一 RB / RVH 的红线编号 | 合仓 T4-4 已裁定不统一(350 处引用 + 无机械守卫),靠双向指针消歧。别重开 |
| 合并两个 debug MCP | rb_supabase_query 与 rvh_supabase_query 确实查同一个 Supabase 项目、是重复实现,但抽公共层的收益 < 破坏两个都能跑的调试链的风险。T1-2 只修连接,不动结构 |
| 改 RB 本体散在根目录的结构 | 收益不确定、风险高。§0.4 已登记为观察 |
rvh/assets/sql/01_create_tables.sql 第三份 schema 真相源 | 合仓评估 §7 已登记为"已知未处理"。cross-end-check.sh §E 现以 Supabase DDL 为仲裁者比两端列集合,机械层已经守住,优先级低 |
5. 退路(⏭ 已不需要 —— P0-1 判定 A,2026-08-29)
本节保留为历史记述:P0-1 实测判定 A,T2-1 前置成立,下面三条退路都不必走。 保留是因为 B2 从"替代方案"变成了一个可选的补充(见下),别把它连同本节一起忘掉。
原文如下(判定为 B 或 C 时适用)—— T2-1 作废,此时 RVH 单端会话的开销降不下来,可选:
- B1 折中:把红线节搬到
rvh/docs/sync-contract.md(普通文档,完全不注入),rvh/CLAUDE.md只留索引 + 一行「改 sync 代码前必读那份」。 收益相同,代价是失去自动注入,完全依赖那行提醒被遵守 —— 比 T2-1 弱,但比现状好。 - B2 保守:只把 12,433 B 的守卫 bash 代码块移出去(它们是判据规格, 合仓评估 §7 已确认「没有任何东西在执行它们」),正文留原地。收益约 -3.5k tokens。
🔵 判定 A 之后,B2 变成了 T2-1 的可选补充:把守卫块从下沉后的
lib/features/sync/CLAUDE.md里再抽进一份普通文档,能让那 7% 的 sync 会话 也降约 3.5k(45.0k → 41.5k)。但本计划不做 —— 那些守卫至今没有任何执行者 (§7 首条),再往外挪一层只会让它们更不可能被接进 CI。 正确顺序是先把它们接进ci-rvh.yml,再谈搬家。 - B3 不动:接受 43.7k,把本计划其余部分照做。
无论走哪条,结论要写回本文件顶部状态行,别让后来会话按作废的方案开工。
6. 附录 A · 数字复现命令
本文所有数字都是 2026-08-29 的快照。别照抄当事实 —— 合仓评估自己就吃过亏(
docs/cross-end/40的行数一天就从 29/45 漂到 54/73)。
bash
cd /Users/larry/reading-browser
# ① CLAUDE.md 家族体量(token ≈ 字节 / 3.5,CJK 启发式,±20%)
for f in CLAUDE.md src/CLAUDE.md src-tauri/CLAUDE.md rvh/CLAUDE.md admin/CLAUDE.md landing/CLAUDE.md; do
printf "%-28s %8s B ≈%5.1fk tok\n" "$f" "$(wc -c < $f)" "$(echo "scale=2; $(wc -c < $f)/3500" | bc)"
done
# ② 根 CLAUDE.md 按节体量
awk '/^## /{if(n){printf " %-42s %6d B %4d 行\n",n,b,l} n=$0;b=0;l=0;next}{b+=length($0)+1;l++}
END{if(n)printf " %-42s %6d B %4d 行\n",n,b,l}' CLAUDE.md
# ③ rvh/CLAUDE.md 红线节占比
awk '/^## 🔄 跨端 Sync 协议红线/,/^## 开发流程/' rvh/CLAUDE.md | wc -lc
# ④ skill description 恒注入成本(只有根 12 个是恒注入,scoped 的按需)
ls .claude/skills/*/SKILL.md | wc -l
# ⑤ 脚本接线矩阵(T3-2 的 scripts/README.md 直接用它生成)
for f in $(ls scripts/ | grep -v '^lib$'); do
printf "%-30s CI=%s pkg=%s skill=%s verif=%s\n" "$f" \
"$(grep -rl -- "$f" .github/workflows/ 2>/dev/null | wc -l | tr -d ' ')" \
"$(grep -c -- "$f" package.json)" \
"$(grep -rl -- "$f" .claude/skills/ rvh/.claude/skills/ admin/.claude/skills/ 2>/dev/null | wc -l | tr -d ' ')" \
"$(grep -rl -- "$f" docs/verification/ 2>/dev/null | wc -l | tr -d ' ')"
done
# ⑥ 标点陷阱扫描
for f in privacy-verify release-verify ops-verify migration-verify; do
echo -n "$f: "; perl -ne 'while(/\$([A-Za-z_]\w*)([^\x00-\x7F])/g){print "x\n"}' scripts/$f.sh | wc -l
done
# ⑦ 记忆库是否仍空置
ls -A ~/.claude-cli/projects/-Users-larry-reading-browser/memory/ | wc -l
# ⑧ P0-1 探针的唯一性核验(三道题的答案各自只能出现在一个文件里)
CLAUDE_MDS='CLAUDE.md src/CLAUDE.md src-tauri/CLAUDE.md rvh/CLAUDE.md admin/CLAUDE.md landing/CLAUDE.md'
grep -rl 'Tauri CLI' $CLAUDE_MDS # 期望只有 CLAUDE.md (Q0 控制题)
grep -rl 'OcrClozeGate' $CLAUDE_MDS # 期望只有 rvh/CLAUDE.md (Q2 深度1对照)
grep -rl '<口令>' . | grep -v node_modules | grep -v '^./.git' # 期望:建探针前 0 命中(Q1)
# ⑨ T2-1 收益的关键变量:多少比例的 RVH 会话会碰 lib/features/sync/
# (祖先链全量注入 ⇒ 收益只在「不碰 sync 目录」的会话上兑现)
echo "近3月 动 rvh/ : $(git log --since=2026-06-01 --oneline -- rvh/ | wc -l)"
echo "近3月 动 sync/: $(git log --since=2026-06-01 --oneline -- rvh/lib/features/sync/ | wc -l)"
echo "全历史 动 rvh/ : $(git log --oneline -- rvh/ | wc -l)"
echo "全历史 动 sync/: $(git log --oneline -- rvh/lib/features/sync/ | wc -l)"
# ⑩ rvh scoped skill 的 description 成本(与 CLAUDE.md 注入共用触发条件)
for d in rvh/.claude/skills/*/SKILL.md; do
awk '/^---$/{n++;next} n==1' "$d" | awk '/^description:/{f=1} f&&!/^(name|allowed-tools|model):/{print}' | head -20
done | wc -c7. 已知悬而未决(本计划不解决,登记备查)
| 项 | 状态 | 影响 |
|---|---|---|
rvh/CLAUDE.md 里那批守卫 grep 没有任何东西在执行 | 合仓评估 §7 已登记 | ci-rvh.yml 只跑 analyze + 5 条架构 grep + test。那些块是判据规格不是闸门;真正在守的是每条点名的 Dart 回归测试。接进 CI 是笔独立的活,接上之前别把"grep 写着"当"已经守住" |
| RVH 的 Dart 格式无机械守卫 | backlog.md 已记 | ci-rvh.yml 的 dart format 门 2026-08-29 删除(它在任何能解析本项目依赖的 Flutter 上都会因 tall-style 重写当场红 502 个文件)。要不要做一次全仓重排版待定 —— 做了会冲掉几乎每个 .dart 的 blame,而 blame 正是合仓不用 subtree 保下来的东西 |
| 百度 OCR 控制台删应用 | backlog.md 已记,待用户操作 | AK/SK 不会自己过期,只要控制台里那个应用还在就还能被计费 |
| 记忆库空置(§0.1 原因 1) | 本计划不解决 | 本计划治的是症状(把已有内容搬到正确的加载层)。要根治棘轮,需要让「值得长期记住但不必每次读」的事实有一个按需召回的落点。建议 T2-1 落地、量到实际收益之后再单独立项 —— 现在就动等于同时改两个变量,量不出哪个起了作用 |
8. 一句话
合仓是成功的(跨端场景持平却换来必然同步),代价全部落在单端会话上, 而其中 RVH 的 +57% 有单一成因、单一修法。
如果只做一件事,做 T2-1 —— 前置 P0-1 已于 2026-08-29 实测通过(判定 A), 且实测占比把它的收益钉死为「约 93% 的 RVH 会话 −36%,期望值 −33%」。其余按阶段择期。