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.
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.
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.
Deliverynovox/mesh-controller@3d05d74400d1 — delivered since 2026-10-06T23:05:28Z
Groupfeat/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`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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.reachOfMergeis 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'sread.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 throughmodule 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 ownmerge-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.jsonnames every verb of the seat (ADR 0132), held by a test;merge-check.shis now the repository's own layer (gofmt, vet, suite under -race when the toolchain has gcc).Tested:
sh merge-check.shagainst 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.
Delivery
novox/mesh-controller@3d05d74400d1— delivered since 2026-10-06T23:05:28ZGroup
feat/the-graph-decides-what-is-checked, in order:Machines
Transitions
plans goThe commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.