Issue 1275 (reopened: today an approved group merged 2 of 3 members: mesh-sdk #92 and mesh-controller #472 merged, mesh-delivery #73 got the forge's 405 "try again later", and another group's #72 merged into mesh-delivery in between, so #73 conflicted). This is a gate fix in mesh-catalog (not mesh-controller), under ADR 0551.
modules/mesh-delivery-gate: before handing any member the gate proves every member: its required statuses, its head still the approved one, and the forge's mergeable flag. A member that does not merge now means nothing is merged; it is asked again every 5 s for 2 minutes, then the group is held and said urgent ("in conflict with it, a work in progress, or still being worked out after main moved"). A moved head holds the group at once.
New rule passWaits: an approved merge waits while another approved group's pass into a repository it shares is under way (with check-gates-merge on or off; it never waits for a check). A half-merged pass stays under way while refused or held, until it is whole, its remaining members are closed or held over, or asked again under a new head — so no group lands between its members.
New tool delivery_merge_again {id, why}: asks again the merge of a refused or held approved group at its approved heads, reading every member first; refused while another pass it waits for is under way (named).
modules/gitea: mergePullRequest asks again after the 405 at 1, 2 and 4 s; carries pull.mergeable.
Tests: issue1275_whole_test.go (every member merges or none; no interleaving with gates true and false; a held half-merged group keeps its repositories and no two passes wait on each other) — fail on main; test/merge-retry.test.ts. Gate suite -race and vet clean. Try try-1793024586334678083 passed.
Notes for later (review): a member merged by hand outside the gate can still form a cycle (fix: wait only for an earlier-approved pass); "declined" in two comments means declined before any Approve; passes() could be computed once per look.
Reviewed-by: review-groupmerge@shanks at 82bd6f49ff
Issue 1275 (reopened: today an approved group merged 2 of 3 members: mesh-sdk #92 and mesh-controller #472 merged, mesh-delivery #73 got the forge's 405 "try again later", and another group's #72 merged into mesh-delivery in between, so #73 conflicted). This is a gate fix in mesh-catalog (not mesh-controller), under ADR 0551.
- modules/mesh-delivery-gate: before handing any member the gate proves every member: its required statuses, its head still the approved one, and the forge's mergeable flag. A member that does not merge now means nothing is merged; it is asked again every 5 s for 2 minutes, then the group is held and said urgent ("in conflict with it, a work in progress, or still being worked out after main moved"). A moved head holds the group at once.
- New rule passWaits: an approved merge waits while another approved group's pass into a repository it shares is under way (with check-gates-merge on or off; it never waits for a check). A half-merged pass stays under way while refused or held, until it is whole, its remaining members are closed or held over, or asked again under a new head — so no group lands between its members.
- New tool `delivery_merge_again {id, why}`: asks again the merge of a refused or held approved group at its approved heads, reading every member first; refused while another pass it waits for is under way (named).
- modules/gitea: mergePullRequest asks again after the 405 at 1, 2 and 4 s; carries pull.mergeable.
Tests: issue1275_whole_test.go (every member merges or none; no interleaving with gates true and false; a held half-merged group keeps its repositories and no two passes wait on each other) — fail on main; test/merge-retry.test.ts. Gate suite -race and vet clean. Try try-1793024586334678083 passed.
Notes for later (review): a member merged by hand outside the gate can still form a cycle (fix: wait only for an earlier-approved pass); "declined" in two comments means declined before any Approve; passes() could be computed once per look.
Reviewed-by: review-groupmerge@shanks at 82bd6f49ff9c6c135487c559080414b93c9370a5
On 2026-10-26 13:40 group fix/734-lost-ask merged two of its three members: the forge answered mesh-delivery#73's
merge 405 "Please try again later", and in the seconds between, group feat/890-placement merged mesh-delivery#72,
so #73 then conflicted.
- mesh-delivery-gate: before any member is handed, every member is read for its required statuses, its head still
the approved one, and the forge's own mergeable (in conflict, or still being worked out); the forge's "no" is asked
again every 5 s for 2 minutes, then the group is held and said urgent with nothing merged.
- mesh-delivery-gate: an approved merge waits while another approved merge's pass is under way into a repository it
goes into (handed until merged whole, or stopped), whether or not mesh/check gates merges (it waits for a merge,
never for a check: ADR 0551).
- mesh-delivery-gate: tool delivery_merge_again asks a refused or held merge again on the operator's word.
- gitea: the merge asks again after the forge's 405 "Please try again later" (1 s, 2 s, 4 s), and a pull request
carries the forge's mergeable, which gitea_commit_statuses answers.
A held half-merged group did not count as under way, so another group sharing a repository could start; asked
again with delivery_merge_again, each then waited on the other. Passes are now read from every approved,
undeclined Approve not merged whole (approvedMerges leaves out merged and refused members), and
delivery_merge_again is refused while passWaits names a pass, naming it. The forge's mergeable is also false
for a work in progress: said so.
Deliverynovox/mesh-catalog@82bd6f49ff9c — merged since 2026-10-26T14:47:37Z
Source — source.main moved to novox/mesh-catalog@8393e29621. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-10-26 14:45 (new) → proposed (announced): novox/mesh-catalog#501's head announced
2026-10-26 14:45 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
2026-10-26 14:47 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@82bd6f49ff9c` — **merged** since 2026-10-26T14:47:37Z
**Source** — source.main moved to novox/mesh-catalog@8393e2962193. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-10-26 14:45 (new) → proposed (announced): novox/mesh-catalog#501's head announced
- 2026-10-26 14:45 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
- 2026-10-26 14:47 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Issue 1275 (reopened: today an approved group merged 2 of 3 members: mesh-sdk #92 and mesh-controller #472 merged, mesh-delivery #73 got the forge's 405 "try again later", and another group's #72 merged into mesh-delivery in between, so #73 conflicted). This is a gate fix in mesh-catalog (not mesh-controller), under ADR 0551.
delivery_merge_again {id, why}: asks again the merge of a refused or held approved group at its approved heads, reading every member first; refused while another pass it waits for is under way (named).Tests: issue1275_whole_test.go (every member merges or none; no interleaving with gates true and false; a held half-merged group keeps its repositories and no two passes wait on each other) — fail on main; test/merge-retry.test.ts. Gate suite -race and vet clean. Try try-1793024586334678083 passed.
Notes for later (review): a member merged by hand outside the gate can still form a cycle (fix: wait only for an earlier-approved pass); "declined" in two comments means declined before any Approve; passes() could be computed once per look.
Reviewed-by: review-groupmerge@shanks at
82bd6f49ffDelivery
novox/mesh-catalog@82bd6f49ff9c— merged since 2026-10-26T14:47:37ZSource — source.main moved to novox/mesh-catalog@8393e29621. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.