Spec 010 — 调研
English: research.md
决策理由记录在 ADR-016 以及 宪章 0.3.0 修订案中。本文件记录背景以及权衡过的各种方案。
问题
单个用户在多台机器上运行 Coffer,每个保险库都会各自分叉。宪章禁止把厂商云 作为权威数据源(system of record),因此在一个有边界的修订案允许使用 用户自有介质之前,同步一直是非目标。
传输方案
| 方案 | 历史/合并 | 本地优先契合度 | 冲突处理 | 结论 |
|---|---|---|---|---|
| 用户自有 git 仓库 | 内建 | 强(用户拥有远端) | git 三方合并 + 单文件粒度 | 选定 |
| 点对点(Syncthing 风格) | 无 | 最强 | 后写者胜,无历史 | 推迟 |
| 用户自有对象存储(S3) | 无 | 强 | 弱 | 否决 |
| 托管的 Coffer 服务 | 不适用 | 违反原则 I | 不适用 | 否决 |
对开发者受众而言 git 胜出:他们本就有 git 凭据,而我们能免费获得 diff/历史/合并能力。
为何采用独立工作区 + 导出/导入(而非提交实时目录)
coffer.db 是二进制且不可合并的,而实时运行时目录把真值 (knowledge/memory 文件)和可重建/本地状态(db、日志、daemon.json)混在一起。 一个专用工作区配合文本导出,能让 git diff 保持有意义,并让 SQLite 继续作为本地权威数据源。Knowledge/memory 本就是文件,因此 可直接镜像;config 和 credentials 则投影为文本。
为何只导出密文 + 带外密钥
把主密钥放进仓库会让密文失去意义,并违反修订案。只导出密文意味着即便是 托管在 GitHub 上的远端也不含任何可用内容。每台机器一次性的密钥引导 是被接受的代价;在密钥存在之前,密文会被报告为已锁定,而不是悄无声息地失败。
为何默认手动 + 可选开启自动
单个用户通常一次只在一台机器上,因此手动 coffer sync 是 可预测且冲突少的。自动同步(防抖推送 + 定时拉取)作为一种无需人工干预的 收敛便利方式提供,但保持为可选开启,以避免意外的后台网络 和意外的冲突。
确定性
干净的合并依赖于稳定的序列化:键排序、时间戳归一化, 以及排除机器本地字段(id、created_at、updated_at)。这一点经过了 单元测试,因为它对整个合并故事是承重的。