ADR-011 · 独立私有 data repo · 语料与生产数据同 git 工作流但隔离访问
| 字段 | 值 |
|---|---|
| 状态 | accepted · 项目主理 2026-06-11 通过 (CTO 签于本 PR review) |
| 日期 | 2026-06-11 |
| 决策者 | 项目主理 + CTO |
| 承接 | v0.6.1 (.gitignore Plan A 全审计放开) · ADR-010 (数据层留持久盘) · review-service PRD §6 决策点 1 |
| 相关 | anchors/*/raw/ (145MB) · cloud_sync.sh · CLAUDE.md §9.1 敏感分级 |
1. Context
三个力量交汇:
- 145MB 锚点语料 (
anchors/*/raw/) gitignored, 只在项目主理本地 + rsync — 远程 Claude Code 会话跑不了 T10, 多机协作靠 rsync 脆弱 - v0.6.1 决策: 主 repo "私有全员审计" — 但语料含
tian_only级 (§9.1: 仅锚点 + 项目主理), 推主 repo 会把 tian_only 降级为全员可见 - review-service (新): 管理层提交的报告是各部门 confidential, 评审产物更不能进"全员审计"的主 repo
2. Decision
两层数据、两种归宿:
| 数据 | 归宿 | 访问集 |
|---|---|---|
锚点语料 anchors/*/raw/ (145MB) + backups/feishu/ 过滤源 | 新私有 repo boss-vault-data | tian_only 集合 (锚点 + 项目主理); CI/VM 用最小权限 deploy key (只读) |
| review-service 生产产物 (管理层提交 doc + 评审 reports/cases) | 留 VM 生产 vault 本地 + 云盘快照备份, MVP 期不进任何共享 repo | VM 运维者; 产物只回推提交者本人 (飞书) |
| 开发 repo (代码/skills/docs + 项目自身判断 cases/reports) | 维持 v0.6.1 现状 (全员审计) | collaborators |
生产产物 Phase B 再评估归档策略 (候选: 飞书文档即存储 / per-dept data repo) — MVP 不过度设计。
3. Options considered
| 选项 | 否决理由 |
|---|---|
| 语料推主 repo | 破坏 tian_only 边界 (Context #2) |
| 语料放 Cloudflare R2 / 对象存储 | §9.2 出站闸阻断 (真名+财务数字); 无消费者 (ADR-010 已论证流水线不上 CF); 新增密钥泄漏面 |
| 生成数据库 | _wiki/ 就是派生索引 (可重生); 违背单一 vault 文件范式; 引入第三套状态同步 |
| git-crypt 在主 repo 内加密 | 密钥管理复杂度 > 独立 repo; 审计工具 (redact/lint) 对密文失效 |
3.4 Invariant impact ★
- sage-wiki watch 路径不变: 本地 checkout 把 data repo clone/symlink 到
anchors/<slug>/raw/原位 — config.yaml 的 sources 零改动 - 主 repo .gitignore 不变:
anchors/*/raw/仍 ignore (物理上是另一个 repo 的工作区) - cloud_sync.sh 降级: 语料同步从 rsync 改 git pull (保留 rsync 作大文件兜底); 脚本加 data-repo 模式
- 新 invariant: data repo 永不加 GitHub Actions / 第三方 App (最小化 tian_only 数据的集成面)
4. 迁移步骤 (本地执行, ~30 分钟)
(2026-06-11 随 §7 修订) 原"原地 init 嵌套 repo"方案与 §7 两目录结构冲突, 改为 独立 checkout + symlink: data repo 是独立工作区, vault 通过软链接进原位 — sage-wiki watch 路径不变, 飞书数据管道 filter 写入即落 data repo 工作区, data_sync 只需 commit+push。
# 1. GitHub 建私有 repo boss-vault-data (collaborators: 仅 tian_only 集合)
# 2. 本地初始化独立 checkout (结构: anchors-raw/<slug>/ + wiki/)
mkdir -p ~/boss-vault-data/anchors-raw && cd ~/boss-vault-data
git init && git remote add origin git@github.com:zhanglunet/boss-vault-data.git
mv ~/boss-vault/anchors/tian/raw anchors-raw/tian # 语料挪入
git add -A && git commit -m "init: tian raw corpus" && git push -u origin main
# 3. vault 原位用 symlink 接回 (sage-wiki watch / 飞书数据管道 filter 路径零改动)
ln -s ~/boss-vault-data/anchors-raw/tian ~/boss-vault/anchors/tian/raw
# 4. wiki 快照首推: bash ~/boss-vault/scripts/data_sync.sh (含 _wiki → wiki/ + 时间戳)
# 5. 验证: 主 repo `git status` 干净 (raw 仍 ignored); data repo 远端含两目录多锚点扩展: data repo 内按
<slug>/分目录, 或 per-anchor repo — 第二锚点出现时定。
5. 关键反共识立场
"一个项目一个 repo" 在这里是错的: 访问控制粒度应该跟着敏感分级走, 而不是跟着项目边界走。git 的最小 ACL 单元是 repo, 所以 tian_only 数据就该有自己的 repo — 用仓库边界实现 §9.1 的分级, 比任何应用层约定都硬。
7. 增补 (2026-06-11 需求检查) · 数据保鲜: 单写者多读者 + 编译在生产地
触发: 用户需求检查 — "新语料进来 / wiki 更新, data repo 如何保持更新?"
关键澄清: 飞书 review-service 运行时不直接读 raw 语料 — Phase 1 读 _wiki/ (派生索引) + 主 repo tracked 的 anchor doctrine。保鲜问题 = "_wiki 新鲜度", 不是 "145MB 同步"。 "语料训练" 实为两条已有回路: ① 语料→wiki 重编译 (本节) ② anchor research 更新 (T10/S5, 走主 repo PR, VM pull 即得, 无新问题)。
决定:
- data repo 内容扩为两目录:
anchors-raw/<slug>/(语料) +wiki/(_wiki 编译快照)。 派生物入库是有意取舍 — 消费端 (VM/远程会话) 零编译依赖, 与静态站 "build 后 deploy" 同范式; 否决替代: VM 自装 sage-wiki 重编译 (工具链+raw+编译时间全上 VM, 运维面扩大)。 - 写者唯一: 仅本地 (语料生产地) 写 data repo。新脚本
data_sync.sh: filter/编译完成后 add+commit+push (append-only); 可挂本地 cron 随飞书数据管道流程自动跑。 - 读者只拉: VM systemd timer 每 30min
git pull --ff-only×2 (主 repo + data repo); worker 接 job 时读 wiki 快照时间戳, 评审卡片标注 "背景知识截至<ts>" (新鲜度显式化)。 - 无冲突 invariant: 单写者 + append-only + ff-only ⇒ 永无 merge 冲突; VM 永不写 data repo (§2 生产产物留 VM 不变)。
新鲜度档位: wiki 滞后 ≤ 本地编译周期 + 30min。评审场景足够; 不够时 Phase B 加 "提交时强制 pull"。