gate: find an approved merge by its ask, not by which member's run was seen first, so a group's turns are written before its first member is handed at every look (ADR 0548 §3; issue 568, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-catalog@565d0a848a85
mesh/delivery-group group feat/548-one-check merged: every member is merged
mesh/check checking e9279ce3c209 on 565d0a848a85 | novox/mesh-catalog#493 in group feat/548-one-check

This commit is contained in:
2026-10-26 12:32:46 +01:00
parent 99cc073e2a
commit e9279ce3c2
@@ -102,7 +102,13 @@ type approvedMerge struct {
func (h *Holder) approvedMerges() []approvedMerge { func (h *Holder) approvedMerges() []approvedMerge {
var out []approvedMerge var out []approvedMerge
seen := map[string]bool{} seen := map[string]bool{}
for _, d := range h.deliveries { ids := make([]string, 0, len(h.deliveries))
for id := range h.deliveries {
ids = append(ids, id)
}
sort.Strings(ids) // the same owner of an ask at every look, whichever member's run holds it
for _, id := range ids {
d := h.deliveries[id]
r := d.Ready r := d.Ready
if r == nil || r.Approved == nil || r.Declined != nil || r.AskID == "" || len(r.Heads) == 0 || seen[r.AskID] || if r == nil || r.Approved == nil || r.Declined != nil || r.AskID == "" || len(r.Heads) == 0 || seen[r.AskID] ||
d.State.Final() || d.State == Rejected || d.Base != MergeBranch || r.RefusedSince != nil || h.allMerged(r.Heads) { d.State.Final() || d.State == Rejected || d.Base != MergeBranch || r.RefusedSince != nil || h.allMerged(r.Heads) {
@@ -146,7 +152,8 @@ func (h *Holder) mergeOfDelivery(d *Delivery) (approvedMerge, bool) {
return approvedMerge{}, false return approvedMerge{}, false
} }
for _, am := range h.approvedMerges() { for _, am := range h.approvedMerges() {
if am.run == c { // By the ask, not the run: a group's members may each hold a run of the same ask, and the merge is the ask's.
if am.run.AskID == c.AskID {
return am, true return am, true
} }
} }