分支
fix/0.6.10-save-safety(基于 mainf05c0b9= 0.6.9)。承接 0.6.9 代码复核结论,修复全部 5 项遗留缺陷。
save-download.js:下载落盘改为「同目录随机 .partial 临时文件 → 收全字节 + 关流 + content-length 校验通过 → rename 发布」。error 后统一 fs.rm(destination),源 URL 404/500/中途断连会把用户上一次成功产物删掉。resolveRedirect,逐跳校验。tests/save-download.test.js(404/500/截断/断连/拒重定向/静态守卫 7 项),并做新旧实现对照复现(旧=404 后文件消失;新=逐字节保留)。public/app.js 统一入口 persistSettings(patch):先更新 state.settings 内存、再刷 UI,最后尽力持久化;失败只置一次性 settingsDegraded 非阻断警告,不再静默丢失。legacy.language,防止迁移失败把用户语言偏好丢回系统语言。tests/settings-degrade-ui.test.js(5 项静态守卫,沿用仓库「渲染进程无 DOM 单测框架」惯例)。.complete 不再是唯一证据store-engine-cache.js:复制到 <final>.staging → 按打包期清单校验关键文件(size 全记,≤5MB 加 sha256,mergedlo 等百 MB 级只 stat)→ 真实最小 CSV→PDF 冒烟转换(90s 超时)→ 写 .complete → rename 发布 → 发布成功后才回收其余旧缓存。scripts/build-engine-manifest.js(48 个关键文件白名单),产物 engine-integrity.json 随 extraResources 进包(bin/libreoffice 为 gitignore,需在引擎齐全的机器生成)。tests/store-engine-cache.test.js(7 项,含本机真实引擎冒烟)。settings-store.js withSettingsLock:要清理的队尾 Promise 先存局部 queued,存入 Map 与比较为同一对象(旧实现比较的是两个不同包装,条件永不成立、Map 无界增长)。_mutationChainsSize() 作回归探针。tests/settings-store.test.js(8 项)。scripts/release-version-sync.js 重写为两阶段:阶段一全部读入 + 校验 + 内存生成(零写入);阶段二逐文件写盘,中途 IO 失败逐一回滚已写文件。tests/release-version-sync-atomic.test.js(4 项:最后一个 lock 非法→零写入;只读 README→回滚;dry-run 不动盘)。bin/ 缺引擎二进制,ffmpeg/pdftoppm ENOENT,经 git stash -u 对照证实非本批引入)。build.files;新测试文件已同时加入 test 与 test:ci 两处列表。