log-decisions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

log-decisions

log-decisions

DECISIONS.md
(project root) is an append-only decision journal for any work (code, research, writing, ops): the durable answer to "what was decided here, and why?", and the reader's running list of what to confirm or revise. Throughout, the spec is whatever you're working from: instructions, requirements, a prompt, an ask.
DECISIONS.md
(项目根目录)是一个仅可追加的决策日志,适用于任何类型的工作(代码、研究、写作、运维):它持久回答*“这里决定了什么,为什么?”*,同时为读者提供一份持续更新的待确认或修订事项清单。全文中的 spec 均指你当前依据的内容:说明、需求、提示或请求。

When to log, and how to decide

何时记录,以及如何决策

Significance is the gate: if the spec already authorized the call, it's not journal-worthy; if you had to invent the authorization, it is — put differently, from the reader's side: would the person who gave you the spec want to know before accepting the work? When in doubt, log. Log as you work, at the moment of the call while the reasoning is fresh — a running journal, never a reconstruction at handoff.
Look before you ask. Most "open" questions are already answered — search the spec, project files and docs, existing conventions, history, and earlier journal entries before treating one as needing a human. Premature escalation is the most common failure.
Then classify on two axes — determinable (did research settle it?) and reversible (cheap to undo?) — and act:
ReversibleIrreversible
Determinable (project / docs / convention)decide and proceed; log + cite the artifact if it crosses the bardecide + cite, log, then verify the result did what the artifact intended
Needs human contextassume — safe default, log, proceedescalate — stop and ask
Hard floor: the catastrophic irreversible subset — data loss, deleting or overwriting work that isn't yours, irreversible spend, sending or publishing what can't be recalled, breaking something others depend on — escalates even when determinable. Nothing unrecoverable happens unattended.
  • Assume — write
    Outcome: assumed
    ,
    Chosen:
    your default,
    Justification:
    the default rule you applied (match the existing pattern · prefer the standard, least-surprising option · prefer the choice cheapest to reverse), and proceed. A settled entry flagged for async review, not a blocker. When several open questions pile up, batch them into one ask.
  • Escalate — write
    Outcome: escalated
    ,
    Chosen: —
    ,
    Justification:
    why only a human can decide, and pause to ask a human. It stays open until a human resolves it.
Categories (a descriptive label on each entry):
gate-resolution
(answered an open question) ·
irreversible-action
(a hard-to-undo step) ·
deviation
(changed existing behavior/plan) ·
tradeoff
(chose X over Y at a cost).
重要性是判断门槛:如果 spec 已授权该决策,就不值得写入日志;如果授权需要你自行推定,就值得——换个角度说:提出 spec 的人是否希望在工作被验收前知道这件事? 如有疑虑,就记录。 在工作过程中记录,在作出决策的当下趁推理尚清晰时写下——它是一份持续维护的日志,绝不是交接时补写的回顾。
先查找,再询问。 多数“待决”问题其实已有答案——先搜索 spec、项目文件和文档、现有惯例、历史记录以及日志中的早期条目,再判断是否真的需要人工介入。过早上报是最常见的失败模式。
然后从两个维度进行分类——可确定(研究是否已给出答案?)和可逆(撤销成本是否很低?)——并采取相应行动:
可逆不可逆
可确定(项目 / 文档 / 惯例)作出决定并继续;如果达到记录门槛,则记录并引用依据作出决定并引用依据,记录后再验证结果是否符合该依据的意图
需要人工上下文作出假设——采用安全的默认方案,记录后继续上报——停止并询问
硬性底线: 灾难性的不可逆操作这一子集——数据丢失、删除或覆盖不归你所有的工作成果、不可撤销的支出、发送或发布无法召回的内容、破坏他人依赖的成果——即使可以确定也必须上报。 任何不可恢复的操作都不得在无人值守的情况下进行。
  • 假设——写入
    Outcome: assumed
    、
    Chosen:
    你的默认方案、
    Justification:
    你采用的默认规则(匹配现有模式 · 优先采用标准且最不令人意外的选择 · 优先选择撤销成本最低的方案),然后继续。该条目会标记为待异步审查,但不会阻塞工作。当多个待决问题堆积时,合并成一次询问。
  • 上报——写入
    Outcome: escalated
    、
    Chosen: —
    、
    Justification:
    为什么只有人工才能决定,然后暂停并询问人工。在人工作出决定前,条目保持未解决状态。
