The forge's announcer reads only repositories whose update time moved; a pull request opened after its push does not move it. Located in the forge module, with the fix (mesh-catalog) and how it is checked.
4.0 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | ||
|---|---|---|---|---|---|---|
| located | 2026-10-09 |
|
347. A pull request opened after its push is never checked, and nothing says so
Symptom
On 2026-10-09 a pull request on the SDK's repository (opened at 10:11 UTC, its branch pushed at 10:03) had no
mesh/merge-gate and no mesh/repo-check status twenty minutes later, while four pull requests opened in the
same minutes on other repositories were checked within three. mesh-delivery.checks answered "no status" for it,
and no condition, log line or status said why. The pull request could not merge, because its base requires both
statuses, and nothing in the mesh knew it existed.
The same day a call of the forge module's gitea_get_pull_request with a misnamed argument asked the forge for
pulls/NaN.
Why it is an issue
- Work is silently never checked. The forge's announcer is the only way the mesh learns of a pull request's head (to-be 45 §9). A pull request it misses waits for ever, with no status and no condition: failure is not loud, the worst kind.
- The cause, measured by the review of ADR 0272. Each pass of the announcer (
pollPulls, modules/gitea index.ts) reads only the repositories whose update time moved since its last pass, less a minute's margin (movedSince, issue 250). A push moves a repository's update time; opening, reopening or retargeting a pull request does not. So a pull request opened more than about a minute after its branch was pushed is in a repository the announcer skips, on every pass, until something else is pushed there. - A number that is not one reaches the forge. A tool's numeric argument read under the wrong name is
NaN, and the client asked the forge about it rather than refusing.
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 with a pull request number that is not one refuses and says why.
The fix
In the forge module (mesh-catalog, modules/gitea):
- 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).
- Every five minutes the forge itself is asked for every open pull request. One whose base requires
mesh/merge-gateand 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) 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. - 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,0and1.5are refused and the forge is never asked. All three fail on the commit before the fix.- Live, after delivery: the next pull request opened later than a minute after its push has its statuses within a
minute;
mesh-controller.conditionsshows none for it.