Issue 347: a base requiring only mesh/repo-check counts, and the delivery's owner says it
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered

The confirmation review: hq requires only mesh/repo-check, so a watcher
that looked for mesh/merge-gate alone would never have said this
repository's own unchecked pull request. And the delivery domain's own
condition, a delivery held past its bound, says it rather than a provider
standing.
This commit is contained in:
jochen
2026-10-09 13:16:27 +02:00
parent 2ba0d68306
commit fc449617be
@@ -1,7 +1,7 @@
---
status: located
opened: 2026-10-09
located-in: [mesh-catalog (modules/gitea, the announcer in index.ts and the client)]
located-in: [mesh-catalog (modules/gitea, the announcer in index.ts and the client; modules/mesh-delivery, saying it), mesh-controller (its words)]
fixed-by:
amended-design:
---
@@ -35,7 +35,8 @@ The same day a call of the forge module's `gitea_get_pull_request` with a misnam
## Acceptance test (the operator's view)
A pull request I open on a protected branch, whenever I open it after pushing its branch, has a merge check within a
minute. If one ever has none for ten minutes, the mesh tells me which pull request, as a condition. A tool asked
minute. If one ever has none for ten minutes — on a branch that requires `mesh/merge-gate` or only `mesh/repo-check` —
the mesh tells me which pull request, as a condition. A tool asked
with a pull request number that is not one refuses and says why.
## The fix
@@ -45,21 +46,28 @@ In the forge module (mesh-catalog, `modules/gitea`):
1. Each pass also looks at every repository holding a pull request updated since the floor, found by the forge's
own search of open pull requests by their own update time; and every ten minutes, or when the search fails, it
looks at every repository (a sweep).
2. Every five minutes the forge itself is asked for every open pull request. One whose base requires
`mesh/merge-gate` and whose head has had no such status for ten minutes is said as the forge failing *the
merge check of that pull request*, a provider standing ([ADR 0224](../../02-DECISIONS/0224-a-provider-that-keeps-failing-a-consumer-is-a-problem-the-controller-reports.md))
the controller keeps as a condition and says to the operator. It is said again every pass while it lasts and
recovered when a check arrives or the pull request closes. The watcher asks the forge, not the announcer's
record, so a fault in the announcer cannot hide itself.
2. Every five minutes the delivery's owner (`mesh-delivery`) asks the forge itself for every open pull request
(`gitea_open_pulls`), never what the announcer remembers. A head on a base that requires the merge check —
`mesh/merge-gate` **or `mesh/repo-check`**, since this repository requires only the second — with neither on it
for ten minutes since the owner first saw it so (its own time: the forge's update time moves on every comment)
is a delivery held past its bound: a `stalled` line in state `unannounced`, which the controller raises as
`delivery.<id>.stalled` like any other, with words that say to push a new commit. The delivery domain's own
word, chosen over a provider standing and over a health check of the forge: that check would need a `tools`
list (turning the forge's tools into seat verbs) and a check of another kind beside it, and would hold the
forge's own deliveries at the first-node gate.
3. The client refuses a pull request or issue number that is not a whole number above zero before it asks.
## How it is checked
- `test/announcing.test.ts` (modules/gitea): a pull request opened two minutes after its push, with the last pass
thirty seconds after that, is in a repository the pass looks at; without its own update time nothing is looked at
(the fault, held as a case); a sweep and the first pass look at every repository. An open pull request on a
protected base with no merge check for ten minutes is said; one with a check, on a base that requires none, or
five minutes old is not. `pulls/NaN`, `0` and `1.5` are refused and the forge is never asked. All three fail on
the commit before the fix.
(the fault, held as a case); a sweep and the first pass look at every repository. Every open pull request is read
with its base's required statuses and its head's. `pulls/NaN`, `0` and `1.5` are refused and the forge is never
asked. Each fails on the commit before the fix.
- `unchecked_test.go` (modules/mesh-delivery): a head on a base requiring only `mesh/repo-check`, with no check,
is a stalled `unannounced` line after ten minutes, counted from when the owner first saw it; one with a check,
on a base requiring none, announced, closed, or behind a forge that cannot be asked is not said or not changed.
- `TestAnUnannouncedPullRequestSaysToPushANewCommit` (mesh-controller): the condition's words say to push a new
commit, never to stop or release a delivery that does not exist.
- Live, after delivery: the next pull request opened later than a minute after its push has its statuses within a
minute; `mesh-controller.conditions` shows none for it.