spec 1.0 · 规范性
决策
决策记录是上下文层中带日期的“为什么”:架构决策、厂商选型、范围边界,以及有意作出的“不做决定”。它们可以避免同一问题被反复讨论,也让智能体获得决策背后的推理,而不只是规则本身。
决策记录是记录的正式子类型(见 content-categories.md 的“意图与记录”):它们本质上就是记录,并拥有普通记录所没有的统一 schema 与生命周期。它们生成的索引条目携带 kind: record;决策记录自身不声明 kind 键(其 schema 是封闭的,显式写 kind 会导致校验失败)。
要求#
- 决策记录是带 YAML frontmatter 的 markdown,frontmatter 对
decision-record.schema.json有效,一份记录一个文件。决策语料由清单声明的两个收录来源取并集得到,上下文层可以使用其中之一或两者:所声明的记录路径(machine.decisionRecordsPath,默认<root>/decisions/),以及decisions类别的索引文件所解析出的条目。一份记录必须至少能通过其中一条途径到达。 - frontmatter 必须携带:
id(稳定)、title、status与date。status取proposed、accepted、superseded、deprecated、rejected之一。 - 正文必须用散文写明:背景(是什么局面迫使做出决策)、决策本身,以及它的后果。推荐的章节标题是
## Context、## Decision、## Consequences;记录可以再加一节## Alternatives。 - 记录是仅可追加的历史:不得把一份记录改写成另一个决策。随着决策变老,frontmatter 中有两个字段是可变的:
status(它的生命周期)与supersededBy(在它被取代时设置);其余一切,id、原始的title与date、所声明的作用域,以及散文正文,一经发布即不可变。翻案或变更是一份新记录,其 frontmatter 设置supersedes,而旧记录的status变为superseded并设置supersededBy。取代关系的链接必须在两个方向上保持一致:当记录 B 设置supersedes: A时,记录 A 携带status: superseded与supersededBy: B,而superseded的记录必须在supersededBy中指名它的后继者。两份记录都保留。参考工具目前会强制执行取代关系的双向一致性。它尚未验证不可变性本身(即已发布记录被冻结的字段与正文相对某个基线版本未被改动);那是路线图上的一项报告式检查,尚未成为阻断性关卡。在它发布之前,不可变性靠流程担保的评审纪律来保障(见 conformance.md)。 - 记录可以声明
affectedPaths与affectedCategories,使工具能够从一项任务的作用域路由到治理它的那些决策。任务作用域如何选中记录(考虑重叠的路径包含、狭义的类别匹配、accepted/deprecated的约束力,以及对两者都不声明的记录按组织级处理),见 machine-readable-surface.md 中的“任务路由”算法。 - 被否决的提案同样属于记录(
status: rejected)。将未被采纳的决策记录下来,是成本最低的防止重复讨论的方式。
与 ADR 的兼容(非规范性)#
Leji 的决策记录刻意与架构决策记录(ADR)兼容:既有的 ADR 目录只需为每份记录(或此后的新记录)添加那些 frontmatter 字段,并在清单中映射该目录,即可满足 decisions。不需要任何 ADR 工具,也不排斥任何 ADR 工具。