DIFF-026:Vault 外部冲突按内容哈希判断,禁止后写覆盖
- 编号:DIFF-026
- 影响:F01 随手记、F04 JSON、A03 文件冲突
- 日期:2026-09-14
原行为(Electron)
fs.watch 递归监视 Vault,180ms 去抖后广播。当前文件未 dirty 时直接从磁盘重载;dirty 时只刷新树,不弹冲突对话框,也不在保存前比较外部版本。因此本地未保存编辑时,外部修改可能被之后的自动/手动保存覆盖。
本产品行为
VaultConflictEngine 用 UTF-8 内容 SHA-256(mtime 只作监视快照的附属,不是同一性)。干净缓冲且磁盘变化则自动重载;本地 dirty 且磁盘已偏离上次保存内容则弹出冲突:载入磁盘版本 / 另存 *.local-{epoch}.* / 继续编辑。保存前再次读盘,外部版本与基准和编辑器都不同则拒绝覆盖。自写通过预期哈希忽略。监视用 400ms 内容哈希轮询(忽略 .tmp、点文件、.git/,随手记还忽略 attachments/),不跟随符号链接。
本轮不做三方合并编辑器。完整 JSON 检查器弹层、frontmatter、全文索引仍未做。
理由
规格要求外部变化与 dirty 同时存在时保留两个版本,且 mtime 不能唯一判断相同内容。NIO WatchService 在 macOS 上延迟不稳定,哈希轮询可在无窗口单测里复现。
证据
VaultConflictEngineTest:路径忽略、reload/conflict/own-write/删除分类、拒绝覆盖、快照 diff、临时目录轮询看到外部写入。desktopTest 143/143(4 项冲突测试均执行)。无运行截图;窗口冲突对话框未手工验收。
受影响范围
- 与 Electron 比:dirty 时不再静默忽略外部更改;保存会被拦住直到用户选择。
- 轮询间隔约 400ms,不是 180ms 事件去抖。
- 另存文件名使用
.local-{epoch},不是用户自选路径。 - 大于 8 MiB 的文件只比较 size 指纹。