Phase 5 (2/4): judge every pull request against the mesh that runs, before it merges (hq ADR 0237) #96

Merged
mesh-admin merged 1 commits from feat/merge-gate into main 2026-10-06 19:19:35 +00:00
Contributor

hq to-be 45 §9 / ADR 0237 decisions 2-4. Stacked on #95 (its first commit is #95's); merge #95 first.

merge-gate: raises the mesh as the facts snapshot says it is, and the mesh with the change's manifests, each in a throwaway PostgreSQL through the controller's own records; composes every machine twice (first as a push, making credentials) and runs the node-engine's validator; fails what the change breaks, naming the machine's roles and the module. Also fails: a manifest the judging controller cannot read (version skew), a consumer left out of a grant / a credential left bound elsewhere, a module removed while a machine runs it, two definitions of one module, a stored setting the change cannot keep, a new module the node-engine would refuse (tried on the first machine that could run it). Warns when a merge would rebuild >12 modules, saying when shared code is why (278; module dirs read from the tree as the announcer reads them).

Tests replay the incidents through the gate: 236 (the very refusal text), 263, version skew, removal, 278 width.

The check on the build seat: the controller follows gitea pull.updated, asks the build seat a check (head + beside: running controller, its main, catalogue, host, lab). The builder reads facts, raises store+bus at the versions the mesh runs, builds the judge (running controller, falls back to main while the running one predates the gate), runs the repo's merge-check.sh in the mesh's Go toolchain without the docker socket, then mesh-lab's replays (reviewed main) with it. Verdict pass/warning/fail/error (never pass on error), said as checked. Nothing recorded or registered.

Grants: controller publishes mesh.seat.mesh-controller.event.checked, subscribes mesh.mod.gitea.event.pull.updated — mirrored in mesh-host's genesis lock (mesh-host PR, merge together). Writers table: two rows (to-be 45 §1 amended in hq).

merge-check.sh added (fmt, vet, the gate by this change's controller, the suite).

Verified: full suite green (-p 1, postgres+nats+docker+registry); race on the new code; the builder's check tests against a real runtime and registry (script beside the mesh's versions, nothing left, failing script fails, timeout is an error, no facts is an error); an end-to-end check of the catalogue and of this repository through builder.Check with real clones; the suite inside the Go toolchain image (25/25 packages).

Found by the gate: mesh-controller's own module.json fails module check (seat verbs not listed in tools, ADR 0132) — pre-existing, so on the real snapshot it is a note, not a failure.

hq to-be 45 §9 / ADR 0237 decisions 2-4. **Stacked on #95** (its first commit is #95's); merge #95 first. **`merge-gate`**: raises the mesh as the facts snapshot says it is, and the mesh with the change's manifests, each in a throwaway PostgreSQL through the controller's own records; composes every machine twice (first as a push, making credentials) and runs the node-engine's validator; fails what the change breaks, naming the machine's roles and the module. Also fails: a manifest the judging controller cannot read (version skew), a consumer left out of a grant / a credential left bound elsewhere, a module removed while a machine runs it, two definitions of one module, a stored setting the change cannot keep, a *new* module the node-engine would refuse (tried on the first machine that could run it). Warns when a merge would rebuild >12 modules, saying when shared code is why (278; module dirs read from the tree as the announcer reads them). Tests replay the incidents through the gate: 236 (the very refusal text), 263, version skew, removal, 278 width. **The check on the build seat**: the controller follows `gitea pull.updated`, asks the build seat a `check` (head + beside: running controller, its main, catalogue, host, lab). The builder reads facts, raises store+bus at the versions the mesh runs, builds the judge (running controller, falls back to main while the running one predates the gate), runs the repo's `merge-check.sh` in the mesh's Go toolchain **without the docker socket**, then mesh-lab's replays (reviewed main) with it. Verdict pass/warning/fail/error (never pass on error), said as `checked`. Nothing recorded or registered. Grants: controller publishes `mesh.seat.mesh-controller.event.checked`, subscribes `mesh.mod.gitea.event.pull.updated` — **mirrored in mesh-host's genesis lock (mesh-host PR, merge together)**. Writers table: two rows (to-be 45 §1 amended in hq). `merge-check.sh` added (fmt, vet, the gate by this change's controller, the suite). Verified: full suite green (-p 1, postgres+nats+docker+registry); race on the new code; the builder's check tests against a real runtime and registry (script beside the mesh's versions, nothing left, failing script fails, timeout is an error, no facts is an error); an end-to-end check of the catalogue and of this repository through `builder.Check` with real clones; the suite inside the Go toolchain image (25/25 packages). Found by the gate: mesh-controller's own module.json fails `module check` (seat verbs not listed in tools, ADR 0132) — pre-existing, so on the real snapshot it is a note, not a failure.
mesh-admin added 2 commits 2026-10-06 19:17:51 +00:00
Every check the mesh had was right about the world it was given and none was given
the mesh's: a real machine's name made an identity too long (263), the node-engine
refused what the catalogue check passed (236). The controller now composes what a
check needs - every machine under a pseudonym of its name's length, its roles,
system, builds, capabilities, assignments, pins, settings and how its declaration
composes; every seat, module and source; the bus, store and node-engine versions it
runs - with no secret, no address and no name, and keeps it in the artifact store
as facts:latest when it moved, or daily. The replaced snapshot's manifest is let go
of, so the nightly collector takes it. S14 raises facts-stale past two days.
Every check the mesh had ran after a merge, on a machine: a manifest the node-engine refused
(236), an identity a real machine's name made too long (263). merge-gate raises the mesh as the
facts snapshot says it is and the mesh with the change, each in a throwaway store through the
controller's own records, composes every machine twice and validates it with the node-engine's
validator, and fails what the change breaks, naming the machine's roles and the module - plus a
manifest the judging controller cannot read, a consumer left out of its grant, a module removed
while a machine runs it, a new module the node-engine would refuse; it warns on a wide rebuild.

The forge's new head of a pull request becomes a check the controller asks of the build seat:
the head and, beside it, the controller the mesh runs, the catalogue, the host and the lab; a
throwaway store and bus of the versions the mesh runs; the repository's merge-check.sh in the
mesh's Go toolchain with no container runtime socket; then mesh-lab's replays. The verdict is
said as checked, an error never a pass, and nothing is recorded or registered.
mesh-admin merged commit bbd442cdf4 into main 2026-10-06 19:19:35 +00:00
mesh-admin deleted branch feat/merge-gate 2026-10-06 19:19:35 +00:00
Author
Contributor

Delivery novox/mesh-controller@bbd442cdf498 — held since 2026-10-06T23:05:28Z

Held for a person: merged without a passing check: only a person decides that it goes on — mesh-delivery.release with why lets it go on.

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#96 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@bbd442cdf498` — **held** since 2026-10-06T23:05:28Z Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on. **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#96 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
This repo is archived. You cannot comment on pull requests.
No Reviewers
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#96