Every remaining cluster merged. Each was one design that had been split across
several records because it was worked out over days rather than at once.
the node host 8 -> 1 applies not decides, depends on nothing,
per operating system, root service, the
launcher, episodic, what a declaration is,
actions from the bundle only
a node and how it joins 4 -> 1 what a node is, joining, the link as
security boundary, the enrolment token
modules and the graph 7 -> 1 everything is a module, no domain modules,
three edges, provisioning, the core library
substrate and control 6 -> 1 the test, seven contexts, one control plane,
plane the authority is not a database, the named
products, the pinned bundle
connectivity 3 -> 1 a route is a grant, reachability declared,
filter rules
delivery 5 -> 1 reconciliation not a pipeline, artifacts,
the three silos, a failed step, the verdict
the lab 5 -> 1 (earlier)
how this repository 10 -> 1 (earlier)
works
Nothing was dropped. Each consolidated record carries the reasoning of the ones
it absorbs -- the measurements, the incidents, the alternatives rejected --
because that reasoning is the only reason to keep a record at all. What is gone
is the fragmentation: eight files to read to understand tier 0, when tier 0 is
one component.
The four superseded records went too. They existed to point at their
successors, and the successors now contain what they said.
The checker made this safe. Each merge left dangling links -- 38 files after
the host merge alone -- and it named every one. Nothing was found by reading,
and a manual pass would certainly have missed some, including references inside
AGENTS.md which every session loads.
78 lines
3.7 KiB
Markdown
78 lines
3.7 KiB
Markdown
---
|
|
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. **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 0058](0058-delivery.md) — the standard a checkpoint is held to: a
|
|
step that reports success without doing anything is the fault, not the shortcut.
|