The approval is the checkpoint, and what a declaration is #10
@@ -41,7 +41,7 @@ incident behind it is not written down, and the fix is to write it down, not to
|
||||
| **Never bypass the pipeline** | No manual database edit, no manual restart as a workaround. Fix the cause and deploy. A workaround that works is a workaround that is never removed, and the next person cannot tell the node from its declaration. |
|
||||
| **Never create a symlink** | A hand-made link caused production data loss through container volume resolution, and the judgement needed to make a safe exception is exactly the judgement unavailable at the moment it matters. **The mesh creates none at all** ([ADR 0018](../02-DECISIONS/0018-the-mesh-creates-no-symlinks.md), which supersedes [ADR 0011](../02-DECISIONS/0011-the-installer-owns-linking.md)). The links the installer still reconciles are a migration, not a permission. |
|
||||
| **Never push directly to the main branch** | Branch, push, review, merge. Every merge is a human checkpoint, without exception — **including in this repository**. A documentation repository is not a lower tier of care; a decision record lands the same way a service does. |
|
||||
| **One change per pull request, and never merge your own** | Unrelated improvements bundled together cannot be reviewed or reverted separately. Self-merging removes the checkpoint that is the entire point. |
|
||||
| **One change per pull request, and never merge unapproved work** | Unrelated improvements bundled together cannot be reviewed or reverted separately. And the checkpoint is **a person deciding, not a person clicking** — work may be merged by whoever wrote it once a human has explicitly approved *that merge*, and never on a standing permission, an instruction to do the work, silence, or the author's own judgement that it is ready. [ADR 0042](../02-DECISIONS/0042-approval-is-the-checkpoint.md) |
|
||||
| **Never open a pull request unprompted** | A permissions list saying it is allowed is not a request. |
|
||||
| **A failed step fails the job** | A sequence that continues past a failure does the next thing in the wrong place. Gate each step on the last. [ADR 0008](../02-DECISIONS/0008-a-failed-step-fails-the-job.md), and §5. |
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-26
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 42. 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. **Name what the checkpoint actually is.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
**The checkpoint is a person deciding, not a person clicking.**
|
||||
|
||||
An agent may merge its own work **when a human has explicitly approved that merge**. The
|
||||
approval is the review; the merge is bookkeeping that follows it.
|
||||
|
||||
Without an explicit approval, nothing changes: the agent does not merge, and
|
||||
[§2](../00-META/how-we-build.md)'s *never open a pull request unprompted* continues to mean
|
||||
that a permissions list is not a request.
|
||||
|
||||
**What "explicit" excludes**, 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 agent'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 0008](0008-a-failed-step-fails-the-job.md) — the standard a checkpoint is held to: a
|
||||
step that reports success without doing anything is the fault, not the shortcut.
|
||||
Reference in New Issue
Block a user