# Agent Note: 每项实质性变更都必须附带 Agent Note

Status: implemented

[English](2026-07-19-require-agent-notes-for-non-trivial-changes.md) | 中文

## 问题

如果只在决策被认为持久、有争议且出人意料时才记录 Agent Note，实质性变更就可能在没有保存决策依据的情况下落地。代码和测试能展示改动内容，却无法稳定保留某种方案胜出的原因、被放弃的备选方案，以及维护者接受的成本。

## 决策

每项实质性变更都在同一个 PR（Pull Request）中新增或更新至少一份 Agent Note。实质性变更包括行为、架构、跨文件或跨包契约、流程或工具、测试策略、磁盘格式、协议格式（wire format）或配置格式，以及维护者可能合理重审的其他决策。

更新已经持有该决策的 Agent Note 即满足规则；仅当没有 Agent Note 持有该决策时才新增记录。完全机械或局部、且不改变行为、契约、结构、流程或决策依据的编辑可豁免。[Agent Notes README](../../README.md#when-to-write-one) 持有这条边界，根目录 `AGENTS.md` 则携带常驻指令。

只有在当前持有该决策的记录保存了所有独有的决策依据、备选方案、影响、验证契约和明确指出的覆盖缺口后，才可将被完全取代的 implemented Agent Note 合并到该记录中并删除。同一变更还要修复入站链接，并删除中文对侧文件和伴随记录。仅部分被取代时，两个记录仍需互相链接并保持与现状一致；合并既不将旧决策改写成与其相反的决策，也不让 git 历史成为决策依据的唯一副本。

后续决策完全移除较早的功能时，只有该功能已从生产代码、配置、schema、持久化格式或协议格式、迁移和兼容行为中消失，当前文档不再将其描述为可用，且没有测试把它作为受支持行为来执行，移除记录才会成为当前持有记录。移除决策的依据和验证该功能已不存在的测试可以保留。它必须保留该功能的最初动机、为什么该动机已不足以证明继续保留该功能、完全移除之外的备选方案、放弃的能力、重新引入的条件，以及证明已彻底移除的验证。只描述已删除行为的实现清单和测试已经过时，不属于当前验证契约。仅移除一种传输、默认值、实现或展示仍属于部分取代。

评审负责执行这条语义边界。自动化门禁不尝试把差异分类为平凡或实质性变更，因此这项政策不会增加门禁阶段或运行时间。

## 备选方案

**只为被判断为持久、有争议且出人意料的决策要求 Agent Note。** 这条门槛过于主观，实质性变更可能被视为显而易见或局部改动，从而丢失 Agent Note 本应保存的决策依据。

**每项变更都必须新增 Agent Note。** 当现有 Agent Note 已经持有该决策时，这会产生重复记录，也会让纯机械编辑承担空洞的流程负担。

**永久保留每份被完全取代的 Agent Note。** 只要旧决策仍有部分适用，就需要保留互相链接的记录；但完全失效的 implemented Agent Note 与记录当前状态的契约相矛盾，并重复保存本可由一个记录持有的决策依据。

**新增 `superseded/` 生命周期。** 新增生命周期仍会保留过时记录并扩张目录树、格式门禁和维护规则，却无法减少重复内容。

**将旧 Agent Note 改写为替代它的决策。** 这样会抹去决策边界及其否决的备选方案。合并做法是在删除过时文件前，先由当前持有决策的记录保存这些事实。

**保留已移除功能的每一项实现与测试细节。** 这会在替代记录中重建过时记录。移除决策的持有记录只保留理解或重新审视当前已移除状态所需的决策依据与验证，已删除机制仍可从 git 历史查看。

**添加 CI 差异分类门禁。** 机械检查无法可靠判断语义变更是否平凡，额外门禁还会增加运行时间，并引入误报或表面合规。

## 影响

- 每项实质性变更都会在实现旁保留其决策依据和被放弃的备选方案。
- 贡献者维护现有的决策持有记录，而不是创建重复记录。
- 被完全取代的记录可以归并到一个当前持有记录中，同时不丢失其独有的决策依据或验证契约。
- 后来被移除的功能可以只有一个当前持有记录，而无需继续保留过时的实现与测试清单。
- 仅部分被取代的情况仍需明确记录并互相链接；删除记录则必须在同一变更中清理链接和双语配对。
- 机械编辑仍保持轻量，门禁拓扑和运行时间也保持不变。
