Parent
来源
2026-07-28 对 #200 落地代码的 Spec review。
问题
replaceFileAtomicallyIfUnchanged() 当前执行:
- 读取目标文件;
- 与
expectedBytes 比较;
await fs.promises.rename(temp, target) 发布新内容。
Project mutation 队列只能串行化 CDF 进程内的写入。任意外部程序仍可在步骤 2 与 3 之间写入目标文件,该写入随后会被 CDF 的 rename 静默覆盖。因此当前实现提供的是“原子发布 + 进程内串行化”,不是 #200 所写的、面向任意外部写入者的原子 compare-and-swap。
现有测试仅覆盖:调用前文件已变化,以及两次 store.saveDocument() 的进程内并发;没有覆盖“比较完成后、发布前”发生外部写入。
必须先完成的决策
标准 Node 文件 API 没有跨平台的“比较现有内容并条件替换”原语,且不合作的外部写入者不会遵守 CDF 的进程锁。因此实现前必须明确产品保证,二选一并记录理由:
A. 严格外部写保护
保证任意外部程序在任何时刻写入都不会被 CDF 静默覆盖。采用此选项时,必须给出可在 macOS / Windows / Linux 上成立的发布协议或明确受支持的平台边界,并用可控竞态测试证明,而不是再次缩短 check→rename 窗口。
B. CDF 内部强保证 + 外部写 best-effort
严格保证所有 CDF 写入者之间不丢数据;对不合作的外部程序只做发布前检测和冲突提示,不宣称无窗口。采用此选项时,必须同步修订 #200 中“原子 CAS / 外部程序不丢修改”的表述、测试口径和用户可见冲突语义,避免实现与承诺继续不一致。
若该保证会成为长期架构约束,按 docs/agents/domain.md 判断是否需要 ADR;不要在代码注释里单独做产品决策。
交付内容
- 写明选定的保证等级、适用写入者和平台边界。
- 使 API/type/注释准确表达该保证;禁止继续把
read + rename 称为无条件原子 CAS。
- 按选定保证实现冲突检测与错误结果。
- 保留原子发布:读者只能看到旧文件或新文件,不能看到半写文件。
- 失败和冲突必须保留用户未保存内容,并返回当前磁盘内容/版本。
测试
必须新增一个可控竞态 seam,在“完成 expected 版本校验”与“发布”之间插入外部写入,并断言选定保证下的预期结果。
同时保留:
- 两个 CDF writer 的交错写入;
- 创建目标时的并发
EEXIST;
- 写入失败无临时文件残留;
- 冲突返回当前内容;
- 发布中断不产生半写文档。
验收标准
非目标
Parent
来源
2026-07-28 对
#200落地代码的 Spec review。问题
replaceFileAtomicallyIfUnchanged()当前执行:expectedBytes比较;await fs.promises.rename(temp, target)发布新内容。Project mutation 队列只能串行化 CDF 进程内的写入。任意外部程序仍可在步骤 2 与 3 之间写入目标文件,该写入随后会被 CDF 的 rename 静默覆盖。因此当前实现提供的是“原子发布 + 进程内串行化”,不是 #200 所写的、面向任意外部写入者的原子 compare-and-swap。
现有测试仅覆盖:调用前文件已变化,以及两次
store.saveDocument()的进程内并发;没有覆盖“比较完成后、发布前”发生外部写入。必须先完成的决策
标准 Node 文件 API 没有跨平台的“比较现有内容并条件替换”原语,且不合作的外部写入者不会遵守 CDF 的进程锁。因此实现前必须明确产品保证,二选一并记录理由:
A. 严格外部写保护
保证任意外部程序在任何时刻写入都不会被 CDF 静默覆盖。采用此选项时,必须给出可在 macOS / Windows / Linux 上成立的发布协议或明确受支持的平台边界,并用可控竞态测试证明,而不是再次缩短 check→rename 窗口。
B. CDF 内部强保证 + 外部写 best-effort
严格保证所有 CDF 写入者之间不丢数据;对不合作的外部程序只做发布前检测和冲突提示,不宣称无窗口。采用此选项时,必须同步修订 #200 中“原子 CAS / 外部程序不丢修改”的表述、测试口径和用户可见冲突语义,避免实现与承诺继续不一致。
若该保证会成为长期架构约束,按
docs/agents/domain.md判断是否需要 ADR;不要在代码注释里单独做产品决策。交付内容
read + rename称为无条件原子 CAS。测试
必须新增一个可控竞态 seam,在“完成 expected 版本校验”与“发布”之间插入外部写入,并断言选定保证下的预期结果。
同时保留:
EEXIST;验收标准
pnpm test覆盖 flow-diagram 全簇并通过。pnpm run typecheck与pnpm run build通过。非目标
manage_flow_diagram动作集或错误码,除非所选一致性保证确实需要新增可区分的冲突码并在 Architecture review 02 — Deepen the Editable Flow Diagram consistency module #200 中明确记录。