Issue 349: a merge acted on late superseded the merge after it, and built the older commit
Plans of a branch superseded each other by when they were made; the catch-up's late plan of an older merge took over a newer one, once a security fix to the forge's module. Recorded with the fix in review.
This commit is contained in:
+3
@@ -173,3 +173,6 @@ registry, is the operator's decision.
|
||||
| live | after delivery: `dnsmasq_health` on both resolvers healthy; a restart by the watch said as `restarted` on the bus |
|
||||
|
||||
A replay in mesh-lab's register is still owed before this core issue resolves (ADR 0237).
|
||||
|
||||
The controller's own test of the resolver's manifest (`TestTheResolverForwardsToFixedUpstreamsAndNeverReadsResolvConf`)
|
||||
now asks for `bind-interfaces` and refuses `bind-dynamic`, so the two pull requests land together.
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
---
|
||||
status: located
|
||||
opened: 2026-10-09
|
||||
located-in: [mesh-controller cmd/mesh-controller (release_plan.go supersededBy, upgrades.go), mesh-controller internal/inventory (release_plan)]
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 349. A merge acted on late superseded the merge after it, and built the older commit
|
||||
|
||||
## Symptom
|
||||
|
||||
On 2026-10-09 the plans of the catalogue superseded each other out of the branch's order, twice
|
||||
(`mesh-controller.plans`):
|
||||
|
||||
- the plan at 1833045c was "superseded at tier 0 by" the plan at a783ac94, a merge made before it;
|
||||
- the plan at a082615b — the merge of a security fix to the forge's module — was "superseded at tier 0 by"
|
||||
the plan at 8ff8197a, the merge before it, with "gitea planned there again". The forge's module was then
|
||||
to be built from the commit without the fix. A third merge (9e4267bf) came a minute later and superseded
|
||||
that plan in turn, so the fix was built from 9e4267bf. Had nothing come after, it would not have been.
|
||||
|
||||
## Why it is an issue
|
||||
|
||||
A newer plan of a branch supersedes the older open ones and builds what they had not
|
||||
([ADR 0218](../../02-DECISIONS/0218-a-plan-sends-grants-before-code-rolls-out-one-machine-first-and-a-newer-merge-takes-over-an-older-plan.md),
|
||||
issue 254). "Newer" was read from when each plan was made, never from the commits. The catch-up acts on a
|
||||
merge the bus did not hand over (issue 266) after the merges that came after it, so its plan was made last
|
||||
and won. The mesh built an older commit than the branch held, and said nothing wrong: each plan said
|
||||
"superseded", as designed.
|
||||
|
||||
## Diagnosis
|
||||
|
||||
The order of merges into one branch is the forge's: each merge is made on the branch as the one before
|
||||
left it, so a later merge's commit contains every earlier one's, and the forge's merge time
|
||||
(`merged_at`, which every announcement carries) is the branch's order. A plan kept none of it.
|
||||
`supersededBy` compared `Created`.
|
||||
|
||||
## Fix
|
||||
|
||||
In mesh-controller, in the same pull request as issue 348 (PR 179):
|
||||
|
||||
- A plan keeps when its merge was made (`merged_at`, migration 0086; null for a release and for a plan kept
|
||||
before it).
|
||||
- `supersededBy` orders two plans of a branch by their merge times where both are known, and by when they
|
||||
were made only where one is not.
|
||||
- A merge older than an open plan of its branch is planned at that plan's commit, which contains it, and
|
||||
that plan is superseded by it as by any newer plan. What both merges moved is built once, from the newest
|
||||
commit of the branch.
|
||||
|
||||
## How it is checked
|
||||
|
||||
`TestTwoMergesActedOnInReverseOrderBuildTheNewerCommit` replays the day's case: the later merge acted on
|
||||
first, the earlier one second; one plan is left open, at the later commit, building what both moved.
|
||||
`TestTheBranchOrderIsTheMerges` holds the order and the lookup. Both fail on the commit before the fix.
|
||||
A replay in mesh-lab's register is still owed before this core issue resolves (ADR 0237).
|
||||
Reference in New Issue
Block a user