Tolaria ADR-0042:自动清除回收站笔记的安全模型——从五重校验到被“确认删除“取代的演进
发布时间:2026/9/13 19:26:10 作者:尧图编辑部 阅读量:1,286

Tolaria ADR-0042自动清除回收站笔记的安全模型——从五重校验到被确认删除取代的演进【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria本文以 Tolaria 的架构决策记录 ADR-0042《Trash auto-purge safety model》为主体完整还原这套自动永久删除机制的设计五重安全校验、操作系统回收站软删除、按小时节流的触发条件与审计日志同时结合仓库当前源码说明该方案后来如何被 ADR-0045 取代以及如今 src-tauri/src/vault/trash.rs 中实际的删除实现长什么样。读完你会理解为一个高危不可逆操作设计防御性删除时校验清单、恢复路径与触发节流各自解决什么问题以及为什么有些项目最终选择用确认弹窗 git 历史替代整套回收站机制。背景UI 承诺了 30 天清理但从未真正执行ADR-0042docs/adr/0042-trash-auto-purge-safety-model.md的出发点非常具体Tolaria 的 Trash 视图界面上已经展示了一句警告——Notes trashed more than 30 days ago will be permanently deleted回收超过 30 天的笔记将被永久删除但应用从未真正执行过这条规则。文档给出的态度是既然向用户承诺了就必须实现否则就是虚假承诺。文档同时开宗明义地强调了这件事的风险等级——这是整个应用中最危险的操作之一一次 bug 就可能导致不可逆的数据丢失。因此安全模型必须显式且保守explicit and conservative。这两句话构成了后续所有设计约束的源头每一条校验规则、每一个触发条件、每一行审计日志都是在回应不可逆这三个字。决策核心五重安全校验缺一不动手ADR-0042 的决策一句话概括是在应用启动和窗口重新聚焦时最多每小时一次自动清除回收超过 30 天的笔记使用trash::delete移入操作系统回收站实现软删除每个文件必须通过 5 项强制安全校验并写入.laputa/purge.log审计日志。其中最值得拆解的是每个文件删除前必须全部通过的 5 项校验序号校验项目的1frontmatter 中存在_trashed: true或旧别名Trashed、trashed且为真值确认该笔记确实处于已回收状态而不是普通笔记2_trashed_at或旧别名Trashed at、trashed_at存在且可解析为日期确认回收时间来源可靠解析失败的笔记不删3解析出的日期严格早于30 天前恰好 30 天 跳过边界保守宁可多等一天不提前删4文件在预期路径上真实存在于磁盘防止基于过期索引删除不存在的文件5文件规范路径必须位于 vault 根目录之内防路径穿越杜绝误删 vault 外部文件文档还规定了两条执行纪律任一校验失败 → 跳过该文件并记录 warning 日志而不是抛出错误或中断整个流程purge 永不提前中止——所有候选文件独立处理一个文件失败不影响其他文件的清理。这套逐文件独立判定 失败降级为跳过的模型本质上是把批量删除操作拆成了一组互不牵连的单文件事务任何一项证据不足就放弃该文件从机制上把误删概率压到最低。删除方式为什么选操作系统回收站而不是直接删ADR 明确拒绝了fs::remove_file这种一步到位的做法选择了trashcrate 的trash::delete把文件移动到 macOS 废纸篓 / Windows 回收站。理由链很清晰给用户留一条最后恢复路径即使 5 重校验全部通过、笔记也被正确标记了 30 天以上用户仍可能事后意识到其实不该删OS 回收站提供了应用外的第二道安全网失败降级如果移入 OS 回收站失败才回退到fs::remove_file硬删除并记录 warning——即软删除是首选硬删除只是兜底。文档在Options considered一节完整列出了三个候选方案的取舍Option A — OS 回收站trashcrate当时胜出可恢复安全默认值代价是引入一个平台相关依赖Option B —fs::remove_file直接永久删除实现最简单、无依赖但对一个自动后台执行的操作来说没有恢复路径风险过高Option C — 移动到.laputa/purged/归档目录自定义恢复机制但会污染 vault 目录结构且用户根本不会想到去那里找回文件。ADR 还诚实列出了 Option A 的平台代价trashcrate 在 macOS 依赖NSFileManager、Windows 依赖IFileOperation、Linux 遵循 freedesktop 规范——这是一个跨平台行为不完全一致的依赖属于为了安全接受的复杂度。触发条件与节流每小时最多跑一次自动清除的触发点被限定在两处应用启动时在run_startup_tasks中执行窗口重新获得焦点时WindowEvent::Focused(true)并用MutexInstant时间戳做节流最多每小时执行一次。节流条款直接回应了一个真实场景用户在多窗口间快速切换时会密集触发 focus/unfocus 事件如果没有节流purge 逻辑可能被高频重复执行造成不必要的磁盘 I/O。用一把Mutex保护一个Instant时间戳是最小代价的进程内限流实现。审计日志.laputa/purge.log记录每一次清除每次 purge 运行都会向 vault 内的.laputa/purge.log追加写入内容包含时间戳、本次检查的文件数、实际清除的文件数、以及每个被清除文件的完整路径。这个设计把自动删除从黑盒变成了可审计操作用户随时可以打开这个文本文件核对什么时间、哪些文件、被自动删了。ADR 在 Consequences 一节也承认了它的副作用——日志会随时间无限增长但对纯文本日志而言可以接受并且预设了复查条件如果用户反馈 OS 回收站被 vault 文件塞满需要重新评估。后续演进ADR-0045 推翻了整个回收站体系理解 ADR-0042 不能只看它自己。该文档 frontmatter 中标注了status: superseded、superseded_by: 0045。紧随其后的 ADR-0045Permanent delete with confirm modal — no Trash system 给出了替代结论而仓库当前源码可以印证这次转向已经落地。ADR-0045 的论点是回收站体系引入了过多复杂度——trashed/trashedAtfrontmatter 字段、侧边栏过滤、编辑器横幅、Inspector 组件、专门的 smoke 测试、以及trashcrate 依赖而用户真正需要的安全保证其实是不可逆操作前的确认提示不是软删除缓冲——毕竟 vault 本身就是一个 git 仓库参见 ADR-0014 与 ADR-0034 确立的 git 恢复机制。该文档记载2026-04-06 的提交e581ad36一次性移除了整个 Trash 体系123 个文件变更约 3164 行删除。仓库现状与这一决策互相印证现在的删除实现位于 src-tauri/src/vault/trash.rsdelete_noteL6-L17直接调用fs::remove_file永久删除单个文件batch_delete_notes批量删除时跳过不存在的文件并记录 warning——与 ADR-0042 中逐文件独立判定、失败即跳过的执行纪律一脉相承只是删除动作本身不再经过 OS 回收站src-tauri/src/vault/mod.rs 将batch_delete_notes, delete_note从trash模块重新导出模块名保留了trash的历史痕迹但实现已是 ADR-0045 定义的立即永久删除 确认弹窗useDeleteActions单一安全门src-tauri/Cargo.toml 中已无trashcrate 依赖与 ADR-0045 所述依赖已移除一致一些化石细节仍可追溯src-tauri/src/vault/frontmatter.rs 的注释里Trashed仍被列在 YAML 解析失败时的兜底提取字段中src-tauri/src/vault/mod_tests.rs 仍保留一行指向vault/trash.rs的purge_trash测试注释——从源码结构看这些是回收站时代留下的痕迹符合 ADR-0045 所述trashed字段被解析器静默忽略、无需迁移、无数据丢失的处理方式。这套演进给自动删除类功能的设计启示把 ADR-0042 与 ADR-0045 放在一起读能提炼出一条完整的设计推演路径对任何要实现自动清理/自动删除的功能都有参考价值承诺必须可执行UI 上写出的30 天后永久删除要么实现、要么删掉文案中间状态承诺了但不执行是最差的选项不可逆操作要按文件独立校验把批量操作拆成单文件判定任一证据不足即跳过该文件而非中断流程误删面最小化边界取保守值恰好 30 天按不删处理解析失败按不删处理宁可慢一天不可错一秒恢复路径要分层应用内回收站 → 应用内自动清除 → OS 回收站 → git 历史。Tolaria 最终把前两层整体砍掉只保留确认弹窗 git 历史两层——这提醒设计者先问一句用户手里是不是已经有一个够用的恢复机制比如版本库如果有软删除缓冲可能只是徒增状态复杂度触发要节流、删除要留痕自动运行的清理逻辑必须有频率上限且每次运行应留下可人工核对的审计记录ADR-0042 的.laputa/purge.log是正面范例。需要说明的是ADR-0042 中描述的purge_trash调度、.laputa/purge.log写入等机制在当前代码中已不存在对应测试注释虽残留但模块内已无 purge 实现本文以仓库文档与源码的实际现状为准——ADR-0042 的价值在于它完整记录了 Tolaria 如何为最危险的操作构建安全模型又如何在实践中承认该模型相对 git 恢复机制属于过度设计从而完成了从回收站自动清除到确认弹窗永久删除的收敛。【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考