agent 添加操作后,明确 Undo 应恢复什么
本文目录
CueSpec 工作流编辑团队撰写 · AI 辅助团队编辑。
定义 Undo 操作时,要说明它逆转哪次操作、允许改变哪些字段,以及必须保留哪些后续工作。然后描述恢复与另一项操作冲突、恢复失败或结果未知时,应当怎么办。
“归档后添加 Undo”留下了一个重要问题:Undo 是恢复整个旧条目,还是仅逆转它的归档状态?如果有人在归档后编辑了标签,恢复旧快照就可能抹去这项有用的修改。
本文通过一个无害的虚构列表条目展开说明。所有状态、事件名称、消息和预期结果都是原创教学材料,描述的是拟议行为,不是采集的软件输出、客户事件或已实现的产品功能。
从条目和操作开始
这个虚构应用有活动条目视图和已归档视图。归档会将条目移出活动视图,但不会删除它。人们仍然可以在已归档视图中编辑该条目的标签。
示例条目为 N17,标题为 Outline welcome note,初始标签为 Draft。归档操作改变其归档状态,不改变标题或标签。
在任何人请求 Undo 之前,共同历史如下:
| 修订 | 事件 | 已归档? | 标签 | 当前归档操作 | 可见结果 |
|---|---|---|---|---|---|
| r0 | 初始状态 | 否 | Draft | 无 | N17 位于活动列表中 |
| r1 | A1:归档 N17 | 是 | Draft | A1 | N17 移到已归档条目中;Undo 指向 A1 |
| r2 | L1:在已归档视图中编辑其标签 | 是 | Ready | A1 | N17 仍被归档,现在显示 Ready |
修订与操作名称让示例更准确。它们描述设计必须考虑的历史,不是要求添加这些确切数据库字段,也不是要求采用某种存储架构。
请求的 Undo 针对 N17 上的 A1,不是“把每个字段恢复到 r0”,也不是“取消归档当前选中的任意条目”。
选择恢复边界
本示例选择针对特定字段的政策:逆转 A1 造成的归档状态,同时保留最新标签和标题。保持条目标识符不变,其他条目及列表现有排序政策也不变。
| 候选政策 | r2 之后的结果 | 本示例中的决定 |
|---|---|---|
| 恢复完整的 r0 条目快照 | 活动条目使用旧的 Draft 标签 | 拒绝:这会丢失 L1 的后续编辑 |
| 逆转指定的归档效果 | 活动条目 N17 保留最新的 Ready 标签 | 采用,前提是当前要逆转的归档操作仍为 A1 |
| 对当前条目提供通用 Unarchive 命令 | 针对条目现状作出一个新决定 | 与撤销 A1 分开处理 |
最后一行的区别很重要。一个人可以在查看条目现状后,再选择取消归档;那是一条新指令。旧 Undo 控件不应悄悄获得这个含义。
成功分支从 r2 继续:
| 修订 | 事件 | 已归档? | 标签 | 当前归档操作 | 必需的可见结果 |
|---|---|---|---|---|---|
| r2 | 恢复之前 | 是 | Ready | A1 | N17 已归档,标签为 Ready |
| r3-success | U1:确认 Undo A1 成功 | 否 | Ready | 无 | N17 返回活动列表,保留 Ready |
条目的完整预期值如下:
{
"id": "N17",
"title": "Outline welcome note",
"label": "Ready",
"archived": false
}
这段 JSON 是手写的验收示例,不是服务器响应。返回活动列表也不承诺回到先前的像素位置:应用应使用正常的当前排序顺序。
检查同一字段是否已由后续操作决定
保留一项无关的标签编辑,只解决了一半问题。后续操作可能已经改变了归档状态本身。
考虑下面从 r2 出发的另一条分支。它不是发生在上述成功分支之后:
| 修订 | 事件 | 已归档? | 标签 | 当前归档操作 | 必需的解释 |
|---|---|---|---|---|---|
| r2 | 共同起点 | 是 | Ready | A1 | 原归档操作仍为当前操作 |
| r3-conflict | R2:有人手动取消归档 N17 | 否 | Ready | 无 | 后续操作改变了归档归属 |
| r4-conflict | A2:有人再次归档 N17 | 是 | Ready | A2 | 新决定 A2 现在决定归档状态 |
| r4-conflict,不变 | 有人请求旧的 Undo A1 | 是 | Ready | A2 | 拒绝旧逆转;保留 A2 |
r2 和 r4-conflict 的可见归档标记相同,但这个值相同,并不代表历史等价。无条件把它改为 false,会覆盖后续决定 A2。
因此,所选政策要在应用恢复时,检查请求逆转的操作与当前归档操作之间的关系。如果 A1 已不再是适用操作,就保持条目不变,并解释冲突:
This item was archived again. Review its current state.
如果应用无法确认所需历史,任务说明就不应让 agent 根据当前布尔值猜测。要求它指出证据缺口,并提出保守拒绝方案,或另一项明确政策供审阅。
屏幕上出现 Undo 链接,不足以证明原操作仍可撤销。设计还必须考虑控件显示之后、恢复实际应用之前发生的变化。
为失败和不确定性定义不同结果
发出了恢复请求,不代表条目已经恢复。应定义请求进行中的界面状态,并区分已确认拒绝与没有收到结果。
下面是另外两条从 r2 出发的分支:
| 分支与事件 | 权威条目状态 | 必需反馈 | 下一步 |
|---|---|---|---|
| 已确认失败:在发生任何状态变化之前,恢复被明确拒绝 | 仍为 r2:已归档、Ready、A1 | “Could not restore. The item is still archived.” | 保持条目不变,让当事人查看失败情况 |
| 结果未知:没有收到恢复结果 | 未知;在这个独立示例中,可能仍为 r2,也可能已达到 r3-success | “Restore status unknown. Check the item before another action.” | 再次改变状态之前,先确认当前条目和目标操作的状态 |
等待时显示 Restoring…,并阻止从同一个控件再次提交相同的 Undo。不要仅因请求已发送,就宣布 Restored。
如果结果缺失,最后显示的已归档行只是最后一次已确认的视图,不能证明恢复失败。反过来,由乐观界面更新造成的行消失,也不是成功的权威确认。
本示例有意不定义重试协议。下一步是确认状态,不是盲目再发一次取消归档操作。如果产品无法确定状态,就继续保留未知,并提供清楚的条目查看方式,不要编造成功结果。
将取消、Undo 和部署回滚分开
这些操作回答不同的问题:
| 操作 | 它在本示例中回答的问题 | 它不能证明什么 |
|---|---|---|
| 取消请求 | 能否请求尚在进行的工作停止? | 已经生效的归档被逆转 |
| Undo A1 | 能否按所选现状规则,逆转这次特定归档的效果? | 所有后续编辑都应被丢弃 |
| 回滚软件部署 | 应运行哪个应用版本? | N17 的数据已经回到某个历史状态 |
MDN 将 AbortController 描述为向异步工作传达取消的一种方式,包括与 fetch 相关的操作。它没有定义列表条目的恢复政策。应将停止尚在进行的工作与逆转已生效操作,作为独立的应用需求。
同样,改变软件版本也不是条目已恢复的证据。任何预期的数据恢复,都需要自己的范围与验证。不应把部署流程当作这个列表中 Undo 按钮面向用户的含义。
复制这份准确的 agent 任务说明
在所选列表应用中,调查并规划针对一次归档操作的 Undo。
第一步交付计划和验收示例,不编辑文件,也不进行生产操作。
对象与目标:
条目 N17,标题为 "Outline welcome note"。
Undo 必须指向 N17 上的归档操作 A1,不是当前选择,也不是同一条目
上的任何后续归档操作。
共同历史:
r0: archived=false, label="Draft".
A1 -> r1: archived=true, label="Draft".
L1 -> r2: archived=true, label="Ready".
在本示例中,可以在已归档条目视图中编辑标签。
所选恢复政策:
仅在恢复实际应用时,A1 仍为适用归档操作的情况下,逆转 A1 的归档
效果。保留最新标题和标签、条目 ID、其他条目,以及列表现有排序政策。
不要恢复整个旧条目快照。
必需案例:
1. 从 r2 开始,确认 Undo A1 成功后,N17 为 archived=false, label="Ready"。
2. 从 r2 开始,后续手动取消归档,再执行归档 A2,意味着旧 Undo A1
不作任何改动。显示:
"This item was archived again. Review its current state."
3. 在状态变更前明确拒绝,保持 r2 不变。显示:
"Could not restore. The item is still archived."
4. 结果缺失时保持未知。显示:
"Restore status unknown. Check the item before another action."
再次改变状态之前,先确认条目和目标操作的状态。
进行中:
显示 "Restoring…",并阻止从同一个控件再次提交。
仅在收到针对该条目和操作的权威结果后,显示成功。
取消请求不算逆转,也不算成功。
首先检查当前归档操作、条目更新行为、历史/状态证据,以及反馈状态。
引用相关文件。解释设计如何保留后续无关编辑,并避免覆盖 A2,
包括恢复请求期间发生变化的情况。
如果无法确认所需历史或安全应用条件,报告该缺口,并提出保守行为
供审阅。不要仅凭 archived=true 就推断可撤销性。
返回范围明确的实现计划,以及针对四个案例的检查。
将预期结果与实际执行过的检查分开标明。
本次调查步骤不编辑文件、不增加基础设施、不调用生产服务、
不恢复真实条目、不公开发布,也不部署。
这份请求定义可观察结果,同时保留实现方式的选择空间。agent 可以先检查既有历史和更新机制,再提出如何落实条件。它不必为应用中的每项操作发明一套通用恢复系统。
在适用范围内使用错误预防指引
W3C 对 WCAG 2.2 成功准则 3.3.6 的解释,针对 AAA 级别,讨论可逆提交、检查输入,或在最终提交前审阅并纠正。这是针对该特定准则的解释性指引,没有规定本示例中的归档冲突政策,也不能证明整体符合 WCAG。
对于这个列表功能,实际决定仍然具体:识别被逆转的操作、保留后续独立工作、拒绝有冲突的旧逆转,并告诉当事人恢复是已确认、已拒绝还是未知。这些才是实现及其检查必须处理的需求。