47 packages carried the marker and were never kept: about 2000 tests per level ran on every check, whatever it
changed. The marker now lists, as paths or globs from the repository's root (? before a path whose absence is read),
what the package's tests read outside it; the digest hashes those files with the package's own non-Go files. A marker
that lists nothing, names an unclean path, or a line that matches nothing keeps today's never-kept digest.
The 46 markers list their reads; checks/deps and checks/trunk lose theirs (their tests read only temporary
directories). Digest form 6.
Quick fix of issue 1936, chosen by the operator 2026-10-26 21:56; the thorough fix (the Go test log's files kept with
each verdict) stays on the issue.
mesh/check pass 24b244bc88dc on 27a7757b970e | carried from 6b6d5cba7195 | unit 2046 run, 2327 kept, 6 skipped | integration 2066 run, 2346 kept, 10 s…
car-hunter #2 was approved and its commit status then refused 403. Before the ask the
gate reads merge.writes for each repository it covers; where the merging account cannot
write, nothing is asked, the delivery waits on 'the forge account cannot write <repo>:
gitea_grant_write' and a condition is raised. gitea.repo.writable reads it again and
asks an approved, refused merge of it again.
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.
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.
mesh/check pass 32ad59fc6402 on 609013a2638f | unit 2010 run, 2322 kept, 5 skipped | integration 2032 run, 2341 kept, 9 skipped | over bound: unit, in…
The operator, 2026-10-25 22:56: "run the check locally only, but not as a gate, it loses us too much time". Tonight each
merge ask waited 3-7 minutes for mesh/check, and every merge into main refused the next approved merge for a check judged
on the trunk before (mesh-delivery#52). Both settings default to true, so nothing changes until the operator sets them.
False: the gate makes a reviewed pull request ready and asks its Approve with no verdict, a trunk's move puts nothing out
of date, a verdict is kept and shown, and a group still merges in one pass; the merge tool merges a head the Approve
names whatever its mesh/check says. delivery_status and show say the mode.
mesh-delivery#51 merged 21:43:11 and the gate read the open list at 21:43:14, before the forge's merged event: taken as
learnt late, it moved no trunk and its group's finish left it out of source.main, so the checker kept judging every
mesh-delivery head on 73be3df. A late merge within replayLate of its landing is now taken as heard as it happened, and
one a gate before this left is written at the catch-up of the start (never backwards).
mesh/check pass 0c216d99d0c0 on 9d9dfda19b7e | unit 2181 run, 2147 kept, 5 skipped | integration 2203 run, 2166 kept, 9 skipped | over bound: unit, in…
A pull request found merged only by its absence from the open list went through PullMerged, which moved every
other open delivery of its repository back to an old trunk (ready ones to proposed, composed checks out of
date), dated the merge now, and so let a later catch-up write the old commit into source.main. pullMerged now
takes such a merge as late: its own delivery is merged and its group closed, no other trunk moves, its time is
the forge's or none, and LearntLate keeps it out of source.main in finish, settleForgeMerges and the catch-up.
The gitea tool gitea_commit_statuses now answers the pull request's merged_at, and the gate reads a gone pull
request by its number alone, so a deleted branch does not fail the read.
The conditions the gate now says would otherwise be wrong three ways:
- A pull request closed or merged on the forge with no event heard stayed ready here for days (de-spiegel #4,
closed 2026-10-17) and would raise a condition. After a complete read of the open list (shorter than the
forge tool's 1000), each delivery not final whose pull request is missing is read from the forge and taken as
its close or merge; a merge learnt so does not move source.main, as it is undated and could move it back.
- A line that comes due on the clock (a state's bound, the author's bound, an answered refusal, an
out-of-date refusal turning urgent after 10 minutes) waited for an unrelated event. The gate now asks a look
at the earliest such time.
- After a restart the heads waiting on the forge start their bound again, so their conditions were cleared and
raised again later. A condition is cleared only once the open list was read since start, and not while the
forge still shows its head open and waiting.
Also: an empty path list ranks with a truncated one in the merge order, and a seat that keeps refusing
conditions is retried on the clock 10 looks in a row, then at events only, said once in the log.
Met again 2026-10-25: group fix/puller-wakes-on-capacity was merged half. Three causes in the gate:
- The next member's turn compared the group's state with "delivering", a word GroupState no longer says
since release 6 renamed it "merging" (ready.go groupTurnToMerge). Once the first member's merge was heard
from the forge the group read merging, and the second member waited for ever. Group states are now named
constants, the turn goes on in ready and merging (groupMayMerge), and a test holds every word to it.
- Members merged in id order, so mesh-catalog went before the mesh-sdk commit it pins. membersOf now orders
by mergeRank: mesh-sdk first, then members that change no go.mod or go.sum, then those that do.
- No condition was raised: the controller's self-check that read `stalled` went with release 6
(mesh-controller dc456d56). The gate now says its stalled lines as conditions itself on the
operator-channel seat (ADR 0437 §9) after every look, clears those listed no more, and keeps which it
raised in its new bucket conditions. A held group's line says "half merged" when a member merged.
A pass held for a required status no longer retries on a timer: the status turning success is the event
that asks the merge again.
Release 6 deletes the plans: the walk half of the holder, the controller port, the carry-over of the former module and the verbs times, what-if, release, stop and retire-history go; the table holds proposed, ready, rejected, merged, held and closed; the delivery's status and view name the source revision the merge moved.
mesh/check pass 40da368ee34e on ee216e4e63f1 | unit 246 run, 4189 kept | integration 228 run, 4249 kept | over bound: unit, integration (slowest unit …
The checker takes a repository's trunk head only from the gate's source.main. On 2026-10-24 gitea's
restarted poll announced mesh-catalog #471's merge while the gate was starting and could not yet tell
whether it held the seat; the gate acknowledged the event unread. It then adopted the controller's walk
of the merge commit, which carries no merge time, so every older merge of the repository looked newer
and source.main was never moved: #472 was checked on the trunk before #471 and its merge refused.
- An event heard before the gate can tell whether it holds the seat is offered again, not taken.
- An adopted merge is dated by its walk's creation, so it settles into source.main as a forge merge does.
- Each time the gate comes to hold the seat it weighs the newest merge of each repository against
source.main once more, so a merge marked there and never written (as #471) is written; never backwards.
mesh/delivery covered after its failure: a later walk that contains it was delivered: plan-1792777718506798022 (novox/mesh-catalog at e8300455 into main,…
A merge the gate handed is known by the bridge's word before the forge's, and finish wrote it already; an older forge-only
merge heard in between overwrote it, since only the forge's word was dated and the write never compared with the head held.
A merge is now dated by either word, and the write leaves a head that is a later merge, or one the gate cannot date while
the merge is older than the records it keeps (a pruned newer merge).
The checker reads the trunk only from the gate's source.main, and the gate moved it only in finish, for a merge it handed to
the forge bridge on an Approve. A pull request merged at the forge directly moved every other delivery's trunk (trunkMoved)
and left source.main behind, so the checker kept judging candidates on the trunk before it (catalogue 89e15c7b after
6c0024e4, 2026-10-23).
settleForgeMerges now writes such a merge into source.main by compare-and-set, never a merge replayed as history or older
than one of its repository already heard; an approved delivery merged at the forge before the gate handed it is moved by
finish with its group, once.