fix(adr): template emitted invalid YAML frontmatter
The frontmatter exists to be machine-read. Two shapes this template
suggested do not parse, so any ADR that copied them dropped silently out of
every "what is still open?" query while looking correct:
supersedes: - a bare dash is a YAML sequence entry
deciders: pending: Mathias the unquoted second colon reads as a
nested mapping
Both were found live during an estate-wide ADR survey on 2026-09-05:
openbanking-api ADR-0001 (the one genuinely open decision in the estate --
invisible to the survey until fixed) and infra ADR-0019, each copied
verbatim from here.
Template corrected to `null` and a quoted `"pending: <name>"`, plus a short
section after the fence explaining why and giving a one-line yaml.safe_load
check to run before committing. The explanation is deliberately OUTSIDE the
fenced block so it is not copied into the ADR being written.
This commit is contained in:
+21
-2
@@ -58,8 +58,8 @@ adr: 0004
|
||||
title: <the decision, as a sentence — not "database choice">
|
||||
status: proposed | accepted | superseded | amended
|
||||
date: 2026-08-29
|
||||
deciders: <who accepted it, by name — or "pending: <name>" while proposed>
|
||||
supersedes: <adr number, or ->
|
||||
deciders: <who accepted it, by name — or "pending: <name>" (QUOTED) while proposed>
|
||||
supersedes: <adr number, or null>
|
||||
---
|
||||
|
||||
# ADR-0004 — <same title>
|
||||
@@ -97,6 +97,25 @@ the condition that fires a revisit. An ADR with no validation section is a prefe
|
||||
with a template around it.
|
||||
```
|
||||
|
||||
### The frontmatter must actually parse
|
||||
|
||||
It exists to be machine-read, so a block that does not load is worse than no block at
|
||||
all: it drops that ADR silently out of every "what is still open?" query, while looking
|
||||
correct. Two shapes this template used to suggest are invalid YAML, and both were found
|
||||
live in the estate on 2026-09-05 — `openbanking-api` ADR-0001 and `infra` ADR-0019, each
|
||||
copied verbatim from here:
|
||||
|
||||
| Wrong | Why | Right |
|
||||
|---|---|---|
|
||||
| `supersedes: -` | a bare dash is a YAML *sequence entry*, not a string | `supersedes: null` |
|
||||
| `deciders: pending: Mathias` | the second, unquoted colon reads as a nested mapping | `deciders: "pending: Mathias"` |
|
||||
|
||||
Check before committing:
|
||||
|
||||
```sh
|
||||
python3 -c "import yaml,sys;yaml.safe_load(open(sys.argv[1]).read().split('---')[1]);print('ok')" docs/adr/0004-*.md
|
||||
```
|
||||
|
||||
## Preserving a productive tension
|
||||
|
||||
Some tradeoffs are not unresolved because nobody thought hard enough. They are
|
||||
|
||||
Reference in New Issue
Block a user