# 原生目录扫描与普通文件恢复性能验证

这批优化基于 `d7d80230`，保留 undo 的五个拓扑检查点，降低完整目录扫描成本，并扩大已有父目录中的普通文件原生恢复范围。

## 实现与边界

- `scan-directories-v1` 在 macOS/Linux 上通过 `openat(O_DIRECTORY | O_NOFOLLOW)` 逐级打开目录，以目录流识别 Git 标记候选。扫描 ignored 目录，不进入名称恰为 `.git` 的元数据目录，不跟随符号链接；标记大小写、损坏仓库、失效 worktree 指针、Git index 与 submodule 仍由现有 TypeScript/Git 逻辑解释。
- 每次重新扫描。上次目录数量仅选择执行器：小于 64 个目录时使用 TypeScript 完整遍历；增长后可重新进入原生扫描。没有缓存拓扑结果，也没有省略任何检查点。
- 目录句柄、父目录绑定与扫描前后目录时间戳必须一致。扫描时并发增删目录项会使原生扫描失败，防止静默接受不完整结果；它不提供跨整个工作区的原子快照。能力确认后的路径错误向上传递。超过 128 层时，helper 明确返回 `depth_limit`，丢弃部分结果，由 TypeScript 从根重扫。
- 原生扫描使用操作剩余预算，并遵守 `PI_UNDO_OPERATION_TIMEOUT_MS`（默认 300 秒）。能力探测只在私有目录运行，缺失能力时回退；取消、超时及无法确认子进程终止均保留现有错误处理契约。探测取消不会永久污染能力缓存。
- `restore-files-v2` 支持普通文件覆盖、创建、删除的混合计划，以及子目录中的文件删除。父目录必须已经存在。读取、校验、no-clobber 安装及隔离均绑定同一组父目录句柄；最多保留 128 个非根父目录句柄。目录创建/删除、类型替换、过多父目录与不支持的平台继续使用 TypeScript。
- durable pack 格式与恢复协议保持不变。仍在修改前发布并持久化 pack，逐项校验内容和 mode，保留同 inode 的 ownership artifacts。失败时由现有 packed recovery 回滚；外来冲突文件不会被当成本次产物删除。

## 实测结果

环境为本机 macOS arm64、Node 23.11.1、真实 Pi 0.86.1 SDK 与离线 faux provider。每个场景执行三次 undo，中间执行 redo 并等待后台恢复/持久化清理结束；校验文件内容、撤回/重做历史状态和扫描次数。表内为中位数，单位毫秒。基线与优化版本在同一机器先后执行，未施加墙钟性能断言。

| 场景 | 优化前 | 优化后 | 耗时降低 |
| --- | ---: | ---: | ---: |
| 无依赖目录，修改 1 文件 | 146 | 148 | 约持平 |
| 3,000 包，修改 1 文件 | 1,976 | 924 | 53% |
| 10,000 包，修改 1 文件 | 5,857 | 2,755 | 53% |
| 100 文件全部覆盖 | 179 | 182 | 约持平 |
| 100 文件在根目录新增后撤销 | 177 | 174 | 约持平 |
| 100 文件在已有子目录新增后撤销 | 517 | 180 | 65% |
| 50 文件覆盖、50 文件新增后混合撤销 | 711 | 186 | 74% |

分阶段计时中，3,000 包场景五次扫描合计从 1,759 ms 降至 716 ms；10,000 包从 5,470 ms 降至 2,398 ms。全部测量仍为五次扫描。新增目录的撤销测试保留父目录中的 `keep.txt`，因此测量的是文件删除，不含目录删除。混合与子目录场景原先未进入 native，优化后三次均调用原生恢复一次。

另一个既有大型工作区基准覆盖 3,000／10,000 包 × 1／100 文件，四组均通过内容、redo 和 `[5, 5, 5]` 扫描次数断言。该次单独运行的中位数依次为 878、923、2,582、2,673 ms；与分阶段诊断是不同批次，不把两批耗时混作同一组数据。

这些是三次采样的本机结果，主要证明已观察到的热路径得到改善。磁盘、目录结构、并发写入和机器负载会影响绝对耗时；没有从这些结果推断其他操作系统上的收益。

## 复现与验证

最终验证通过：默认原生路径 617 项、强制 TypeScript 回退 586 项、Rust 单测 8 项；TypeScript 类型检查、四组大型工作区基准及 npm 打包内容检查通过。跳过项为不适用平台/能力及按需基准，不计入通过数。

```bash
npm run build:native
cp native/pi-undo-fs/target/release/pi-undo-fs native/bin/pi-undo-fs-darwin-arm64
npm run test:native
npm test
PI_UNDO_DISABLE_NATIVE=1 npm test
npm run typecheck
PI_UNDO_LARGE_WORKSPACE=1 npx vitest run test/large-workspace.test.ts
```

上面的二进制复制路径用于本次 macOS arm64 环境；其他平台须使用对应构建产物。此批已更新仓库现有的 macOS arm64 二进制。Linux、其他架构和 Windows 的源码构建/运行不在本机验证范围内；缺少二进制或扩展能力时会回退，发布时仍需现有六平台构建流程提供对应产物。

补充测试覆盖：原生/TypeScript 拓扑一致性、ignored 嵌套仓库、大小写不同的 Git 标记、符号链接及目录删除/替换、深度回退、取消后重新探测、超时、混合计划回滚/前滚、外来文件冲突、旧 helper 门控，以及 128／129 个父目录的边界。

独立审查运行器异常退出，正式审查结果未能落盘。已保留失败运行的状态与补丁证据，并人工核对日志中的具体意见；这不计为独立审查通过。已修复候选错误类型与扫描预算，补充句柄边界测试。旧 helper 在混合计划中仍可能先准备 pack 再回退，存在额外准备开销；兼容性分类与平台发布覆盖也仍需后续维护。
