Files
hq/02-DECISIONS/0023-approval-is-the-checkpoint.md
T
jschoubben b4607dfc03 Numbers are identity; the reading order is a generated, checked index
Decided after measuring what renumbering actually costs: 96 references in code
comments across two repositories, none of which would have failed to compile.
They would have pointed at the wrong reasoning, which is worse than a broken
link because nothing reports it.

So a number identifies a record and never changes. It cannot also be a
position -- a position moves when the set changes, and an identity that moves
is not one.

The reading order moves into an index generated from each record's `topic:`.
Six topics, in the order somebody learns the system.

The index is WRITTEN rather than only generated on demand, which reverses what
this repository previously said. The reason it said otherwise is that a
hand-written index drifts -- but a reader looking at the folder on a forge sees
the folder, not a command, and the drift objection is answered by checking
rather than by refusing to write one. That is §5's own rule: a rule states how
it is checked.

Two checks, both confirmed to bite. index.py fails when the written order no
longer matches the records. records.py fails when a record has no topic or one
nobody defined -- the quiet failure being a record that vanishes from the order
rather than appearing in the wrong place.
2026-08-28 23:39:18 +02:00

79 lines
3.7 KiB
Markdown

---
topic: how we work
status: accepted
date: 2026-08-26
deciders: jochen
reconstructed: false
---
# 23. The approval is the checkpoint, not the second pair of hands
## Context
[§2](../00-META/how-we-build.md) reads *"one change per pull request, and never merge your
own"*, and gives the reason: *"self-merging removes the checkpoint that is the entire point."*
The rule was written for people. Applied literally to an agent it produces a contradiction
that surfaced immediately: an agent asked to merge cannot merge, because it authored what it
is being asked to merge. Every merge this repository has seen was therefore either performed
by the thing that wrote it, or not performed at all.
Stated by the operator: *"you are allowed to self-merge, after I've given you explicit
approval."*
## Considered options
1. **Read it literally.** An agent never merges; the operator merges by hand every time.
Rejected: it makes the operator a mechanical step rather than a reviewer, and a step
performed dozens of times without reading is not a checkpoint — it is the *shape* of one,
which is worse, because the record then claims a review that did not happen.
2. **Drop the rule for agents.** Rejected: the rule is right, and the failure it prevents —
work merged with nobody having looked — is not one an agent is less prone to.
3. **Require notification and approval, and stop there.** Chosen. Who performs the merge is
not the thing worth constraining.
## Decision
**Every merge into the main branch is notified and approved.** Stated by the operator in
exactly those terms, and the whole of the rule.
Notified: the merge is proposed and said out loud, not performed and mentioned. Approved: a
person says yes to *that merge*. Who then performs it does not matter, which is what makes an
agent merging its own work unremarkable — the checkpoint already happened.
**What approval is not**, because this is the half that can rot:
- A standing permission granted once and cited forever.
- An instruction to do the work, read as approval to merge it.
- Silence.
- The author's own judgement that the work is ready.
## Consequences
- **The record must show which it was.** A merge performed on approval and a merge performed
unilaterally look identical afterwards, and the difference is the whole rule. Until the forge
can record an approval, the merge commit says so — which is weaker than a recorded review and
is stated here rather than left to be discovered.
- **Branch protection would make this structural instead of textual.** Required approvals turn
the rule into something the forge enforces. It cannot be set through the API on the forge
version in use, so this remains a rule held by intention — the condition
[§5](../00-META/how-we-build.md) exists to name.
- **The one-change-per-pull-request half is untouched**, and was broken twice on 2026-08-26.
Both breaches are recorded in the pull requests themselves rather than in a conversation.
- **This narrows a rule rather than relaxing one.** The obligation moves from *who performs the
merge* to *whether a person decided*, which is a higher bar in the case the original wording
actually permits: a reviewer who merges someone else's work without reading it satisfies the
old rule and fails this one.
## Sync
Run and verified 2026-08-26. §2 in the enforced page now reads *never merge unapproved work*,
confirmed by reading the rule back out of the live page rather than by trusting the publish —
the previous sync reported success and changed nothing.
## References
- [`how-we-build.md`](../00-META/how-we-build.md) §2 — the rule, now carrying this.
- [ADR 0010](0010-delivery.md) — the standard a checkpoint is held to: a
step that reports success without doing anything is the fault, not the shortcut.