The module graph decides what a pull request's check runs; one commit, one change plan; publish only the trunk (hq ADR 0238) #101

Merged
mesh-admin merged 5 commits from feat/the-graph-decides-what-is-checked into main 2026-10-06 21:00:26 +00:00
Contributor

Implements hq ADR 0238 (amends ADR 0237 decision 4; to-be 45 §9, Phase 5).

One mapping of changed files onto modules. touchedBy (upgrades.go) is now the only place a changed path is mapped to modules — touched, added (new module.json), and read by no build. reachOfMerge is the planner's whole answer (candidates, touched, deleted, packaging, the plan's dependency walk). The merge handler, plans --what-if, the merge gate's width and composition, and a pull request's check all ask it. Rule change (issue 280): a changed file touches exactly the modules whose build reads it — a root file (merge-check.sh, README) touches nothing; a repository a recipe packages is reached through the build record's read.

Graph-driven check, two layers. Every announced PR is mapped onto the graph: touching a module (or adding one) runs the gate (mesh/merge-gate: touched manifests through module check — only problems the change brings fail —, every machine composed with the definitions of the modules a merge would rebuild or add, the replays); a repository of the mesh runs its own merge-check.sh (mesh/repo-check; a warning when it has none). A PR touching nothing is answered at once, never left pending. The judge is chosen from the graph (controller judges itself; node-engine judged with its validator). A script declares its toolchain (# mesh-check-toolchain: go|typescript).

Trunk rule. The build seat reports which branches hold the built commit; the controller records and never registers a build whose commit is not on the branch the module follows (the default branch for a new module). Checks and dry runs are never registered.

Change plan. A PR's check carries its change plan (tiers, what each machine receives, bus step / waits-for-a-person / provider / data steps, one-line summary), posted by the forge holder.

Also: module.json names every verb of the seat (ADR 0132), held by a test; merge-check.sh is now the repository's own layer (gofmt, vet, suite under -race when the toolchain has gcc).

Tested: sh merge-check.sh against a throwaway PostgreSQL (all packages, -race) passes; the builder's live check tests (MESH_TEST_DOCKER=1 MESH_TEST_REGISTRY=…) pass against a local registry, including the gate layer with a stand-in judge.

Depends on: mesh-catalog (announcer fields, statuses), mesh-tools-go (gcc/python3 in the toolchain). Do not merge before review.

Implements hq ADR 0238 (amends ADR 0237 decision 4; to-be 45 §9, Phase 5). **One mapping of changed files onto modules.** `touchedBy` (upgrades.go) is now the only place a changed path is mapped to modules — touched, added (new module.json), and read by no build. `reachOfMerge` is the planner's whole answer (candidates, touched, deleted, packaging, the plan's dependency walk). The merge handler, `plans --what-if`, the merge gate's width and composition, and a pull request's check all ask it. Rule change (issue 280): **a changed file touches exactly the modules whose build reads it** — a root file (merge-check.sh, README) touches nothing; a repository a recipe packages is reached through the build record's `read`. **Graph-driven check, two layers.** Every announced PR is mapped onto the graph: touching a module (or adding one) runs the gate (`mesh/merge-gate`: touched manifests through `module check` — only problems the change brings fail —, every machine composed with the definitions of the modules a merge would rebuild or add, the replays); a repository of the mesh runs its own `merge-check.sh` (`mesh/repo-check`; a warning when it has none). A PR touching nothing is answered at once, never left pending. The judge is chosen from the graph (controller judges itself; node-engine judged with its validator). A script declares its toolchain (`# mesh-check-toolchain: go|typescript`). **Trunk rule.** The build seat reports which branches hold the built commit; the controller records and never registers a build whose commit is not on the branch the module follows (the default branch for a new module). Checks and dry runs are never registered. **Change plan.** A PR's check carries its change plan (tiers, what each machine receives, bus step / waits-for-a-person / provider / data steps, one-line summary), posted by the forge holder. Also: `module.json` names every verb of the seat (ADR 0132), held by a test; `merge-check.sh` is now the repository's own layer (gofmt, vet, suite under -race when the toolchain has gcc). Tested: `sh merge-check.sh` against a throwaway PostgreSQL (all packages, -race) passes; the builder's live check tests (`MESH_TEST_DOCKER=1 MESH_TEST_REGISTRY=…`) pass against a local registry, including the gate layer with a stand-in judge. Depends on: mesh-catalog (announcer fields, statuses), mesh-tools-go (gcc/python3 in the toolchain). Do not merge before review.
mesh-admin added 5 commits 2026-10-06 20:51:20 +00:00
Every pull request the forge announces is mapped onto the mesh's module graph by the
merge handler's rule (issue 278): touching a module — or adding one — runs the gate
(mesh/merge-gate), its judge chosen by the graph (the controller judges itself, the
node-engine by its validator); a repository of the mesh that touches none runs only its
own merge-check.sh (mesh/repo-check), a warning when it has none. Nothing is left pending:
a repository outside the mesh touching nothing is told so as a pass.