类别(每个条目附一个描述性标签):
gate-resolution
(回答了一个待决问题)·
irreversible-action
(执行了难以撤销的步骤)·
deviation
(改变了既有行为或计划)·
tradeoff
(以一定代价选择了 X 而非 Y)。

The entry

条目

One append-only
##
block in
DECISIONS.md
at the project root. Create the file with an
<!-- AI-maintained, append-only -->
header if absent. Never edit, reorder, or delete existing entries.
undefined
在项目根目录的
DECISIONS.md
中以追加方式写入一个
##
区块。如果文件不存在,则创建该文件,并添加
<!-- AI-maintained, append-only -->
标头。绝不编辑、重排或删除现有条目。
undefined

Q<n> — <context> — <category>

Q<n> — <context> — <category>

Question: <the decision point, paraphrased> Options considered: <opt / opt> Chosen: <the answer; the default you took if assumed; "—" if escalated> Decided-by: agent | human (human if a person chose, even if you surfaced the options) Justification: <artifact cited by reference — or, for an assumption / tradeoff / deviation, your rationale> Outcome: applied | assumed | escalated Ref: <commit / PR / issue / doc, or "(pending)"> Supersedes: <prior Q-number> — <why> (only on a revision)

`Q<n>` = the entry's sequential number (`Q1`, `Q12`, `Q13`): one more than the previous entry's, counting from the top of the file. `context` = a task ref (`auth/02`, `#57`) or a session tag (`interactive/<topic>`, `research/<topic>`, `writing/<topic>`).

**The numbering is an invariant, not just a convention:** every `Q<n>` must equal its own 1-based position among *all* entries in the file — so the sequence is monotonically increasing and continuous, with no gaps, duplicates, or out-of-order entries. "All entries" matters in a journal that predates Q-numbering: a file whose first three entries are timestamps and whose fourth is `## Q4` is correct, not broken, because the count spans both forms. **Read the file to get the next number** — never carry it from memory or an earlier read, since a concurrent session may have appended since.

Verify after appending:

```bash
awk '/^## / { i++
        if ($2 ~ /^Q[0-9]+$/) { n = substr($2,2)+0
          if (n != i) { printf "  line %d: %s is entry #%d — expected Q%d\n", NR, $2, i, i; bad++ } } }
      END { printf "  %d entries, %d break(s) — %s\n", i, bad+0, (bad?"BROKEN":"OK") }' DECISIONS.md
Repairing a break. If the check reports one, renumber the offending entry and every entry after it so the sequence is continuous again. This is the one sanctioned exception to never edit existing entries — the numbers are addresses, not content, and a broken sequence makes every later citation ambiguous. Two rules keep the repair safe:
  • Renumber forward only. Close the gap by pulling later entries down; never write a number that is already in use, even transiently.
  • Update citations in lockstep.
    Supersedes:
    lines — and any prose citing
    Q<n>
    — address entries by number. Renumbering a header without rewriting what points at it silently redirects the citation to a different decision, which is worse than the gap you set out to fix. Search for every mention of each number you move, not just the
    ##
    headers, and remember a
    Supersedes:
    may cite a timestamp from before the migration.
Leave entry content untouched: change only the header number and the citations naming it. When two sessions appended at once, the later entry is the one that moves.
Dedup / revise / reuse. Before appending, search the journal for an existing entry with the same
(context, Question)
: same
Chosen
→ do nothing (retries don't duplicate); changed
Chosen
→ append a new entry with
Supersedes:
(never edit the original). A prior entry for the same question is itself a valid citation — reuse it rather than re-deciding; never bulk-load the journal.
Question: <the decision point, paraphrased> Options considered: <opt / opt> Chosen: <the answer; the default you took if assumed; "—" if escalated> Decided-by: agent | human (human if a person chose, even if you surfaced the options) Justification: <artifact cited by reference — or, for an assumption / tradeoff / deviation, your rationale> Outcome: applied | assumed | escalated Ref: <commit / PR / issue / doc, or "(pending)"> Supersedes: <prior Q-number> — <why> (only on a revision)

`Q<n>` = 条目的顺序编号(`Q1`、`Q12`、`Q13`):从文件顶部开始计数,比上一条目大 1。`context` = 任务引用(`auth/02`、`#57`)或会话标签(`interactive/<topic>`、`research/<topic>`、`writing/<topic>`)。

