One gated in-file format for Agent Notes
Agent Note 的统一受门禁约束的文件内格式
Agent Note paths encoded lifecycle and class, but file contents still mixed headings, status formats, ADR and proposal templates, and proposal-era sections in implemented records. Authors copied whichever neighbor they found, and lifecycle moves could skip the required rewrite because no gate enforced an in-file contract.
English
Problem
Agent Note paths encoded lifecycle and class, but file contents still mixed headings, status formats, ADR and proposal templates, and proposal-era sections in implemented records. Authors copied whichever neighbor they found, and lifecycle moves could skip the required rewrite because no gate enforced an in-file contract.
Decision
README.md § The file format is the in-file contract — the header block (# Agent Note: <title> plus a dateless, folder-agreeing Status: enum whose only content is the rejection reason), the per-lifecycle body skeleton (Problem opener everywhere; Proposal/Acceptance criteria/Risks in proposed/; present-tense Decision/Consequences with proposal-era headings banned in implemented/; frozen proposal shape in rejected/), a mandatory Alternatives considered section, and the canonical section vocabulary between which bespoke technical sections stay free-form. pnpm run verify-agent-note-format (scripts/verify-agent-note-format.ts) enforces every mechanical clause as part of doc-sync, so a lifecycle move that skips its rewrite now fails CI instead of review memory.
The whole corpus was normalized in the same change that defined the format — the pre-release stance: no transition period, no dual-format tolerance. The one grandfather is content, not format: alternatives are recorded, never invented, so a pre-format Agent Note whose alternatives are not reconstructible from the record carries the exact agent-note-format: alternatives-not-recorded comment, which the gate accepts only for files dated before this Agent Note.
Alternatives considered
- A full rigid template (one fixed section sequence per lifecycle, every Agent Note restructured to fit) — rejected: the big design Agent Notes carry eight to fifteen bespoke technical sections (package topology, wire contracts, schemas) that are load-bearing content, not drift; a rigid sequence would force destructive rewrites now and template-fighting forever.
- Header-only normalization (H1 and Status, bodies untouched) — rejected: the debt markers flagged the body genre split, and leaving
Context/DecisionbesideProblem/Proposalindefinitely resolves nothing. - No Status line (the folder already is the status; the three newest pre-format Agent Notes (and the zh counterpart of one) omitted the line) — rejected in favor of keeping a self-describing file: the drift risk that motivated dropping it is neutralized by gating the line against the folder instead.
- Dated status (
Status: implemented (accepted YYYY-MM-DD)) — rejected: the acceptance date is narrated history the writing rules keep out of docs; the filename carries first-proposed, git carries the rest, and the gate could check a date's format but never its truth. - A bare
# <title>H1 — rejected: theAgent Note:prefix self-describes the genre when a file is read outside its tree, and the format gate prevents it from drifting. ## What we give upas the implemented closer (the README's own phrase for what an Agent Note records) — rejected: it names only costs, and an honest consequences section records what the trade-off bought as well.- Convention without a gate (write the contract down, enforce by review) — rejected: the slop checklist already outlawed spec-speak in
implemented/by convention, and nineteen files show what convention alone achieves here. - A standalone
FORMAT.mdcontract file — rejected because one entry point carrying layout, classification, and format is easier to discover and maintain than two contract files.
Consequences
Every Agent Note now costs slightly more structure, and the mandatory Alternatives considered section is deliberate friction: a decision recorded without what it beat invites the re-litigation Agent Notes exist to prevent. Pre-format Agent Notes whose alternatives were not reconstructible carry the grandfather comment permanently — an honest gap on the record rather than fabricated rationale. doc-sync gains one gate, and moving an Agent Note between lifecycle folders is now real work at move time (the body rewrite the move always owed) instead of deferred cleanup nothing tracked. The thirty-nine debt markers are gone, resolved by the template they were waiting for.
中文
问题
Agent Note 的路径编码了生命周期和类别,但文件内容仍混杂着不同标题、状态格式、ADR 与提案模板,以及已实现记录中的提案阶段章节。作者会复制随手找到的相邻文件,而生命周期迁移可能跳过必要的改写,因为没有门禁强制执行文件内约定。
决策
README.md § 文件格式是文件内约定——头部块(# Agent Note: <title>,加上无日期且与文件夹一致的 Status: 枚举,其中只有拒绝原因可作为额外内容)、各生命周期的正文骨架(所有文件均以 Problem 开篇;proposed/ 使用 Proposal/Acceptance criteria/Risks;implemented/ 使用现在时的 Decision/Consequences,并禁止提案阶段标题;rejected/ 冻结提案结构)、强制的 Alternatives considered 章节,以及规范章节词汇;定制技术章节可在这些规范章节之间保持自由形式。pnpm run verify-agent-note-format(scripts/verify-agent-note-format.ts)作为 doc-sync 的一部分强制执行每项机械规则,因此跳过改写的生命周期迁移现在会使 CI 失败,而不再依赖评审者记忆。
定义该格式的同一变更规范化了整个语料库——遵循预发布立场:不设过渡期,不容忍双格式。唯一适用既有内容豁免的是内容,而非格式:替代方案只能记录、不能杜撰,因此若某份格式制定前的 Agent Note 无法从记录中还原替代方案,就会带有内容完全匹配 agent-note-format: alternatives-not-recorded 的注释;门禁只对日期早于本文的文件接受该注释。
曾考虑的替代方案
- 完整的刚性模板(每个生命周期使用固定章节顺序,重构每份 Agent Note 以适配):否决。大型设计 Agent Note 包含八到十五个定制技术章节(包拓扑、协议约定、schema),它们是承载设计的内容,而非漂移;刚性顺序会迫使我们现在进行破坏性改写,并永远与模板较劲。
- 仅规范化头部(H1 和 Status,正文不动):否决。债务标记指出的是正文的体裁分裂,让
Context/Decision与Problem/Proposal无限期并存什么也解决不了。 - 不设 Status 行(文件夹已经表示状态;格式制定前最新的三份 Agent Note 及其中一份的中文对应文件省略了该行):否决,保留文件的自描述性。通过门禁校验该行与文件夹一致,消除了原本促使我们删除它的漂移风险。
- 带日期的 Status(
Status: implemented (accepted YYYY-MM-DD)):否决。接受日期属于叙述性历史,写作规则将其排除在文档之外;文件名承载首次提出日期,git 承载其余信息;门禁能检查日期格式,但永远无法检查其真实性。 - 裸
# <title>H1:否决。文件脱离目录树单独阅读时,Agent Note:前缀能自描述其体裁,而格式门禁可防止它漂移。 - 以
## What we give up作为已实现记录的结尾(README 对 Agent Note 所记录内容的原有表述):否决。它只点出成本,而诚实的后果章节也会记录取舍换来了什么。 - 只有惯例没有门禁(写下约定,靠评审强制执行):否决。slop checklist 已经通过惯例禁止在
implemented/中使用 spec 语气,而十九个文件展示了仅靠惯例在此处能达到什么效果。 - 独立的
FORMAT.md约定文件:否决。由一个入口同时承载布局、分类和格式,比维护两个约定文件更易发现和维护。
后果
现在每份 Agent Note 都需要稍多一些结构,而强制的 Alternatives considered 章节是有意设置的阻力:记录决策却不记录它胜过什么,会招致 Agent Note 本应防止的重新争论。无法还原替代方案的格式制定前 Agent Note 会永久保留既有内容豁免注释——这是记录中诚实的缺口,而不是杜撰的理由。doc-sync 增加一道门禁;在生命周期文件夹之间移动 Agent Note 时,现在必须当场完成真正的工作(迁移本就应包含的正文改写),而不是推迟为无人跟踪的清理任务。三十九个债务标记已经消失,由它们一直等待的模板解决。