The gate moves out of the per-repository scripts into the build seat, so a script is the
repository's own tests and declares its toolchain (go or typescript). The controller's
manifest names every verb of its seat again (ADR 0132), held by a test.
de-spiegel's and link2pay's manifests already fail the module check on main; without
comparing against the base branch every pull request touching them would fail the gate
for a fault none of them made. The gate's own rule: what was already so is said.
The builder reads a module's own directory (the repository for one built from its root)
and a repository its recipe packages, nothing else. A file in no module's directory was
read as shared code and rebuilt everything built from the repository: 103 modules for a
merge-check.sh added at the catalogue's root. It now touches nothing, in the merge
handler, the release planner and the pull request's check alike, and the gate says so.
touchedBy is now the only mapping of changed files onto modules — touched, added, and
read by no build — and reachOfMerge the planner's whole answer with the dependency walk.
The merge handler, the plan what-if, the merge gate's width and composition, and a pull
request's check all ask it, so planning and gating cannot disagree. The gate composes
the definitions of the modules a merge would rebuild or add, not every one in the tree,
and the check says the dependents a merge would build after them.
Publish only a commit on its module's trunk; post a pull request's change plan (hq ADR 0238)
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/delivery delivered
mesh/delivery-group group feat/the-graph-decides-what-is-checked merged: every member is merged
3d05d74400
One commit, one plan: a commit off the trunk — a pull request's head, a branch built by
hand, a rebuild or replay of one — is for checking. The build seat reads from its clone
which branches hold the commit, and the controller records and never registers a build
whose commit is not on the branch the module follows (the repository's default for a
new one), so nothing off the trunk can be sent.

A pull request's check now carries its change plan, computed by the planner: what a
merge would build in which order, what each machine would receive, and what is not an
ordinary send — the bus step, a module waiting for a person, a provider's consumers.
mesh-admin merged commit ba26ba2772 into main 2026-10-06 21:00:26 +00:00
mesh-admin deleted branch feat/the-graph-decides-what-is-checked 2026-10-06 21:00:26 +00:00
Author
Contributor

Delivery novox/mesh-controller@3d05d74400d1 — delivered since 2026-10-06T23:05:28Z

Group feat/the-graph-decides-what-is-checked, in order:

Machines

  • mesh-controller on novox: passed — healthy 3 times over 3m18s
  • mesh-controller on the rest running it: sent
  • route-proxy on ace: passed — healthy 3 times over 2m9s
  • route-proxy on the rest running it: sent

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#101's head announced
  • 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
  • 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's plans go
  • 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says

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

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@3d05d74400d1` — **delivered** since 2026-10-06T23:05:28Z **Group** `feat/the-graph-decides-what-is-checked`, in order: **Machines** - mesh-controller on novox: passed — healthy 3 times over 3m18s - mesh-controller on the rest running it: sent - route-proxy on ace: passed — healthy 3 times over 2m9s - route-proxy on the rest running it: sent **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#101's head announced - 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 - 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's `plans go` - 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says 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#101