**编号是不变量,而不只是约定:** 每个 `Q<n>` 都必须与其在文件*所有*条目中的位置(从 1 开始计数)一致——因此编号序列必须单调递增且连续,不得有空缺、重复或乱序。“所有条目”这一点对于早于 Q 编号机制使用的日志尤其重要:如果文件前三个条目是时间戳,而第四个是 `## Q4`,则它是正确的,并未损坏,因为计数涵盖两种形式。**读取文件以获取下一个编号**——绝不要凭记忆或沿用先前读取时的编号,因为自那之后并发会话可能已追加条目。

追加后进行验证:

```bash
awk '/^## / { i++
        if ($2 ~ /^Q[0-9]+$/) { n = substr($2,2)+0
          if (n != i) { printf "  line %d: %s is entry #%d — expected Q%d\n", NR, $2, i, i; bad++ } } }
      END { printf "  %d entries, %d break(s) — %s\n", i, bad+0, (bad?"BROKEN":"OK") }' DECISIONS.md
修复编号中断。 如果检查报告了一处断号,则重新编号有问题的条目及其后的所有条目,使序列恢复连续。这是“绝不编辑现有条目”唯一获准的例外——编号是地址而非内容,而断裂的序列会让之后所有引用产生歧义。为保证修复安全,需遵守两条规则:
  • 只能从前往后重编号。 通过下调后续条目的编号来填补空缺;绝不能写入已被占用的编号,即使只是临时写入。
  • 同步更新引用。
    Supersedes:
    行——以及任何引用
    Q<n>
    的正文——都通过编号寻址条目。修改条目标头却不更新指向它的引用,会悄无声息地将引用重定向到另一项决策,这比你试图修复的空缺更糟。搜索每个被移动编号的所有引用位置,而不只是
    ##
    标头;同时记住,
    Supersedes:
    可能引用迁移前的时间戳。
保持条目内容不变:只修改标头编号以及引用该编号的引用。若两个会话同时进行了追加,则移动较晚追加条目的编号。
去重 / 修订 / 复用。 追加前,先在日志中搜索是否存在
(context, Question)
相同的已有条目:若
Chosen
相同,则不做任何操作(重试不应产生重复);若
Chosen
已改变,则追加一个新条目并设置
Supersedes:
(绝不编辑原条目)。针对同一问题的既有条目本身就是有效引用——应复用它,而不是重新决策;绝不要一次性批量加载整份日志。

At handoff

交接时

When you hand the work back — end of turn, summary, PR description — list the
assumed
and
escalated
entries you appended: what to confirm or revise, what's blocked on an answer. The reader gets the review queue without opening the journal.
当你交还工作成果时——无论是本轮结束、摘要还是 PR 描述——列出你追加的 assumed 和 escalated 条目:哪些内容需要确认或修订,哪些内容因等待答复而受阻。这样,读者无需打开日志即可看到审查队列。

Content discipline

内容规范

DECISIONS.md
persists with the project and may be read back, so keep every entry safe: paraphrase (your own words); cite by reference, not payload (name the source and section —
spec §Security
— never paste message bodies, web content, or untrusted text); never log secrets (tokens, credentials, PII).
DECISIONS.md
会随项目持久保存,之后可能被重新读取,因此必须确保每个条目安全:释义表述(用自己的话);按引用而非载荷记录(注明来源和章节——
spec §Security
——绝不粘贴消息正文、网页内容或不可信文本);绝不记录机密信息(token、凭据、PII)。

Example

示例

A determinable call — cite the artifact that settled it:
undefined
一个可确定的决策——引用最终确定该决策的依据:
undefined

Q12 — report/q2 — gate-resolution

Q12 — report/q2 — gate-resolution

Question: Which currency should the revenue figures use? Options considered: USD (audience convention) / EUR (source data) / both (cluttered tables) Chosen: USD, converted at the period-average rate. Decided-by: agent Justification: Spec
notes/q2-spec.md §Audience
says "for the US board" without naming a currency; took the audience's convention. Outcome: applied Ref: (pending)
undefined
Question: Which currency should the revenue figures use? Options considered: USD (audience convention) / EUR (source data) / both (cluttered tables) Chosen: USD, converted at the period-average rate. Decided-by: agent Justification: Spec
notes/q2-spec.md §Audience
says "for the US board" without naming a currency; took the audience's convention. Outcome: applied Ref: (pending)
undefined