# 文件回退的追踪边界

> 行为说明——这**不是 bug**。插件的文件回退**有意只追踪模型的专用编辑工具**，并对**已登记文件**额外施加一层边界（消息边界复查）。为 issue [#5](https://github.com/SiriLee/dsh-rewind/issues/5) 编写；与 Claude Code 的 checkpoint 语义保持一致。 [English](tracking-boundary.md)

## 一句话概括

回退**始终能还原**用专用编辑工具（`write` / `edit`）编辑过的文件，因为插件会在编辑前对其快照。**命令行（或手动）编辑**仅当该文件在同一会话中**先前已被某个编辑工具登记**时才会被覆盖——此时变更本身会被记录，但回退到"未变区间中间的边界"时，只能精确到**下一处被记录的状态**（见[已登记文件被编辑工具之外的方式改动时的回退精度](#已登记文件被编辑工具之外的方式改动时的回退精度)）。

## 文件变更的分类

**编辑工具**（创建/覆盖、按行编辑）：每次调用都会告诉插件*将要改动哪个文件*，因此插件会在编辑前对文件的当前内容**快照**，回退时能还原。这条路径是**确定性**的——用了就一定可还原。

**命令行或手动编辑**：Windows 上的 PowerShell（`pwsh`）写入、Linux 上的 `sed -i`，或手动保存文件。它们**不告诉**插件动了哪个文件，所以**没有可预先快照的对象**。

命令/手动编辑仍有一种情况会被覆盖：若该文件在本会话中**先前被某个编辑工具登记过**，插件会在每个用户消息边界复查已登记文件并记录它看到的变更，因此这类文件也能在回退时还原。

## 何时无法回退

这类是**完全没有记录到"变更前"状态**（有别于下一节的"精度缺口"——那是有记录、但某个中间消息的精确值丢失）：

1. **模型第一次触达时用命令编辑，且该文件从未被登记。** 无快照、无登记——变更前后都没有记录，无从还原；回退到任何消息对该文件都报告"无变更可恢复"。
2. **文件在模型第一次编辑工具改动前就被手动编辑过。** 插件的首个快照是在编辑工具调用时拍的，因此回退只能把文件还原到手动编辑**之后**的状态，而非**之前**。

两者都来自**刻意求轻**的取舍。要覆盖各种命令编辑，就得扫描整个工作区、并分类任意命令改了什么——代价高、易错、难维护。插件只登记会交出手确切路径的编辑工具，并以消息边界复查作为轻量安全网。代价是未登记文件的命令编辑不被记录；收益是简单、可靠、易维护——与 Claude Code 相同。

## 已登记文件被编辑工具之外的方式改动时的回退精度

已登记文件的快照只来自：(a) 编辑工具的 before 捕获，(b) 边界复查的变更检测。所以**只有"文件状态相对上次记录发生变化"的那条消息才是记录点**；回退到消息 *M* 会把各文件还原到 *M* 之后**最早**的那条记录。

若文件在 *M* 处**未变**（相对上次记录），则 *M* **不是记录点**。若随后文件被命令/手动编辑改掉，*M* 之后最早的那条记录是**变更后**状态——于是回退到 *M* 会还原成**变更后**状态，而非 *M* 时刻文件**真实**的状态：

```
消息 1   write 设 f="X"        记录 before=null（文件新建）
消息 2   边界记录 f="X"        （null→X）
        命令把 f "X"→"Y"
消息 3   边界记录 f="Y"        （X→Y）
回退到消息 2 → 还原成 "X"     （正确：消息 2 时 f 是 "X"）
```

插入一条**未变**消息，精度缺口才显现：

```
消息 1   write 设 f="X"        记录 before=null（文件新建）
消息 2   边界记录 f="X"        （null→X）
消息 3   回复，f 仍="X"        不是记录点（未变）
        命令把 f "X"→"Y"
消息 4   边界记录 f="Y"        （X→Y）
回退到消息 3 → 还原成 "Y"     （错：消息 3 时 f 实际是 "X"）
```

消息 2 是记录点，所以回退它能恢复**变更前**状态 `X`；消息 3 不是记录点，一旦文件被命令改掉，它那刻的精确状态就丢了。要关闭这个缺口，就得让每条边界都是快照——每条消息都记录每个已登记文件（哪怕没变）——代价是**每条消息×每个文件都写一个文件**。插件**刻意不做**，以保持轻量（见[定位](#定位)）。Claude Code 的 checkpoint 同样如此。

## 定位

要把"未登记首触即命令编辑"的情形也做成可还原，意味着对整个工作区反复备份，或依赖 Git 工作树——都笨重，且与插件"轻量快照"的设计相悖。Git 才是管理工作区变更的正确工具。插件的定位是**快速、会话内回退**，因此**刻意不采纳**该能力。
